run(3) run(3)

NAME

node - adapt function to execute on remote node

SYNOPSIS

#include <cfl/run/node.hpp>

auto f = [] (int u) { return u + 1; };

auto g = node (1, f); // 1_node (f);

auto r = g (0);

DESCRIPTION

node adapts a function for remote execution. There is a corresponding user-defined literal _node for convenience. When an adapted function is invoked, it (immediately) returns a future to a remote future.

SYNCHRONIZATION

Function and arguments are put in a send queue and sent to the remote node, preserving call order. When received at the remote node, a remote future is sent back as receipt to caller, and function invocation is (autmoatically) submitted to a task queue, preserving the same order. Once evaluated, a remote value is sent back as reply to the original caller. However, task completion order is indeterminate, as well as reply order.

The different stages of evaluation can be forced using a set of modifiers: send, receipt, wait, get, fetch, fetch_wait or fetch_get, with slightly different meaning depending on whether they operate on the function g or the result r.

As an example, to execute remotely and get an asynchronous local result:

auto r = fetch (g) (0);

COMPOSITION

Asynchronous remote values can be used as arguments to container functions. The return type is changed correspondingly to a future instead.

auto h = cfn ([] (int u) { return u + 2; });
auto s = h (r);

Here, the value in the remote future is fetched and passed to h asynchronously.

Nested remote calls are currently limited to remote value arguments, so a wait call is implied for such arguments.

RETURN VALUES

A function. When invoked, it executes on a remote node and locally immediately returns a future to a remote future.

STANDARDS

Both node and its resulting function are container functions.

NOTES

In the case of over-subscription (i.e. when the program runs with more processes than there are available nodes), another “node” may actually be a processes residing on the same machine as the caller. Because of this, the name node is slightly misleading. MPI uses the term rank instead, but in CFL this conflicts with the rank of arrays. Between the two, CFL chose node, as over-subscription is not the first choice to parallelize work. Local communication is done through a UNIX socket, so it is normally faster than over the network, but data is still serialized and sent between the two processes. A better alternative would be to defer work to local threads instead.