Built-ins
Built-in Attributes
TML objects (scalars, tensors and strings) support the following attributes.
Note
Attributes represent values related to the type of the expression, and not to the value of the expression itself. Evaluating expression is thus not necessary to obtain value of the attribute. To avoid confusion, subexpression of attribute access is always evaluated.
Currently, evaluating expression is avoided only for scalar literals and variables. In the future, code pruning will be implemented for subexpressions that have no side effects, while expressions with visible side effects will still be evaluated.
len
len attribute represents the length of an object.
len acts as an alias for .size[0] and can be used on arbitrary tensor types.
Strings support this attribute.
m = [1, 2, 3; 4, 5, 6]
m.len # Output 2
n = [1, 2; 3, 4; 5, 6; 7, 8]
n.len # Output 4
v = [1, 2, 3]
v.len # Output: 3
tensor<tensor<tensor<int, 5>, 5>, 3, 3> t = 1
t.size # Output: 3
size
size attribute is an array (tensor<uint, x>) with the size (number of elements)
of each dimension for an object.
Note that size returns dimensions of the outermost tensor, not regarding base type.
Strings do not support this attribute.
m = [1, 2, 3; 4, 5, 6]
m.size # Output [2, 3]
v = [1, 2, 3]
v.size # Output: [3]
tensor<tensor<tensor<int, 5>, 5>, 3, 3> t = 1
t.size # Output: [3, 3]
numel
numel attribute indicates the number of element that an object contains.
Note that numel returns number of elements of the outermost tensor,
not regarding base type.
Scalars and strings do not support this attribute.
m = [1, 2, 3; 4, 5, 6]
m.numel # Output 6
v = [1, 2, 3]
v.numel # Output: 3
tensor<tensor<tensor<int, 5>, 5>, 3, 3> t = 1
t.size # Output: 9
rows
rows attribute indicates the number of rows of an object.
rows acts as an alias for .size[0] and can be used on arbitrary tensor types.
Scalars and strings do not support this attribute.
m = [1, 2, 3; 4, 5, 6]
m.rows # Output: 2
v = [1, 2, 3]
v.rows # Output: 1
s = 3
s.rows # Output: 1
tensor<int, 2, 3, 4> t = 1
t.rows # Output: 9
cols
cols attribute indicates the number of columns of an object.
cols acts as an alias for .size[1] and can be used on tensor types
with two or more dimensions.
Scalars and strings do not support this attribute.
m = [1, 2, 3; 4, 5, 6]
m.cols # Output: 3
tensor<int, 2, 3, 4> t = 1
t.cols # Output: 3
Built-in functions
min
min(x) - Finds minimum value in x using innermost reduction
min!(x) - Finds minimum value in x using overlapping reduction
Only numeric scalar and tensor values can be passed as an argument to min(x).
a = [1, 2, 3]
b = [1, 2, 3; 1, 2, 3]
c = [1, 2, 3 | 1, 2, 3]
d = [a, a, a]
min_a = min(a) # Output: 1
min_b = min(b) # Output: 1
min_c = min(c) # Output: 1
if min([t.in1, t.in2]) < n.min_threshold:
x = 0
max
max(x) - Finds maximum value in x using innermost reduction
max!(x) - Finds maximum value in x using overlapping reduction
Only numeric scalar and tensor values can be passed as an argument to max(x).
a = [1, 2, 3]
b = [1, 2, 3; 1, 2, 3]
c = [1, 2, 3 | 1, 2, 3]
d = [a, a, a]
max_a = max(a) # Output: 3
max_b = max(b) # Output: 3
max_c = max(c) # Output: 3
if max([t.in1, t.in2]) > n.max_threshold:
x = 0
all
all(arg) - return true if all elements of the arg are true using innermost reduction
all!(arg) - return true if all elements of the arg are true using overlapping reduction
a = [1, 2, 3]
b = [4, 5, -1]
c = a > b # [false, false, true]
d = all(c) # false
if all(a > b)
x = 1
else
x = 0 # this branch is executed
a = [[1, 2, 3], [5, 5, 5]]
b = [[4, 5, -1], [4, 4, 4]]
c = a > b # [[false, false, true], [true, true, true]]
d = all(c) # [all([false, false, true]), all([true, true, true])]
# [false, true]
e = all(all(c)) # false
if all(all(a > b))
x = 1
else
x = 0 # this branch is executed
any
any(arg) - return true if any element of the arg is true using innermost reduction
any(arg) - return true if any element of the arg is true using overlapping reduction
a = [1, 2, 3]
b = [4, 5, -1]
c = a > b # [false, false, true]
d = any(c) # true
if any(a > b)
x = 1 # this branch is executed
else
x = 0
a = [[1, 2, 3], [5, 5, 5]]
b = [[4, 5, -1], [4, 4, 4]]
c = a > b # [[false, false, true], [true, true, true]]
d = any(c) # [any([false, false, true]), any([true, true, true])]
# [true, true]
e = any(any(c)) # true
if any(any(a > b))
x = 1 # this branch is executed
else
x = 0
isnan
isnan(x) - checks whether the x is nan. If so, returns true.
Otherwise, the return value is false.
The result is of the same dimension as x.
Examples:
sc = 0
sc_nan = nan
vec = [1, 0, nan]
mat = [1, 0, nan; nan, -1, 0]
sc_no = isnan(sc) # `sc_no` is false
sc_yes = isnan(sc_nan) # `sc_yes` is true
vec_nan_check = isnan(vec) # [false, false, true]
mat_nan_check = isnan(mat) # [false, false, true; true, false, false]
getbit
getbit(base, index) - return bit from base at position index.
For tensor base, either single bit can be extracted via scalar index, or different
bits of corresponding scalars can be extracted via same dimension index tensor.
Scalar type (or root scalar type) of base and index must be uint.
If base is scalar, index must also be scalar.
If base if tensor, index can either be scalar or tensor of same dimensions.
setbit
setbit(base, index, value) - return new tensor constructed by setting
base bit at position index to value of lowest bit of value.
For tensor base, either single position bit can be set for all elements via scalar
index, or different bits of corresponding scalars can be set via same dimension index
tensor. Scalar type (or root scalar type) of base, index and value must be uint.
If base is scalar, index and value must also be scalar.
If base if tensor, index and value can either be scalar or tensor of same
dimensions.
Built-ins mapped to math.h counterparts.
Directly mapped functions
The TML maps following built-in functions to direct math.h counterparts:
sincostanasinacosatanfloorceilroundtruncabs(maps tofabs)loglog10sqrt
All of the above built-in functions can accept scalars and tensors.
If argument is a scalar, function is directly called and return type is real.
If argument is a tensor, function is applied to every scalar at the root nestin level and
return type is tensor of same dimensions and nesting level,
but with real as root scalar type.
sc = 3
res1 = sin(3)
vec = [1, 2, 3]
res2 = sin(vec) # TML unpacks the call to each of the element
# of the `vec` so the `res2` is equal to
# [sin(1), sin(2), sin(3)]
tensor<tensor<tensor<int, 5>, 5>, 5> t = 5
sin_t = sin(t) # tensor<tensor<tensor<real, 5>, 5>, 5>
TML similarly maps the following constants to the math.h counterparts.
- M_PI
- M_E
atan2
Function atan2(a, b) is mapped to C counterpart, but with the following rules:
- If both parameters are scalars, return type is
real - If one parameter is scalar and other is tensor, return type is tensor but with
realas root scalar type - If both parameters are tensors, they must have same nesting level and same dimensions
on all nesting levels. Return is tensor but with
realas root scalar type