Skip to main content
Log in

Mojo struct

Tensor

struct Tensor[type: DType]

A tensor type which owns its underlying data and is parameterized on DType.

Example:

from max.tensor import Tensor, TensorSpec, TensorShape
from utils.index import Index

def main():
height = 256
width = 256
channels = 3

# Create the tensor of dimensions height, width, channels
# and fill with random values.
image = Tensor[DType.float32].rand(TensorShape(height, width, channels))

# Declare the grayscale image.
spec = TensorSpec(DType.float32, height, width)
gray_scale_image = Tensor[DType.float32](spec)

# Perform the RGB to grayscale transform.
for y in range(height):
for x in range(width):
r = image[y, x, 0]
g = image[y, x, 1]
b = image[y, x, 2]
gray_scale_image[Index(y, x)] = 0.299 * r + 0.587 * g + 0.114 * b

print(gray_scale_image.shape())
from max.tensor import Tensor, TensorSpec, TensorShape
from utils.index import Index

def main():
height = 256
width = 256
channels = 3

# Create the tensor of dimensions height, width, channels
# and fill with random values.
image = Tensor[DType.float32].rand(TensorShape(height, width, channels))

# Declare the grayscale image.
spec = TensorSpec(DType.float32, height, width)
gray_scale_image = Tensor[DType.float32](spec)

# Perform the RGB to grayscale transform.
for y in range(height):
for x in range(width):
r = image[y, x, 0]
g = image[y, x, 1]
b = image[y, x, 2]
gray_scale_image[Index(y, x)] = 0.299 * r + 0.587 * g + 0.114 * b

print(gray_scale_image.shape())

Parameters

  • type (DType): The underlying element type of the tensor.

Implemented traits

AnyType, CollectionElement, Copyable, EqualityComparable, Movable, Stringable, UnknownDestructibility, Writable

Methods

__init__

__init__(out self)

Default initializer for TensorShape.

__init__(out self, other: Self)

Creates a deep copy of an existing tensor.

Args:

  • other (Self): The tensor to copy from.

__init__(out self, *dims: Int)

Allocates a tensor using the shape provided.

Args:

  • *dims (Int): The tensor dimensions.

__init__(out self, owned shape: TensorShape)

Allocates a tensor using the shape provided.

Args:

  • shape (TensorShape): The tensor shape.

__init__(out self, owned spec: TensorSpec)

Allocates a tensor using the spec provided.

Args:

  • spec (TensorSpec): The tensor spec.

__init__(out self, shape: Tuple[element_types])

Allocates a tensor using the shape provided.

Args:

  • shape (Tuple[element_types]): The tensor shape.

__init__(out self, owned shape: TensorShape, owned ptr: UnsafePointer[SIMD[type, 1]])

Initializes a Tensor from the pointer and shape provided. The caller relinquishes the ownership of the pointer being passed in.

Args:

  • shape (TensorShape): The tensor shapes.
  • ptr (UnsafePointer[SIMD[type, 1]]): The data pointer.

__init__(out self, owned spec: TensorSpec, owned ptr: UnsafePointer[SIMD[type, 1]])

Initializes a Tensor from the pointer and shape provided. The caller relinquishes the ownership of the pointer being passed in.

Args:

  • spec (TensorSpec): The tensor spec.
  • ptr (UnsafePointer[SIMD[type, 1]]): The data pointer.

__init__(out self, shape: TensorShape, *data: SIMD[type, 1])

Initializes a Tensor from the shape and data provided. If a single scalar is passed in, then the scalar is splatted to all elements in the tensor.

Args:

  • shape (TensorShape): The tensor shape.
  • *data (SIMD[type, 1]): Elements to place into the created tensor.

__init__(out self, shape: TensorShape, owned list: List[SIMD[type, 1], hint_trivial_type])

Initializes a 1-dimensional Tensor from the provided list.

Args:

  • shape (TensorShape): The tensor shape.
  • list (List[SIMD[type, 1], hint_trivial_type]): The list to construct this Tensor from.

__init__(out self, owned list: List[SIMD[type, 1], hint_trivial_type])

Initializes a 1-dimensional Tensor from the provided list.

Args:

  • list (List[SIMD[type, 1], hint_trivial_type]): The list to construct this Tensor from.

__copyinit__

__copyinit__(out self, other: Self)

Creates a deep copy of an existing tensor.

Args:

  • other (Self): The tensor to copy from.

__del__

__del__(owned self)

Delete the spec and release any owned memory.

__getitem__

__getitem__(self, index: Int) -> SIMD[type, 1]

Gets the value at the specified index.

Args:

  • index (Int): The index of the value to retrieve.

Returns:

The value at the specified indices.

__getitem__(self, *indices: Int) -> SIMD[type, 1]

Gets the value at the specified indices.

Args:

  • *indices (Int): The indices of the value to retrieve.

Returns:

The value at the specified indices.

__getitem__(self, indices: VariadicList[Int]) -> SIMD[type, 1]

Gets the value at the specified indices.

Args:

  • indices (VariadicList[Int]): The indices of the value to retrieve.

Returns:

The value at the specified indices.

__getitem__[len: Int](self, indices: IndexList[len]) -> SIMD[type, 1]

Gets the SIMD value at the specified indices.

Parameters:

  • len (Int): The length of the indecies.

Args:

  • indices (IndexList[len]): The indices of the value to retrieve.

Returns:

The value at the specified indices.

__setitem__

__setitem__(mut self, index: Int, val: SIMD[type, 1])

Sets the value at the specified index.

Args:

  • index (Int): The index of the value to set.
  • val (SIMD[type, 1]): The value to store.

__setitem__(mut self, indices: VariadicList[Int], val: SIMD[type, 1])

Sets the value at the specified indices.

Args:

  • indices (VariadicList[Int]): The indices of the value to set.
  • val (SIMD[type, 1]): The value to store.

__setitem__[len: Int](mut self, indices: IndexList[len], val: SIMD[type, 1])

Sets the value at the specified indices.

Parameters:

  • len (Int): The length of the indecies.

Args:

  • indices (IndexList[len]): The indices of the value to set.
  • val (SIMD[type, 1]): The value to store.

__eq__

__eq__(self, other: Self) -> Bool

Returns True if the two tensors are the same and False otherwise.

Args:

  • other (Self): The other Tensor to compare against.

Returns:

True if the two tensors are the same and False otherwise.

__ne__

__ne__(self, other: Self) -> Bool

Returns True if the two tensors are not the same and False otherwise.

Args:

  • other (Self): The other Tensor to compare against.

Returns:

True if the two tensors are the not the same and False otherwise.

__add__

__add__(self, other: Self) -> Self

Adds this tensor with another tensor.

Constraints:

The two tensors must have the same rank, type, and dimensions.

Args:

  • other (Self): The RHS of the add operation.

Returns:

The addition of both tensors.

__add__(self, other: SIMD[type, 1]) -> Self

Adds this tensor with a scalar.

Args:

  • other (SIMD[type, 1]): The RHS of the add operation.

Returns:

The addition result.

__sub__

__sub__(self, other: Self) -> Self

Subtracts a tensor from this tensor.

Constraints:

The two tensors must have the same rank, type, and dimensions.

Args:

  • other (Self): The RHS of the sub operation.

Returns:

The addition of both tensors.

__sub__(self, other: SIMD[type, 1]) -> Self

Subtracts a scalar from this tensor.

Args:

  • other (SIMD[type, 1]): The RHS of the sub operation.

Returns:

The subtraction result.

__mul__

__mul__(self, other: Self) -> Self

Multiplies this tensor with another tensor.

Constraints:

The two tensors must have the same rank, type, and dimensions.

Args:

  • other (Self): The RHS of the mul operation.

Returns:

The multiplication of both tensors.

__mul__(self, other: SIMD[type, 1]) -> Self

Multiplies this tensor with a scalar.

Args:

  • other (SIMD[type, 1]): The RHS of the mul operation.

Returns:

The multiplication result.

__truediv__

__truediv__(self, other: Self) -> Self

Divides this tensor by another tensor.

TODO: Change the return type if inputs are int

Constraints:

The two tensors must have the same rank, type, and dimensions.

Args:

  • other (Self): The RHS of the div operation.

Returns:

The division of both tensors.

__truediv__(self, other: SIMD[type, 1]) -> Self

Divides this tensor by a scalar.

Args:

  • other (SIMD[type, 1]): The RHS of the div operation.

Returns:

The division result.

__pow__

__pow__(self, exp: Int) -> Self

Returns a copy of the tensor with each element raised to the power of exponent.

Constraints:

For integral values the exponent cannot be negative.

Args:

  • exp (Int): Integer power to raise tensor to.

Returns:

An exponentiated copy of tensor.

__radd__

__radd__(self, other: SIMD[type, 1]) -> Self

Adds this tensor with a scalar.

Args:

  • other (SIMD[type, 1]): The LHS of the add operation.

Returns:

The addition result.

__rsub__

__rsub__(self, other: SIMD[type, 1]) -> Self

Subtracts this tensor from a scalar.

Args:

  • other (SIMD[type, 1]): The LHS of the sub operation.

Returns:

The addition result.

__rmul__

__rmul__(self, other: SIMD[type, 1]) -> Self

Multiplies this tensor with a scalar.

Args:

  • other (SIMD[type, 1]): The LHS of the mul operation.

Returns:

The multiplication result.

__rtruediv__

__rtruediv__(self, other: SIMD[type, 1]) -> Self

Divides a scalar by this tensor, broadcasting elementwise.

Args:

  • other (SIMD[type, 1]): The LHS of the div operation.

Returns:

The division result.

__ipow__

__ipow__(mut self, exponent: Int)

In-place pow operator.

Raises each element of the tensor to the power of exponent in place.

Constraints:

For integral values the exponent cannot be negative.

Args:

  • exponent (Int): Integer power to raise tensor to.

rand

static rand(owned shape: TensorShape) -> Self

Constructs a new tensor with the specified shape and fills it with random elements.

Args:

  • shape (TensorShape): The tensor shape.

Returns:

A new tensor of specified shape and filled with random elements.

randn

static randn(owned shape: TensorShape, mean: SIMD[float64, 1] = SIMD(#kgen.float_literal<0|1>), variance: SIMD[float64, 1] = SIMD(#kgen.float_literal<1|1>)) -> Self

Constructs a new Tensor from the shape and fills it with random values from a Normal(mean, variance) distribution.

Constraints:

The type should be floating point.

Args:

  • shape (TensorShape): The shape of the Tensor to fill with random values.
  • mean (SIMD[float64, 1]): Normal distribution mean.
  • variance (SIMD[float64, 1]): Normal distribution variance.

Returns:

A Tensor filled with random dtype samples from Normal(mean, variance).

ireshape

ireshape(mut self, new_shape: TensorShape)

(Inplace) Reshapes the tensor by assigning it a new shape.

Args:

  • new_shape (TensorShape): The new shape.

reshape

reshape(mut self, new_shape: TensorShape) -> Self

Returns a reshaped tensor.

Args:

  • new_shape (TensorShape): The new shape.

Returns:

A Tensor that is a reshaped version of the original tensor.

astype

astype[new_type: DType](self) -> Tensor[new_type]

Copy the Tensor with elements cast to the new type.

Parameters:

  • new_type (DType): The type to cast the values to.

Returns:

A new tensor with the same values but the new type.

clip

clip(self, lower_bound: SIMD[type, 1], upper_bound: SIMD[type, 1]) -> Self

Clips the values of the tensor.

Args:

  • lower_bound (SIMD[type, 1]): The lower bound.
  • upper_bound (SIMD[type, 1]): The upper bound.

Returns:

A clipped version of the tensor.

unsafe_ptr

unsafe_ptr(self) -> UnsafePointer[SIMD[type, 1]]

Gets the underlying Data pointer to the Tensor.

Returns:

The underlying data pointer of the tensor.

unsafe_uint8_ptr

unsafe_uint8_ptr(self) -> UnsafePointer[SIMD[uint8, 1]]

Gets the underlying Data pointer to the Tensor.

Returns:

The underlying data pointer of the tensor.

rank

rank(self) -> Int

Gets the rank of the tensor.

Returns:

The rank of the tensor.

num_elements

num_elements(self) -> Int

Gets the total number of elements in the tensor.

Returns:

The total number of elements in the tensor.

bytecount

bytecount(self) -> Int

Gets the total bytecount of the tensor.

Returns:

The total bytecount of the tensor.

spec

spec(self) -> TensorSpec

Gets the specification of the tensor.

Returns:

The underlying tensor spec of the tensor.

shape

shape(self) -> TensorShape

Gets the shape of the tensor.

Returns:

The underlying tensor shape of the tensor.

dim

dim(self, idx: Int) -> Int

Gets the dimension at the specified index.

Args:

  • idx (Int): The dimension index.

Returns:

The dimension at the specified index.

__str__

__str__(self) -> String

Gets the tensor as a string.

Returns:

A compact string of the tensor.

write_to

write_to[W: Writer](self, mut writer: W)

Formats this Tensor to the provided Writer.

Parameters:

  • W (Writer): A type conforming to the Writable trait.

Args:

  • writer (W): The object to write to.

__repr__

__repr__(self) -> String

Gets the tensor as a string.

Returns:

A compact string representation of the tensor.

load

load[*, width: Int = 1](self, index: Int) -> SIMD[type, width]

Gets the SIMD value at the specified index.

Parameters:

  • width (Int): The SIMD width of the vector.

Args:

  • index (Int): The index of the value to retrieve.

Returns:

The SIMD value at the specified indices.

load[*, width: Int = 1](self, *indices: Int) -> SIMD[type, width]

Gets the SIMD value at the specified indices.

Parameters:

  • width (Int): The SIMD width of the vector.

Args:

  • *indices (Int): The indices of the value to retrieve.

Returns:

The SIMD value at the specified indices.

load[*, width: Int = 1](self, indices: VariadicList[Int]) -> SIMD[type, width]

Gets the SIMD value at the specified indices.

Parameters:

  • width (Int): The SIMD width of the vector.

Args:

  • indices (VariadicList[Int]): The indices of the value to retrieve.

Returns:

The SIMD value at the specified indices.

load[len: Int, /, *, width: Int = 1](self, indices: IndexList[len]) -> SIMD[type, width]

Gets the SIMD value at the specified indices.

Parameters:

  • len (Int): The length of the indecies.
  • width (Int): The SIMD width of the vector.

Args:

  • indices (IndexList[len]): The indices of the value to retrieve.

Returns:

The SIMD value at the specified indices.

static load(path: Path) -> Self

Read tensor from a file. The path should be a file saved with Tensor.save method.

Args:

  • path (Path): Path to the output file.

Returns:

The tensor read from file.

store

store[*, width: Int = 1](mut self, index: Int, val: SIMD[type, width])

Sets the SIMD value at the specified index.

Parameters:

  • width (Int): The SIMD width of the vector.

Args:

  • index (Int): The index of the value to set.
  • val (SIMD[type, width]): The SIMD value to store.

store[*, width: Int = 1](mut self, indices: VariadicList[Int], val: SIMD[type, width])

Sets the SIMD value at the specified indices.

Parameters:

  • width (Int): The SIMD width of the vector.

Args:

  • indices (VariadicList[Int]): The indices of the value to set.
  • val (SIMD[type, width]): The SIMD value to store.

store[len: Int, /, *, width: Int = 1](mut self, indices: IndexList[len], val: SIMD[type, width])

Sets the SIMD value at the specified indices.

Parameters:

  • len (Int): The length of the indecies.
  • width (Int): The SIMD width of the vector.

Args:

  • indices (IndexList[len]): The indices of the value to set.
  • val (SIMD[type, width]): The SIMD value to store.

tofile

tofile(self, path: Path)

Write values to a file.

Args:

  • path (Path): Path to the output file.

fromfile

static fromfile(path: Path) -> Self

Read tensor from a file.

Args:

  • path (Path): Path to the output file.

Returns:

The tensor read from file.

save

save(self, path: Path)

Save given tensor to file. This method preserves shape and datatype information.

Args:

  • path (Path): Path of file.