legate::Library#

class Library#

A library class that provides APIs for registering components.

Public Functions

std::string_view get_library_name() const#

Returns the name of the library.

Returns:

Library name

std::string_view get_task_name(LocalTaskID local_task_id) const#

Returns the name of a task.

Parameters:

local_task_id – Task id

Returns:

Name of the task

Scalar get_tunable(std::int64_t tunable_id, const Type &type)#

Retrieves a tunable parameter.

Parameters:
  • tunable_id – ID of the tunable parameter

  • typeType of the tunable value

Returns:

The value of tunable parameter in a Scalar

template<typename REDOP>
GlobalRedopID register_reduction_operator(
LocalRedopID redop_id
)#

Registers a library specific reduction operator.

The type parameter REDOP points to a class that implements a reduction operator. Each reduction operator class has the following structure:

struct RedOp {
  using LHS = ...; // Type of the LHS values
  using RHS = ...; // Type of the RHS values

  static const RHS identity = ...; // Identity of the reduction operator

  template <bool EXCLUSIVE>
  LEGATE_HOST_DEVICE inline static void apply(LHS& lhs, RHS rhs)
  {
    ...
  }
  template <bool EXCLUSIVE>
  LEGATE_HOST_DEVICE inline static void fold(RHS& rhs1, RHS rhs2)
  {
    ...
  }
};

Semantically, Legate performs reductions of values V0, …, Vn to element E in the following way:

RHS T = RedOp::identity;
RedOp::fold(T, V0)
...
RedOp::fold(T, Vn)
RedOp::apply(E, T)
I.e., Legate gathers all reduction contributions using fold and applies the accumulator to the element using apply.

Oftentimes, the LHS and RHS of a reduction operator are the same type and fold and apply perform the same computation, but that’s not mandatory. For example, one may implement a reduction operator for subtraction, where the fold would sum up all RHS values whereas the apply would subtract the aggregate value from the LHS.

The reduction operator id (REDOP_ID) can be local to the library but should be unique for each operator within the library.

Finally, the contract for apply and fold is that they must update the reference atomically when the EXCLUSIVE is false.

Warning

Because the runtime can capture the reduction operator and wrap it with CUDA boilerplates only at compile time, the registration call should be made in a .cu file that would be compiled by NVCC. Otherwise, the runtime would register the reduction operator in CPU-only mode, which can degrade the performance when the program performs reductions on non-scalar stores.

Template Parameters:

REDOP – Reduction operator to register

Parameters:

redop_id – Library-local reduction operator ID

Returns:

Global reduction operator ID

void register_task(
LocalTaskID local_task_id,
const TaskInfo &task_info
)#

Register a task with the library.

See also

find_task()

Parameters:
  • local_task_id – The library-local task ID to assign for this task.

  • task_info – The TaskInfo object describing the task.

Throws:
  • std::out_of_range – If the chosen local task ID exceeds the maximum local task ID for the library.

  • std::invalid_argument – If the task (or another task with the same local_task_id) has already been registered with the library.

TaskInfo find_task(LocalTaskID local_task_id) const#

Look up a task registered with the library.

See also

register_task()

Parameters:

local_task_id – The task ID to find.

Throws:

std::out_of_range – If the task could not be found.

Returns:

The TaskInfo object describing the task.