For the complete Mojo documentation index, see llms.txt. Markdown versions of all pages are available by appending .md to any URL (e.g. /docs/manual/basics.md).
Span
struct Span[mut: Bool, //, T: AnyType, origin: Origin[mut=mut], *, address_space: AddressSpace = .GENERIC]
A non-owning view of contiguous data.
Parameters
- mut (
Bool): Whether the span is mutable. - T (
AnyType): The type of the elements in the span. - origin (
Origin[mut=mut]): The origin of the Span. - address_space (
AddressSpace): The address space of the data the span views.
Implemented traits
AnyType,
Boolable,
Copyable,
Defaultable,
Deinitable,
DevicePassable (where (address_space == AddressSpace.GENERIC)),
Hashable (where conforms_to(T, Hashable) and (address_space == AddressSpace.GENERIC)),
ImplicitlyCopyable,
Iterable (where (address_space == AddressSpace.GENERIC)),
IterableOwned (where conforms_to(T, Copyable) and (address_space == AddressSpace.GENERIC)),
Movable,
RegisterPassable,
Sized,
TrivialRegisterPassable,
Writable (where conforms_to(T, Writable) and (address_space == AddressSpace.GENERIC))
comptime members
device_type
comptime device_type = Span[T, origin, address_space=address_space]
The device-side type for this Span.
Immutable
comptime Immutable = Span[T, origin_of(_mlir_origin), address_space=address_space]
The immutable version of the Span.
IteratorOwnedType
comptime IteratorOwnedType = _SpanIter[T(Copyable), origin]
The owned iterator type for this Span.
IteratorType
comptime IteratorType[iterable_mut: Bool, //, iterable_origin: Origin[mut=iterable_mut]] = _SpanIter[T(Copyable), origin]
The iterator type for this Span.
Parameters
- iterable_mut (
Bool): Whether the iterable is mutable. - iterable_origin (
Origin[mut=iterable_mut]): The origin of the iterable.
Methods
__init__
def __init__() -> Self
Create an empty / zero-length span.
def __init__(*, unsafe_ptr: Pointer[T, origin, address_space=address_space], length: Int) -> Self
Unsafe construction from a pointer and length.
Args:
- unsafe_ptr (
Pointer[T, origin, address_space=address_space]): The underlying pointer of the span. - length (
Int): The length of the view.
@implicit
def __init__(ref[origin] list: List[T]) -> Self
Construct a Span from a List.
Args:
- list (
List[T]): The list to which the span refers.
@implicit
def __init__(ref[origin, address_space] array: Array[T]) -> Self
Construct a Span from an Array.
Args:
- array (
Array[T]): The array to which the span refers.
__bool__
def __bool__(self) -> Bool
Check if a span is non-empty.
Returns:
Bool: True if a span is non-empty, False otherwise.
__getitem__
def __getitem__(self, idx: Int, /) -> ref[origin, address_space] T
Gets the span element at the given index.
Args:
- idx (
Int): The index of the element.
Returns:
ref[origin, address_space] T: A reference to the element at the given index.
def __getitem__(self, idx: T) -> ref[origin, address_space] T
Gets the span element at the given index.
Args:
- idx (
T): The index of the element.
Returns:
ref[origin, address_space] T: A reference to the element at the given index.
def __getitem__(self, idx: IntLiteral) -> ref[origin, address_space] T
Gets the span element at the given index.
Args:
- idx (
IntLiteral): The index of the element.
Returns:
ref[origin, address_space] T: A reference to the element at the given index.
def __getitem__(self, slc: ContiguousSlice) -> Self
Get a new span from a slice of the current span.
Aborts if slc's start or end index is out of bounds (valid range is
0 to len(self), inclusive), or if start is greater than end.
Negative indices are not supported and always abort.
Args:
- slc (
ContiguousSlice): The slice specifying the range of the new subslice.
Returns:
Self: A new span that points to the same data as the current span.
__eq__
def __eq__(self: Span[T], rhs: Span[T]) -> Bool where conforms_to(T, Equatable)
Verify if span is equal to another span.
Args:
- rhs (
Span[T]): The span to compare against.
Returns:
Bool: True if the spans are equal in length and contain the same elements, False otherwise.
__ne__
def __ne__(self: Span[T], rhs: Span[T]) -> Bool where conforms_to(T, Equatable)
Verify if span is not equal to another span.
Args:
- rhs (
Span[T]): The span to compare against.
Returns:
Bool: True if the spans are not equal in length or contents, False otherwise.
__contains__
def __contains__[dtype: DType, //](self: Span[Scalar[dtype], address_space=self.address_space], value: Scalar[dtype]) -> Bool
Verify if a given value is present in the Span.
Parameters:
- dtype (
DType): The DType of the scalars stored in the Span.
Args:
- value (
Scalar[dtype]): The value to find.
Returns:
Bool: True if the value is contained in the list, False otherwise.
def __contains__(self: Span[T], value: T) -> Bool where conforms_to(T, Equatable)
Verify if a given value is present in the span.
Performs a linear scan over all elements comparing with ==.
Args:
- value (
T): The value to find.
Returns:
Bool: True if the value is contained in the span, False
otherwise.
get_type_name
static def get_type_name() -> String
Gets this type's name, for use in error messages when handing arguments to kernels.
Returns:
String: This type's name.
__iter__
def __iter__(var self) -> Self.IteratorOwnedType where (address_space == AddressSpace.GENERIC)
Consume the span and return an iterator over its elements.
Returns:
Self.IteratorOwnedType: An iterator over the elements of the span.
def __iter__(ref self) -> _SpanIter[T(Copyable), origin] where (address_space == AddressSpace.GENERIC)
Get an iterator over the elements of the Span.
Returns:
_SpanIter[T(Copyable), origin]: An iterator over the elements of the Span.
__reversed__
def __reversed__(self) -> _SpanIter[T(Copyable), origin, False] where (address_space == AddressSpace.GENERIC)
Iterate backwards over the Span.
Returns:
_SpanIter[T(Copyable), origin, False]: A reversed iterator of the Span elements.
__len__
def __len__(self) -> Int
Returns the length of the span. This is a known constant value.
Returns:
Int: The size of the span.
write_to
def write_to(self, mut writer: T) where conforms_to(T, Writable) and (address_space == AddressSpace.GENERIC)
Write this span to a Writer.
Args:
- writer (
T): The object to write to.
write_repr_to
def write_repr_to(self, mut writer: T) where conforms_to(T, Writable) and (address_space == AddressSpace.GENERIC)
Write this span to a Writer.
Args:
- writer (
T): The object to write to.
__hash__
def __hash__[H: Hasher](self, mut hasher: H) where conforms_to(T, Hashable) and (address_space == AddressSpace.GENERIC)
Updates hasher with the hash of each element in the span.
Parameters:
- H (
Hasher): The hasher type.
Args:
- hasher (
H): The hasher instance.
as_imm
def as_imm(self) -> Self.Immutable
Return an immutable version of this Span.
Returns:
Self.Immutable: An immutable version of the same Span.
unsafe_get
def unsafe_get(self, idx: T) -> ref[origin, address_space] T
Get a reference to the element at index without bounds checking.
Safety:
- This function does not do bounds checking and assumes the provided index is in: [0, len(self)). Not upholding this contract will result in undefined behavior.
- This function does not support wraparound for negative indices.
Args:
- idx (
T): The index of the element to get.
Returns:
ref[origin, address_space] T: A reference to the element at the specified index.
unsafe_ptr
def unsafe_ptr(self) -> Pointer[T, origin, address_space=address_space]
Retrieves a pointer to the underlying memory, or a dangling pointer if the span doesn't point to anything.
You should use the len of this Span to determine if the pointer
is valid for reads and writes.
Returns:
Pointer[T, origin, address_space=address_space]: The pointer to the underlying memory.
as_ref
def as_ref(self) -> Pointer[T, origin, address_space=address_space]
Gets a Pointer to the first element of this span.
Returns:
Pointer[T, origin, address_space=address_space]: A Pointer pointing at the first element of this span.
copy_from
def copy_from(self: Span[T], other: Span[T]) where conforms_to(T, Copyable & Deinitable)
Performs an element wise copy from all elements of other into all elements of self.
Args:
- other (
Span[T]): TheSpanto copy all elements from.
fill
def fill(self, value: T) where mut and conforms_to(T, Copyable & Deinitable) if (address_space == AddressSpace.GENERIC) else (address_space == AddressSpace.GENERIC) or conforms_to(T, TrivialRegisterPassable)
Fill the memory that a span references with a given value.
Constraints:
The span must be mutable. A register-passable element type works in any address space. All other element types require the span to view the default (generic) address space.
Args:
- value (
T): The value to assign to each element.
unsafe_swap_elements
def unsafe_swap_elements(self: Span[T], a: Int, b: Int) where conforms_to(T, Movable)
Swap the values at indices a and b without performing bounds checking.
Safety:
- Both
aandbmust be in: [0, len(self)).
Args:
swap_elements
def swap_elements(self: Span[T], a: Int, b: Int) where conforms_to(T, Movable)
Swap the values at indices a and b.
Args:
Raises:
If a or b are larger than the length of the span.
__merge_with__
def __merge_with__[other_type: AnyStruct[Span[T, other_type.origin, address_space=address_space]]](self) -> Span[T, origin_of(origin, other_type.origin), address_space=address_space]
Returns a pointer merged with the specified other_type.
Parameters:
- other_type (
AnyStruct[Span[T, other_type.origin, address_space=address_space]]): The type of the pointer to merge with.
Returns:
Span[T, origin_of(origin, other_type.origin), address_space=address_space]: A pointer merged with the specified other_type.
reverse
def reverse[dtype: DType, //](self: Span[Scalar[dtype]])
Reverse the elements of the Span inplace.
Parameters:
- dtype (
DType): The DType of the scalars theSpanstores.
apply
def apply[dtype: DType, //](self: Span[Scalar[dtype]], func: T)
Apply the function to the Span inplace.
Parameters:
- dtype (
DType): The DType.
Args:
- func (
T): The function to evaluate.
def apply[dtype: DType, //](self: Span[Scalar[dtype]], func: T, *, cond: T)
Apply the function to the Span inplace where the condition is True.
Parameters:
- dtype (
DType): The DType.
Args:
- func (
T): The function to evaluate. - cond (
T): The condition to apply the function.
count
def count[dtype: DType, //, F: def[w: SIMDLength](v: SIMD[dtype, w]) -> SIMD[.bool, w]](self: Span[Scalar[dtype], address_space=self.address_space], func: F) -> Int
Count the amount of times the function returns True.
Parameters:
- dtype (
DType): The DType. - F (
def[w: SIMDLength](v: SIMD[dtype, w]) -> SIMD[.bool, w]): The function type to evaluate.
Args:
- func (
F): The function value to evaluate.
Returns:
Int: The amount of times the function returns True.
unsafe_subspan
def unsafe_subspan(self, *, offset: Int, length: Int) -> Self
Returns a subspan of the current span.
Safety: This function does not do bounds checking and assumes the current span contains the specified subspan.
Args:
- offset (
Int): The starting offset of the subspan (self._data + offset). - length (
Int): The length of the new subspan.
Returns:
Self: A new span representing the specified subspan.
binary_search_by
def binary_search_by[func: def(T) thin -> Int](self: Span[T]) -> Optional[Int]
Finds an element using binary search with a custom comparison function.
The comparison function should return:
- A negative value if the element is less than the target
- Zero if the element matches the target
- A positive value if the element is greater than the target
Notes:
This function assumes that self is sorted according to the ordering
defined by func. If not sorted, the result is unspecified.
Example:
var data: List[String] = ["a", "bb", "ccc"]
var span = Span(data)
# Search for "bb"
def cmp(elem: String) -> Int:
if elem < "bb":
return -1
elif elem > "bb":
return 1
else:
return 0
var index = span.binary_search_by[cmp]()
if index:
print("Found at index: ", index.value())
else:
print("Not found")
Parameters:
- func (
def(T) thin -> Int): A function that takes an element and returns an Int representing the comparison result.
Returns:
Optional[Int]: Returns the index of the matching element if found, None otherwise.
def binary_search_by[FuncType: def(T) -> Int](self: Span[T], func: FuncType) -> Optional[Int]
Finds an element using binary search with a custom comparison function.
The comparison function should return:
- A negative value if the element is less than the target
- Zero if the element matches the target
- A positive value if the element is greater than the target
Notes:
This function assumes that self is sorted according to the ordering
defined by func. If not sorted, the result is unspecified.
Example:
def main():
var data: List[String] = ["a", "bb", "ccc"]
var span = Span(data)
# Search for "bb"
def cmp(elem: String) {} -> Int:
if elem < "bb":
return -1
elif elem > "bb":
return 1
else:
return 0
var index = span.binary_search_by(cmp)
if index:
print("Found at index: ", index.value())
else:
print("Not found")
Parameters:
- FuncType (
def(T) -> Int): The type of the supplied function.
Args:
- func (
FuncType): A function that takes an element and returns an Int representing the comparison result.
Returns:
Optional[Int]: Returns the index of the matching element if found, None otherwise.
unsafe_deinit_elements
def unsafe_deinit_elements[U: Deinitable](self: Span[U])
Destroys every element, leaving the memory uninitialized.
Each element's deinitializer runs in place, in index order, so the storage behind the span can be reused or released without moving anything out of it.
Safety:
- Every element must hold a live
U. Deinitializing an element that was never initialized, or that was already deinitialized, is undefined behavior. - The elements are left uninitialized. Reading them, or deinitializing them a second time, is undefined behavior.
Parameters:
- U (
Deinitable): The span's element type.
unsafe_deinit_elements_with
def unsafe_deinit_elements_with[U: AnyType](self: Span[U], f: T, /)
Destroys every element by passing it to f, leaving the memory uninitialized.
This is the Deinitable-free counterpart to unsafe_deinit_elements:
each element is handed to f as an owned value, in index order, so a
span of elements that have no destructor of their own can still be
torn down. U is unconstrained, so this works for element types that
are neither Deinitable nor Movable.
Safety:
- Every element must hold a live
U. Deinitializing an element that was never initialized, or that was already deinitialized, is undefined behavior. - The elements are left uninitialized. Reading them, or deinitializing them a second time, is undefined behavior.
Parameters:
- U (
AnyType): The span's element type.
Args:
- f (
T): The function that consumes, and is responsible for disposing of, each element.
unsafe_assume_init
def unsafe_assume_init[U: AnyType](self: Span[MaybeUninit[U]]) -> Span[U, self.origin]
Reinterprets this span as a span of initialized U elements.
Safety:
- Every element must hold a live
U. Reading an element that was never initialized is undefined behavior.
Examples:
var storage = Array[MaybeUninit[Int], 3]()
var uninit = Span(storage)
for i in range(len(uninit)):
uninit[i].write(i + 1)
# SAFETY: the loop above wrote every element.
print(uninit.unsafe_assume_init()) # [1, 2, 3]
Parameters:
- U (
AnyType): The type held by this span'sMaybeUninitelements.
Returns:
Span[U, self.origin]: A span of the same length over the same memory, typed as U.
unsafe_init_with
def unsafe_init_with[U: AnyType](self: Span[MaybeUninit[U]], f: T, /) -> Span[U, self.origin]
Initializes every element with the result of f(i).
Safety:
- Writing over an element does not destroy what it held, so an
element already holding a live
Uleaks whatever thatUowns. Deinitialize those first.
Examples:
var storage = Array[MaybeUninit[Int], 5]()
var squares = Span(storage).unsafe_init_with(
lambda (i: Int) -> Int: i * i
)
print(squares) # [0, 1, 4, 9, 16]
Parameters:
- U (
AnyType): The type held by this span'sMaybeUninitelements.
Args:
- f (
T): A function called with each index in[0, len(self)), whose result is written to that position.
Returns:
Span[U, self.origin]: A span over the newly initialized elements, covering all of self.
unsafe_init_copy_from
def unsafe_init_copy_from[U: Copyable](self: Span[MaybeUninit[U]], copy_from: Span[U], /) -> Span[U, self.origin]
Initializes every element with a copy of the matching copy_from element.
Aborts if copy_from is not the same length as self.
Safety:
- Writing over an element does not destroy what it held, so an
element already holding a live
Uleaks whatever thatUowns. Deinitialize those first.
Examples:
var source: Array[Int, 3] = [1, 2, 3]
var storage = Array[MaybeUninit[Int], 3]()
var copied = Span(storage).unsafe_init_copy_from(source)
print(copied) # [1, 2, 3]
Parameters:
- U (
Copyable): The type held by this span'sMaybeUninitelements.
Args:
- copy_from (
Span[U]): The elements to copy, of the same length asself.
Returns:
Span[U, self.origin]: A span over the newly initialized elements, covering all of self.
unsafe_init_move_from
def unsafe_init_move_from[U: Movable](self: Span[MaybeUninit[U]], move_from: Span[U], /) -> Span[U, self.origin]
Initializes every element by moving out of the matching move_from element.
Aborts if move_from is not the same length as self.
Safety:
- Writing over an element does not destroy what it held, so an
element already holding a live
Uleaks whatever thatUowns. Deinitialize those first. - Every element of
move_fromis left uninitialized. Reading them, or letting their owner destroy them, is undefined behavior.
Examples:
var source: Array[String, 2] = ["a", "b"]
var storage = Array[MaybeUninit[String], 2]()
var moved = Span(storage).unsafe_init_move_from(source)
print(moved) # ["a", "b"]
# `source` now holds two uninitialized elements.
Parameters:
- U (
Movable): The type held by this span'sMaybeUninitelements.
Args:
- move_from (
Span[U]): The elements to move out of, of the same length asself.
Returns:
Span[U, self.origin]: A span over the newly initialized elements, covering all of self.