Base class for defining and using CnC (sub-)graphs. More...
Public Member Functions | |
template<typename Ctxt > | |
graph (CnC::context< Ctxt > &ctxt, const std::string &name="") | |
A graph requires a context and a name for its initialization. | |
void | enter_quiescence () const |
Tell the runtime that the graph reached (temporary) quiescence. | |
void | leave_quiescence () const |
Tell the runtime that the graph leaves quiescence and goes back to activity. Must be called only within a on_put callback (to be registered through item_collection::on_put, tag_collection::on_put) or within a CnC step. Leaving quiescence outside a callback/step leads to undefined behaviour (like dead-locks or worse). | |
virtual void | cleanup () |
cleanup, e.g. collect garbage | |
virtual void | unsafe_reset (bool dist) |
virtual void | recv_msg (serializer *) |
Overwrite this if you need to exchange messages on distributed memory. Each graph must implement its own "protocol" Sending message is done through graph::new_serializer followed by graph::send_msg / graph::bcast_msg. | |
serializer * | new_serializer () const |
Get a serializer Caller must pass it to send/bcast or delete it. Receiving messages is done in recv_msg callback. | |
void | send_msg (serializer *ser, int rcver) const |
send a message (in serializer) to given recipient Receiving messages is done in recv_msg callback. | |
void | bcast_msg (serializer *ser) const |
broadcast message (in serializer) to all (other) ranks/processes Receiving messages is done in recv_msg callback. | |
bool | bcast_msg (serializer *ser, const int *rcvers, int nrecvrs) const |
broadcast message (in serializer) to given recipients Receiving messages is done in recv_msg callback. | |
virtual void | flush () |
Flush a potentially hidden graph. Usually is a nop. Our reduction uses this to finalize all pending reductions. (e.g. when the number of reduced items per reduction cannot be determined). |
Base class for defining and using CnC (sub-)graphs.
Derive from this class to define your own graph. It might cooperate with other CnC graphs in the same context. A graph can either be a normal CnC graph or anything else that uses CnC collections as input and output.
It is recommended to always use CnC types (e.g. collections) to implement a graph. It facilitates implementation because the CnC semantics allow automatically managing various tasks, like distribution and termination detection.
The fundamental communication channel between graphs and their input/output collections are the normal get and put calls.
The following paragraphs explain specifics needed to write graphs which do not adhere to core CnC semantics. None of this is needed for graphs that internally are "normal", fully CnC compliant constructs.
Besides get calls, tag- and item-collections also provide a callback mechanism. Such callbacks can be registered for any (input) collection individually (item_collection::on_put and tag_collection::on_put). The registered callback will then be called for every incoming item/tag after it was succesfully put. The callback might (or might not) be called asynchronously.
If you're using non-CnC data structures you will probably need to explicitly take of distributed memory. A clone of the graph gets instantiated on each process. You can send essages between siblings through serializers which get instantiated through graph::new_serializer. After marshalling the desired data (CnC::serializer), the messages can be sent to individual processes (graph::send_msg) or they may be broadcasted (graph::bcast_msg). Messages can only be send from one instance of a graph to its siblings on other processes. Receiving messages is done by overwriting the graph::recv_msg callback.
Callbacks are executed on the first process of the list of consumers/executing processes as provided by the collection's tuner. If no consumer/executing process is provided /e.g. the default) the callback is executed on the process where the item/tag is produced.
graph | ( | CnC::context< Ctxt > & | ctxt, |
const std::string & | name = "" |
||
) |
A graph requires a context and a name for its initialization.
Do all your initialization/start-up stuff in the constructor of your derived class. This implies that your constructor needs to accept and wire all input-and output-collections. The constructor must also call the respective consumes/produces/prescribes calls. If your graph operates/computes outside the steps and callbacks you need to explicitly handle/manage quiescence (see graph::enter_quiescence, graph::leave_quiescence).
void bcast_msg | ( | serializer * | ser | ) | const |
broadcast message (in serializer) to all (other) ranks/processes Receiving messages is done in recv_msg callback.
bool bcast_msg | ( | serializer * | ser, |
const int * | rcvers, | ||
int | nrecvrs | ||
) | const |
broadcast message (in serializer) to given recipients Receiving messages is done in recv_msg callback.
void enter_quiescence | ( | ) | const |
Tell the runtime that the graph reached (temporary) quiescence.
virtual void flush | ( | ) | [inline, virtual] |
Flush a potentially hidden graph. Usually is a nop. Our reduction uses this to finalize all pending reductions. (e.g. when the number of reduced items per reduction cannot be determined).
Definition at line 503 of file cnc.h.
{};
void leave_quiescence | ( | ) | const |
Tell the runtime that the graph leaves quiescence and goes back to activity. Must be called only within a on_put callback (to be registered through item_collection::on_put, tag_collection::on_put) or within a CnC step. Leaving quiescence outside a callback/step leads to undefined behaviour (like dead-locks or worse).
serializer* new_serializer | ( | ) | const |
Get a serializer Caller must pass it to send/bcast or delete it. Receiving messages is done in recv_msg callback.
virtual void recv_msg | ( | serializer * | ) | [virtual] |
Overwrite this if you need to exchange messages on distributed memory. Each graph must implement its own "protocol" Sending message is done through graph::new_serializer followed by graph::send_msg / graph::bcast_msg.
void send_msg | ( | serializer * | ser, |
int | rcver | ||
) | const |
send a message (in serializer) to given recipient Receiving messages is done in recv_msg callback.
virtual void unsafe_reset | ( | bool | dist | ) | [virtual] |
reset instance, e.g. remove entries from collection
dist | if false, the current context is actually not distributed -> don't sync with remote siblings |