data#
- group Data abstractions and allocators
- Defines - 
LEGATE_TRUE_WHEN_DEBUG#
 - Typedefs - 
template<typename VAL, std::int32_t DIM = 1>
 using Buffer = Legion::DeferredBuffer<VAL, DIM>#
- A typed buffer class for intra-task temporary allocations. - Values in a buffer can be accessed by index expressions with Point objects, or via a raw pointer to the underlying allocation, which can be queried with the - Buffer::ptr()method.- Buffer is an alias to Legion::DeferredBuffer. - Note on using temporary buffers in CUDA tasks: - We use - Legion::DeferredBuffer, whose lifetime is not connected with the CUDA stream(s) used to launch kernels. The buffer is allocated immediately at the point when create_buffer() is called, whereas the kernel that uses it is placed on a stream, and may run at a later point. Normally a- Legion::DeferredBufferis deallocated automatically by Legion once all the kernels launched in the task are complete. However, a- Legion::DeferredBuffercan also be deallocated immediately using- Legion::DeferredBuffer::destroy(), which is useful for operations that want to deallocate intermediate memory as soon as possible. This deallocation is not synchronized with the task stream, i.e. it may happen before a kernel which uses the buffer has actually completed. This is safe as long as we use the same stream on all GPU tasks running on the same device (which is guaranteed by the current implementation of TaskContext::get_task_stream()), because then all the actual uses of the buffer are done in order on the one stream. It is important that all library CUDA code uses TaskContext::get_task_stream(), and all CUDA operations (including library calls) are enqueued on that stream exclusively. This analysis additionally assumes that no code outside of Legate is concurrently allocating from the eager pool, and that it’s OK for kernels to access a buffer even after it’s technically been deallocated.
 - Functions - 
template<typename VAL, std::int32_t DIM>
 Buffer<VAL, DIM> create_buffer(
- const Point<DIM> &extents,
- Memory::Kind kind = Memory::Kind::NO_MEMKIND,
- std::size_t alignment = DEFAULT_ALIGNMENT
- Creates a Buffer of specific extents. - Parameters:
- extents – Extents of the buffer 
- kind – Kind of the target memory (optional). If not given, the runtime will pick automatically based on the executing processor 
- alignment – Alignment for the memory allocation (optional) 
 
- Returns:
- A Buffer object 
 
 
 - 
template<typename VAL, std::int32_t DIM>
 Buffer<VAL, DIM> create_buffer(
- const Point<DIM> &extents,
- Memory mem,
- std::size_t alignment = DEFAULT_ALIGNMENT
- Creates a Buffer of specific extents. - Parameters:
- extents – Extents of the buffer. 
- mem – The target memory of the buffer. 
- alignment – Alignment for the memory allocation (optional). 
 
- Returns:
- A Buffer object. 
 
 
 - 
template<typename VAL>
 Buffer<VAL> create_buffer(
- std::size_t size,
- Memory::Kind kind = Memory::Kind::NO_MEMKIND,
- std::size_t alignment = DEFAULT_ALIGNMENT
- Creates a Buffer of a specific size. Always returns a 1D Buffer. 
 
 - 
template<typename VAL>
 Buffer<VAL> create_buffer(
- std::size_t size,
- Memory mem,
- std::size_t alignment = DEFAULT_ALIGNMENT
- Creates a Buffer of a specific size. Always returns a 1D Buffer. 
 
 - 
Scalar null()#
- Creates a null - Scalar- Null scalars hold a copy of the singleton “Null” - Typebut hold no physical data or allocation. Their- Typemay be queried, but they have zero size, and return- nullptrwhen- Scalar::ptr()is called on them. They are useful as tombstone values, or to represent invalid data.- Returns:
- A null - Scalar
 
 - inline InlineAllocation(
- void *ptr_,
- std::vector<std::size_t> strides_,
- mapping::StoreTarget target_
 
 - Variables - 
std::size_t DEFAULT_ALIGNMENT = 16#
- The default alignment for memory allocations. 
 - 
class ScopedAllocator
- #include <legate/data/allocator.h>A simple allocator backed by Buffer objects. For each allocation request, this allocator creates a 1D Buffer of std::int8_tand returns the raw pointer to it. By default, all allocations are deallocated when the allocator is destroyed, and can optionally be made alive until the task finishes by making the allocator unscoped.ScopedAllocatoris copyable (primarily so types derived fromScopedAllocatorcan satisfy theAllocator named requirement <>_), but all copies share a reference to the sameScopedAllocator::Impl, so scoped deallocation will not occur until all copies go out of scope.Public Functions - explicit ScopedAllocator(
- Memory::Kind kind,
- bool scoped = true,
- std::size_t alignment = DEFAULT_ALIGNMENT
- Create a - ScopedAllocatorfor a specific memory kind.- Parameters:
- kind – - Memory::Kindof the memory on which the Buffer should be created
- scoped – If true, the allocator is scoped; i.e., lifetimes of allocations are tied to the allocator’s lifetime. Otherwise, the allocations are alive until the task finishes (and unless explicitly deallocated). 
- alignment – Alignment for the allocations from - allocate()(use- allocate_aligned()to specify a different alignment)
 
- Throws:
- std::domain_error – If - alignmentis 0, or not a power of 2.
 
 
 - 
void *allocate(std::size_t bytes)
- Allocates a contiguous buffer of the given - Memory::Kind- When the allocator runs out of memory, the runtime will fail with an error message. Otherwise, the function returns a valid pointer. If - bytesis- 0, returns- nullptr.- See also - See also - Parameters:
- bytes – Size of the allocation in bytes 
- Returns:
- A raw pointer to the allocation 
 
 - 
void *allocate_aligned(std::size_t bytes, std::size_t alignment)
- Allocates a contiguous buffer of the given - Memory::Kindwith a specified alignment.- See also - See also - Parameters:
- bytes – Size of the allocation in bytes. 
- alignment – Alignment in bytes of this allocation. 
 
- Throws:
- std::domain_error – If - alignmentis 0, or not a power of 2.
- Returns:
- A raw pointer to the allocation 
 
 - 
template<typename T>
 T *allocate_type(std::size_t num_items)
- Allocates a contiguous buffer of uninitialized - Ts with the given- Memory::Kind.- See also - Parameters:
- num_items – The number of items to allocate 
- Returns:
- A raw pointer to the allocation 
 
 - 
void deallocate(void *ptr)
- Deallocates an allocation. - The input pointer must be one that was previously returned by an - allocate()call. If- ptris- nullptr, this call does nothing.- See also - Parameters:
- ptr – Pointer to the allocation to deallocate 
- Throws:
- std::invalid_argument – If - ptrwas not allocated by this allocator.
 
 - 
class Impl
- Detail-hiding implementation class for - ScopedAllocator.- See also 
 
 - 
class TaskLocalBuffer
- #include <legate/data/buffer.h>A task-local temporary buffer. A TaskLocalBufferis, as the name implies, “local” to a task. Its lifetime is bound to that of the task. When the task ends, the buffer is destroyed. It is most commonly used as temporary scratch-space within tasks for that reason.The buffer is allocated immediately at the point when TaskLocalBufferis created, so it is safe to use it immediately, even if it used asynchronously (for example, in GPU kernel launches) after the fact.Public Functions - TaskLocalBuffer(
- const Legion::UntypedDeferredBuffer<> &buf,
- const Type &type,
- const Domain &bounds
- Construct a - TaskLocalBuffer.- Parameters:
- buf – The Legion buffer from which to construct this buffer. 
- type – The type to interpret - bufas.
- bounds – The extent of the buffer. 
 
 
 
 - TaskLocalBuffer(
- const Type &type,
- Span<const std::uint64_t> bounds,
- std::optional<mapping::StoreTarget> mem_kind = std::nullopt
- Construct a - TaskLocalBuffer.- If - mem_kindis not given, the memory kind is automatically deduced based on the type of processor executing the task. For example, GPU tasks will allocate GPU memory (pure GPU memory that is, not zero-copy), while CPU tasks will allocate regular system memory.- Parameters:
- type – The type of the buffer. 
- bounds – The extents of the buffer. 
- mem_kind – The kind of memory to allocate. 
 
 
 
 - 
template<typename T, std::int32_t DIM>
 TaskLocalBuffer( 
)
- Construct a - TaskLocalBuffer.- If this kind of constructor is used, the user should almost always prefer the - type-less version of this ctor. That constructor will deduce the- Typebased on- T. The point of this ctor is to provide the ability to type-pun the- Bufferwith an equivalent type.- Parameters:
- buf – The typed Legion buffer from which to construct this buffer from. 
- type – The type to interpret - bufas.
 
- Throws:
- std::invalid_argument – If - sizeof(T)is not the same as the type size.
- std::invalid_argument – If - alignof(T)is not the same as the type alignment.
 
 
 
 - 
template<typename T, std::int32_t DIM>
 explicit TaskLocalBuffer( 
)
- Construct a - TaskLocalBuffer.- The type of the buffer is deduced from - T.- Parameters:
- buf – The typed Legion buffer from which to construct this buffer from. 
 
 
 - 
Type type() const
- Returns:
- The type of the buffer. 
 
 - 
std::int32_t dim() const
- Returns:
- The dimension of the buffer 
 
 - 
const Domain &domain() const
- Returns:
- The shape of the buffer. 
 
 - 
mapping::StoreTarget memory_kind() const
- Returns:
- The memory kind of the buffer. 
 
 - 
template<typename T, std::int32_t DIM>
 explicit operator Buffer<T, DIM>(
- Convert this object to a typed - Buffer.- Since - TaskLocalBufferis type-erased, there is not a whole lot you can do with it normally. Access to the underlying data (and ability to create accessors) is only possible with a typed buffer.- Returns:
- The typed buffer. 
 
 
 - 
InlineAllocation get_inline_allocation() const
- Get the - InlineAllocationfor the buffer.- This routine constructs a fresh - InlineAllocationfor each call. This process may not be cheap, so the user is encouraged to call this sparingly.- Returns:
- The inline allocation object. 
 
 
 - 
class ExternalAllocation
- #include <legate/data/external_allocation.h>Descriptor for external allocations. An ExternalAllocationis a handle to a memory allocation outside Legate’s memory management.ExternalAllocationobjects are used when users want to create Legate stores from existing allocations external to Legate. (See two overloads ofRuntime::create_store()that takeExternalAllocations.)ExternalAllocations can be tagged either read-only or mutable.- If the allocation is read-only, the calling code must not mutate the contents of the allocation until it is detached. Doing so will result in undefined behavior. Legate will not make any updates of its own to a read-only allocation. 
- If the allocation is mutable, Legate guarantees that any updates to the store to which the allocation is attached are eagerly written-through to the attached allocation, at the expense of block-waiting on tasks updating the store. The calling code is free to make updates to the allocation in-between tasks. 
 The client code that creates an external allocation and attaches it to a Legate store must guarantee that the allocation stays alive until all the tasks accessing the store are finished. An external allocation attached to a store can be safely deallocated in two ways: 1) The client code calls the detach()method on the store before it deallocates the allocation. Thedetach()call makes sure that all outstanding operations on the store complete (seeLogicalStore::detach()). 2) The client code can optionally pass in a deleter for the allocation, which will be invoked once the store is destroyed and the allocation is no longer in use.Deleters don’t need to be idempotent; Legate makes sure that they will be invoked only once on the allocations. Deleters must not throw exceptions (throwable deleters are disallowed by the type system). Deleters need not handle null pointers correctly, as external allocations are not allowed to be created on null pointers. Each deleter is responsible for deallocating only the allocation it is associated with and no other allocations. Public Types - 
using Deleter = std::function<void(void*)>
- Signature for user-supplied deletion function. 
 Public Functions - 
bool read_only() const
- Indicates if the allocation is read-only. - Returns:
- true If the allocation is read-only 
- Returns:
- false Otherwise 
 
 - 
mapping::StoreTarget target() const
- Returns the kind of memory to which the allocation belongs. - Returns:
- Memory kind in a - mapping::StoreTarget
 
 - 
void *ptr() const
- Returns the beginning address of the allocation. - Returns:
- Address to the allocation 
 
 - 
std::size_t size() const
- Returns the allocation size in bytes. - Returns:
- Allocation size in bytes 
 
 Public Static Functions - static ExternalAllocation create_sysmem(
- void *ptr,
- std::size_t size,
- bool read_only = true,
- std::optional<Deleter> deleter = std::nullopt
- Creates an external allocation for a system memory. - Parameters:
- ptr – Pointer to the allocation 
- size – Size of the allocation in bytes 
- read_only – Indicates if the allocation is read-only 
- deleter – Optional deleter for the passed allocation. If none is given, the user is responsible for the deallocation. 
 
- Throws:
- std::invalid_argument – If the - ptris null
- Returns:
- An external allocation 
 
 
 - static ExternalAllocation create_sysmem(
- const void *ptr,
- std::size_t size,
- std::optional<Deleter> deleter = std::nullopt
- Creates a read-only external allocation for a system memory. - Parameters:
- ptr – Pointer to the allocation 
- size – Size of the allocation in bytes 
- deleter – Optional deleter for the passed allocation. Passing a deleter means that the ownership of the allocation is transferred to the Legate runtime. If none is given, the user is responsible for the deallocation. 
 
- Throws:
- std::invalid_argument – If the - ptris null
- Returns:
- An external allocation 
 
 
 - static ExternalAllocation create_zcmem(
- void *ptr,
- std::size_t size,
- bool read_only = true,
- std::optional<Deleter> deleter = std::nullopt
- Creates an external allocation for a zero-copy memory. - Parameters:
- ptr – Pointer to the allocation 
- size – Size of the allocation in bytes 
- read_only – Indicates if the allocation is read-only 
- deleter – Optional deleter for the passed allocation. Passing a deleter means that the ownership of the allocation is transferred to the Legate runtime. If none is given, the user is responsible for the deallocation. 
 
- Throws:
- std::invalid_argument – If the - ptris null
- std::runtime_error – If Legate is not configured with CUDA support enabled 
 
- Returns:
- An external allocation 
 
 
 - static ExternalAllocation create_zcmem(
- const void *ptr,
- std::size_t size,
- std::optional<Deleter> deleter = std::nullopt
- Creates a read-only external allocation for a zero-copy memory. - Parameters:
- ptr – Pointer to the allocation 
- size – Size of the allocation in bytes 
- deleter – Optional deleter for the passed allocation. Passing a deleter means that the ownership of the allocation is transferred to the Legate runtime. If none is given, the user is responsible for the deallocation. 
 
- Throws:
- std::invalid_argument – If the - ptris null
- std::runtime_error – If Legate is not configured with CUDA support enabled 
 
- Returns:
- An external allocation 
 
 
 - static ExternalAllocation create_fbmem(
- std::uint32_t local_device_id,
- void *ptr,
- std::size_t size,
- bool read_only = true,
- std::optional<Deleter> deleter = std::nullopt
- Creates an external allocation for a framebuffer memory. - Parameters:
- local_device_id – Local device ID 
- ptr – Pointer to the allocation 
- size – Size of the allocation in bytes 
- read_only – Indicates if the allocation is read-only 
- deleter – Optional deleter for the passed allocation. Passing a deleter means that the ownership of the allocation is transferred to the Legate runtime. If none is given, the user is responsible for the deallocation. 
 
- Throws:
- std::invalid_argument – If the - ptris null
- std::runtime_error – If Legate is not configured with CUDA support enabled 
- std::out_of_range – If the local device ID is invalid 
 
- Returns:
- An external allocation 
 
 
 - static ExternalAllocation create_fbmem(
- std::uint32_t local_device_id,
- const void *ptr,
- std::size_t size,
- std::optional<Deleter> deleter = std::nullopt
- Creates a read-only external allocation for a framebuffer memory. - Parameters:
- local_device_id – Local device ID 
- ptr – Pointer to the allocation 
- size – Size of the allocation in bytes 
- deleter – Optional deleter for the passed allocation. Passing a deleter means that the ownership of the allocation is transferred to the Legate runtime. If none is given, the user is responsible for the deallocation. 
 
- Throws:
- std::invalid_argument – If the - ptris null
- std::runtime_error – If Legate is not configured with CUDA support enabled 
- std::out_of_range – If the local device ID is invalid 
 
- Returns:
- An external allocation 
 
 
 
 - 
class InlineAllocation
- #include <legate/data/inline_allocation.h>An object representing the raw memory and strides held by a PhysicalStore.Public Members - 
void *ptr = {}
- pointer to the start of the allocation. 
 - 
std::vector<std::size_t> strides = {}
- vector of byte-offsets into - ptr.- The offsets are given in bytes, and represent the number of bytes needed to jump to the next array element in the corresponding dimension. For example: - #. For an array whose entries are 4 bytes long, and whose shape is - (1,),- strideswould be- [4](entry- igiven by- 4*i). #. For an array whose entries are 8 bytes long, and whose shape is- (1, 2,),- strideswould be- [16, 8](entry- (i, j)given by- 16*i + 8*j). #. For an array whose entries are 8 bytes long, and whose shape is- (1, 2, 3), strides- would be[48, 24, 8]- (entry(i, j, k)- given by48*i + 24*j + 8*k`).
 - 
mapping::StoreTarget target = {}
- The type of memory that - ptrresides in.
 
- 
void *ptr = {}
 - 
class LogicalArray
- #include <legate/data/logical_array.h>A multi-dimensional array. Subclassed by legate::ListLogicalArray, legate::StringLogicalArray, legate::StructLogicalArray Public Functions - 
std::uint32_t dim() const
- Returns the number of dimensions of the array. - Returns:
- The number of dimensions 
 
 - 
tuple<std::uint64_t> extents() const
- Returns the extents of the array. - The call can block if the array is unbound - Returns:
- The store’s extents 
 
 - 
std::size_t volume() const
- Returns the number of elements in the array. - The call can block if the array is unbound - Returns:
- The number of elements in the store 
 
 - 
bool unbound() const
- Indicates whether the array is unbound. - Returns:
- trueif the array is unbound,- falseif it is normal
 
 - 
bool nullable() const
- Indicates whether the array is nullable. - Returns:
- trueif the array is nullable,- falseotherwise
 
 - 
bool nested() const
- Indicates whether the array has child arrays. - Returns:
- trueif the array has child arrays,- falseotherwise
 
 - 
std::uint32_t num_children() const
- Returns the number of child sub-arrays. - Returns:
- Number of child sub-arrays 
 
 - LogicalArray promote(
- std::int32_t extra_dim,
- std::size_t dim_size
- Adds an extra dimension to the array. - The call can block if the array is unbound - Parameters:
- extra_dim – Position for a new dimension 
- dim_size – Extent of the new dimension 
 
- Throws:
- std::invalid_argument – When - extra_dimis not a valid dimension name
- std::runtime_error – If the array or any of the sub-arrays is a list array 
 
- Returns:
- A new array with an extra dimension 
 
 
 - 
LogicalArray project(std::int32_t dim, std::int64_t index) const
- Projects out a dimension of the array. - The call can block if the array is unbound - Parameters:
- dim – Dimension to project out 
- index – Index on the chosen dimension 
 
- Throws:
- std::invalid_argument – If - dimis not a valid dimension name or- indexis out of bounds
- std::runtime_error – If the array or any of the sub-arrays is a list array 
 
- Returns:
- A new array with one fewer dimension 
 
 - 
LogicalArray broadcast(std::int32_t dim, std::size_t dim_size) const
- Broadcasts a unit-size dimension of the array. - The call can block if the array is unbound. - See also - Parameters:
- dim – A dimension to broadcast 
- dim_size – A new size of the chosen dimension 
 
- Throws:
- std::invalid_argument – When - dimis not a valid dimension index.
- std::invalid_argument – When the size of dimension - dimis not 1.
- std::runtime_error – If the array or any of the sub-arrays is a list array. 
 
- Returns:
- A new array where the chosen dimension is logically broadcasted 
 
 - 
LogicalArray slice(std::int32_t dim, Slice sl) const
- Slices a contiguous sub-section of the array. - The call can block if the array is unbound - Parameters:
- dim – Dimension to slice 
- sl – Slice descriptor 
 
- Throws:
- std::invalid_argument – If - dimis not a valid dimension name
- std::runtime_error – If the array or any of the sub-arrays is a list array 
 
- Returns:
- A new array that corresponds to the sliced section 
 
 - 
LogicalArray transpose(Span<const std::int32_t> axes) const
- Reorders dimensions of the array. - The call can block if the array is unbound - Parameters:
- axes – Mapping from dimensions of the resulting array to those of the input 
- Throws:
- std::invalid_argument – If any of the following happens: 1) The length of - axesdoesn’t match the array’s dimension; 2)- axeshas duplicates; 3) Any axis in- axesis an invalid axis name.
- std::runtime_error – If the array or any of the sub-arrays is a list array 
 
- Returns:
- A new array with the dimensions transposed 
 
 - LogicalArray delinearize(
- std::int32_t dim,
- Span<const std::uint64_t> sizes
- Delinearizes a dimension into multiple dimensions. - The call can block if the array is unbound - Parameters:
- dim – Dimension to delinearize 
- sizes – Extents for the resulting dimensions 
 
- Throws:
- std::invalid_argument – If - dimis invalid for the array or- sizesdoes not preserve the extent of the chosen dimension
- std::runtime_error – If the array or any of the sub-arrays is a list array 
 
- Returns:
- A new array with the chosen dimension delinearized 
 
 
 - 
LogicalStore data() const
- Returns the store of this array. - Returns:
 
 - 
LogicalStore null_mask() const
- Returns the null mask of this array. - Returns:
 
 - 
LogicalArray child(std::uint32_t index) const
- Returns the sub-array of a given index. - Parameters:
- index – Sub-array index 
- Throws:
- std::invalid_argument – If the array has no child arrays, or the array is an unbound struct array 
- std::out_of_range – If the index is out of range 
 
- Returns:
 
 - PhysicalArray get_physical_array(
- std::optional<mapping::StoreTarget> target = std::nullopt
- Creates a - PhysicalArrayfor this- LogicalArray- This call blocks the client’s control flow and fetches the data for the whole array to the current node. - When the target is - StoreTarget::FBMEM, the data will be consolidated in the framebuffer of the first GPU available in the scope.- If no - targetis given, the runtime uses- StoreTarget::SOCKETMEMif it exists and- StoreTarget::SYSMEMotherwise.- If there already exists a physical array for a different memory target, that physical array will be unmapped from memory and become invalid to access. - Parameters:
- target – The type of memory in which the physical array would be created. 
- Throws:
- std::invalid_argument – If no memory of the chosen type is available 
- Returns:
- A - PhysicalArrayof the- LogicalArray
 
 
 - 
ListLogicalArray as_list_array() const
- Casts this array as a - ListLogicalArray- Throws:
- std::invalid_argument – If the array is not a list array 
- Returns:
- The array as a - ListLogicalArray
 
 - 
StringLogicalArray as_string_array() const
- Casts this array as a - StringLogicalArray- Throws:
- std::invalid_argument – If the array is not a string array 
- Returns:
- The array as a - StringLogicalArray
 
 - 
StructLogicalArray as_struct_array() const
- Casts this array as a - StructLogicalArray- Throws:
- std::invalid_argument – If the array is not a struct array 
- Returns:
- The array as a - StructLogicalArray
 
 - 
void offload_to(mapping::StoreTarget target_mem) const
- Offload array to specified target memory. - Copies the array to the specified memory, if necessary, and marks it as the most up-to-date copy, allowing the runtime to discard any copies in other memories. - Main usage is to free up space in one kind of memory by offloading resident arrays and stores to another kind of memory. For example, after a GPU task that reads or writes to an array, users can manually free up Legate’s GPU memory by offloading the array to host memory. - All the stores that comprise the array are offloaded, i.e., the data store, the null mask, and child arrays, etc. - Currently, the runtime does not validate if the target memory has enough capacity or free space at the point of launching or executing the offload operation. The program will most likely crash if there isn’t enough space in the target memory. The user is therefore encouraged to offload to a memory type that is likely to have sufficient space. - This should not be treated as a prefetch call as it offers little benefit to that end. The runtime will ensure that data for a task is resident in the required memory before the task begins executing. - If this array is backed by another array, e.g., if this array is a slice or some other transform of another array, then both the arrays will be offloaded due to being backed by the same memory. - // This snippet launches two GPU tasks that manipulate two different stores, // where each store occupies more than 50% of GPU memory. Runtime can map and // schedule both the tasks at the same time. Without offloading the first store, // mapping will fail for the second task. Therefore, we insert an `offload_to` // call for the first store after submitting the first task and before submitting // the second task. { auto task1 = runtime->create_task(library, GPUonlyTask::TASK_CONFIG.task_id()); task1.add_output(store1); runtime->submit(std::move(task1)); } store1.offload_to(legate::mapping::StoreTarget::SYSMEM); { auto task2 = runtime->create_task(library, GPUonlyTask::TASK_CONFIG.task_id()); task2.add_output(store2); runtime->submit(std::move(task2)); } - Parameters:
- target_mem – The target memory. 
- Throws:
- std::invalid_argument – If Legate was not configured to support - target_mem.
 
 - 
class Impl
 
- 
std::uint32_t dim() const
 - 
class ListLogicalArray : public legate::LogicalArray
- #include <legate/data/logical_array.h>Represents a logical array of variable-length lists. Each element of the array is itself a list, potentially of different length. For example, a ListLogicalArray may represent: [[a, b], [c], [d, e, f]] This is stored using two arrays: - A descriptor array that defines the start and end indices of each sublist within the value data array. The descriptor array is stored as a series of - Rect<1>s, where- loand- himembers indicate the start and end of each range.
- A value data array ( - vardata) containing all list elements in a flattened form.
 For example: descriptor: [ (0, 1), (2, 2), (3, 5) ] vardata: [ a, b, c, d, e, f ] Where the mapping of descriptortovardatafollows:descriptor vardata ---------- -------------------- (0, 1) ---> [ a, b ] (2, 2) ---> [ c ] (3, 5) ---> [ d, e, f ] Note The user can achieve the same effects of a ListLogicalArraythemselves by applying an image constraint (image(Variable, Variable, ImageComputationHint)) to twoLogicalArrays when passing them to a task. In that casedescriptorwould bevar_functionwhilevardatawould bevar_range.Public Functions - 
LogicalArray descriptor() const
- Returns the sub-array for descriptors. Each element is a - Rect<1>of start and end indices for each subregion in- vardata.- Returns:
- Sub-array’s for descriptors. 
 
 - 
LogicalArray vardata() const
- Returns the sub-array for variable size data. - Returns:
- LogicalArrayof variable sized data.
 
 
 - 
class StringLogicalArray : public legate::LogicalArray
- #include <legate/data/logical_array.h>A multi-dimensional array representing a collection of strings. This class is essentially a ListLogicalArrayspecialized for lists-of-strings data. The member functionsoffsets()andchars()are directly analogous toListLogicalArray::descriptor()andListLogicalArray::vardata().The strings are stored in a compact form, accessible through chars(), whileoffsets()gives the start and end indices for each sub-string.See also Public Functions - 
LogicalArray offsets() const
- Returns the sub-array for offsets giving the bounds of each string. - Returns:
- LogicalArrayof offsets into this array.
 
 - 
LogicalArray chars() const
- Returns the sub-array for characters of the strings. - Returns:
- LogicalArrayrepresenting the characters of the strings.
 
 
- 
LogicalArray offsets() const
 - 
class StructLogicalArray : public legate::LogicalArray
- #include <legate/data/logical_array.h>A multi-dimensional array representing a struct. The struct is defined by fields that are each represented by an LogicalArray. The data of theStructLogicalArrayis represented in a struct of arrays format.Public Functions - 
std::vector<LogicalArray> fields() const
- Return a vector of the sub-arrays, one for each field. - Returns:
- Vector of - LogicalArrays representing the fields.
 
 
- 
std::vector<LogicalArray> fields() const
 - 
class LogicalStore
- #include <legate/data/logical_store.h>A multi-dimensional data container. LogicalStoreis a multi-dimensional data container for fixed-size elements. Stores are internally partitioned and distributed across the system. By default, Legate clients need not create nor maintain the partitions explicitly, and the Legate runtime is responsible for managing them. Legate clients can control how stores should be partitioned for a given task by attaching partitioning constraints to the task (see the constraint module for partitioning constraint APIs).Each LogicalStoreobject is a logical handle to the data and is not immediately associated with a physical allocation. To access the data, a client must “map” the store to a physical store (PhysicalStore). A client can map a store by passing it to a task, in which case the task body can see the allocation, or callingLogicalStore::get_physical_store(), which gives the client a handle to the physical allocation (seePhysicalStorefor details about physical stores).Normally, a LogicalStoregets a fixedShapeupon creation. However, there is a special type of logical stores called “unbound” stores whose shapes are unknown at creation time. (seeRuntimefor the logical store creation API.) The shape of an unbound store is determined by a task that first updates the store; upon the submission of the task, theLogicalStorebecomes a normal store. Passing an unbound store as a read-only argument or requesting aPhysicalStoreof an unbound store are invalid.One consequence due to the nature of unbound stores is that querying the shape of a previously unbound store can block the client’s control flow for an obvious reason; to know the shape of the LogicalStorewhoseShapewas unknown at creation time, the client must wait until the updater task to finish. However, passing a previously unbound store to a downstream operation can be non-blocking, as long as the operation requires no changes in the partitioning and mapping for theLogicalStore.Public Functions - 
std::uint32_t dim() const
- Returns the number of dimensions of the store. - Returns:
- The number of dimensions 
 
 - 
bool has_scalar_storage() const
- Indicates whether the store’s storage is optimized for scalars. - Returns:
- true The store is backed by a scalar storage 
- Returns:
- false The store is a backed by a normal region storage 
 
 - 
bool overlaps(const LogicalStore &other) const
- Indicates whether this store overlaps with a given store. - Returns:
- true The stores overlap 
- Returns:
- false The stores are disjoint 
 
 - 
tuple<std::uint64_t> extents() const
- Returns the extents of the store. - The call can block if the store is unbound - Returns:
- The store’s extents 
 
 - 
std::size_t volume() const
- Returns the number of elements in the store. - The call can block if the store is unbound - Returns:
- The number of elements in the store 
 
 - 
bool unbound() const
- Indicates whether the store is unbound. - Returns:
- trueif the store is unbound,- falseotherwise
 
 - 
bool transformed() const
- Indicates whether the store is transformed. - Returns:
- trueif the store is transformed,- falseotherwise
 
 - 
LogicalStore reinterpret_as(const Type &type) const
- Reinterpret the underlying data of a - LogicalStorebyte-for-byte as another type.- The size and alignment of the new type must match that of the existing type. - The reinterpreted store will share the same underlying storage as the original, and therefore any writes to one will also be reflected in the other. No type conversions of any kind are performed across the stores, the bytes are interpreted as-is. In effect, if one were to model a - LogicalStoreas a pointer to an array, then this routine is equivalent to- reinterpret_cast-ing the pointer.- Example: - // Create a store of some shape filled with int32 data. constexpr std::int32_t minus_one = -1; const auto store = runtime->create_store(shape, legate::int32()); runtime->issue_fill(store, legate::Scalar{minus_one}); // Reinterpret the underlying data as unsigned 32-bit integers. auto reinterp_store = store.reinterpret_as(legate::uint32()); // Our new store should have the same type as it was reinterpreted to. ASSERT_EQ(reinterp_store.type(), legate::uint32()); // Our old store still has the same type though. ASSERT_EQ(store.type(), legate::int32()); // Both stores should refer to the same underlying storage. ASSERT_TRUE(store.equal_storage(reinterp_store)); const auto phys_store = reinterp_store.get_physical_store(); const auto acc = phys_store.read_accessor<std::uint32_t, 1>(); std::uint32_t interp_value; // Need to memcpy here in order to do a "true" bitcast. A reinterpret_cast() may or may not // result in the compilers generating the conversion, since type-punning with // reinterpret_cast is UB. std::memcpy(&interp_value, &minus_one, sizeof(minus_one)); for (auto it = legate::PointInRectIterator<1>{phys_store.shape<1>()}; it.valid(); ++it) { ASSERT_EQ(acc[*it], interp_value); } - Parameters:
- type – The new type to interpret the data as. 
- Returns:
- The reinterpreted store. 
- Throws:
- std::invalid_argument – If the size (in bytes) of the new type does not match that of the old type. 
- std::invalid_argument – If the alignment of the new type does not match that of the old type. 
 
 
 - LogicalStore promote(
- std::int32_t extra_dim,
- std::size_t dim_size
- Adds an extra dimension to the store. - Value of - extra_dimdecides where a new dimension should be added, and each dimension \(i\), where \(i\) >=- extra_dim, is mapped to dimension \(i+1\) in a returned store. A returned store provides a view to the input store where the values are broadcasted along the new dimension.- For example, for a 1D store - Acontains- [1, 2, 3],- A.promote(0, 2)yields a store equivalent to:- [[1, 2, 3], [1, 2, 3]] - whereas - A.promote(1, 2)yields:- [[1, 1], [2, 2], [3, 3]] - The call can block if the store is unbound - Parameters:
- extra_dim – Position for a new dimension 
- dim_size – Extent of the new dimension 
 
- Throws:
- std::invalid_argument – When - extra_dimis not a valid dimension index.
- Returns:
- A new store with an extra dimension 
 
 
 - 
LogicalStore project(std::int32_t dim, std::int64_t index) const
- Projects out a dimension of the store. - Each dimension \(i\), where \(i\) > - dim, is mapped to dimension \(i-1\) in a returned store. A returned store provides a view to the input store where the values are on hyperplane \(x_\mathtt{dim} = \mathtt{index}\).- For example, if a 2D store - Acontains- [[1, 2], [3, 4]],- A.project(0, 1)yields a store equivalent to- [3, 4], whereas- A.project(1, 0)yields- [1, 3].- The call can block if the store is unbound - Parameters:
- dim – Dimension to project out 
- index – Index on the chosen dimension 
 
- Throws:
- std::invalid_argument – If - dimis not a valid dimension index or- indexis out of bounds of the dimension.
- Returns:
- A new store with one fewer dimension 
 
 - 
LogicalStore broadcast(std::int32_t dim, std::size_t dim_size) const
- Broadcasts a unit-size dimension of the store. - The output store is a view to the input store where the dimension - dimis broadcasted to size- dim_size.- For example, For a 2D store - A- [[1, 2, 3]] - A.broadcast(0, 3)yields the following output:- [[1, 2, 3], [1, 2, 3], [1, 2, 3]] - The broadcasting is logical; i.e., the broadcasted values are not materialized in the physical allocation. - The call can block if the store is unbound. - Parameters:
- dim – A dimension to broadcast. Must have size 1. 
- dim_size – A new size of the chosen dimension. 
 
- Throws:
- std::invalid_argument – If - dimis not a valid dimension index.
- std::invalid_argument – If the size of dimension - dimis not 1.
 
- Returns:
- A new store where the chosen dimension is logically broadcasted. 
 
 - 
LogicalStore slice(std::int32_t dim, Slice sl) const
- Slices a contiguous sub-section of the store. - For example, consider a 2D store - A:- [[1, 2, 3], [4, 5, 6], [7, 8, 9]] - A slicing - A.slice(0, legate::Slice{1})yields- [[4, 5, 6], [7, 8, 9]] - The result store will look like this on a different slicing call - A.slice(1, legate::Slice{legate::Slice::OPEN, 2}):- [[1, 2], [4, 5], [7, 8]] - Finally, chained slicing calls - A.slice(0, legate::Slice{1}) .slice(1, legate::Slice{legate::Slice::OPEN, 2}) - results in: - [[4, 5], [7, 8]] - The call can block if the store is unbound - Parameters:
- dim – Dimension to slice 
- sl – - Slicedescriptor
 
- Throws:
- std::invalid_argument – If - dimis not a valid dimension name
- Returns:
- A new store that corresponds to the sliced section 
 
 - 
LogicalStore transpose(std::vector<std::int32_t> &&axes) const
- Reorders dimensions of the store. - Dimension \(i\)i of the resulting store is mapped to dimension - axes[i]of the input store.- For example, for a 3D store - A- [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] - transpose calls - A.transpose({1, 2, 0})and- A.transpose({2, 1, 0})yield the following stores, respectively:- [[[1, 5], [2, 6]], [[3, 7], [4, 8]]] - [[[1, 5], [3, 7]], [[2, 6], [4, 8]]] - The call can block if the store is unbound - Parameters:
- axes – Mapping from dimensions of the resulting store to those of the input 
- Throws:
- std::invalid_argument – If any of the following happens: 1) The length of - axesdoesn’t match the store’s dimension; 2)- axeshas duplicates; 3) Any axis in- axesis an invalid axis name.
- Returns:
- A new store with the dimensions transposed 
 
 - LogicalStore delinearize(
- std::int32_t dim,
- std::vector<std::uint64_t> sizes
- Delinearizes a dimension into multiple dimensions. - Each dimension \(i\) of the store, where \(i >\) - dim, will be mapped to dimension \(i+N\) of the resulting store, where \(N\) is the length of- sizes. A delinearization that does not preserve the size of the store is invalid.- For example, consider a 2D store - A- [[1, 2, 3, 4], [5, 6, 7, 8]] - A delinearizing call - A.delinearize(1, {2, 2}))yields:- [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] - Unlike other transformations, delinearization is not an affine transformation. Due to this nature, delinearized stores can raise - legate::NonInvertibleTransformationin places where they cannot be used.- The call can block if the store is unbound - Parameters:
- dim – Dimension to delinearize 
- sizes – Extents for the resulting dimensions 
 
- Throws:
- std::invalid_argument – If - dimis invalid for the store or- sizesdoes not preserve the extent of the chosen dimension
- Returns:
- A new store with the chosen dimension delinearized 
 
 
 - 
std::optional<LogicalStorePartition> get_partition() const
- Gets the current partition for the store. - A partition describes how the store’s data is distributed across multiple processors or memory regions for parallel computation. It defines the color space (number of parallel tasks) and how the store’s logical space maps to these parallel instances. - Users typically need partition information when: - Creating manual tasks that must match existing partitioning schemes 
- Ensuring data alignment between multiple stores in the same computation 
- Debugging performance issues related to data distribution 
 - The partition contains the color shape (dimensions of the parallel task grid), tile shape (size of each data chunk), and the mapping between logical indices and parallel task instances. - This function will flush the scheduling window to make sure the partition is up to date. - Returns:
- The current partition if one exists, or std::nullopt if the store has not been partitioned (e.g., for sequential computation) 
 
 - LogicalStorePartition partition_by_tiling(
- Span<const std::uint64_t> tile_shape,
- std::optional<Span<const std::uint64_t>> color_shape = std::nullopt
- Creates a tiled partition of the store. - The call can block if the store is unbound - The function returns a partition created by tiling with a given tile shape. As a default with no color shape being provided, the partition will be created by splitting the store dimensions by the tile shape: - For example, a 2D store - Aof shape- (3, 4)partitioned with a tile shape of- (2, 2)would be partitioned in 4 chunks with corresponding to the color shape of- (2, 2).- Overriding a color shape will allow for either truncating or extending the partition in each dimension, independent of the actual extents of the store shape. This behavior can be desired for aligning partitions for stores with different shapes. - For example, a task working on a 2D store - Aof shape- (4, 2)with a tile shape of- (2, 2)has a native coloring of- (2, 1). If the task also requires access to a 2D store- Bof shape- (2, 2)with the same tile shape, that store would have a native coloring of- (1, 1). Forcing the desired color shape of- (2, 1)to- Bduring tiling creates a partition containing the same amount of tiles as the partition for- Aallowing for alignment.- Running the task with - A:*- [[a, b], [c, d], [e, f], [g, g]] - and - B:- [[x, y], [z, w]] - and a tilesize of - (2, 2)would then allow for a shared coloring of- (2, 1), with one point task running on- [[a, b], [[x, y], [c, d]] [z, w]] - and the other on - [[a, b], [[], [c, d]] []] - Parameters:
- tile_shape – Shape of tiles 
- color_shape – (optional) color shape to satisfy during partition creation. 
 
- Throws:
- std::invalid_argument – If dimension of input shapes don’t match the store dimension or the volume defined by any of the input shapes is 0. 
- Returns:
- A store partition 
 
 
 - PhysicalStore get_physical_store(
- std::optional<mapping::StoreTarget> target = std::nullopt
- Creates a - PhysicalStorefor this- LogicalStore- This call blocks the client’s control flow and fetches the data for the whole store to the current node. - When the target is - StoreTarget::FBMEM, the data will be consolidated in the framebuffer of the first GPU available in the scope.- If no - targetis given, the runtime uses- StoreTarget::SOCKETMEMif it exists and- StoreTarget::SYSMEMotherwise.- If there already exists a physical store for a different memory target, that physical store will be unmapped from memory and become invalid to access. - Parameters:
- target – The type of memory in which the physical store would be created. 
- Throws:
- std::invalid_argument – If no memory of the chosen type is available 
- Returns:
- A - PhysicalStoreof the- LogicalStore
 
 
 - 
void detach()
- Detach a store from its attached memory. - This call will wait for all operations that use the store (or any sub-store) to complete. - After this call returns, it is safe to deallocate the attached external allocation. If the allocation was mutable, the contents would be up-to-date upon the return. The contents of the store are invalid after that point. 
 - 
void offload_to(mapping::StoreTarget target_mem)
- Offload store to specified target memory. - See also - Parameters:
- target_mem – The target memory. 
 
 - 
bool equal_storage(const LogicalStore &other) const
- Determine whether two stores refer to the same memory. - This routine can be used to determine whether two seemingly unrelated stores refer to the same logical memory region, including through possible transformations in either - thisor- other.- The user should note that some transformations do modify the underlying storage. For example, the store produced by slicing will not share the same storage as its parent, and this routine will return false for it: - const auto store = runtime->create_store(legate::Shape{4, 3}, legate::int64()); const auto transformed = store.slice(1, legate::Slice{-2, -1}); // Slices partition a store into a parent and sub-store which both cover distinct regions, // and hence don't share storage. ASSERT_FALSE(store.equal_storage(transformed)); - Transposed stores, on the other hand, still share the same storage, and hence this routine will return true for them: - const auto store = runtime->create_store(legate::Shape{4, 3}, legate::int64()); const auto transformed = store.transpose({1, 0}); // Transposing a store doesn't modify the storage ASSERT_TRUE(store.equal_storage(transformed)); - Parameters:
- other – The - LogicalStoreto compare with.
- Returns:
- trueif two stores cover the same underlying memory region,- falseotherwise.
 
 - 
class Impl
 
- 
std::uint32_t dim() const
 - 
class LogicalStorePartition
- 
class Impl
 
- 
class Impl
 - 
class PhysicalArray
- #include <legate/data/physical_array.h>A multi-dimensional array abstraction for fixed- or variable-size elements. PhysicalArrays can be backed by one or morePhysicalStores, depending on their types.Subclassed by legate::ListPhysicalArray, legate::StringPhysicalArray Public Functions - 
bool nullable() const noexcept
- Indicates if the array is nullable. - Returns:
- trueif the array is nullable,- falseotherwise
 
 - 
std::int32_t dim() const noexcept
- Returns the dimension of the array. - Returns:
- Array’s dimension 
 
 - 
bool nested() const noexcept
- Indicates if the array has child arrays. - Returns:
- trueif the array has child arrays,- falseotherwise
 
 - 
PhysicalStore data() const
- Returns the store containing the array’s data. - Throws:
- std::invalid_argument – If the array is not a base array 
- Returns:
 
 - 
PhysicalStore null_mask() const
- Returns the store containing the array’s null mask. - Throws:
- std::invalid_argument – If the array is not nullable 
- Returns:
 
 - 
PhysicalArray child(std::uint32_t index) const
- Returns the sub-array of a given index. - Parameters:
- index – Sub-array index 
- Throws:
- std::invalid_argument – If the array has no child arrays 
- std::out_of_range – If the index is out of range 
 
- Returns:
- Sub- - PhysicalArrayat the given index
 
 - 
Domain domain() const
- Returns the array’s - Domain- Returns:
- Array’s - Domain
 
 - 
ListPhysicalArray as_list_array() const
- Casts this array as a - ListPhysicalArray- Throws:
- std::invalid_argument – If the array is not a list array 
- Returns:
- This array as a - ListPhysicalArray
 
 - 
StringPhysicalArray as_string_array() const
- Casts this array as a - StringPhysicalArray- Throws:
- std::invalid_argument – If the array is not a string array 
- Returns:
- This array as a - StringPhysicalArray
 
 
- 
bool nullable() const noexcept
 - 
class ListPhysicalArray : public legate::PhysicalArray
- #include <legate/data/physical_array.h>A multi-dimensional array abstraction for variable-size list of elements. Public Functions - 
PhysicalArray descriptor() const
- Returns the sub-array for descriptors. - Returns:
- PhysicalArrayof descriptors
 
 - 
PhysicalArray vardata() const
- Returns the sub-array for variable size data. - Returns:
- PhysicalArrayof variable sized data
 
 
- 
PhysicalArray descriptor() const
 - 
class StringPhysicalArray : public legate::PhysicalArray
- #include <legate/data/physical_array.h>A multi-dimensional array abstraction representing a string. Public Functions - 
PhysicalArray ranges() const
- Returns the sub-array for ranges. - Returns:
- PhysicalArrayof ranges
 
 - 
PhysicalArray chars() const
- Returns the sub-array for characters. - Returns:
- PhysicalArrayof the characters in the string.
 
 
- 
PhysicalArray ranges() const
 - 
class PhysicalStore
- #include <legate/data/physical_store.h>A multi-dimensional data container storing task data. Public Functions - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 mdspan_type<const T, DIM> span_read_accessor(
- std::size_t elem_size = sizeof(T)
- Returns a read-only mdspan to the store over its entire domain. Equivalent to - span_read_accessor<T, DIM>(shape<DIM>()).- elem_sizeshould not normally need to be passed. It is, however, necessary for type-punning when the size of the stored type and viewed type differ. For example, a store might refer to binary data where each element is of size 10, but we wish to view it as an mspan of- std::bytes (which would have size = 1). In this case:- #. Pass the viewed type (e.g. - std::byte) as the template parameter- T. #. Pass- VALIDATE_TYPE = false(to avoid warnings about type mismatch). #. Pass- type().size()as- elem_size.- Note - This API is experimental. It will eventually replace the Legion accessor interface, but we are seeking user feedback on it before such time. If you encounter issues, and/or have suggestions for improvements, please file a bug at nv-legate/legate#issues. - Template Parameters:
- T – The element type of the mdspan. 
- DIM – The rank of the mdspan. 
- VALIDATE_TYPE – If - true(default), checks that the type and rank of the mdspan match that of the- PhysicalStore.
 
- Parameters:
- elem_size – The size (in bytes) of each element. 
- Returns:
- The read-only mdspan accessor. 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 mdspan_type<T, DIM> span_write_accessor(
- std::size_t elem_size = sizeof(T)
- Returns a write-only mdspan to the store over its entire domain. Equivalent to - span_write_accessor<T, DIM>(shape<DIM>()).- The user may read from a write-only accessor, but must write to the read-from location first, otherwise the returned values are undefined: - auto acc = store.span_write_accessor<float, 2>(); v = acc(0, 0); // Note: undefined value acc(0, 0) = 42.0; v = acc(0, 0); // OK, value will be 42.0 - elem_sizeshould not normally need to be passed. It is, however, necessary for type-punning when the size of the stored type and viewed type differ. For example, a store might refer to binary data where each element is of size 10, but we wish to view it as an mspan of- std::bytes (which would have size = 1). In this case:- #. Pass the viewed type (e.g. - std::byte) as the template parameter- T. #. Pass- VALIDATE_TYPE = false(to avoid warnings about type mismatch). #. Pass- type().size()as- elem_size.- Note - This API is experimental. It will eventually replace the Legion accessor interface, but we are seeking user feedback on it before such time. If you encounter issues, and/or have suggestions for improvements, please file a bug at nv-legate/legate#issues. - Template Parameters:
- T – The element type of the mdspan. 
- DIM – The rank of the mdspan. 
- VALIDATE_TYPE – If - true(default on debug builds), checks that the type and rank of the mdspan match that of the- PhysicalStore.
 
- Parameters:
- elem_size – The size (in bytes) of each element. 
- Returns:
- The mdspan accessor. 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 mdspan_type<T, DIM> span_read_write_accessor(
- std::size_t elem_size = sizeof(T)
- Returns a read-write mdspan to the store over its entire domain. Equivalent to - span_read_write_accessor<T, DIM>(shape<DIM>()).- elem_sizeshould not normally need to be passed. It is, however, necessary for type-punning when the size of the stored type and viewed type differ. For example, a store might refer to binary data where each element is of size 10, but we wish to view it as an mspan of- std::bytes (which would have size = 1). In this case:- #. Pass the viewed type (e.g. - std::byte) as the template parameter- T. #. Pass- VALIDATE_TYPE = false(to avoid warnings about type mismatch). #. Pass- type().size()as- elem_size.- Note - This API is experimental. It will eventually replace the Legion accessor interface, but we are seeking user feedback on it before such time. If you encounter issues, and/or have suggestions for improvements, please file a bug at nv-legate/legate#issues. - Template Parameters:
- T – The element type of the mdspan. 
- DIM – The rank of the mdspan. 
- VALIDATE_TYPE – If - true(default on debug builds), checks that the type and rank of the mdspan match that of the- PhysicalStore.
 
- Parameters:
- elem_size – The size (in bytes) of each element. 
- Returns:
- The mdspan accessor. 
 
 
 - 
template<typename Redop, bool EXCLUSIVE, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 mdspan_type<typename Redop::LHS, DIM, detail::ReductionAccessor<Redop, EXCLUSIVE>> span_reduce_accessor(
- std::size_t elem_size = sizeof(typename Redop::LHS)
- Returns a reduction mdspan to the store over its entire domain. Equivalent to - span_reduce_accessor<Redop, EXCLUSIVE, DIM>(shape<DIM>()).- elem_sizeshould not normally need to be passed. It is, however, necessary for type-punning when the size of the stored type and viewed type differ. For example, a store might refer to binary data where each element is of size 10, but we wish to view it as an mspan of- std::bytes (which would have size = 1). In this case:- #. Pass the viewed type (e.g. - std::byte) as the template parameter- T. #. Pass- VALIDATE_TYPE = false(to avoid warnings about type mismatch). #. Pass- type().size()as- elem_size.- Note - This API is experimental. It will eventually replace the Legion accessor interface, but we are seeking user feedback on it before such time. If you encounter issues, and/or have suggestions for improvements, please file a bug at nv-legate/legate#issues. - Template Parameters:
- Redop – The reduction operator (e.g. - SumReduction).
- EXCLUSIVE – Whether the reduction accessor has exclusive access to the buffer. 
- DIM – The rank of the mdspan. 
- VALIDATE_TYPE – If - true(default on debug builds), checks that the type and rank of the mdspan match that of the- PhysicalStore.
 
- Parameters:
- elem_size – The size (in bytes) of each element. 
- Returns:
- The mdspan accessor. 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 mdspan_type<const T, DIM> span_read_accessor( 
) const
- Returns a read-only mdspan to the store over the selected domain. - elem_sizeshould not normally need to be passed. It is, however, necessary for type-punning when the size of the stored type and viewed type differ. For example, a store might refer to binary data where each element is of size 10, but we wish to view it as an mspan of- std::bytes (which would have size = 1). In this case:- #. Pass the viewed type (e.g. - std::byte) as the template parameter- T. #. Pass- VALIDATE_TYPE = false(to avoid warnings about type mismatch). #. Pass- type().size()as- elem_size.- Note - This API is experimental. It will eventually replace the Legion accessor interface, but we are seeking user feedback on it before such time. If you encounter issues, and/or have suggestions for improvements, please file a bug at nv-legate/legate#issues. - Note - If - boundsis empty then the strides of the returned- mdspanwill be all 0 instead of what it might normally be. The object is still perfectly usable as normal but the strides will not be correct.- Template Parameters:
- T – The element type of the mdspan. 
- DIM – The rank of the mdspan. 
- VALIDATE_TYPE – If - true(default on debug builds), checks that the type and rank of the mdspan match that of the- PhysicalStore.
 
- Parameters:
- bounds – The (sub-)domain over which to access the store. 
- elem_size – The size (in bytes) of each element. 
 
- Returns:
- The mdspan accessor. 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 mdspan_type<T, DIM> span_write_accessor( 
)
- Returns a write-only mdspan to the store over the selected domain. - The user may read from a write-only accessor, but must write to the read-from location first, otherwise the returned values are undefined: - auto acc = store.span_write_accessor<float, 2>(bounds); v = acc(0, 0); // Note: undefined value acc(0, 0) = 42.0; v = acc(0, 0); // OK, value will be 42.0 - elem_sizeshould not normally need to be passed. It is, however, necessary for type-punning when the size of the stored type and viewed type differ. For example, a store might refer to binary data where each element is of size 10, but we wish to view it as an mspan of- std::bytes (which would have size = 1). In this case:- #. Pass the viewed type (e.g. - std::byte) as the template parameter- T. #. Pass- VALIDATE_TYPE = false(to avoid warnings about type mismatch). #. Pass- type().size()as- elem_size.- Note - This API is experimental. It will eventually replace the Legion accessor interface, but we are seeking user feedback on it before such time. If you encounter issues, and/or have suggestions for improvements, please file a bug at nv-legate/legate#issues. - Note - If - boundsis empty then the strides of the returned- mdspanwill be all 0 instead of what it might normally be. The object is still perfectly usable as normal but the strides will not be correct.- Template Parameters:
- T – The element type of the mdspan. 
- DIM – The rank of the mdspan. 
- VALIDATE_TYPE – If - true(default on debug builds), checks that the type and rank of the mdspan match that of the- PhysicalStore.
 
- Parameters:
- bounds – The (sub-)domain over which to access the store. 
- elem_size – The size (in bytes) of each element. 
 
- Returns:
- The mdspan accessor. 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 mdspan_type<T, DIM> span_read_write_accessor( 
)
- Returns a read-write mdspan to the store over the selected domain. - elem_sizeshould not normally need to be passed. It is, however, necessary for type-punning when the size of the stored type and viewed type differ. For example, a store might refer to binary data where each element is of size 10, but we wish to view it as an mspan of- std::bytes (which would have size = 1). In this case:- #. Pass the viewed type (e.g. - std::byte) as the template parameter- T. #. Pass- VALIDATE_TYPE = false(to avoid warnings about type mismatch). #. Pass- type().size()as- elem_size.- Note - This API is experimental. It will eventually replace the Legion accessor interface, but we are seeking user feedback on it before such time. If you encounter issues, and/or have suggestions for improvements, please file a bug at nv-legate/legate#issues. - Note - If - boundsis empty then the strides of the returned- mdspanwill be all 0 instead of what it might normally be. The object is still perfectly usable as normal but the strides will not be correct.- Template Parameters:
- T – The element type of the mdspan. 
- DIM – The rank of the mdspan. 
- VALIDATE_TYPE – If - true(default on debug builds), checks that the type and rank of the mdspan match that of the- PhysicalStore.
 
- Parameters:
- bounds – The (sub-)domain over which to access the store. 
- elem_size – The size (in bytes) of each element. 
 
- Returns:
- The mdspan accessor. 
 
 
 - 
template<typename Redop, bool EXCLUSIVE, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 mdspan_type<typename Redop::LHS, DIM, detail::ReductionAccessor<Redop, EXCLUSIVE>> span_reduce_accessor( 
)
- Returns a reduction mdspan to the store over the selected domain. - elem_sizeshould not normally need to be passed. It is, however, necessary for type-punning when the size of the stored type and viewed type differ. For example, a store might refer to binary data where each element is of size 10, but we wish to view it as an mspan of- std::bytes (which would have size = 1). In this case:- #. Pass the viewed type (e.g. - std::byte) as the template parameter- T. #. Pass- VALIDATE_TYPE = false(to avoid warnings about type mismatch). #. Pass- type().size()as- elem_size.- Note - This API is experimental. It will eventually replace the Legion accessor interface, but we are seeking user feedback on it before such time. If you encounter issues, and/or have suggestions for improvements, please file a bug at nv-legate/legate#issues. - Note - If - boundsis empty then the strides of the returned- mdspanwill be all 0 instead of what it might normally be. The object is still perfectly usable as normal but the strides will not be correct.- Template Parameters:
- Redop – The reduction operator (e.g. - SumReduction).
- EXCLUSIVE – Whether the reduction accessor has exclusive access to the buffer. 
- DIM – The rank of the mdspan. 
- VALIDATE_TYPE – If - true(default on debug builds), checks that the type and rank of the mdspan match that of the- PhysicalStore.
 
- Parameters:
- bounds – The (sub-)domain over which to access the store. 
- elem_size – The size (in bytes) of each element. 
 
- Returns:
- The mdspan accessor. 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 AccessorRO<T, DIM> read_accessor(
- Returns a read-only accessor to the store for the entire domain. - Template Parameters:
- T – Element type 
- DIM – Number of dimensions 
- VALIDATE_TYPE – If - true(default), validates type and number of dimensions
 
- Returns:
- A read-only accessor to the store 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 AccessorWO<T, DIM> write_accessor(
- Returns a write-only accessor to the store for the entire domain. - Template Parameters:
- T – Element type 
- DIM – Number of dimensions 
- VALIDATE_TYPE – If - true(default), validates type and number of dimensions
 
- Returns:
- A write-only accessor to the store 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 AccessorRW<T, DIM> read_write_accessor(
- Returns a read-write accessor to the store for the entire domain. - Template Parameters:
- T – Element type 
- DIM – Number of dimensions 
- VALIDATE_TYPE – If - true(default), validates type and number of dimensions
 
- Returns:
- A read-write accessor to the store 
 
 
 - 
template<typename OP, bool EXCLUSIVE, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 AccessorRD<OP, EXCLUSIVE, DIM> reduce_accessor(
- Returns a reduction accessor to the store for the entire domain. - Template Parameters:
- OP – Reduction operator class. 
- EXCLUSIVE – Indicates whether reductions can be performed in exclusive mode. If - EXCLUSIVEis- false, every reduction via the accessor is performed atomically.
- DIM – Number of dimensions 
- VALIDATE_TYPE – If - true(default), validates type and number of dimensions
 
- Returns:
- A reduction accessor to the store 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 AccessorRO<T, DIM> read_accessor( 
) const
- Returns a read-only accessor to the store for specific bounds. - Template Parameters:
- T – Element type 
- DIM – Number of dimensions 
- VALIDATE_TYPE – If - true(default), validates type and number of dimensions
 
- Parameters:
- bounds – Domain within which accesses should be allowed. The actual bounds for valid access are determined by an intersection between the store’s domain and the bounds. 
- Returns:
- A read-only accessor to the store 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 AccessorWO<T, DIM> write_accessor( 
) const
- Returns a write-only accessor to the store for the entire domain. - Template Parameters:
- T – Element type 
- DIM – Number of dimensions 
- VALIDATE_TYPE – If - true(default), validates type and number of dimensions
 
- Parameters:
- bounds – Domain within which accesses should be allowed. The actual bounds for valid access are determined by an intersection between the store’s domain and the bounds. 
- Returns:
- A write-only accessor to the store 
 
 
 - 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 AccessorRW<T, DIM> read_write_accessor( 
) const
- Returns a read-write accessor to the store for the entire domain. - Template Parameters:
- T – Element type 
- DIM – Number of dimensions 
- VALIDATE_TYPE – If - true(default), validates type and number of dimensions
 
- Parameters:
- bounds – Domain within which accesses should be allowed. The actual bounds for valid access are determined by an intersection between the store’s domain and the bounds. 
- Returns:
- A read-write accessor to the store 
 
 
 - 
template<typename OP, bool EXCLUSIVE, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 AccessorRD<OP, EXCLUSIVE, DIM> reduce_accessor( 
) const
- Returns a reduction accessor to the store for the entire domain. - Template Parameters:
- OP – Reduction operator class. 
- EXCLUSIVE – Indicates whether reductions can be performed in exclusive mode. If - EXCLUSIVEis- false, every reduction via the accessor is performed atomically.
- DIM – Number of dimensions 
- VALIDATE_TYPE – If - true(default), validates type and number of dimensions
 
- Parameters:
- bounds – Domain within which accesses should be allowed. The actual bounds for valid access are determined by an intersection between the store’s domain and the bounds. 
- Returns:
- A reduction accessor to the store 
 
 
 - 
template<typename VAL>
 VAL scalar() const
- Returns the scalar value stored in the store. - The requested type must match with the store’s data type. If the store is not backed by the future, the runtime will fail with an error message. - Template Parameters:
- VAL – Type of the scalar value 
- Returns:
- The scalar value stored in the store 
 
 - 
template<typename T, std::int32_t DIM>
 Buffer<T, DIM> create_output_buffer( 
) const
- Creates a Buffer of specified extents for the unbound store. - The returned Buffer is always consistent with the mapping policy for the store. Can be invoked multiple times unless - bind_bufferis true.
 
 - TaskLocalBuffer create_output_buffer(
- const DomainPoint &extents,
- bool bind_buffer = false
- Creates a - TaskLocalBufferof specified extents for the unbound store.- The returned - TaskLocalBufferis always consistent with the mapping policy for the store. Can be invoked multiple times unless- bind_bufferis true.- Parameters:
- extents – Extents of the - TaskLocalBuffer
- bind_buffer – If the value is - true, the created- TaskLocalBufferwill be bound to the store upon return.
 
- Returns:
- A - TaskLocalBufferin which to write the output to.
 
 
 - 
template<typename T, std::int32_t DIM>
 void bind_data( 
) const
- Binds a Buffer to the store. - Valid only when the store is unbound and has not yet been bound to another Buffer. The Buffer must be consistent with the mapping policy for the store. Recommend that the Buffer be created by a - create_output_buffer()call.
 
 - void bind_data(
- const TaskLocalBuffer &buffer,
- const DomainPoint &extents,
- bool check_type = false
- Binds a - TaskLocalBufferto the store.- Valid only when the store is unbound and has not yet been bound to another - TaskLocalBuffer. The- TaskLocalBuffermust be consistent with the mapping policy for the store. Recommend that the- TaskLocalBufferbe created by a- create_output_buffer()call.- Passing - extentsthat are smaller than the actual extents of the- TaskLocalBufferis legal; the runtime uses the passed extents as the extents of this store.- If - check_typeis- true, then- buffermust have the same type as the- PhysicalStore.- Parameters:
- buffer – - TaskLocalBufferto bind to the store.
- extents – Extents of the - TaskLocalBuffer.
- check_type – Whether to check the type of the buffer against the type of this store for validity. 
 
- Throws:
- std::invalid_argument – If the type of - bufferis not compatible with the type of the store (only thrown if- check_typeis- true).
 
 
 - void bind_untyped_data( ) const
- Binds a 1D Buffer of byte-size elements to the store in an untyped manner. - Values in the Buffer are reinterpreted based on the store’s actual type. The Buffer must have enough bytes to be aligned on the store’s element boundary. For example, a 1D Buffer of size 4 wouldn’t be valid if the store had the int64 type, whereas it would be if the store’s element type is int32. - Like the typed counterpart (i.e., - bind_data()), the operation is legal only when the store is unbound and has not yet been bound to another buffer. The memory in which the buffer is created must be the same as the mapping decision of this store.- Can be used only with 1D unbound stores. - constexpr auto num_elements = 9; const auto element_size_in_bytes = store.type().size(); constexpr auto UNTYPEED_DATA_DIM = 1; auto buffer = legate::create_buffer<std::int8_t, UNTYPEED_DATA_DIM>(num_elements * element_size_in_bytes); store.bind_untyped_data(buffer, legate::Point<UNTYPEED_DATA_DIM>{num_elements}); 
 
 - 
void bind_empty_data() const
- Makes the unbound store empty. - Valid only when the store is unbound and has not yet been bound to another buffer. 
 - 
std::int32_t dim() const
- Returns the dimension of the store. - Returns:
- The store’s dimension 
 
 - 
template<typename TYPE_CODE = Type::Code>
 inline TYPE_CODE code(
- Returns the type code of the store. - Returns:
- The store’s type code 
 
 
 - 
template<std::int32_t DIM>
 Rect<DIM> shape() const
- Returns the store’s domain. - Returns:
- Store’s domain 
 
 - 
Domain domain() const
- Returns the store’s - Domain- Returns:
- Store’s - Domain
 
 - 
InlineAllocation get_inline_allocation() const
- Returns a raw pointer and strides to the allocation. - Returns:
- An - InlineAllocationobject holding a raw pointer and strides
 
 - 
mapping::StoreTarget target() const
- Returns the kind of memory where this - PhysicalStoreresides.- Throws:
- std::invalid_argument – If this function is called on an unbound store 
- Returns:
- The memory kind 
 
 - 
bool is_readable() const
- Indicates whether the store can have a read accessor. - Returns:
- trueif the store can have a read accessor,- falseotherwise
 
 - 
bool is_writable() const
- Indicates whether the store can have a write accessor. - Returns:
- trueif the store can have a write accessor,- falseotherwise
 
 - 
bool is_reducible() const
- Indicates whether the store can have a reduction accessor. - Returns:
- trueif the store can have a reduction accessor,- falseotherwise
 
 - 
bool valid() const
- Indicates whether the store is valid. - A store passed to a task can be invalid only for reducer tasks for tree reduction. Otherwise, if the store is invalid, it cannot be used in any data access. - Returns:
- trueif the store is valid,- falseotherwise
 
 - 
bool transformed() const
- Indicates whether the store is transformed in any way. - Returns:
- trueif the store is transformed,- falseotherwise
 
 - 
bool is_future() const
- Indicates whether the store is backed by a future (i.e., a container for scalar value) - Returns:
- trueif the store is backed by a future,- falseotherwise
 
 - 
bool is_unbound_store() const
- Indicates whether the store is an unbound store. - The value DOES NOT indicate that the store has already assigned to a buffer; i.e., the store may have been assigned to a buffer even when this function returns - true.- Returns:
- trueif the store is an unbound store,- falseotherwise
 
 - 
bool is_partitioned() const
- Indicates whether the store is partitioned. - Tasks sometimes need to know whether a given - PhysicalStoreis partitioned, i.e., corresponds to a subset of the (global)- LogicalStorepassed at the launch site. Unless the task explicitly requests broadcasting on the- LogicalStore, the partitioning decision on the store is at the whim of the runtime. In this case, the task can use the- is_partitioned()function to retrieve that information.- Returns:
- trueif the store is partitioned,- falseotherwise
 
 - std::unique_ptr<DLManagedTensorVersioned, void (*)(DLManagedTensorVersioned*)> to_dlpack(
- std::optional<bool> copy = std::nullopt,
- std::optional<CUstream_st*> stream = std::nullopt
- Export this store into the DLPack format. - The value of - copyhas the following semantics:- true: Legate must copy the data. If Legate fails to copy the data, for any reason, an exception is thrown.
- false: Legate must never copy the data. If the store cannot be exported without a copy, then an exception is thrown.
- std::nullopt: Legate may copy the data if it is deemed necessary. Currently, this is never the case, and Legate will always provide a view.
 - In any case, if a copy is made, the - DLManagedTensorVersioned::flagsmember will have the- DLPACK_FLAG_BITMASK_IS_COPIEDbit set.- The - std::unique_ptrreturned by this routine will automatically call the deleter of the DLPack tensor in its destructor.- Parameters:
- copy – Whether to copy the underlying data or not. 
- stream – A stream on which the data must be coherent after this routine returns. 
 
- Returns:
- The DLPack managed tensor. 
 
 
 - 
PhysicalStore(const PhysicalArray &array)
- Constructs a store out of an array. - Throws:
- std::invalid_argument – If the array is nullable or has sub-arrays 
 
 
- 
template<typename T, std::int32_t DIM, bool VALIDATE_TYPE = LEGATE_TRUE_WHEN_DEBUG>
 - 
class Scalar
- #include <legate/data/scalar.h>A type-erased container for scalars. A Scalarcan be owned or shared, depending on whether it owns the backing allocation: If aScalaris shared, it does not own the allocation and any of its copies are also shared. If aScalaris owned, it owns the backing allocation and releases it upon destruction. Any copy of an ownedScalaris owned as well.Public Functions - 
Scalar()
- Creates a null scalar. - See also 
 - 
Scalar(const Type &type, const void *data, bool copy = false)
- Creates a shared - Scalarwith an existing allocation. The caller is responsible for passing in a sufficiently big allocation.- Parameters:
- type – - Typeof the scalar
- data – Allocation containing the data. 
- copy – If - true, the scalar copies the data stored in the allocation and becomes owned.
 
 
 - 
template<typename T, typename = std::enable_if_t<!std::is_convertible_v<T, std::string> && !std::is_same_v<std::decay_t<T>, InternalSharedPtr<detail::Scalar>>>>
 explicit Scalar(
- const T &value
- Creates an owned - Scalarfrom a scalar value.- Template Parameters:
- T – The scalar type to wrap 
- Parameters:
- value – A scalar value to create a - Scalarwith
 
 
 - 
template<typename T>
 Scalar(const T &value, const Type &type)
- Creates an owned - Scalarof a specified type from a scalar value.
 - 
explicit Scalar(std::string_view string)
- Creates an owned - Scalarfrom a- std::string_view. The value from the original string will be copied.- Parameters:
- string – The - std::string_viewto create a- Scalarwith
 
 - 
template<typename T>
 explicit Scalar(Span<const T> values)
- Creates an owned - Scalarfrom a- Spanof scalars. The values in the input span will be copied.- Parameters:
- values – Values to create a - Scalarwith in a vector.
 
 - 
template<typename T>
 explicit Scalar(const std::vector<T> &values)
- Creates an owned - Scalarfrom a- std::vectorof scalars. The values in the input vector will be copied.- Parameters:
- values – Values to create a - Scalarwith in a vector.
 
 - 
template<typename T>
 explicit Scalar(const tuple<T> &values)
- Creates an owned - Scalarfrom a- tupleof scalars. The values in the input- tuplewill be copied.- Parameters:
- values – Values to create a - Scalarwith in a- tuple
 
 - 
explicit Scalar(const std::vector<bool> &values)
- Creates an owned - Scalarfrom a- std::vector<bool>. The values in the input vector will be copied.- Like most things with - std::vector<bool>, this construction is not particularly efficient. In order to be copied into the- Scalar, the vector will first be “expanded” into a temporary- std::vector<std::uint8_t>, resulting in multiple copies being performed.- The user is therefore highly encouraged to use - std::vector<std::uint8_t>directly instead of- std::vector<bool>(if possible), especially if such vectors are commonly passed to tasks.- Parameters:
- values – The values with which to create the - Scalar.
 
 - 
template<std::int32_t DIM>
 explicit Scalar( 
)
- Creates a point - Scalar
 
 - 
std::size_t size() const
- Returns the size of allocation for the - Scalar.- Returns:
- The size of allocation in bytes 
 
 - 
template<typename VAL>
 VAL value() const
- Returns a copy of the value stored in this - Scalar.- 1) size of the scalar does not match with size of - VAL, 2) the scalar holds a string but- VALisn’t- std:stringor- std:string_view, or 3) the inverse; i.e.,- VALis- std:stringor- std:string_viewbut the scalar’s type isn’t string
 - 
template<typename VAL>
 Span<const VAL> values() const
- Returns values stored in the - Scalar. If the- Scalardoes not have a fixed array type, a unit span will be returned.- 1) the scalar has a fixed array type whose element type has a different size from - VAL, 2) the scalar holds a string and size of- VALisn’t 1 byte, 3) the scalar’s type isn’t a fixed array type and the size is different from size of- VAL- Throws:
- std::invalid_argument – If one of the following cases is encountered: 
- Returns:
- Values stored in the - Scalar
 
 - 
const void *ptr() const
- Returns a raw pointer to the backing allocation. - Returns:
- A raw pointer to the - Scalar’s data
 
 
- 
Scalar()
 - 
class Shape
- #include <legate/data/shape.h>A class to express shapes of multi-dimensional entities in Legate. Shapeobjects describe logical shapes, of multi-dimensional containers in Legate such as Legate arrays and Legate stores. For example, if the shape of a Legate store is(4, 2), the store is conceptually a 2D container having four rows and two columns of elements. The shape however does not entail any particular physical manifestation of the container. The aforementioned 2D store can be mapped to an allocation in which the elements of each row would be contiguously located or an allocation in which the elements of each column would be contiguously located.A Shapeobject is essentially a tuple of extents, one for each dimension, and the dimensionality, i.e., the number of dimensions, is the size of this tuple. The volume of theShapeis a product of all the extents.Since Legate allows containers’ shapes to be determined by tasks, some shapes may not be “ready” when the control code tries to introspect their extents. In this case, the control code will be blocked until the tasks updating the containers are complete. This asynchrony behind the shape objects is hidden from the control code and it’s recommended that introspection of the shapes of unbound arrays or stores should be avoided. The blocking behavior of each API call can be found in its reference (methods with no mention of blocking should exhibit no shape-related blocking). Public Functions - 
Shape(Span<const std::uint64_t> extents)
- Constructs a - Shapefrom a- Spanof extents.- The constructed - Shapeis immediately ready- Parameters:
- extents – Dimension extents 
 
 - 
Shape(const tuple<std::uint64_t> &extents)
- Constructs a - Shapefrom a- tupleof extents.- The constructed - Shapeis immediately ready- Parameters:
- extents – Dimension extents 
 
 - 
explicit Shape(const std::vector<std::uint64_t> &extents)
- Constructs a - Shapefrom a- std::vectorof extents.- The constructed - Shapeis immediately ready- Parameters:
- extents – Dimension extents 
 
 - 
Shape(std::initializer_list<std::uint64_t> extents)
- Constructs a - Shapefrom a- std::initializer_listof extents.- The constructed - Shapeis immediately ready- Parameters:
- extents – Dimension extents 
 
 - 
tuple<std::uint64_t> extents() const
- Returns the - Shape’s extents.- If the - Shapeis of an unbound array or store, the call blocks until the shape becomes ready.- Returns:
- Dimension extents 
 
 - 
std::size_t volume() const
- Returns the - Shape’s volume.- Equivalent to - extents().volume(). If the- Shapeis of an unbound array or store, the call blocks until the- Shapebecomes ready.- Returns:
- Volume of the - Shape
 
 - 
std::uint32_t ndim() const
- Returns the number of dimensions of this - Shape- Unlike other - Shape-related queries, this call is non-blocking.- Returns:
- Number of dimensions 
 
 - 
std::uint64_t operator[](std::uint32_t idx) const
- Returns the extent of a given dimension. - If the - Shapeis of an unbound array or store, the call blocks until the- Shapebecomes ready. Unlike- Shape::at(), this method does not check the dimension index.- Parameters:
- idx – Dimension index 
- Returns:
- Extent of the chosen dimension 
 
 - 
std::uint64_t at(std::uint32_t idx) const
- Returns the extent of a given dimension. - If the - Shapeis of an unbound array or store, the call blocks until the- Shapebecomes ready.- Parameters:
- idx – Dimension index 
- Throws:
- std::out_of_range – If the dimension index is invalid 
- Returns:
- Extent of the chosen dimension 
 
 - 
std::string to_string() const
- Generates a human-readable string from the - Shape(non-blocking)- Returns:
- std::stringgenerated from the- Shape
 
 
- 
Shape(Span<const std::uint64_t> extents)
 - 
class Slice
- #include <legate/data/slice.h>A slice descriptor. Slicebehaves similarly to how the slice in Python does, and has different semantics fromstd::slice.Public Functions - inline Slice(
- std::optional<std::int64_t> _start = OPEN,
- std::optional<std::int64_t> _stop = OPEN
- Constructs a - Slice- If provided (and not - Slice::OPEN),- _startmust compare less than or equal to- _stop. Similarly, if provided (and not- Slice::OPEN),- _stopmust compare greater than or equal to- _start. Put simply, unless one or both of the ends are unbounded,- [_start, _stop]must form a valid (possibly empty) interval.- Parameters:
- _start – The optional begin index of the slice, or - Slice::OPENif the start of the slice is unbounded.
- _stop – The optional stop index of the slice, or - Slice::OPENif the end of the slice if unbounded.
 
 
 
 Public Members - 
std::optional<std::int64_t> start = {OPEN}
- The start index of the slice 
 - 
std::optional<std::int64_t> stop = {OPEN}
- The end index of the slice 
 
 
- 
LEGATE_TRUE_WHEN_DEBUG#