Task#

group task

Typedefs

using SymbolicPoint = tuple<SymbolicExpr>#

A symbolic representation of points.

Symbolic points are used to capture mappings between points in different domains in a concise way. Each element of a symbolic point is a SymbolicExpr symbolically representing the coordinate of that dimension. A ManualTask can optionally pass for its logical store partition argument a symbolic point that describes a mapping from points in the launch domain to sub-stores in the partition.

Functions

inline SymbolicExpr dimension(std::uint32_t dim)#

Constructs a SymbolicExpr representing coordinates of a dimension.

Parameters:

dim – The dimension index

Returns:

A symbolic expression for the given dimension

inline SymbolicExpr constant(std::int32_t value)#

Constructs a SymbolicExpr representing a constant value.

Parameters:

value – The constant value to embed

Returns:

A symbolic expression for the given constant

class Communicator#
#include <core/comm/communicator.h>

A thin wrapper class for communicators stored in futures. This class only provides a tempalte method to retrieve the communicator handle and the client is expected to pass the right handle type.

The following is the list of handle types for communicators supported in Legate:

  • NCCL: ncclComm_t*

  • CPU communicator in Legate: legate::comm::coll::CollComm*

  • CAL: cal_comm_t

Public Functions

template<typename T>
T get() const#

Returns the communicator stored in the wrapper.

Template Parameters:

T – The type of communicator handle to get (see valid types above)

Returns:

A communicator

class StreamView#
#include <core/cuda/stream_pool.h>

A simple wrapper around CUDA streams to inject auxiliary features.

When LEGATE_SYNC_STREAM_VIEW is set to 1, every StreamView synchronizes the CUDA stream that it wraps when it is destroyed.

Public Functions

inline explicit StreamView(cudaStream_t stream)#

Creates a StreamView with a raw CUDA stream.

Parameters:

stream – Raw CUDA stream to wrap

inline operator cudaStream_t() const#

Unwraps the raw CUDA stream.

Returns:

Raw CUDA stream wrapped by the StreamView

class StreamPool#
#include <core/cuda/stream_pool.h>

A stream pool.

Public Functions

StreamView get_stream()#

Returns a StreamView in the pool.

Returns:

A StreamView object. Currently, all stream views returned from this pool are backed by the same CUDA stream.

Public Static Functions

static StreamPool &get_stream_pool()#

Returns a singleton stream pool.

The stream pool is alive throughout the program execution.

Returns:

A StreamPool object

class SymbolicExpr#
#include <core/operation/projection.h>

A class that symbolically represents coordinates.

A \(\mathtt{SymbolicExpr}(i, w, c)\) object denotes an expression \( w \cdot \mathit{dim}_i + c \), where \( \mathit{dim}_i \) corresponds to the coordinate of the \(i\)-th dimension. A special case is when \(i\) is \(-1\), which means the expression denotes a constant \(c\).

Public Functions

inline std::uint32_t dim() const#

Returns the dimension index of this expression.

Returns:

Dimension index

inline std::int32_t weight() const#

Returns the weight for the coordinates.

Returns:

Weight value

inline std::int32_t offset() const#

Returns the offset of the expression.

Returns:

Offset

inline bool is_identity(std::uint32_t dim) const#

Indicates if the expression denotes an identity mapping for the given dimension.

Parameters:

dim – The dimension for which the identity mapping is checked

Returns:

true The expression denotes an identity mapping

Returns:

false The expression does not denote an identity mapping

inline bool is_constant() const#

Indicates if the expression denotes a constant.

Returns:

true The expression denotes a constant

Returns:

false The expression does not denote a constant

class AutoTask#
#include <core/operation/task.h>

A class for auto-parallelized task desciptors.

Public Functions

Variable add_input(const LogicalArray &array)#

Adds an array to the task as input.

Partitioning of the array is controlled by constraints on the partition symbol associated with the array

Parameters:

array – An array to add to the task as input

Returns:

The partition symbol assigned to the array

Variable add_output(const LogicalArray &array)#

Adds an array to the task as output.

Partitioning of the array is controlled by constraints on the partition symbol associated with the array

Parameters:

array – An array to add to the task as output

Returns:

The partition symbol assigned to the array

Variable add_reduction(const LogicalArray &array, ReductionOpKind redop)#

Adds an array to the task for reductions.

Partitioning of the array is controlled by constraints on the partition symbol associated with the array

Parameters:
  • array – An array to add to the task for reductions

  • redop – ID of the reduction operator to use. The array’s type must support the operator.

Returns:

The partition symbol assigned to the array

Variable add_reduction(const LogicalArray &array, std::int32_t redop)#

Adds an array to the task for reductions.

Partitioning of the array is controlled by constraints on the partition symbol associated with the array

Parameters:
  • array – An array to add to the task for reductions

  • redop – ID of the reduction operator to use. The array’s type must support the operator.

Returns:

The partition symbol assigned to the array

Variable add_input(const LogicalArray &array, Variable partition_symbol)#

Adds an array to the task as input.

Partitioning of the array is controlled by constraints on the partition symbol associated with the array

Parameters:
  • array – An array to add to the task as input

  • partition_symbol – A partition symbol for the array

Returns:

The partition symbol assigned to the array

Variable add_output(const LogicalArray &array, Variable partition_symbol)#

Adds an array to the task as output.

Partitioning of the array is controlled by constraints on the partition symbol associated with the array

Parameters:
  • array – An array to add to the task as output

  • partition_symbol – A partition symbol for the array

Returns:

The partition symbol assigned to the array

Variable add_reduction(const LogicalArray &array, ReductionOpKind redop, Variable partition_symbol)#

Adds an array to the task for reductions.

Partitioning of the array is controlled by constraints on the partition symbol associated with the array

Parameters:
  • array – An array to add to the task for reductions

  • redop – ID of the reduction operator to use. The array’s type must support the operator.

  • partition_symbol – A partition symbol for the array

Returns:

The partition symbol assigned to the array

Variable add_reduction(const LogicalArray &array, std::int32_t redop, Variable partition_symbol)#

Adds an array to the task for reductions.

Partitioning of the array is controlled by constraints on the partition symbol associated with the array

Parameters:
  • array – An array to add to the task for reductions

  • redop – ID of the reduction operator to use. The array’s type must support the operator.

  • partition_symbol – A partition symbol for the array

Returns:

The partition symbol assigned to the array

void add_scalar_arg(const Scalar &scalar)#

Adds a by-value scalar argument to the task.

Parameters:

scalar – The Scalar to add to the task

template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, Scalar> && std::is_constructible_v<Scalar, T>>>
void add_scalar_arg(T &&value)#

Adds a by-value scalar argument to the task.

Template Parameters:

T – The scalar value’s type. Scalar must be constructible from a value of T

Parameters:

value – The scalar value to convert to Scalar and add to the task

void add_constraint(const Constraint &constraint)#

Adds a partitioning constraint to the task.

Parameters:

constraint – A partitioning constraint

Variable find_or_declare_partition(const LogicalArray &array)#

Finds or creates a partition symbol for the given array.

Parameters:

array – Array for which the partition symbol is queried

Returns:

The existing symbol if there is one for the array, a fresh symbol otherwise

Variable declare_partition()#

Declares partition symbol.

Returns:

A new symbol that can be used when passing an array to an operation

std::string_view provenance() const#

Returns the provenance information of this operation.

Returns:

Provenance

void set_concurrent(bool concurrent)#

Sets whether the task needs a concurrent task launch.

Any task with at least one communicator will implicitly use concurrent task launch, so this method is to be used when the task needs a concurrent task launch for a reason unknown to Legate.

Parameters:

concurrent – A boolean value indicating whether the task needs a concurrent task launch

void set_side_effect(bool has_side_effect)#

Sets whether the task has side effects or not.

A task is assumed to be free of side effects by default if the task only has scalar arguments.

Parameters:

has_side_effect – A boolean value indicating whether the task has side effects

void throws_exception(bool can_throw_exception)#

Sets whether the task can throw an exception or not.

Parameters:

can_throw_exception – A boolean value indicating whether the task can throw an exception

void add_communicator(std::string_view name)#

Requests a communicator for this task.

Parameters:

name – The name of the communicator to use for this task

class ManualTask#
#include <core/operation/task.h>

A class for manually parallelized task descriptors.

Public Functions

void add_input(const LogicalStore &store)#

Adds a store to the task as input.

The store will be unpartitioned but broadcasted to all the tasks

Parameters:

store – A store to add to the task as input

void add_input(const LogicalStorePartition &store_partition, std::optional<SymbolicPoint> projection = std::nullopt)#

Adds a store partition to the task as input.

Parameters:
  • store_partition – A store partition to add to the task as input

  • projection – An optional symbolic point describing a mapping between points in the launch domain and substores in the partition

void add_output(const LogicalStore &store)#

Adds a store to the task as output.

The store will be unpartitioned but broadcasted to all the tasks

Parameters:

store – A store to add to the task as output

void add_output(const LogicalStorePartition &store_partition, std::optional<SymbolicPoint> projection = std::nullopt)#

Adds a store partition to the task as output.

Parameters:
  • store_partition – A store partition to add to the task as output

  • projection – An optional symbolic point describing a mapping between points in the launch domain and substores in the partition

void add_reduction(const LogicalStore &store, ReductionOpKind redop)#

Adds a store to the task for reductions.

The store will be unpartitioned but broadcasted to all the tasks

Parameters:
  • store – A store to add to the task for reductions

  • redop – ID of the reduction operator to use. The store’s type must support the operator.

void add_reduction(const LogicalStore &store, std::int32_t redop)#

Adds a store to the task for reductions.

The store will be unpartitioned but broadcasted to all the tasks

Parameters:
  • store – A store to add to the task for reductions

  • redop – ID of the reduction operator to use. The store’s type must support the operator.

void add_reduction(const LogicalStorePartition &store_partition, ReductionOpKind redop, std::optional<SymbolicPoint> projection = std::nullopt)#

Adds a store partition to the task for reductions.

Parameters:
  • store_partition – A store partition to add to the task for reductions

  • redop – ID of the reduction operator to use. The store’s type must support the operator.

  • projection – An optional symbolic point describing a mapping between points in the launch domain and substores in the partition

void add_reduction(const LogicalStorePartition &store_partition, std::int32_t redop, std::optional<SymbolicPoint> projection = std::nullopt)#

Adds a store partition to the task for reductions.

Parameters:
  • store_partition – A store partition to add to the task for reductions

  • redop – ID of the reduction operator to use. The store’s type must support the operator.

  • projection – An optional symbolic point describing a mapping between points in the launch domain and substores in the partition

void add_scalar_arg(const Scalar &scalar)#

Adds a by-value scalar argument to the task.

Parameters:

scalar – The Scalar to add to the task

template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, Scalar> && std::is_constructible_v<Scalar, T>>>
void add_scalar_arg(T &&value)#

Adds a by-value scalar argument to the task.

Template Parameters:

T – The scalar value’s type. Scalar must be constructible from a value of T

Parameters:

value – The scalar value to convert to Scalar and add to the task

std::string_view provenance() const#

Returns the provenance information of this operation.

Returns:

Provenance

void set_concurrent(bool concurrent)#

Sets whether the task needs a concurrent task launch.

Any task with at least one communicator will implicitly use concurrent task launch, so this method is to be used when the task needs a concurrent task launch for a reason unknown to Legate.

Parameters:

concurrent – A boolean value indicating whether the task needs a concurrent task launch

void set_side_effect(bool has_side_effect)#

Sets whether the task has side effects or not.

A task is assumed to be free of side effects by default if the task only has scalar arguments.

Parameters:

has_side_effect – A boolean value indicating whether the task has side effects

void throws_exception(bool can_throw_exception)#

Sets whether the task can throw an exception or not.

Parameters:

can_throw_exception – A boolean value indicating whether the task can throw an exception

void add_communicator(std::string_view name)#

Requests a communicator for this task.

Parameters:

name – The name of the communicator to use for this task

class TaskException : public std::exception#
#include <core/task/exception.h>

An exception class used in cross language exception handling.

Any client that needs to catch a C++ exception during task execution and have it rethrown on the launcher side should wrap that C++ exception with a TaskException. In case the task can raise more than one type of exception, they are distinguished by integer ids; the launcher is responsible for enumerating a list of all exceptions that can be raised and the integer ids are positions in that list.

Subclassed by legate::detail::PythonTaskException

Public Functions

inline TaskException(std::int32_t index, std::string error_message)#

Constructs a TaskException object with an exception id and an error message. The id must be a valid index for the list of exceptions declared by the launcher.

Parameters:
  • index – Exception id

  • error_message – Error message

inline explicit TaskException(std::string error_message)#

Constructs a TaskException object with an error message. The exception id is set to 0.

Parameters:

error_message – Error message

inline std::int32_t index() const noexcept#

Returns the exception id.

Returns:

The exception id

inline const std::string &error_message() const noexcept#

Returns the error message.

Returns:

The error message

class TaskRegistrar#
#include <core/task/registrar.h>

A helper class for task variant registration.

The legate::TaskRegistrar class is designed to simplify the boilerplate that client libraries need to register all its task variants. The following is a boilerplate that each library needs to write:

struct MyLibrary {
  static legate::TaskRegistrar& get_registrar();
};

template <typename T>
struct MyLibraryTaskBase : public legate::LegateTask<T> {
  using Registrar = MyLibrary;

  ...
};

In the code above, the MyLibrary has a static member that returns a singleton legate::TaskRegistrar object. Then, the MyLibraryTaskBase points to the class so Legate can find where task variants are collected.

Once this registrar is set up in a library, each library task can simply register itself with the LegateTask::register_variants method like the following:

// In a header
struct MyLibraryTask : public MyLibraryTaskBase<MyLibraryTask> {
  ...
};

// In a C++ file
static void __attribute__((constructor)) register_tasks()
{
  MyLibraryTask::register_variants();
}

Public Functions

void register_all_tasks(Library library)#

Registers all tasks recorded in this registrar. Typically invoked in a registration callback of a library.

Parameters:

library – Library that owns this registrar

class Impl#
template<typename T>
class LegateTask#
#include <core/task/task.h>

A base class template for Legate task implementations.

Any Legate task class must inherit legate::LegateTask directly or transitively. The type parameter T needs to be bound to a child Legate task class that inherits legate::LegateTask.

Curently, each task can have up to three variants and the variants need to be static member functions of the class under the following names:

  • cpu_variant: CPU implementation of the task

  • gpu_variant: GPU implementation of the task

  • omp_variant: OpenMP implementation of the task

Tasks must have at least one variant, and all task variants must be semantically equivalent (modulo some minor rounding errors due to floating point imprecision).

Each task class must also have a type alias Registrar that points to a library specific registrar class. (See legate::TaskRegistrar for details.)

Each task can also declare the following static members which are used as defaults in variious circumstances:

  • static constexpr std::int32_t TASK_ID: Specifies the default local task ID used when registering a task with a library, and subsequent creation. If not present, then the user must pass the required task ID whenever creating or registering the task.

  • static constexpr VariantOptions CPU_VARIANT_OPTIONS: Specifies the default variant options used when registering the CPU variant of the task.

  • static constexpr VariantOptions OMP_VARIANT_OPTIONS: Specifies the default variant options used when registering the OMP variant of the task.

  • static constexpr VariantOptions GPU_VARIANT_OPTIONS: Specifies the default variant options used when registering the GPU variant of the task.

If the default variant options are not present, the variant options for a given variant v are selected in the following order:

  1. The variant options (if any) supplied at the call-site of register_variants().

  2. The default variant options (if any) found in XXX_VARIANT_OPTIONS.

  3. The global default variant options found in VariantOptions::DEFAULT_OPTIONS.

Public Static Functions

static void register_variants(const std::map<LegateVariantCode, VariantOptions> &all_options = {})#

Records all variants of this task in a registrar.

The registrar is pointed to by the task’s static type alias Registrar (see legate::TaskRegistrar for details about setting up a registrar in a library). The client can optionally specify variant options.

Parameters:

all_options – Options for task variants. Variants with no entires in all_options will use the default set of options as discussed in the class description.

static void register_variants(Library library, const std::map<LegateVariantCode, VariantOptions> &all_options = {})#

Registers all variants of this task immediately.

Unlike the other method, this one takes a library so the registration can be done immediately. The value of T::TASK_ID is used as the task id.

Parameters:
  • library – Library to which the task should be registered

  • all_options – Options for task variants. Variants with no entires in all_options will use the default set of options as discussed in the class description.

static void register_variants(Library library, std::int64_t task_id, const std::map<LegateVariantCode, VariantOptions> &all_options = {})#

Registers all variants of this task immediately.

Unlike the other method, this one takes a library so the registration can be done immediately.

Parameters:
  • library – Library to which the task should be registered

  • task_id – Task id

  • all_options – Options for task variants. Variants with no entires in all_options will use the default set of options as discussed in the class description.

class TaskContext#
#include <core/task/task_context.h>

A task context that contains task arguments and communicators.

Public Functions

std::int64_t task_id() const noexcept#

Returns the global ID of the task.

Returns:

The global task id

LegateVariantCode variant_kind() const noexcept#

Returns the Legate variant kind of the task.

Returns:

The variant kind

PhysicalArray input(std::uint32_t index) const#

Returns an input array of the task.

Parameters:

index – Index of the array

Returns:

Array

std::vector<PhysicalArray> inputs() const#

Returns all input arrays of the task.

Returns:

Vector of arrays

PhysicalArray output(std::uint32_t index) const#

Returns an output array of the task.

Parameters:

index – Index of the array

Returns:

Array

std::vector<PhysicalArray> outputs() const#

Returns all output arrays of the task.

Returns:

Vector of arrays

PhysicalArray reduction(std::uint32_t index) const#

Returns a reduction array of the task.

Parameters:

index – Index of the array

Returns:

Array

std::vector<PhysicalArray> reductions() const#

Returns all reduction arrays of the task.

Returns:

Vector of arrays

const Scalar &scalar(std::uint32_t index) const#

Returns a by-value argument of the task.

Parameters:

index – Index of the scalar

Returns:

Scalar

const std::vector<Scalar> &scalars() const#

Returns by-value arguments of the task.

Returns:

Vector of scalars

const comm::Communicator &communicator(std::uint32_t index) const#

Returns a communicator of the task.

If a task launch ends up emitting only a single point task, that task will not get passed a communicator, even if one was requested at task launching time. Therefore, tasks using communicators should be prepared to handle the case where the returned vector is empty.

Parameters:

index – Index of the communicator

Returns:

Communicator

const std::vector<comm::Communicator> &communicators() const#

Returns communicators of the task.

If a task launch ends up emitting only a single point task, that task will not get passed a communicator, even if one was requested at task launching time. Therefore, most tasks using communicators should be prepared to handle the case where the returned vector is empty.

Returns:

Vector of communicators

std::size_t num_inputs() const#

Returns the number of task’s inputs.

Returns:

Number of arrays

std::size_t num_outputs() const#

Returns the number of task’s outputs.

Returns:

Number of arrays

std::size_t num_reductions() const#

Returns the number of task’s reductions.

Returns:

Number of arrays

std::size_t num_communicators() const#

Returns the number of communicators.

Returns:

Number of communicators

bool is_single_task() const#

Indicates whether the task is parallelized.

Returns:

true The task is a single task

Returns:

false The task is one in a set of multiple parallel tasks

bool can_raise_exception() const#

Indicates whether the task is allowed to raise an exception.

Returns:

true The task can raise an exception

Returns:

false The task must not raise an exception

const DomainPoint &get_task_index() const#

Returns the point of the task. A 0D point will be returned for a single task.

Returns:

The point of the task

const Domain &get_launch_domain() const#

Returns the task group’s launch domain. A single task returns an empty domain.

Returns:

The task group’s launch domain

mapping::TaskTarget target() const#

Returns the kind of processor executing this task.

Returns:

The processor kind

class VariantOptions#
#include <core/task/variant_options.h>

A helper class for specifying variant options.

Public Functions

constexpr VariantOptions &with_leaf(bool leaf)#

Changes the value of the leaf flag.

Parameters:

`leaf` – A new value for the leaf flag

constexpr VariantOptions &with_concurrent(bool concurrent)#

Changes the value of the concurrent flag.

Parameters:

`concurrent` – A new value for the concurrent flag

constexpr VariantOptions &with_return_size(std::size_t return_size)#

Sets a maximum aggregate size for scalar output values.

Parameters:

`return_size` – A new maximum aggregate size for scalar output values

void populate_registrar(Legion::TaskVariantRegistrar &registrar) const#

Populate a Legion::TaskVariantRegistrar using the options contained.

Parameters:

registrar – The registrar to fill out.

Public Members

bool leaf = {true}#

If the flag is true, the variant launches no subtasks. true by default.

bool concurrent = {false}#

If the flag is true, the variant needs a concurrent task launch. false by default.

std::size_t return_size = {LEGATE_MAX_SIZE_SCALAR_RETURN}#

Maximum aggregate size for scalar output values. 4096 by default.

Public Static Attributes

static const VariantOptions DEFAULT_OPTIONS = {}#

The default variant options used during task creation if no user-supplied options are given.