legate::VariantOptions#

class VariantOptions#

A helper class for specifying variant options.

Public Functions

VariantOptions &with_concurrent(bool concurrent)#

Changes the value of the concurrent flag.

Parameters:

`concurrent` – A new value for the concurrent flag

VariantOptions &with_has_allocations(bool has_allocations)#

Changes the value of the has_allocations flag.

Parameters:

`has_allocations` – A new value for the has_allocations flag

VariantOptions &with_elide_device_ctx_sync(bool elide_sync)#

Sets whether the variant can elide device context synchronization after task completion.

Parameters:

`elide_sync`true if this variant can skip synchronizing the device context after task completion, false otherwise.

Returns:

reference to this.

VariantOptions &with_has_side_effect(bool side_effect)#

Sets whether the variant has side effects.

See also

has_side_effect.

Parameters:

side_effecttrue if the task has side-effects, false otherwise.

Returns:

reference to this.

VariantOptions &with_may_throw_exception(bool may_throw)#

Sets whether the variant may throw exceptions.

Parameters:

may_throwtrue if the variant may throw exceptions, false otherwise.

Returns:

reference to this.

inline VariantOptions &with_communicators(
std::initializer_list<std::string_view> comms
) noexcept#

Sets the communicator(s) for the variant.

This call implies concurrent = true as well.

The VariantOptions does not take ownership of comms in any way. If comms are not constructed from a string-literal, or some other object with static storage duration, then the user must ensure that the string(s) outlives this object.

Due to limitations with constexpr in C++17, the user may register at most MAX_COMMS number of communicators. This restriction is expected to be lifted in the future.

See also

communicators.

Parameters:

comms – The communicator(s) to use.

Returns:

reference to this.

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 concurrent = {false}#

Whether the variant needs a concurrent task launch. false by default.

Normally, leaf tasks (i.e. all individual task instances created by a single launch) are allowed to execute in any order so long as their preconditions are met. For example, if a task is launched that creates 100 leaf tasks, those tasks can execute at any time so long as each individual task’s inputs are satisfied. It is even possible to have other leaf tasks (from other tasks) executing at the same time or between them.

Setting concurrent to true says: if this task is parallelized, then all leaf tasks must execute concurrently. Note, concurrency is a requirement, not a grant. The entire machine must execute the tasks at exactly the same time as one giant block. No other tasks marked concurrent may execute at the same time.

Setting concurrent to false (the default) says: the task can execute as normal. The leaf tasks can execute in any order.

This feature is most often used when doing collective communications (i.e. all-reduce, all-gather) inside the tasks. In this case, the tasks need to execute in lockstep because otherwise deadlocks may occur.

Suppose there are 2 tasks (A and B) that do collectives. If they execute without concurrency, it is possible for half of the “task A” tasks and half of the “task B” tasks to be running at the same time. Eventually each of those tasks will reach a point where they must all-gather. The program would deadlock because both sides would be waiting for the communication that would never be able to finish.

For this reason, adding any communicators (see communicators) automatically implies concurrent = true.

bool has_allocations = {false}#

If the flag is true, the variant is allowed to create buffers (temporary or output) during execution. false by default.

bool elide_device_ctx_sync = {}#

Whether this variant can skip device context synchronization after completion.

Normally, for device-enabled task variants, Legate will emit a device-wide barrier to ensure that all outstanding (potentially asynchronous) work performed by the variant has completed. However, if the task launches no such work, or if that work is launched using the task-specific device streams, then such a context synchronization is not necessary.

Setting this value to true ensures that no context synchronization is performed. Setting it to false guarantees that a context synchronization is done.

Has no effect on non-device variants (for example CPU variants).

bool has_side_effect = {}#

Indicate whether a task has side effects outside of the runtime’s tracking that forbid it from replicated a task.

When a task only takes scalar stores, it gets replicated by default on all the ranks, as that’s more efficient than having only one of the ranks run it and broadcast the results.

However, sometimes a task may have “side effects” (which are outside the runtime’s tracking) which should otherwise forbid the runtime from replicating a particular variant.

For example, the task may write something to disk, or effect some other kind of permanent change to the system. In these cases the runtime must not replicate the task, as the effect must occur exactly once.

bool may_throw_exception = {}#

Whether this variant may throw an exception.

Tasks that throw exception must be handled specially by the runtime in order to safely and correctly propagate the thrown exceptions. For this reason, tasks must explicitly declare whether they throw an exception.

Warning

This special handling usually comes with severe performance penalties. For example, the runtime may block the calling thread (i.e. the main thread) on the completion of the possibly throwing task, or may opt not to schedule any other tasks concurrently.

Warning

It is highly recommended that tasks do not throw exceptions, and instead indicate an error state using some other way. Exceptions should be used as an absolute last resort.

std::optional<std::array<std::string_view, MAX_COMMS>> communicators = {}#

The communicator(s) to be used by the variant, or std::nullopt if no communicator is to be used.

Setting this to anything other than std::nullopt implies concurrent to be true.

Public Static Attributes

static auto MAX_COMMS = 3#

The maximum number of communicators allowed per variant.

This is a workaround for insufficient constexpr support in C++17 and will be removed in a future release.

class WithCommunicatorsAccessKey#