Skip to content

Data tensors in RDF

Unofficial Draft
Date: March 28, 2026

Editors:
 Nikita Kozlov (NeverBlink)
 Piotr Sowiński (NeverBlink)

Former editors:
 Piotr Marciniak (Warsaw University of Technology)


Abstract

This specification defines an approach to represent data tensors (multi-dimensional arrays) as literals in RDF. It introduces two new RDF datatypes – tensor:DataTensor and tensor:DataTensor, along with an extension of the SPARQL language. This extension includes 36 functions and 6 aggregates, enabling the efficient processing of tensor data within RDF frameworks.

See our paper for more information

Status of This Document

This document is a draft and does not represent an official standard. It is intended for discussion and gathering feedback within the community.

1. Introduction

1.1 Document Conventions

This section is non-normative.

Examples in this document assume that the following prefixes have been declared to represent the IRIs shown with them here:

Prefixes used:

Prefix Namespace
ex http://example.org/data-tensor#
tensor https://w3id.org/rdf-tensor/vocab#
xsd http://www.w3.org/2001/XMLSchema#

2. The tensor:DataTensor Datatype

IRI

https://w3id.org/rdf-tensor/vocab#DataTensor

Definition

Represents a multi-dimensional array (tensor) of numeric or boolean values.

Lexical Space

A valid JSON object [RFC-8259] with the following structure:

Key Type Description
type string Must be one of: float16, float32, float64, int16, int32, int64, bool, uint8, uint16, uint32, uint64. Defines the type of elements.
shape array of integers Specifies the size of each dimension. The product of the integers must equal the length of the data array.
data array of numbers or bools A flat array of numbers or booleans in row-major (C-style) order. Numbers must use decimal or exponential notation. Booleans are represented as true or false.

Other keys may be present in the JSON object, but they are ignored by the datatype.

Value Space

An n-dimensional numeric tensor, where n is the length of shape array.

Lexical-To-Value Mapping

The lexical representation is parsed as a JSON object. The shape key is used to determine the dimensions of the tensor, the data key contains the numeric values, the type key is used to efficiently choose the number of bytes for storing numbers and set precision. After parsing, the JSON object is converted into a tensor structure.

Example

"{\"type\": \"float32\", \"shape\": [3, 2], \"data\": [0.1, 1.2, 2.2, 3.2, 4.1, 5.4e2]}"^^tensor:DataTensor
"{\"type\": \"int32\", \"shape\": [1, 2, 2, 2], \"data\": [1, 3, 4, 12, 22, 32, 41, 5]}"^^tensor:DataTensor
"{\"type\": \"bool\", \"shape\": [2, 3], \"data\": [true, false, true, false, true, false]}"^^tensor:DataTensor

3. The tensor:Range Datatype

IRI

https://w3id.org/rdf-tensor/vocab#Range

Definition

Represents a range of numeric values, defined by a minimum (inclusive) and maximum (exclusive) value or a "full" range, which includes all possible numeric values.

Lexical Space

A valid JSON object [RFC-8259] with the following structure:

Key Type Description
type string Either full or concrete. If full, the range includes all possible numeric values. If concrete, the range is defined by the from and to keys.
from number The minimum value of the range. Required if type is concrete.
to number The maximum value of the range. Required if type is concrete.

Other keys may be present in the JSON object, but they are ignored by the datatype.

Value Space

An interval of numeric values, defined by the minimum (inclusive) and maximum (exclusive) values, or the full range of numeric values.

Lexical-To-Value Mapping

The lexical representation is parsed as a JSON object. The type key is used to determine if the range is full or concrete. If type is concrete, the from and to keys are used to define the range, where from is the minimum value (inclusive) and to is the maximum value (exclusive). After parsing, the JSON object is converted into a tensor structure.

Example

"{\"type\": \"full\"}"^^tensor:Range .
"{\"type\": \"concrete\", \"from\": 0, \"to\": 10}"^^tensor:Range .

4. SPARQL Functions

Each SPARQL function in this specification is defined as an ONNX model template. These templates contain model variables that depend on the actual input (i.e., the data type or shape of an input tensor, axis value). The model variables are denoted in the ONNX model definition using angle brackets, e.g., <input_type>, and are described in the "Model description" section for each function. Implementations are expected to resolve these variables at query evaluation time, generate a concrete ONNX model from the template, and execute it using an ONNX runtime.

With this approach it is ensured that the semantics of each function are precisely and unambiguously defined by a machine-readable model, while remaining portable across any ONNX-compatible execution environment.

Examples and description are provided for users to understand the expected behavior of each function, but the actual implementation must follow the ONNX model definition.

RDF tensor type to ONNX data type mapping

The mapping from RDF tensor types to ONNX data types is as follows:

RDF Tensor Type ONNX Data Type
float16 FLOAT16
float32 FLOAT
float64 DOUBLE
int16 INT16
int32 INT32
int64 INT64
bool BOOL
uint8 UINT8
uint16 UINT16
uint32 UINT32
uint64 UINT64

Any other types are not supported and will result in an error during query evaluation.

4.1. Transforming Functions

tensor:cos

tensor:DataTensor tensor:cos (tensor:DataTensor term_1)

The result of the function is a tensor of the same shape as the input tensor, where each element is replaced by its cosine value.

Example

Evaluating the SPARQL expression

tensor:cos("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [0, 3.1415]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, -1]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and DOUBLE type, where each element is the cosine of the corresponding element in input1.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_cos_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor cosine function"
graph {
    node {
        input: "input1"
        output: "cast_input"
        op_type: "Cast"
        attribute {
            name: "to"
            i: 11
            type: INT
        }
    }
    node {
        input: "cast_input"
        input: "pi_over_2"
        output: "shifted_input"
        op_type: "Add"
    }
    node {
        input: "shifted_input"
        output: "output1"
        op_type: "Sin"
    }
    initializer {
        dims: 1
        data_type: 11
        name: "pi_over_2"
        double_data: 1.5707963267948966
    }
    input {
        name: "input1"
        type {
            tensor_type {
                elem_type: <input_type>
            }
        }
    }
    output {
        name: "output1"
        type {
            tensor_type {
                elem_type: 11
            }
        }
    }
}
opset_import {
    version: 23
}

tensor:exp

tensor:DataTensor tensor:exp (tensor:DataTensor term_1)

The result of the function is a tensor of the same shape as the input tensor, where each element is replaced by its exponential value.

Example

Evaluating the SPARQL expression

tensor:exp("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [0, 1]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, 2.7183]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and DOUBLE type, where each element is the exponential of the corresponding element in input1.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_exp_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor exponential function"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "output1"
    op_type: "Exp"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:log

tensor:DataTensor tensor:log (tensor:DataTensor term_1)

The result of the function is a tensor of the same shape as the input tensor, where each element is replaced by its natural logarithm value.

Example

Evaluating the SPARQL expression

tensor:log("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, 2.7183]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [0, 1]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and DOUBLE type, where each element is the natural logarithm of the corresponding element in input1.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_log_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor natural logarithm function"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "output1"
    op_type: "Log"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:logp

tensor:DataTensor tensor:logp (xsd:double p, tensor:DataTensor term_1)

The result is a tensor of the same shape, where each element is replaced by its logarithm with base p.

Example

Evaluating the SPARQL expression

tensor:logp(10, "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, 10]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [0, 1]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and DOUBLE type, where each element is the logarithm with base p of the corresponding element in input1.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • log_base_value: The logarithm base log(p), where p is the value of the first argument of the function.
tensor_logp_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor p-base logarithm function"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "log_input"
    op_type: "Log"
  }
  node {
    input: "log_input"
    input: "log_base"
    output: "output1"
    op_type: "Div"
  }
  initializer {
    data_type: 11
    name: "log_base"
    double_data: <log_base_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:poly

tensor:DataTensor tensor:poly (xsd:double n, tensor:DataTensor term_1)

The result is a tensor where each element is raised to the power n.

Example

Evaluating the SPARQL expression

tensor:poly(2, "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [2, 3]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [4, 9]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and DOUBLE type, where each element is the corresponding element in input1 raised to the power n.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • exponent_value: The exponent value n of type DOUBLE, which is the value of the first argument of the function.
tensor_poly_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor power function"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "exponent"
    output: "output1"
    op_type: "Pow"
  }
  initializer {
    data_type: 11
    name: "exponent"
    double_data: <exponent_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:scale

tensor:DataTensor tensor:scale (xsd:double factor, tensor:DataTensor term_1)

The result is a tensor of the same shape, where each element is multiplied by the given scalar factor.

Example

Evaluating the SPARQL expression

tensor:scale(3, "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [2, 3]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [6, 9]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and DOUBLE type, where each element is the corresponding element in input1 multiplied by the scalar factor.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • factor_value: The scaling factor of type DOUBLE, which is the value of the first argument of the function.
tensor_scale_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor scaling function"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "factor"
    output: "output1"
    op_type: "Mul"
  }
  initializer {
    data_type: 11
    name: "factor"
    double_data: <factor_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:sin

tensor:DataTensor tensor:sin (tensor:DataTensor term_1)

The result of the function is a tensor of the same shape as the input tensor, where each element is replaced by its sine value.

Example

Evaluating the SPARQL expression

tensor:sin("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [0, 3.1415]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [0, 0]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and DOUBLE type, where each element is the sine of the corresponding element in input1.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_sin_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor sine function"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "output1"
    op_type: "Sin"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:abs

tensor:DataTensor tensor:abs (tensor:DataTensor term_1)

The result of the function is a tensor of the same shape as the input tensor, where each element is replaced by its absolute value.

Example

Evaluating the SPARQL expression

tensor:abs("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [-1, 2]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, 2]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and type, where each element is the absolute value of the corresponding element in input1.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_abs_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor absolute value function"
graph {
  node {
    input: "input1"
    output: "output1"
    op_type: "Abs"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:cast

tensor:DataTensor tensor:cast (xsd:string type, tensor:DataTensor term_1)

The result of the function is a tensor of the same shape as the input tensor, where each element is cast to the specified type. The supported types are: float16, float32, float64, int16, int32, int64 and bool. Bool type is special - all non-zero values are cast to true, and zero values are cast to false. If a bool DataTensor is cast to a numeric type, true values become 1, and false values become 0.

Example 1

Evaluating the SPARQL expression

tensor:cast("int32", "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1.5, 2.5]}"^^tensor:DataTensor)

returns

"{\"type\": \"int32\", \"shape\": [1, 2], \"data\": [1, 2]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:cast("bool", "{\"type\": \"int32\", \"shape\": [1, 2], \"data\": [0, 5]}"^^tensor:DataTensor)

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [false, true]}"^^tensor:DataTensor

Example 3

Evaluating the SPARQL expression

tensor:cast("float32", "{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1.0, 0.0]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and type, where each element is the corresponding element in input1 cast to the specified type.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • output_type: The data type to which the elements of the input tensor will be cast, determined by the value of the first argument of the function.
tensor_cast_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor cast function"
graph {
  node {
    input: "input1"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <output_type>
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <output_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:reshape

tensor:DataTensor tensor:reshape (xsd:integer ... newShape, tensor:DataTensor term_1)

The result of the function is a tensor with the specified new shape. The total number of elements will remain the same; thus, the product of the dimensions in the new shape must equal the product of the dimensions in the original shape.

If one of the dimensions in the new shape is specified as -1, its size will be inferred such that the total number of elements remains unchanged.

Example 1

Evaluating the SPARQL expression

tensor:reshape(2, 2, "{\"type\":\"int32\",\"shape\":[4],\"data\":[1, 2, 3, 4]}"^^tensor:DataTensor)

returns

"{\"type\": \"int32\", \"shape\": [2, 2], \"data\": [1, 2, 3, 4]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:reshape(1, 4, "{\"type\":\"bool\",\"shape\":[4],\"data\":[true, false, true, false]}"^^tensor:DataTensor)

returns

"{\"type\": \"bool\", \"shape\": [1, 4], \"data\": [true, false, true, false]}"^^tensor:DataTensor

Example 3

Evaluating the SPARQL expression

tensor:reshape(2, -1, "{\"type\":\"int32\",\"shape\":[6],\"data\":[1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor)

returns

"{\"type\": \"int32\", \"shape\": [2, 3], \"data\": [1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the new shape specified by the first argument and the same type, containing the same data as input1 but reshaped.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • new_shape_length: The number of dimensions in the new shape, determined by the number of integer arguments before the tensor argument.
  • new_shape_values: The values of the new shape dimensions, determined by the integer arguments before the tensor argument.
tensor_reshape_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor reshape function"
graph {
  node {
    input: "input1"
    input: "shape"
    output: "output1"
    op_type: "Reshape"
  }
  initializer {
    dims: <new_shape_length>
    data_type: 7
    int64_data: <new_shape_values[0]>
    int64_data: <new_shape_values[1]>
    int64_data: <new_shape_values[2]>
    ...
    int64_data: <new_shape_values[new_shape_length-1]>
    name: "shape"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:transpose

tensor:DataTensor tensor:transpose (tensor:DataTensor term_1)

The result of the function is a tensor where the dimensions are reversed. For example, a tensor with shape [2, 3, 4] will become a tensor with shape [4, 3, 2].

Example 1

Evaluating the SPARQL expression

tensor:transpose("{\"type\":\"int32\",\"shape\":[2, 3],\"data\":[1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor)

returns

"{\"type\": \"int32\", \"shape\": [3, 2], \"data\": [1, 4, 2, 5, 3, 6]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:transpose("{\"type\": \"bool\", \"shape\":[2, 2],\"data\":[true, false, false, true]}"^^tensor:DataTensor)

returns

"{\"type\": \"bool\", \"shape\": [2, 2], \"data\": [true, false, false, true]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor where the dimensions are reversed compared to input1, and the data is transposed accordingly.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_transpose_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor transpose function"
graph {
  node {
    input: "input1"
    output: "output1"
    op_type: "Transpose"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:flatten

tensor:DataTensor tensor:flatten (tensor:DataTensor term_1)

The result of the function is a one-dimensional tensor containing all the elements of the input tensor in row-major (C-style) order.

Example 1

Evaluating the SPARQL expression

tensor:flatten("{\"type\":\"int32\",\"shape\":[2, 3],\"data\":[1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor)

returns

"{\"type\": \"int32\", \"shape\": [6], \"data\": [1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:flatten("{\"type\": \"bool\", \"shape\":[2, 2],\"data\":[true, false, false, true]}"^^tensor:DataTensor)

returns

"{\"type\": \"bool\", \"shape\": [4], \"data\": [true, false, false, true]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A one-dimensional tensor containing all the elements of input1 in row-major order, with the same type.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_flatten_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor flatten function"
graph {
  node {
    input: "input1"
    input: "shape"
    output: "output1"
    op_type: "Reshape"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: -1
    name: "shape"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:not

tensor:DataTensor tensor:not (tensor:DataTensor term_1)

The result of the function is a tensor of the same shape as the input tensor, where each element is logically negated. For numeric tensors, non-zero values are treated as true, and zero and negative values as false.

Example 1

Evaluating the SPARQL expression

tensor:not("{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}"^^tensor:DataTensor)

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [false, true]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:not("{\"type\": \"int32\", \"shape\": [1, 2], \"data\": [0, 5]}"^^tensor:DataTensor)

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and BOOL type, where each element is the logical negation of the corresponding element in input1.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_not_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor not function"
graph {
  node {
    input: "input1"
    output: "output1"
    op_type: "Not"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:sort

tensor:DataTensor tensor:sort (xsd:string direction, xsd:integer axis, tensor:DataTensor term_1)

The result of the function is a tensor of the same shape as the input tensor, where the elements are sorted along the specified axis in the given direction. The direction argument can be either asc for ascending order or desc for descending order. The axis argument specifies the axis along which to sort, where 0 is the first axis, 1 is the second axis, and so on, and negative values count from the last axis backwards (e.g., -1 is the last axis).

Example 1

Evaluating the SPARQL expression

tensor:sort("asc", 0, "{\"type\": \"int32\", \"shape\": [2, 3], \"data\": [2, 3, 1, 5, 6, 4]}"^^tensor:DataTensor)

returns

"{\"type\": \"int32\", \"shape\": [2, 3], \"data\": [3, 2, 1, 6, 5, 4]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:sort("asc", 2, "{\"type\": \"float64\", \"shape\": [2, 2, 3], \"data\": [3, 1, 2, 6, 4, 5, 9, 7, 8, 12, 10, 11]}"^^tensor:DataTensor)

returns

"{\"type\": \"float64\", \"shape\": [2, 2, 3], \"data\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same shape as input1 and the same type, where the elements are sorted along the specified axis in the given direction.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • largest_value: 1 if the sorting direction is desc, and 0 if the sorting direction is asc.
  • axis_value: The value of the axis argument, which specifies the axis along which to sort.
  • axis_size_value: The size of the specified axis, which can be determined from the shape of the input tensor.

Model definition dispatch:

  • For int16 tensors, the implementation is expected to use a different model definition that handles the ONNX limitation of not supporting int16 reduction operations.
tensor_sort_int16_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor sorting function for int16 tensors"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "k_tensor"
    output: "values"
    output: "indices"
    op_type: "TopK"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
    attribute {
      name: "largest"
      i: <largest_value>
      type: INT
    }
    attribute {
      name: "sorted"
      i: 1
      type: INT
    }
  }
  node {
    input: "values"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_size_value>
    name: "k_tensor"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_sort_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor sorting function"
graph {
  node {
    input: "input1"
    input: "k_tensor"
    output: "output1"
    output: "indices"
    op_type: "TopK"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
    attribute {
      name: "largest"
      i: <largest_value>
      type: INT
    }
    attribute {
      name: "sorted"
      i: 1
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_size_value>
    name: "k_tensor"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

4.2 Operators

When using the binary operators, the input tensors are broadcasted to a common shape. The broadcasting rules are the same as in ONNX Broadcasting. After broadcasting, the binary operator is applied element-wise to the input tensors.

Casting of input tensors to a common type is performed according to the rules defined in the ONNX model for each operator, which are based on the precision hierarchy of data types. The resulting tensor will have the more precise type of the two input tensors.

Type casting rules for binary operators

When applying a binary operator to two tensors of different types, the resulting tensor will have the more precise type of the two input tensors. The precision hierarchy is as follows:

  • float64 > float32 > float16
  • uint64 >= int64 > uint32 >= int32 > uint16 >= int16 > uint8 >= int8
  • bool is considered less precise than any numeric type.

For example, if one tensor is of type float32 and the other is of type int32, the resulting tensor will be of type float32. If one tensor is of type bool and the other is of type int16, the resulting tensor will be of type int16.

In general, follow this algorithm for determining the resulting type:

  1. If both tensors have the same type, the result is of that type.
  2. If both tensors are floating-point types, the result is the type with greater precision.
  3. If both tensors are integer types of the same signedness, the result is the type with greater precision.
  4. If both tensors are integer types but one is signed and the other is unsigned, the result is the unsigned type with greater precision.
  5. If one tensor is a floating-point type and the other is an integer type, the result is the floating-point type with greater precision.
  6. If one tensor is of type bool, the result is the other tensor's type.
Optimizing casts for binary operators with identical input types

If the input tensors of a binary operator have identical types, it is allowed to skip the type casting step (usually first two Cast nodes in the ONNX model definition) and directly apply the operator to the input tensors. This optimization can improve performance by avoiding unnecessary type conversions. However, it is crucial to ensure that the semantics of the function remain unchanged, and the result is the same as if the casts were applied.

Implementations may verify that the input tensors have the same type before applying this optimization. If the types are different, the implementation must follow the type casting rules as defined in the ONNX model to ensure correct results.

tensor:add

tensor:DataTensor tensor:add (tensor:DataTensor term_1, tensor:DataTensor term_2)

The result of the function is a tensor of broadcasted shape, where each element is the sum of corresponding elements in the input tensors.

Example 1

Evaluating the SPARQL expression

tensor:add("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, 2]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [3, 4]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [4, 6]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:add("{\"type\":\"float32\",\"shape\":[1, 2, 2], \"data\":[3, 2, 3, 4]}"^^tensor:DataTensor, "{\"type\":\"int32\",\"shape\":[1],\"data\":[1, 2]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2, 2], \"data\": [4, 4, 4, 6]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A tensor of the broadcasted shape and the more precise type of the two input tensors, where each element is the sum of corresponding elements in input1 and input2.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • resolved_type: The data type of the output tensor, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details)
tensor_add_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor addition function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "Add"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <resolved_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:subtract

tensor:DataTensor tensor:subtract (tensor:DataTensor term_1, tensor:DataTensor term_2)

The result of the function is a tensor of broadcasted shape, where each element is the difference between corresponding elements in the input tensors.

Example 1

Evaluating the SPARQL expression

tensor:subtract("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [5, 7]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [2, 3]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [3, 4]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:subtract("{\"type\":\"float32\",\"shape\":[2, 2], \"data\":[3, 2, 3, 4]}"^^tensor:DataTensor, "{\"type\":\"int32\",\"shape\":[2],\"data\":[2, 1]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [1, 1, 1, 3]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A tensor of the broadcasted shape and the more precise type of the two input tensors, where each element is the difference between corresponding elements in input1 and input2.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • resolved_type: The data type of the output tensor, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details)
tensor_subtract_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor subtraction function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "Sub"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <resolved_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:multiply

tensor:DataTensor tensor:multiply (tensor:DataTensor term_1, tensor:DataTensor term_2)

The result of the function is a tensor of broadcasted shape, where each element is the product of corresponding elements in the input tensors.

Example 1

Evaluating the SPARQL expression

tensor:multiply("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [2, 3]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [4, 5]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [8, 15]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:multiply("{\"type\":\"int32\",\"shape\":[2, 2], \"data\":[3, 2, 3, 4]}"^^tensor:DataTensor, "{\"type\":\"int32\",\"shape\":[2],\"data\":[2, 1]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [6, 2, 6, 4]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A tensor of the broadcasted shape and the more precise type of the two input tensors, where each element is the product of corresponding elements in input1 and input2.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • resolved_type: The data type of the output tensor, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details)
tensor_multiply_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor multiplication function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "Mul"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <resolved_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:divide

tensor:DataTensor tensor:divide (tensor:DataTensor term_1, tensor:DataTensor term_2)

The result of the function is a tensor of broadcasted shape, where each element is the quotient of corresponding elements in the input tensors.

Example 1

Evaluating the SPARQL expression

tensor:divide("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [8, 9]}", "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [2, 3]}")

returns

"{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [4, 3]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:divide("{\"type\":\"int32\",\"shape\":[2, 2], \"data\":[3, 2, 3, 4]}"^^tensor:DataTensor, "{\"type\":\"int32\",\"shape\":[2],\"data\":[2, 1]}"^^tensor:DataTensor)

returns

"{\"type\": \"int32\", \"shape\": [2, 2], \"data\": [1, 2, 1, 2]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A tensor of the broadcasted shape and the more precise type of the two input tensors, where each element is the quotient of corresponding elements in input1 and input2.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • resolved_type: The data type of the output tensor, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details)

tensor:eq

tensor:DataTensor tensor:eq (tensor:DataTensor term_1, tensor:DataTensor term_2)

The function returns a boolean tensor with a broadcasted shape, where each element is true if the corresponding elements in the two tensors are equal, and false otherwise.

Example 1

Evaluating the SPARQL expression

tensor:eq("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, 2]}", "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, 3]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:eq("\"shape\": [1, 2], \"data\": [true, false]}", "{\"type\": \"bool\", \"shape\": [1], \"data\": [true]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A boolean tensor of the broadcasted shape, where each element is true if the corresponding elements in input1 and input2 are equal, and false otherwise.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • resolved_type: The data type of the resolved input tensors, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details).
tensor_eq_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor equality function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "Equal"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:neq

tensor:DataTensor tensor:neq (tensor:DataTensor term_1, tensor:DataTensor term_2)

tensor:DataTensor tensor:neq (tensor:DataTensor term_1, tensor:DataTensor term_2)

The function returns a boolean tensor with a broadcasted shape, where each element is true if the corresponding elements in the two tensors are not equal, and false otherwise.

Example 1

Evaluating the SPARQL expression

tensor:neq("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, 2]}", "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [1, 3]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [false, true]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:neq("{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}", "{\"type\": \"bool\", \"shape\": [1], \"data\": [true]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [false, true]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A boolean tensor of the broadcasted shape, where each element is true if the corresponding elements in input1 and input2 are not equal, and false otherwise.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • resolved_type: The data type of the resolved input tensors, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details).
tensor_neq_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor inequality function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "equal_output"
    op_type: "Equal"
  }
  node {
    input: "equal_output"
    output: "output1"
    op_type: "Not"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:and

tensor:DataTensor tensor:and (tensor:DataTensor term_1, tensor:DataTensor term_2)

The function returns a boolean tensor with a broadcasted shape, where each element is the logical AND of the input tensors.

Example

Evaluating the SPARQL expression

tensor:and("{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}", "{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, true]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:and("{\"type\": \"int32\", \"shape\": [1, 2], \"data\": [0, 5]}", "{\"type\": \"int32\", \"shape\": [1, 2], \"data\": [2, 0]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [false, false]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A boolean tensor of the broadcasted shape, where each element is the logical AND of the corresponding elements in input1 and input2.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
tensor_and_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor and function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 9
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 9
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "And"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:or

tensor:DataTensor tensor:or (tensor:DataTensor term_1, tensor:DataTensor term_2)

The function returns a boolean tensor with a broadcasted shape, where each element is the logical OR of the input tensors.

Example

Evaluating the SPARQL expression

tensor:or("{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}", "{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [false, true]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, true]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:or("{\"type\": \"int32\", \"shape\": [1, 2], \"data\": [0, 5]}", "{\"type\": \"int32\", \"shape\": [1, 2], \"data\": [2, 0]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, true]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A boolean tensor of the broadcasted shape, where each element is the logical OR of the corresponding elements in input1 and input2.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
tensor_or_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor or function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 9
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 9
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "Or"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:gt

tensor:DataTensor tensor:gt (tensor:DataTensor term_1, tensor:DataTensor term_2)

The function returns a boolean tensor with a broadcasted shape, where each element is true if the corresponding element from term_1 is greater than the corresponding element from term_2, and false otherwise.

Example

Evaluating the SPARQL expression

tensor:gt("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [4, 2]}", "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [3, 3]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [true, false]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A boolean tensor of the broadcasted shape, where each element is true if the corresponding element in input1 is greater than the corresponding element in input2, and false otherwise.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • resolved_type: The data type of the resolved input tensors, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details).
tensor_gt_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor greater than function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "Greater"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:lt

tensor:DataTensor tensor:lt (tensor:DataTensor term_1, tensor:DataTensor term_2)

The function returns a boolean tensor with a broadcasted shape, where each element is true if the corresponding element from term_1 is lesser than the corresponding element from term_2, and false otherwise.

Example

Evaluating the SPARQL expression

tensor:lt("{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [4, 2]}", "{\"type\": \"float32\", \"shape\": [1, 2], \"data\": [3, 3]}")

returns

"{\"type\": \"bool\", \"shape\": [1, 2], \"data\": [false, true]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of any shape and type, which can be broadcasted to the shape of input1.
  • output1: A boolean tensor of the broadcasted shape, where each element is true if the corresponding element in input1 is lesser than the corresponding element in input2, and false otherwise.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • resolved_type: The data type of the resolved input tensors, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details).
tensor_lt_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor less than function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <input2_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "Less"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
}
opset_import {
  version: 23
}

4.3. Indexing Functions

tensor:sub

tensor:DataTensor tensor:sub (tensor:Range range1, ..., tensor:DataTensor tensor)

Extracts a sub-tensor from the input tensor using range-based slicing, similar to NumPy array slicing. Each range argument specifies how to slice along the corresponding dimension of the tensor. The number of range arguments must match the number of dimensions in the input tensor.

Example

Evaluating the SPARQL expression (equivalent to NumPy tensor[1:3])

tensor:sub(
    tensor:range(1, 3),
    "{\"type\":\"int32\",\"shape\":[5],\"data\":[10, 20, 30, 40, 50]}"^^tensor:DataTensor
)

returns

"{\"type\": \"int32\", \"shape\": [2], \"data\": [20, 30]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression (equivalent to NumPy tensor[:, 1:2])

tensor:sub(
    tensor:range(),
    tensor:range(1, 2),
    "{\"type\":\"int32\",\"shape\":[2, 3],\"data\":[1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor
)

returns

"{\"type\": \"int32\", \"shape\": [2, 1], \"data\": [2, 5]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression (equivalent to NumPy tensor[:, 0:1, 1:2])

tensor:sub(
    tensor:range(),
    tensor:range(0, 1),
    tensor:range(1, 2),
    "{\"type\":\"int32\",\"shape\":[2, 2, 2],\"data\":[1, 2, 3, 4, 5, 6, 7, 8]}"^^tensor:DataTensor
)

returns

"{\"type\": \"int32\", \"shape\": [2, 1, 1], \"data\": [2, 6]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression (equivalent to NumPy tensor[1:2, :])

tensor:sub(
    tensor:range(1, 2),
    tensor:range(),
    "{\"type\":\"int32\",\"shape\":[3, 2],\"data\":[1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor
)

returns

"{\"type\": \"int32\", \"shape\": [1, 2], \"data\": [3, 4]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of the same type as input1, where the shape is determined by the specified ranges along each dimension.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axes_length: The number of dimensions in the input tensor, which must match the number of range arguments.
  • axes_values, starts_values, ends_values: The values of the range arguments, which determine how to slice along each dimension. For each dimension, the range is deconstructed into its corresponding axis, start, and end values. For full slices, the start is set to 0 and the end is set to the size of the dimension.
tensor_sub_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor slice function"
graph {
  node {
    input: "input1"
    input: "starts"
    input: "ends"
    input: "axes"
    output: "output1"
    op_type: "Slice"
  }
  initializer {
    dims: <axes_length>
    data_type: 7
    int64_data: <starts_values[0]>
    int64_data: <starts_values[1]>
    ...
    int64_data: <starts_values[starts_length-1]>
    name: "starts"
  }
  initializer {
    dims: <axes_length>
    data_type: 7
    int64_data: <ends_values[0]>
    int64_data: <ends_values[1]>
    ...
    int64_data: <ends_values[ends_length-1]>
    name: "ends"
  }
  initializer {
    dims: <axes_length>
    data_type: 7
    int64_data: <axes_values[0]>
    int64_data: <axes_values[1]>
    ...
    int64_data: <axes_values[axes_length-1]>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:mask

tensor:DataTensor tensor:mask (tensor:DataTensor tensor, tensor:DataTensor maskTensor)

Extracts elements from the input tensor using a boolean mask tensor. The mask tensor must have the same shape as the input tensor or be broadcastable to it.

The function selects elements from the input tensor where the corresponding value in the mask tensor is true. The result is always a 1-dimensional tensor containing the selected elements in row-major (C-style) order.

Example

Evaluating the SPARQL expression

tensor:mask(
    "{\"type\":\"int32\",\"shape\":[2, 2],\"data\":[3, 2, 3, 4]}"^^tensor:DataTensor,
    "{\"shape\":[2, 2],\"data\":[true, false, true, true]}"^^tensor:DataTensor
)

returns

"{\"type\": \"int32\", \"shape\": [3], \"data\": [3, 3, 4]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A boolean tensor of the same shape as input1 or broadcastable to it, where true values indicate which elements to select from input1.
  • output1: A 1-dimensional tensor containing the selected elements from input1 in row-major (C-style) order.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • mask_length: The count of true values in the mask tensor, which determines the length of the output tensor.
tensor_mask_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor mask function"
graph {
  node {
    input: "input1"
    input: "input2"
    output: "output1"
    op_type: "Compress"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
        shape {
          dim {
            dim_value: <mask_length>
          }
        }
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:index

tensor:DataTensor tensor:index (tensor:DataTensor tensor, tensor:DataTensor indexTensor)

Extracts an element or sub-tensor from the input tensor using a numerical index tensor. The behavior depends on the structure of the index tensor.

Behavior:

  • When the index tensor size matches the number of dimensions in the input tensor, each element corresponds to an index for each dimension. The result is a scalar value at that index.
  • When the index tensor size is less than the number of dimensions in the input tensor, each element corresponds to an index for the first N dimensions. The result is a sub-tensor with the remaining dimensions.
  • When the index tensor size is greater than the number of dimensions in the input tensor, an error is raised.

Example

Evaluating the SPARQL expression

tensor:index(
    "{\"type\":\"int32\",\"shape\":[2, 2],\"data\":[3, 2, 3, 4]}"^^tensor:DataTensor,
    "{\"type\":\"int32\",\"shape\":[2],\"data\":[1, 0]}"^^tensor:DataTensor
)

returns

"3"^^xsd:int

Example

Evaluating the SPARQL expression

tensor:index(
    "{\"type\":\"int32\",\"shape\":[2, 2, 2],\"data\":[1, 2, 3, 4, 5, 6, 7, 8]}"^^tensor:DataTensor,
    "{\"type\":\"int32\",\"shape\":[1],\"data\":[1]}"^^tensor:DataTensor
)

returns

"{\"type\": \"int32\", \"shape\": [2, 2], \"data\": [5, 6, 7, 8]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: An integer tensor where each element is an index for the corresponding dimension of input1. The shape of input2 must be 1D and its size must be less than or equal to the number of dimensions in input1.
  • output1: A scalar value if the size of input2 matches the number of dimensions in input1, or a sub-tensor containing the remaining dimensions if the size of input2 is less than the number of dimensions in input1.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_index_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor index function"
graph {
  node {
    input: "input2"
    input: "unsqueeze_axes"
    output: "index_reshaped"
    op_type: "Unsqueeze"
  }
  node {
    input: "input1"
    input: "index_reshaped"
    output: "gathered"
    op_type: "GatherND"
    attribute {
      name: "batch_dims"
      i: 0
      type: INT
    }
  }
  node {
    input: "gathered"
    output: "output1"
    op_type: "Squeeze"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: 0
    name: "unsqueeze_axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: 7
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

4.4 Concatenating Functions

For concatenation functions, the input tensors must have compatible shapes according to the rules of broadcasting. The output tensor's shape is determined by the shapes of the input tensors and the specified axis of concatenation.

The rules of type resolution and precision hierarchy apply to these functions as well, meaning that the output tensor's data type is determined by the input tensors' data types according to the defined hierarchy.

See both at the Operators section above.

tensor:concat

tensor:DataTensor tensor:concat (xsd:integer axis, tensor:DataTensor term_1, tensor:DataTensor term_2, tensor:DataTensor term_3, ...)

This function returns a tensor that is the concatenation of the input tensors along the specified axis. The other dimensions must match.

Example

Evaluating the SPARQL expression

tensor:concat(0, "{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [1, 2, 3, 4]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [5, 6, 7, 8]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [4, 2], \"data\": [1, 2, 3, 4, 5, 6, 7, 8]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:concat(1, "{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [1, 2, 3, 4]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [5, 6, 7, 8]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [9, 10, 11, 12]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2, 6], \"data\": [1, 2, 5, 6, 9, 10, 3, 4, 7, 8, 11, 12]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor that can be concatenated with input1 along the specified axis, and has type.
  • input3, ..., inputN: Additional tensors that can be concatenated with input1 and input2 along the specified axis, and have compatible types.
  • output1: A tensor of type, where the shape is determined by concatenating the shapes of input1 and input2 along the specified axis.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • input3_type, ..., inputN_type: The data types of additional input tensors, which can be any supported type.
  • resolved_type: The data type of the output tensor, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details) (for more than 2 input tensors, the resolution is applied iteratively across all input types).
  • axis_value: The axis along which to concatenate the input tensors, which can be any integer value from -rank to rank-1, where rank is the number of dimensions in the input tensors.
tensor_concat_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor concat function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input3"
    output: "cast_input3"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  ...
  node {
    input: "inputN"
    output: "cast_inputN"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    input: "cast_input3"
    ...
    input: "cast_inputN"
    output: "output1"
    op_type: "Concat"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  input {
    name: "input3"
    type {
      tensor_type {
        elem_type: <input3_type>
      }
    }
  }
  ...
  input {
    name: "inputN"
    type {
      tensor_type {
        elem_type: <inputN_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <resolved_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:hstack

tensor:DataTensor tensor:hstack (tensor:DataTensor term_1, tensor:DataTensor term_2, tensor:DataTensor term_3, ...)

This function returns a tensor that is the result of horizontally stacking the input tensors (i.e., concatenation along the last axis). The tensors must be broadcast-compatible along other dimensions.

Example

Evaluating the SPARQL expression

tensor:hstack("{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [1, 2, 3, 4]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [5, 6, 7, 8]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2, 4], \"data\": [1, 2, 5, 6, 3, 4, 7, 8]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:hstack("{\"type\": \"float32\", \"shape\": [2], \"data\": [1, 2]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2], \"data\": [3, 4],}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2], \"data\": [5, 6],}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2], \"data\": [7, 8],}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2, 8], \"data\": [1, 2, 3, 4, 5, 6, 7, 8]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor that can be concatenated with input1 along the last axis, and has type.
  • input3, ..., inputN: Additional tensors that can be concatenated with input1 and input2 along the last axis, and have compatible types.
  • output1: A tensor of type, where the shape is determined by concatenating the shapes of input1 and input2 along the last axis.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • input3_type, ..., inputN_type: The data types of additional input tensors, which can be any supported type.
  • resolved_type: The data type of the output tensor, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details) (for more than 2 input tensors, the resolution is applied iteratively across all input types).
  • axis_value: The last axis along which to concatenate the input tensors, which is determined by the rank of the input tensors. For 1D tensors, the axis is 0; for higher-dimensional tensors, the axis is the last one (i.e., rank-1).
tensor_hstack_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor hstack function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input3"
    output: "cast_input3"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  ...
  node {
    input: "inputN"
    output: "cast_inputN"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    input: "cast_input3"
    ...
    input: "cast_inputN"
    output: "output1"
    op_type: "Concat"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  input {
    name: "input3"
    type {
      tensor_type {
        elem_type: <input3_type>
      }
    }
  }
  ...
  input {
    name: "inputN"
    type {
      tensor_type {
        elem_type: <inputN_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <resolved_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:vstack

tensor:DataTensor tensor:vstack (tensor:DataTensor term_1, tensor:DataTensor term_2, tensor:DataTensor term_3, ...)

This function returns a tensor that is the result of vertically stacking the input tensors (i.e., concatenation along the first axis). The tensors must be broadcast-compatible along other dimensions.

Example

Evaluating the SPARQL expression

tensor:vstack("{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [1, 2, 3, 4]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2, 2], \"data\": [5, 6, 7, 8]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [4, 2], \"data\": [1, 2, 3, 4, 5, 6, 7, 8]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:vstack("{\"type\": \"float32\", \"shape\": [2], \"data\": [1, 2]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2], \"data\": [3, 4],}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2], \"data\": [5, 6],}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2], \"data\": [7, 8],}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [8], \"data\": [1, 2, 3, 4, 5, 6, 7, 8]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor that can be concatenated with input1 along the first axis, and has type.
  • input3, ..., inputN: Additional tensors that can be concatenated with input1 and input2 along the first axis, and have compatible types.
  • output1: A tensor of type, where the shape is determined by concatenating the shapes of input1 and input2 along the first axis.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
  • input3_type, ..., inputN_type: The data types of additional input tensors, which can be any supported type.
  • resolved_type: The data type of the output tensor, determined by the resolution of the input types according to the precision hierarchy. (see the info box above for more details) (for more than 2 input tensors, the resolution is applied iteratively across all input types).

Definition dispatch:

  • If the input tensors are 1D, then the implementation is expected to use model definition for 1D tensors.
  • If the input tensors are ND (N > 1), then the implementation is expected to use model definition for ND tensors.
tensor_vstack_1d_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor vstack function for 1D tensors"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input3"
    output: "cast_input3"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  ...
  node {
    input: "inputN"
    output: "cast_inputN"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "unsqueeze_axes"
    output: "unsqueezed_input1"
    op_type: "Unsqueeze"
  }
  node {
    input: "cast_input2"
    input: "unsqueeze_axes"
    output: "unsqueezed_input2"
    op_type: "Unsqueeze"
  }
  node {
    input: "cast_input3"
    input: "unsqueeze_axes"
    output: "unsqueezed_input3"
    op_type: "Unsqueeze"
  }
  ...
  node {
    input: "cast_inputN"
    input: "unsqueeze_axes"
    output: "unsqueezed_inputN"
    op_type: "Unsqueeze"
  }
  node {
    input: "unsqueezed_input1"
    input: "unsqueezed_input2"
    input: "unsqueezed_input3"
    ...
    input: "unsqueezed_inputN"
    output: "output1"
    op_type: "Concat"
    attribute {
      name: "axis"
      i: 0
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: 0
    name: "unsqueeze_axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  input {
    name: "input3"
    type {
      tensor_type {
        elem_type: <input3_type>
      }
    }
  }
  ...
  input {
    name: "inputN"
    type {
      tensor_type {
        elem_type: <inputN_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <resolved_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_vstack_nd_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor vstack function for ND tensors"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input3"
    output: "cast_input3"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  ...
  node {
    input: "inputN"
    output: "cast_inputN"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    input: "cast_input3"
    ...
    input: "cast_inputN"
    output: "output1"
    op_type: "Concat"
    attribute {
      name: "axis"
      i: 0
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  input {
    name: "input3"
    type {
      tensor_type {
        elem_type: <input3_type>
      }
    }
  }
  ...
  input {
    name: "inputN"
    type {
      tensor_type {
        elem_type: <inputN_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <resolved_type>
      }
    }
  }
}
opset_import {
  version: 23
}

4.5. Reduction Functions

tensor:all

xsd:boolean tensor:all (tensor:DataTensor term_1)

This function checks if all elements in the boolean tensor are true. In case of numeric tensor, it checks if all elements are non-zero. Returns a single boolean value.

Example 1

Evaluating the SPARQL expression

tensor:all("{\"type\": \"bool\", \"shape\": [2], \"data\": [true, true]}"^^tensor:DataTensor)

returns

"true"^^xsd:boolean

Example 2

Evaluating the SPARQL expression

tensor:all("{\"type\": \"bool\", \"shape\": [2], \"data\": [1, 2]}"^^tensor:DataTensor)

returns

"true"^^xsd:boolean
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A single boolean value that is true if all elements in the input tensor are true (for boolean tensors) or non-zero (for numeric tensors), and false otherwise.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_all_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor all function"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 9
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "output1"
    op_type: "ReduceMin"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:any

xsd:boolean tensor:any (tensor:DataTensor term_1)

This function checks if any element in the boolean tensor is true. In case of numeric tensor, it checks if any element is non-zero. Returns a single boolean value.

Example 1

Evaluating the SPARQL expression

tensor:any("{\"type\": \"bool\", \"shape\": [2], \"data\": [false, true]}"^^tensor:DataTensor)

returns

"true"^^xsd:boolean

Example 2

Evaluating the SPARQL expression

tensor:any("{\"type\": \"bool\", \"shape\": [2], \"data\": [1, 0]}"^^tensor:DataTensor)

returns

"true"^^xsd:boolean
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A single boolean value that is true if any element in the input tensor is true (for boolean tensors) or non-zero (for numeric tensors), and false otherwise.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_any_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor any function"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 9
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "output1"
    op_type: "ReduceMax"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:none

xsd:boolean tensor:none (tensor:DataTensor term_1)

This function checks if no elements in the boolean tensor are true. In case of numeric tensor, it checks if all elements are zero. Returns a single boolean value.

Example 1

Evaluating the SPARQL expression

tensor:none("{\"type\": \"bool\", \"shape\": [2], \"data\": [false, false]}"^^tensor:DataTensor)

returns

"true"^^xsd:boolean

Example 2

Evaluating the SPARQL expression

tensor:none("{\"type\": \"bool\", \"shape\": [2], \"data\": [0, 0]}"^^tensor:DataTensor)

returns

"true"^^xsd:boolean
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A single boolean value that is true if no elements in the input tensor are true (for boolean tensors) or all elements are zero (for numeric tensors), and false otherwise.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
tensor_none_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor none function"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 9
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "reduced_input"
    op_type: "ReduceMax"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "reduced_input"
    output: "output1"
    op_type: "Not"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 9
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:avg

tensor:DataTensor tensor:avg (xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:avg (xsd:integer axis, tensor:DataTensor term_1)

This function computes the average along the specified axis. If the axis is negative, the average is calculated over the entire tensor. It returns a reduced tensor or a scalar.

Example

Evaluating the SPARQL expression

tensor:avg(1, "{\"type\": \"float32\", \"shape\": [2,2], \"data\": [1, 2, 3, 4]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2], \"data\": [1.5, 3.5]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the average, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
tensor_avg_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor average function for full reduction"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "output1"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_avg_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor average function for axis reduction"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "axes"
    output: "output1"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:sum

tensor:DataTensor tensor:sum (xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:sum (xsd:integer axis, tensor:DataTensor term_1)

This function computes the sum along the specified axis. If the axis is negative, the sum is calculated over the entire tensor. It returns a reduced tensor or a scalar.

Example

Evaluating the SPARQL expression

tensor:sum(1, "{\"type\": \"float32\", \"shape\": [2,2], \"data\": [1, 2, 3, 4]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2], \"data\": [3, 7]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the sum, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
  • For int16 tensors, the implementation is expected to use a different model definition that handles the ONNX limitation of not supporting int16 reduction operations.
tensor_sum_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor sum function for full reduction and int16 data type"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "reduction_output"
    op_type: "ReduceSum"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_sum_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor sum function for axis reduction and int16 data type"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "axes"
    output: "reduction_output"
    op_type: "ReduceSum"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_sum_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor sum function for full reduction"
graph {
  node {
    input: "input1"
    output: "output1"
    op_type: "ReduceSum"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_sum_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor sum function for axis reduction"
graph {
  node {
    input: "input1"
    input: "axes"
    output: "output1"
    op_type: "ReduceSum"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:prod

tensor:DataTensor tensor:prod (xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:prod (xsd:integer axis, tensor:DataTensor term_1)

This function computes the product along the specified axis. If the axis is negative, the product is calculated over the entire tensor. It returns a reduced tensor or a scalar.

Example

Evaluating the SPARQL expression

tensor:prod(1, "{\"type\": \"float32\", \"shape\": [2,2], \"data\": [1, 2, 3, 4]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2], \"data\": [2, 12]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the product, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
  • For int16 tensors, the implementation is expected to use a different model definition that handles the ONNX limitation of not supporting int16 reduction operations.
tensor_prod_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor product function for full reduction on int16 tensors"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "reduction_output"
    op_type: "ReduceProd"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_prod_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor product function for axis reduction on int16 tensors"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "axes"
    output: "reduction_output"
    op_type: "ReduceProd"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_prod_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor product function for full reduction"
graph {
  node {
    input: "input1"
    output: "output1"
    op_type: "ReduceProd"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_prod_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor product function for axis reduction"
graph {
  node {
    input: "input1"
    input: "axes"
    output: "output1"
    op_type: "ReduceProd"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:max

tensor:DataTensor tensor:max (xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:max (xsd:integer axis, tensor:DataTensor term_1)

This function computes the maximum along the specified axis. If the axis is negative, the maximum is calculated over the entire tensor. It returns a reduced tensor or a scalar.

Example

Evaluating the SPARQL expression

tensor:max(1, "{\"type\": \"float32\", \"shape\": [2,2], \"data\": [1, 5, 2, 4]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2], \"data\": [5, 4]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the maximum, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
  • For int16 tensors, the implementation is expected to use a different model definition that handles the ONNX limitation of not supporting int16 reduction operations.
tensor_max_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor max function for full reduction on int16 tensors"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "reduction_output"
    op_type: "ReduceMax"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_max_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor max function for axis reduction for int16 tensors"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "axes"
    output: "reduction_output"
    op_type: "ReduceMax"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_max_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor max function for full reduction"
graph {
  node {
    input: "input1"
    output: "output1"
    op_type: "ReduceMax"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_max_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor max function for axis reduction"
graph {
  node {
    input: "input1"
    input: "axes"
    output: "output1"
    op_type: "ReduceMax"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:min

tensor:DataTensor tensor:min (xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:min (xsd:integer axis, tensor:DataTensor term_1)

This function computes the minimum along the specified axis. If the axis is negative, the minimum is calculated over the entire tensor. It returns a reduced tensor or a scalar.

Example

Evaluating the SPARQL expression

tensor:min(1, "{\"type\": \"float32\", \"shape\": [1,3], \"data\": [7, 1, 3]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1], \"data\": [1]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the minimum, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
  • For int16 tensors, the implementation is expected to use a different model definition that handles the ONNX limitation of not supporting int16 reduction operations.
tensor_min_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor min function for full reduction on int16 data type"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "reduction_output"
    op_type: "ReduceMin"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_min_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor min function for axis reduction on int16 data type"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "axes"
    output: "reduction_output"
    op_type: "ReduceMin"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_min_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor min function for full reduction"
graph {
  node {
    input: "input1"
    output: "output1"
    op_type: "ReduceMin"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_min_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor min function for axis reduction"
graph {
  node {
    input: "input1"
    input: "axes"
    output: "output1"
    op_type: "ReduceMin"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:std

tensor:DataTensor tensor:std (xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:std (xsd:integer axis, tensor:DataTensor term_1)

This function computes the standard deviation along the specified axis. If the axis is negative, the standard deviation is calculated over the entire tensor. It returns a reduced tensor or a scalar.

Example

Evaluating the SPARQL expression

tensor:std(1, "{\"type\": \"float32\", \"shape\": [1,3], \"data\": [1, 2, 3]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1], \"data\": [0.8165]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the standard deviation, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.
  • bessel_factor_value: The Bessel's correction factor, which is used to determine the divisor for calculating the standard deviation. Calculated as n / (n-1), where n is the number of elements along the specified axis.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
tensor_std_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor standard deviation function for full reduction"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "mean"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "mean"
    output: "diff"
    op_type: "Sub"
  }
  node {
    input: "diff"
    input: "diff"
    output: "sq_diff"
    op_type: "Mul"
  }
  node {
    input: "sq_diff"
    output: "pop_variance"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "pop_variance"
    input: "bessel_factor"
    output: "variance"
    op_type: "Mul"
  }
  node {
    input: "variance"
    output: "output1"
    op_type: "Sqrt"
  }
  initializer {
    data_type: 11
    name: "bessel_factor"
    double_data: <bessel_factor_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_std_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor standard deviation function for axis reduction"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "axes"
    output: "mean"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "mean"
    output: "diff"
    op_type: "Sub"
  }
  node {
    input: "diff"
    input: "diff"
    output: "sq_diff"
    op_type: "Mul"
  }
  node {
    input: "sq_diff"
    input: "axes"
    output: "pop_variance"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "pop_variance"
    input: "bessel_factor"
    output: "variance"
    op_type: "Mul"
  }
  node {
    input: "variance"
    output: "output1"
    op_type: "Sqrt"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  initializer {
    data_type: 11
    name: "bessel_factor"
    double_data: <bessel_factor_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:var

tensor:DataTensor tensor:var (xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:var (xsd:integer axis, tensor:DataTensor term_1)

This function computes the variance along the specified axis. If the axis is negative, the variance is calculated over the entire tensor. It returns a reduced tensor or a scalar.

Example

Evaluating the SPARQL expression

tensor:var(1, "{\"type\": \"float32\", \"shape\": [1,3], \"data\": [1, 2, 3]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [1], \"data\": [0.6667]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the variance, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.
  • bessel_factor_value: The Bessel's correction factor, which is used to determine the divisor for calculating the variance. Calculated as n / (n-1), where n is the number of elements along the specified axis.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
tensor_var_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor variance function for full reduction"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "mean"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "mean"
    output: "diff"
    op_type: "Sub"
  }
  node {
    input: "diff"
    input: "diff"
    output: "sq_diff"
    op_type: "Mul"
  }
  node {
    input: "sq_diff"
    output: "pop_variance"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "pop_variance"
    input: "bessel_factor"
    output: "output1"
    op_type: "Mul"
  }
  initializer {
    data_type: 11
    name: "bessel_factor"
    double_data: <bessel_factor_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_var_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor variance function for axis reduction"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "axes"
    output: "mean"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "mean"
    output: "diff"
    op_type: "Sub"
  }
  node {
    input: "diff"
    input: "diff"
    output: "sq_diff"
    op_type: "Mul"
  }
  node {
    input: "sq_diff"
    input: "axes"
    output: "pop_variance"
    op_type: "ReduceMean"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "pop_variance"
    input: "bessel_factor"
    output: "output1"
    op_type: "Mul"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  initializer {
    data_type: 11
    name: "bessel_factor"
    double_data: <bessel_factor_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:norm1

tensor:DataTensor tensor:norm1 (xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:norm1 (xsd:integer axis, tensor:DataTensor term_1)

This function computes the L1 norm (sum of absolute values) along the specified axis. If the axis is negative, the L1 norm (sum of absolute values) is calculated over the entire tensor. It returns a reduced tensor or a scalar.

Example

Evaluating the SPARQL expression

tensor:norm1(1, "{\"type\": \"float32\", \"shape\": [2,2], \"data\": [1, -1, -2, 2]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2], \"data\": [2, 4]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the L1 norm, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
  • For int16 tensors, the implementation is expected to use a different model definition that handles the ONNX limitation of not supporting int16 reduction operations.
tensor_norm1_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor L1 norm function for full reduction with int16 input"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "reduction_output"
    op_type: "ReduceL1"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_norm1_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor L1 norm function for axis reduction with int16 input"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 6
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "axes"
    output: "reduction_output"
    op_type: "ReduceL1"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "reduction_output"
    output: "output1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 5
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 5
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_norm1_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor L1 norm function for full reduction"
graph {
  node {
    input: "input1"
    output: "output1"
    op_type: "ReduceL1"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_norm1_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor L1 norm function for axis reduction"
graph {
  node {
    input: "input1"
    input: "axes"
    output: "output1"
    op_type: "ReduceL1"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:norm2

tensor:DataTensor tensor:norm2 (xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:norm1 (xsd:integer axis, tensor:DataTensor term_1)

This function computes the L2 norm (Euclidean norm) along the specified axis. If the axis is negative, the L2 norm (Euclidean norm) is calculated over the entire tensor. It returns a reduced tensor or a scalar.

Example

Evaluating the SPARQL expression

tensor:norm2(1, "{\"type\": \"float32\", \"shape\": [2,2], \"data\": [3, 4, 6, 8]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2], \"data\": [5, 10]}"^^tensor:DataTensor
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the L2 norm, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
tensor_norm2_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor L2 norm function for full reduction"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    output: "output1"
    op_type: "ReduceL2"
    attribute {
      name: "keepdims"
      i: 1
      type: INT
    }
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_norm2_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor L2 norm function for axis reduction"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "axes"
    output: "output1"
    op_type: "ReduceL2"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_value>
    name: "axes"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:quantile

tensor:DataTensor tensor:quantile (xsd:double q, xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:quantile (xsd:double q, xsd:integer axis, tensor:DataTensor term_1)

This function computes the q-th quantile along the specified axis. The quantile value q should be between 0 and 1 (e.g., 0.5 for median, 0.25 for first quartile). If the axis is negative, the quantile is calculated over the entire flattened tensor. It returns a reduced tensor or a scalar.

If the quantile falls between two data points, the function should return the nearest data point to the quantile.

Example

Evaluating the SPARQL expression

tensor:quantile(0.5, 1, "{\"type\": \"float32\", \"shape\": [2,3], \"data\": [1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2], \"data\": [2, 5]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:quantile(0.25, -1, "{\"type\": \"float32\", \"shape\": [2,3], \"data\": [1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor)

returns

"2"^^xsd:float
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • output1: A tensor of type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the quantile, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.
  • axis_size_value: The size of the specified axis, which is used to determine the position of the quantile in the sorted order of the data along that axis. For axis_value >= 0, this is the size of the dimension corresponding to axis_value. For axis_value < 0, this is the total number of elements in the input tensor.
  • quantile_index_value: The index of the quantile in the sorted order of the data along the specified axis, calculated as quantile_index_value = floor(q * (axis_size_value - 1)), where q is the quantile value.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
tensor_quantile_full_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor quantile function for full reduction"
graph {
  node {
    input: "input1"
    input: "reshape_shape"
    output: "reshaped"
    op_type: "Reshape"
  }
  node {
    input: "reshaped"
    input: "k_tensor"
    output: "sorted_values"
    output: "sorted_indices"
    op_type: "TopK"
    attribute {
      name: "axis"
      i: 0
      type: INT
    }
    attribute {
      name: "largest"
      i: 0
      type: INT
    }
    attribute {
      name: "sorted"
      i: 1
      type: INT
    }
  }
  node {
    input: "sorted_values"
    input: "quantile_idx"
    output: "gathered"
    op_type: "Gather"
    attribute {
      name: "axis"
      i: 0
      type: INT
    }
  }
  node {
    input: "gathered"
    output: "output1"
    op_type: "Squeeze"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_size_value>
    name: "k_tensor"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <quantile_index_value>
    name: "quantile_idx"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: -1
    name: "reshape_shape"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_quantile_axis_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor quantile function for axis reduction"
graph {
  node {
    input: "input1"
    input: "k_tensor"
    output: "sorted_values"
    output: "sorted_indices"
    op_type: "TopK"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
    attribute {
      name: "largest"
      i: 0
      type: INT
    }
    attribute {
      name: "sorted"
      i: 1
      type: INT
    }
  }
  node {
    input: "sorted_values"
    input: "quantile_idx"
    output: "output1"
    op_type: "Gather"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_size_value>
    name: "k_tensor"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <quantile_index_value>
    name: "quantile_idx"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:quantileInterpolate

tensor:DataTensor tensor:quantileInterpolate (xsd:double q, xsd:integer axis, tensor:DataTensor term_1)

xsd:double tensor:quantileInterpolate (xsd:double q, xsd:integer axis, tensor:DataTensor term_1)

This function computes the q-th quantile along the specified axis. The quantile value q should be between 0 and 1 (e.g., 0.5 for median, 0.25 for first quartile). If the axis is negative, the quantile is calculated over the entire flattened tensor. It returns a reduced tensor or a scalar.

If the quantile falls between two data points, the function should interpolate between them to return a value that represents the quantile. The interpolation method is defined as linear interpolation between the two nearest data points.

Example

Evaluating the SPARQL expression

tensor:quantileInterpolate(0.5, 1, "{\"type\": \"float32\", \"shape\": [2,3], \"data\": [1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor)

returns

"{\"type\": \"float32\", \"shape\": [2], \"data\": [2, 5]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:quantileInterpolate(0.25, -1, "{\"type\": \"float32\", \"shape\": [2,3], \"data\": [1, 2, 3, 4, 5, 6]}"^^tensor:DataTensor)

returns

"2.25"^^xsd:float
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • lower_index: A tensor of integer type representing the index of the lower data point for interpolation. For axis_value >= 0, this is calculated as floor(q * (axis_size_value - 1)). For axis_value < 0, this is calculated as floor(q * (total_size - 1)), where total_size is the total number of elements in the input tensor.
  • upper_index: A tensor of integer type representing the index of the upper data point for interpolation. For axis_value >= 0, this is calculated as ceil(q * (axis_size_value - 1)). For axis_value < 0, this is calculated as ceil(q * (total_size - 1)), where total_size is the total number of elements in the input tensor.
  • fraction: A tensor of float type representing the fractional part for interpolation, calculated as q * (axis_size_value - 1) - lower_index for axis_value >= 0, or q * (total_size - 1) - lower_index for axis_value < 0.
  • output1: A tensor of DOUBLE type, where the shape is determined by reducing the input tensor along the specified axis.

Model variables:

  • input_type: The data type of the input tensor, which can be any supported type.
  • axis_value: The axis along which to compute the quantile, which can be any integer value from -1 to rank-1, where rank is the number of dimensions in the input tensor.
  • axis_size_value: The size of the specified axis, which is used to determine the position of the quantile in the sorted order of the data along that axis. For axis_value >= 0, this is the size of the dimension corresponding to axis_value. For axis_value < 0, this is the total number of elements in the input tensor.

Model definition dispatch:

  • if axis_value is negative, then the implementation is expected to use model definition for full reduction.
  • if axis_value is non-negative, then the implementation is expected to use model definition for axis reduction.
  • if it is determined that interpolation is needed (i.e., the quantile falls between two data points), then the implementation is expected to use the model definition for interpolation. Otherwise, it should use the model definition for no interpolation.
tensor_quantile_interpolate_no_interpolation_full_reduction_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor quantile interpolate function for full reduction without interpolation"
graph {
  node {
    input: "input1"
    input: "reshape_shape"
    output: "reshaped"
    op_type: "Reshape"
  }
  node {
    input: "reshaped"
    input: "k_tensor"
    output: "sorted_values"
    output: "sorted_indices"
    op_type: "TopK"
    attribute {
      name: "axis"
      i: 0
      type: INT
    }
    attribute {
      name: "largest"
      i: 0
      type: INT
    }
    attribute {
      name: "sorted"
      i: 1
      type: INT
    }
  }
  node {
    input: "sorted_values"
    input: "quantile_index"
    output: "gathered"
    op_type: "Gather"
    attribute {
      name: "axis"
      i: 0
      type: INT
    }
  }
  node {
    input: "gathered"
    output: "output1"
    op_type: "Squeeze"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_size_value>
    name: "k_tensor"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: -1
    name: "reshape_shape"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  input {
    name: "quantile_index"
    type {
      tensor_type {
        elem_type: 7
        shape {
          dim {
            dim_value: 1
          }
        }
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_quantile_interpolate_no_interpolation_axis_reduction_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor quantile interpolate function for axis reduction without interpolation"
graph {
  node {
    input: "input1"
    input: "k_tensor"
    output: "sorted_values"
    output: "sorted_indices"
    op_type: "TopK"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
    attribute {
      name: "largest"
      i: 0
      type: INT
    }
    attribute {
      name: "sorted"
      i: 1
      type: INT
    }
  }
  node {
    input: "sorted_values"
    input: "quantile_index"
    output: "output1"
    op_type: "Gather"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_size_value>
    name: "k_tensor"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  input {
    name: "quantile_index"
    type {
      tensor_type {
        elem_type: 7
        shape {
          dim {
            dim_value: 1
          }
        }
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_quantile_interpolate_with_interpolation_full_reduction_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor quantile interpolate function for full reduction with interpolation"
graph {
  node {
    input: "input1"
    input: "reshape_shape"
    output: "reshaped"
    op_type: "Reshape"
  }
  node {
    input: "reshaped"
    input: "k_tensor"
    output: "sorted_values"
    output: "sorted_indices"
    op_type: "TopK"
    attribute {
      name: "axis"
      i: 0
      type: INT
    }
    attribute {
      name: "largest"
      i: 0
      type: INT
    }
    attribute {
      name: "sorted"
      i: 1
      type: INT
    }
  }
  node {
    input: "sorted_values"
    output: "sorted_float"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "sorted_float"
    input: "lower_index"
    output: "lower_gathered"
    op_type: "Gather"
    attribute {
      name: "axis"
      i: 0
      type: INT
    }
  }
  node {
    input: "sorted_float"
    input: "upper_index"
    output: "upper_gathered"
    op_type: "Gather"
    attribute {
      name: "axis"
      i: 0
      type: INT
    }
  }
  node {
    input: "lower_gathered"
    output: "lower_values"
    op_type: "Squeeze"
  }
  node {
    input: "upper_gathered"
    output: "upper_values"
    op_type: "Squeeze"
  }
  node {
    input: "upper_values"
    input: "lower_values"
    output: "diff"
    op_type: "Sub"
  }
  node {
    input: "fraction"
    input: "diff"
    output: "scaled_diff"
    op_type: "Mul"
  }
  node {
    input: "lower_values"
    input: "scaled_diff"
    output: "output1"
    op_type: "Add"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_size_value>
    name: "k_tensor"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: -1
    name: "reshape_shape"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  input {
    name: "lower_index"
    type {
      tensor_type {
        elem_type: 7
        shape {
          dim {
            dim_value: 1
          }
        }
      }
    }
  }
  input {
    name: "upper_index"
    type {
      tensor_type {
        elem_type: 7
        shape {
          dim {
            dim_value: 1
          }
        }
      }
    }
  }
  input {
    name: "fraction"
    type {
      tensor_type {
        elem_type: 11
        shape {
          dim {
            dim_value: 1
          }
        }
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_quantile_interpolate_with_interpolation_axis_reduction_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor quantile interpolate function for axis reduction with interpolation"
graph {
  node {
    input: "input1"
    input: "k_tensor"
    output: "sorted_values"
    output: "sorted_indices"
    op_type: "TopK"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
    attribute {
      name: "largest"
      i: 0
      type: INT
    }
    attribute {
      name: "sorted"
      i: 1
      type: INT
    }
  }
  node {
    input: "sorted_values"
    output: "sorted_float"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "sorted_float"
    input: "lower_index"
    output: "lower_values"
    op_type: "Gather"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
  }
  node {
    input: "sorted_float"
    input: "upper_index"
    output: "upper_values"
    op_type: "Gather"
    attribute {
      name: "axis"
      i: <axis_value>
      type: INT
    }
  }
  node {
    input: "upper_values"
    input: "lower_values"
    output: "diff"
    op_type: "Sub"
  }
  node {
    input: "fraction"
    input: "diff"
    output: "scaled_diff"
    op_type: "Mul"
  }
  node {
    input: "lower_values"
    input: "scaled_diff"
    output: "output1"
    op_type: "Add"
  }
  initializer {
    dims: 1
    data_type: 7
    int64_data: <axis_size_value>
    name: "k_tensor"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
        shape {
          dim {
            dim_value: 2
          }
          dim {
            dim_value: 4
          }
        }
      }
    }
  }
  input {
    name: "lower_index"
    type {
      tensor_type {
        elem_type: 7
        shape {
          dim {
            dim_value: 1
          }
        }
      }
    }
  }
  input {
    name: "upper_index"
    type {
      tensor_type {
        elem_type: 7
        shape {
          dim {
            dim_value: 1
          }
        }
      }
    }
  }
  input {
    name: "fraction"
    type {
      tensor_type {
        elem_type: 11
        shape {
          dim {
            dim_value: 1
          }
        }
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

4.6. Similarity Functions

tensor:cosineSimilarity

xsd:double tensor:cosineSimilarity (tensor:DataTensor term_1, tensor:DataTensor term_2)

This function computes the cosine similarity between two tensors. Returns a numeric scalar value.

Example

Evaluating the SPARQL expression

tensor:cosineSimilarity( "{\"type\": \"float32\", \"shape\": [3], \"data\": [1, 0, 1]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [3], \"data\": [1, 1, 0]}"^^tensor:DataTensor)

returns

"0.5"^^xsd:float
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of the same shape and type.
  • output1: A single numeric value representing the cosine similarity between the two input tensors.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
tensor_cosine_similarity_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor cosine similarity function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "mul_ab"
    op_type: "Mul"
  }
  node {
    input: "mul_ab"
    output: "dot_product"
    op_type: "ReduceSum"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input1"
    output: "square_a"
    op_type: "Mul"
  }
  node {
    input: "square_a"
    output: "sum_square_a"
    op_type: "ReduceSum"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "sum_square_a"
    output: "norm_a"
    op_type: "Sqrt"
  }
  node {
    input: "cast_input2"
    input: "cast_input2"
    output: "square_b"
    op_type: "Mul"
  }
  node {
    input: "square_b"
    output: "sum_square_b"
    op_type: "ReduceSum"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "sum_square_b"
    output: "norm_b"
    op_type: "Sqrt"
  }
  node {
    input: "norm_a"
    input: "norm_b"
    output: "norm_product"
    op_type: "Mul"
  }
  node {
    input: "dot_product"
    input: "norm_product"
    output: "output1"
    op_type: "Div"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:euclideanDistance

xsd:double tensor:euclideanDistance (tensor:DataTensor term_1, tensor:DataTensor term_2)

This function computes the Euclidean distance between two tensors. Returns a numeric scalar value.

Example

Evaluating the SPARQL expression

tensor:euclideanDistance("{\"type\": \"float32\", \"shape\": [2], \"data\": [3, 4]}"^^tensor:DataTensor, "{\"type\": \"float32\", \"shape\": [2], \"data\": [0, 0]}"^^tensor:DataTensor)

returns

`"5.0"^^xsd:float
ONNX definition of this function

Model inputs and outputs:

  • input1: A tensor of any shape and type.
  • input2: A tensor of the same shape and type.
  • output1: A single numeric value representing the Euclidean distance between the two input tensors.

Model variables:

  • input1_type: The data type of the first input tensor, which can be any supported type.
  • input2_type: The data type of the second input tensor, which can be any supported type.
tensor_euclidean_distance_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor euclidean distance function"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "diff"
    op_type: "Sub"
  }
  node {
    input: "diff"
    input: "diff"
    output: "diff_squared"
    op_type: "Mul"
  }
  node {
    input: "diff_squared"
    output: "sum_squared"
    op_type: "ReduceSum"
    attribute {
      name: "keepdims"
      i: 0
      type: INT
    }
  }
  node {
    input: "sum_squared"
    output: "output1"
    op_type: "Sqrt"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input1_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input2_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

4.7 Creation Functions

tensor:create

tensor:DataTensor tensor:create (xsd:string type, xsd:integer | xsd:float | xsd:double | xsd:boolean ... values)

This function creates a DataTensor from a list of scalar values of the specified type. The resulting tensor has a shape of [N], where N is the number of input values.

Example 1

Evaluating the SPARQL expression

tensor:create("int32", 1, 2, 3, 4)

returns

"{\"type\": \"int32\", \"shape\": [4], \"data\": [1, 2, 3, 4]}"^^tensor:DataTensor

Example 2

Evaluating the SPARQL expression

tensor:create("bool", true, false, true)

returns

"{\"type\": \"bool\", \"shape\": [3], \"data\": [true, false, true]}"^^tensor:DataTensor

tensor:range

tensor:Range tensor:range (xsd:integer from, xsd:integer to)

tensor:Range tensor:range ()

This function creates a Range object representing a sequence of indices from from to to (inclusive of from, exclusive of to). If no arguments are provided, it represents the full range.

Example 1

Evaluating the SPARQL expression

tensor:range(0, 5)

returns a Range object representing the indices from 0 to 4.

"{\"type\": \"concrete\", \"from\": 0, \"to\": 5}"^^tensor:Range

Example 2

Evaluating the SPARQL expression

tensor:range()

returns a Range object representing the full range of indices for slicing tensors.

"{\"type\": \"full\"}"^^tensor:Range

tensor:shape

tensor:DataTensor tensor:shape (tensor:DataTensor term_1)

This function returns a 1-dimensional tensor of type int64 containing the shape (dimensions) of the input tensor. For example, if the input tensor has shape [2, 3, 4], the result is a 1-dimensional tensor [2, 3, 4] with shape [3].

Example

Evaluating the SPARQL expression

tensor:shape("{\"type\": \"float32\", \"shape\": [2, 3, 4], \"data\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]}"^^tensor:DataTensor)

returns

"{\"type\": \"int64\", \"shape\": [3], \"data\": [2, 3, 4]}"^^tensor:DataTensor

tensor:arange

tensor:DataTensor tensor:arange (xsd:string type, xsd:integer start, xsd:integer stop)

tensor:DataTensor tensor:arange (xsd:string type, xsd:integer start, xsd:integer stop, xsd:integer step)

tensor:DataTensor tensor:arange (xsd:string type, tensor:Range range, xsd:integer step)

tensor:DataTensor tensor:arange (xsd:string type, tensor:Range range)

tensor:DataTensor tensor:arange (xsd:string type, xsd:DataTensor dt, xsd:integer step)

tensor:DataTensor tensor:arange (xsd:string type, xsd:DataTensor dt)

This function creates a 1D tensor containing evenly spaced values within the half-open interval [start, stop). Similar to NumPy's np.arange. The first argument is the data type (e.g., "int32", "float64"), followed by start, stop, and optionally step (default 1). The resulting tensor has shape [N], where N is the number of values in the range.

The function supports multiple overloads for specifying the range: - Using start, stop, and optional step as integers. - Using a Range object to specify the start and stop values. - Using a DataTensor of shape [2] to specify the start and stop values, where the first element is the start and the second element is the stop.

Example

Evaluating the SPARQL expression

tensor:arange("int32", 0, 5)

returns

"{\"type\": \"int32\", \"shape\": [5], \"data\": [0, 1, 2, 3, 4]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:arange("float64", 0, 10, 2)

returns

"{\"type\": \"float64\", \"shape\": [5], \"data\": [0.0, 2.0, 4.0, 6.0, 8.0]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:arange("int32", 5, 0, -1)

returns

"{\"type\": \"int32\", \"shape\": [5], \"data\": [5, 4, 3, 2, 1]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:arange("int32", tensor:range(0, 5))

returns

"{\"type\": \"int32\", \"shape\": [5], \"data\": [0, 1, 2, 3, 4]}"^^tensor:DataTensor

Example

Evaluating the SPARQL expression

tensor:arange("int32", "{\"type\": \"int64\", \"shape\": [2], \"data\": [0, 5]}"^^tensor:DataTensor)

returns

"{\"type\": \"int32\", \"shape\": [5], \"data\": [0, 1, 2, 3, 4]}"^^tensor:DataTensor

5. SPARQL Aggregates

The following aggregation functions are implemented as SPARQL extension aggregates. Each aggregate operates over a group of tensor:DataTensor values bound during SPARQL GROUP BY evaluation and returns a single tensor:DataTensor. All tensors within a group must have the same shape. When tensors have different numeric data types, automatic type casting is performed to a common type. These aggregates do not support the DISTINCT modifier.

Each aggregate is defined by up to three ONNX model templates, corresponding to the three phases of aggregation:

  • Initial model – processes the first value in a group to set up internal accumulators.
  • Reduce model – incorporates each subsequent value into the accumulators.
  • Complete model – produces the final aggregated result from the accumulators.

Simple aggregates (e.g., tensor:SUM) may not require a separate initial model if the first value can be used directly as the accumulator.

tensor:SUM

tensor:DataTensor tensor:SUM (tensor:DataTensor ?expr)

Computes the element-wise sum of all tensors in a group. The result is a tensor of the same shape as the input tensors, where each element is the sum of the corresponding elements across all tensors in the group. When input tensors have different numeric data types, they are cast to a common type before summation.

Example

Given the following RDF data:

:x :p1 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .
:x :p2 "{\"type\":\"float64\",\"shape\":[3],\"data\":[15.5, 25.5, 30.5]}"^^tensor:DataTensor .
:x :p3 "{\"type\":\"float64\",\"shape\":[3],\"data\":[15.5, 25.5, 30.5]}"^^tensor:DataTensor .

Evaluating the SPARQL query

SELECT (tensor:SUM(?val) AS ?sum)
WHERE { ?s ?p ?val }
GROUP BY ?s

returns a binding where ?sum is

"{\"type\": \"float64\", \"shape\": [3], \"data\": [41.0, 71.0, 91.0]}"^^tensor:DataTensor
ONNX definition of this aggregate

Aggregation phases:

  • Initial: The first tensor value is used directly as the accumulator. No ONNX model is needed.
  • Reduce: Each subsequent tensor is added element-wise to the accumulator using an ONNX Add operation.
  • Complete: The accumulator is returned directly as the result. No ONNX model is needed.

Reduce model inputs and outputs:

  • input1: The current accumulator tensor of type.
  • input2: The next tensor to add, of type.
  • output1: The updated accumulator tensor after element-wise addition of type.

Model variables:

  • accumulator_type: The data type of the current accumulator tensor.
  • input_type: The data type of the incoming tensor, which can be any supported numeric type.
  • resolved_type: The common data type to which both the accumulator and input tensor are cast for addition, determined by type hierarchy and casting rules.
tensor_SUM_reduce_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor SUM aggregation function reduction step"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "Add"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <accumulator_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <resolved_type>
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:AVG

tensor:DataTensor tensor:AVG (tensor:DataTensor ?expr)

Computes the element-wise average (arithmetic mean) of all tensors in a group. The result is always a DOUBLE-typed tensor of the same shape as the input tensors, where each element is the mean of the corresponding elements across all tensors in the group.

Internally, the aggregate accumulates the element-wise sum and the count of tensors. On completion, the sum is cast to DOUBLE and divided by the count.

Example

Given the following RDF data:

:x :p1 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .
:x :p2 "{\"type\":\"float64\",\"shape\":[3],\"data\":[15.5, 25.5, 30.5]}"^^tensor:DataTensor .
:x :p3 "{\"type\":\"float64\",\"shape\":[3],\"data\":[15.5, 25.5, 30.5]}"^^tensor:DataTensor .
:x :p4 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .
:x :p5 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .

Evaluating the SPARQL query

SELECT (tensor:AVG(?val) AS ?avg)
WHERE { ?s ?p ?val }
GROUP BY ?s

returns a binding where ?avg is

"{\"type\": \"float64\", \"shape\": [3], \"data\": [12.2, 22.2, 30.2]}"^^tensor:DataTensor
ONNX definition of this aggregate

Aggregation phases:

  • Initial: The first tensor value and a count of 1 are stored as the accumulator. No ONNX model is needed.
  • Reduce: Each subsequent tensor is added element-wise to the accumulator sum using an ONNX Add operation, and the count is incremented.
  • Complete: The accumulated sum is cast to DOUBLE and divided element-wise by the count to produce the mean.

Reduce model inputs and outputs:

  • input1: The current sum accumulator tensor of type.
  • input2: The next tensor to add, of type.
  • output1: The updated sum accumulator tensor after element-wise addition of type.

Complete model inputs and outputs:

  • input1: The accumulated sum tensor of type.
  • output1: The average tensor of DOUBLE type, computed as Cast(input1, DOUBLE) / count.

Model variables:

  • accumulator_type: The data type of the current sum accumulator tensor.
  • input_type: The data type of the incoming tensor, which can be any supported numeric type.
  • resolved_type: The common data type to which both the accumulator and input tensor are cast for addition, determined by type hierarchy and casting rules.
  • count_value: The total number of tensors in the group, of type DOUBLE.
tensor_AVG_reduce_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor AVG aggregation function reduction step"
graph {
  node {
    input: "input1"
    output: "cast_input1"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "input2"
    output: "cast_input2"
    op_type: "Cast"
    attribute {
      name: "to"
      i: <resolved_type>
      type: INT
    }
  }
  node {
    input: "cast_input1"
    input: "cast_input2"
    output: "output1"
    op_type: "Add"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <accumulator_type>
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: <resolved_type>
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_AVG_complete_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor AVG aggregation function completion step"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "divisor"
    output: "output1"
    op_type: "Div"
  }
  initializer {
    data_type: 11
    name: "divisor"
    double_data: <count_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <accumulator_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:VAR

tensor:DataTensor tensor:VAR (tensor:DataTensor ?expr)

Computes the element-wise population variance of all tensors in a group. The result is always a DOUBLE-typed tensor of the same shape as the input tensors, where each element is the variance of the corresponding elements across all tensors in the group.

The variance is computed using the formula: Var(X) = E[X^2] − (E[X])^2, where E denotes the mean over the group. Internally, the aggregate tracks the element-wise sum of squares and the element-wise sum. On completion, it divides both by the count and applies the formula.

Requires at least two tensors in the group.

Example

Given the following RDF data:

:x :p1 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .
:x :p2 "{\"type\":\"float64\",\"shape\":[3],\"data\":[15.5, 25.5, 30.5]}"^^tensor:DataTensor .
:x :p3 "{\"type\":\"float64\",\"shape\":[3],\"data\":[15.5, 25.5, 30.5]}"^^tensor:DataTensor .
:x :p4 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .
:x :p5 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .

Evaluating the SPARQL query

SELECT (tensor:VAR(?val) AS ?variance)
WHERE { ?s ?p ?val }
GROUP BY ?s

returns a binding where ?variance is approximately

"{\"type\": \"float64\", \"shape\": [3], \"data\": [9.075, 9.075, 0.075]}"^^tensor:DataTensor
ONNX definition of this aggregate

Aggregation phases:

  • Initial: the first tensor is cast to DOUBLE. The element-wise square (x^2) is computed as one accumulator, and the cast value itself is the other. The count is initialized to 1.
  • Reduce: each subsequent tensor is cast to DOUBLE, squared, and added to the sum-of-squares accumulator. The cast value is added to the sum accumulator. The count is incremented.
  • Complete: the variance is computed as E[X^2] − (E[X])^2 by dividing both accumulators by the count and applying the formula.

Initial model inputs and outputs:

  • input1: The first tensor value of type.
  • output1: The squared tensor (x^2), cast to DOUBLE type.
  • output2: The tensor value itself, cast to DOUBLE type.

Reduce model inputs and outputs:

  • input1: The current sum-of-squares accumulator tensor of DOUBLE type.
  • input2: The current sum accumulator tensor of DOUBLE type.
  • input3: The next tensor to accumulate, of type.
  • output1: The updated sum-of-squares accumulator (input1 + Cast(input3)^2).
  • output2: The updated sum accumulator (input2 + Cast(input3)).

Complete model inputs and outputs:

  • input1: The accumulated sum-of-squares tensor of DOUBLE type.
  • input2: The accumulated sum tensor of DOUBLE type.
  • output1: The variance tensor of DOUBLE type, computed as (input1 / count) − (input2 / count)^2.

Model variables:

  • input_type: The data type of the incoming tensor, which can be any supported numeric type.
  • count_value: The total number of tensors in the group, of type DOUBLE.
tensor_VAR_initial_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor VAR aggregation function initial step"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "cast_input"
    output: "output1"
    op_type: "Mul"
  }
  node {
    input: "cast_input"
    output: "output2"
    op_type: "Identity"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  output {
    name: "output2"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_VAR_reduce_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor VAR aggregation function reduction step"
graph {
  node {
    input: "input3"
    output: "cast_new"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_new"
    input: "cast_new"
    output: "newSq"
    op_type: "Mul"
  }
  node {
    input: "newSq"
    input: "input1"
    output: "output1"
    op_type: "Add"
  }
  node {
    input: "cast_new"
    input: "input2"
    output: "output2"
    op_type: "Add"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  input {
    name: "input3"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  output {
    name: "output2"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_VAR_complete_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor VAR aggregation function complete model"
graph {
  node {
    input: "input1"
    input: "count"
    output: "meanSq"
    op_type: "Div"
  }
  node {
    input: "input2"
    input: "count"
    output: "mean"
    op_type: "Div"
  }
  node {
    input: "mean"
    input: "mean"
    output: "meanSquared"
    op_type: "Mul"
  }
  node {
    input: "meanSq"
    input: "meanSquared"
    output: "output1"
    op_type: "Sub"
  }
  initializer {
    dims: 1
    data_type: 11
    name: "count"
    double_data: <count_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

tensor:STD

tensor:DataTensor tensor:STD (tensor:DataTensor ?expr)

Computes the element-wise population standard deviation of all tensors in a group. The result is always a DOUBLE-typed tensor of the same shape as the input tensors, where each element is the standard deviation of the corresponding elements across all tensors in the group.

The standard deviation is computed as the square root of the population variance: Std(X) = sqrtVar(X) = sqrt(E[X^2] − (E[X])^2). Internally, the aggregate uses the same accumulation strategy as tensor:VAR (tracking sum of squares and sum), but applies an additional square root in the completion phase.

Requires at least two tensors in the group.

Example

Given the following RDF data:

:x :p1 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .
:x :p2 "{\"type\":\"float64\",\"shape\":[3],\"data\":[15.5, 25.5, 30.5]}"^^tensor:DataTensor .
:x :p3 "{\"type\":\"float64\",\"shape\":[3],\"data\":[15.5, 25.5, 30.5]}"^^tensor:DataTensor .
:x :p4 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .
:x :p5 "{\"type\":\"int32\",\"shape\":[3],\"data\":[10, 20, 30]}"^^tensor:DataTensor .

Evaluating the SPARQL query

SELECT (tensor:STD(?val) AS ?stddev)
WHERE { ?s ?p ?val }
GROUP BY ?s

returns a binding where ?stddev is approximately

"{\"type\": \"float64\", \"shape\": [3], \"data\": [3.0125, 3.0125, 0.2739]}"^^tensor:DataTensor
ONNX definition of this aggregate

Aggregation phases:

  • Initial: the first tensor is cast to DOUBLE. The element-wise square (x^2) is computed as one accumulator, and the cast value itself is the other. The count is initialized to 1.
  • Reduce: each subsequent tensor is cast to DOUBLE, squared, and added to the sum-of-squares accumulator. The cast value is added to the sum accumulator. The count is incremented.
  • Complete: the variance is computed as E[X^2] − (E[X])^2, followed by an element-wise square root to produce the standard deviation.

Initial model inputs and outputs:

  • input1: The first tensor value of type.
  • output1: The squared tensor (x^2), cast to DOUBLE type.
  • output2: The tensor value itself, cast to DOUBLE type.

Reduce model inputs and outputs:

  • input1: The current sum-of-squares accumulator tensor of DOUBLE type.
  • input2: The current sum accumulator tensor of DOUBLE type.
  • input3: The next tensor to accumulate, of type.
  • output1: The updated sum-of-squares accumulator (input1 + Cast(input3)^2).
  • output2: The updated sum accumulator (input2 + Cast(input3)).

Complete model inputs and outputs:

  • input1: The accumulated sum-of-squares tensor of DOUBLE type.
  • input2: The accumulated sum tensor of DOUBLE type.
  • output1: The standard deviation tensor of DOUBLE type, computed as sqrt((input1 / count) − (input2 / count)^2).

Model variables:

  • input_type: The data type of the incoming tensor, which can be any supported numeric type.
  • count_value: The total number of tensors in the group, of type DOUBLE.
tensor_STD_initial_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor STD aggregation function initial step"
graph {
  node {
    input: "input1"
    output: "cast_input"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_input"
    input: "cast_input"
    output: "output1"
    op_type: "Mul"
  }
  node {
    input: "cast_input"
    output: "output2"
    op_type: "Identity"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  output {
    name: "output2"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_STD_reduce_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor STD aggregation function reduction step"
graph {
  node {
    input: "input3"
    output: "cast_new"
    op_type: "Cast"
    attribute {
      name: "to"
      i: 11
      type: INT
    }
  }
  node {
    input: "cast_new"
    input: "cast_new"
    output: "newSq"
    op_type: "Mul"
  }
  node {
    input: "newSq"
    input: "input1"
    output: "output1"
    op_type: "Add"
  }
  node {
    input: "cast_new"
    input: "input2"
    output: "output2"
    op_type: "Add"
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  input {
    name: "input3"
    type {
      tensor_type {
        elem_type: <input_type>
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  output {
    name: "output2"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}
tensor_STD_complete_model.pbtxt
ir_version: 11
domain: "eu.neverblink.rdf"
model_version: 1
doc_string: "RDF tensor STD aggregation function complete model"
graph {
  node {
    input: "input1"
    input: "count"
    output: "meanSq"
    op_type: "Div"
  }
  node {
    input: "input2"
    input: "count"
    output: "mean"
    op_type: "Div"
  }
  node {
    input: "mean"
    input: "mean"
    output: "meanSquared"
    op_type: "Mul"
  }
  node {
    input: "meanSq"
    input: "meanSquared"
    output: "variance"
    op_type: "Sub"
  }
  node {
    input: "variance"
    output: "output1"
    op_type: "Sqrt"
  }
  initializer {
    data_type: 11
    name: "count"
    double_data: <count_value>
  }
  input {
    name: "input1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  input {
    name: "input2"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
  output {
    name: "output1"
    type {
      tensor_type {
        elem_type: 11
      }
    }
  }
}
opset_import {
  version: 23
}

A. References

A.1. Informative references

[rdf11-concepts]

  RDF 1.1 Concepts and Abstract Syntax. Richard Cyganiak; David Wood; Markus Lanthaler. W3C. 25 February 2014. W3C Recommendation. URL: https://www.w3.org/TR/rdf11-concepts/

[RFC-8259]

  RFC 8259. Tim Bray. JSON Data Interchange Format. 2017. URL: https://www.rfc-editor.org/rfc/rfc8259

[NumPy]

  NumPy. NumPy Developers. NumPy. 2023. URL: https://numpy.org/

[ONNX (Open Neural Network Exchange)]

  ONNX (Open Neural Network Exchange). ONNX. 2019. URL: https://onnx.ai/