Skeleton class for concurrent branching. More...
#include <gmfork.h>

Public Member Functions | |
| gmFork (const string &name_="", gmManager *manager=&gmExperiment) | |
| Constructor of the fork. | |
| size_t | branchcount () const |
| Returns current number of branches in the fork (construction and worker mode). | |
| void | set_name (const string &name_="") |
| Sets/changes the name of the fork. | |
| template<class link_type > | |
| int | begin (const string &name_, gmSelector input=gmNODE_PREV, const link_type &t=gmHardLink(), int srcport=-1) |
| Adds the top join node of the fork (begin node). | |
| int | begin (const string &name_="", gmSelector input=gmNODE_PREV) |
| Hard link version of gmFork::begin<>(). | |
| void | begin_here () |
| Begins the fork with the current node whatever it is. | |
| int | split (const string &name_="") |
| Starts a new branch by creating a split node and linking it to the fork begin node with split_tt data link (or hard link when split_tt is void). | |
| void | split_here () |
| Starts a branch without creating a new node. | |
| template<class link_type > | |
| int | merge (const string &name_, gmSelector input=gmNODE_PREV, const link_type &t=gmHardLink(), int srcport=-1, bool same_ports=false) |
| Finishes current branch by creating a merge node. | |
| int | merge (const string &name="", gmSelector input=gmNODE_AUTO, bool same_ports=false) |
| Automatic/Hard link version of gmFork::merge<>(). | |
| void | merge_here (bool same_ports=false) |
| Finishes current branch without creating a new node. | |
| int | end (const string &name_="", bool same_ports=false) |
| Adds a final node where all branches join. | |
| void | end_here (bool same_ports=false) |
| Uses current node as an end node of the fork. | |
| split_t & | vbegin_out (int branchid) const |
| Returns a reference to split_tt to put the value of split data for branch branchid. | |
| const split_t & | vsplit_in () const |
| Returns a reference to split_tt to get the value of split data for current branch. | |
| branch_t & | vsplit_out () |
| Returns a reference to branch_tt to put the value of split data for current branch. | |
| const branch_t & | vmerge_in () const |
| Returns a reference to branch_tt to get the value of branch data for current branch. | |
| merge_t & | vmerge_out (int portid=0) |
| Returns a reference to merge_tt to put the value of merge data for current branch. | |
| const merge_t & | vend_in (int branchid) const |
| Returns a reference to merge_tt to get the value of merge data for branch branchid. | |
Skeleton class for concurrent branching.
Fork skeleton is used to split execution into several branches that may be run concurrently. The branches may have the same or different code. The skeleton has 4 building elements:
begin_node -- the node where the branches deviate from each other, only one begin node is possible for each fork;
split_node -- beginning of the branch, each branch (tooth) of the fork has one split node;
merge_node -- end of the branch, each branch (tooth) of the fork has one merge node. It may coincide with the split node;
end_node -- a node where the branches join, there may be 0, 1 or several end nodes of the fork.
Template parameters are data types corresponding to the links between begin node and split nodes (split_tt) and merge nodes and end node (merge_tt). Also, if there are no added nodes between the split and merge nodes of the branch, and the split and merge nodes are different, a datalink of type branch_tt is automatically created. If any of the data types is void, then corresponding hard link is used. Node construction for the fork is performed by calling markup functions, for example gmFork::begin() creates the begin node. All markup functions appear in two versions: the one creating a new node, and the other using the current node as building element of the fork. The second version markup functions end with _here postfix, for example fork.begin_here() will assign the current node as the begin node of fork. Usually the fork is constructed in the following sequence:
gmFork::begin() -- adds begin node;
gmFork::split() -- adds a starting node of the new branch, links it with the begin node using split_tt datalink;
gmManager::mark_node() -- adds a node to this branch;
gmManager::mark_node() -- adds a node to this branch;
...
gmFork::merge() -- finishes this branch by adding a node which will be linked by merge_tt datalink with end node(s);
gmFork::split() -- adds another branch;
...
gmFork::end() -- adds an end node, links it with all merge nodes by merge_t datalink. Deviations from this sequence are also possible (fork with no end nodes, fork with multiple end nodes, parallel forks sharing some building elements, nested forks, etc.) The link data for all created nodes may be acessed in the usual way by gridmd::node_input<>() and gridmd::node_output<>() functions. There is also a more type safe way of acessing this data by using the branch data access gmFork functions (gmFork::vsplit_out(), gmFork::vsplit_in(), ... etc.)
| gmFork< split_tt, branch_tt, merge_tt >::gmFork | ( | const string & | name_ = "", |
|
| gmManager * | manager = &gmExperiment | |||
| ) | [inline] |
Constructor of the fork.
| name_ | the name of the fork. By default constructs the name 'forkN', where N is the count of currently existing forks. The fork name is also used for naming the parant elements (like fork0.begin for begin node, etc.) if their names are not explicitly specified; | |
| manager | is a pointer to managing object, defaults to the common gmExperiment. |
| int gmFork< split_tt, branch_tt, merge_tt >::begin | ( | const string & | name_, | |
| gmSelector | input = gmNODE_PREV, |
|||
| const link_type & | t = gmHardLink(), |
|||
| int | srcport = -1 | |||
| ) | [inline] |
Adds the top join node of the fork (begin node).
The parameters and the return value are the same as for gmManager::mark_node(), except for the name rule: if the name_ is empty, the node is named <fork_name>.begin. As usual, the return value (nonzero for processing request in the worker mode, 0 otherwise) may be analyzed to trigger begin node exection. If template parameter split_tt is not void, the created node will have an output dataport for each branch (indexed form 0, the number of branches is returned by gmFork::branchcount()). The dataports are accesible in the usual way by gmManager::node_output<>(portid) function. Alternatively, the link data may be output by using gmFork::vbegin_out() function, allowing more accurate worker mode type control. All existing fork branches and their data is deleted by calling this function. The fork may be reinitialized for reuse by this function.
| int gmFork< split_tt, branch_tt, merge_tt >::begin | ( | const string & | name_ = "", |
|
| gmSelector | input = gmNODE_PREV | |||
| ) | [inline] |
Hard link version of gmFork::begin<>().
Constructs incoming hard links from the nodes specified by input.
| void gmFork< split_tt, branch_tt, merge_tt >::begin_here | ( | ) | [inline] |
Begins the fork with the current node whatever it is.
The output dataports (see gmFork::begin<>()) are added to the current node.
| int gmFork< split_tt, branch_tt, merge_tt >::end | ( | const string & | name_ = "", |
|
| bool | same_ports = false | |||
| ) | [inline] |
Adds a final node where all branches join.
If the name_ is empty, the node is named '<fork_name>.end'. The return value (nonzero for processing request in the worker mode, 0 otherwise) may be analyzed to trigger merge node exection. All existing branches (merge nodes or split nodes, if merge nodes are undefined) are linked to the end node with merge_tt data link (or hard link when split_tt is void). If template parameter merge_tt is not void, the merge node of each branch will have output dataports. The number of these dataports is controlled by same_ports parameter. If it is true, then the end node will be linked from the same (0th) dataport of the merge node. If it is false, then the end node will be linked from a separate dataport of each of the merge nodes. In this case each merge node will have an output dataport to this end node (its id corresponding to the order of end nodes creation). The dataports are accesible in the usual way by gmManager::node_output<>(portid) function. The end node has input data ports for each of the branches with ids matching the branch number starting form 0. If this function is never called for the fork, the fork remains open from the bottom and its ends may be explicitly linked with other nodes.
| void gmFork< split_tt, branch_tt, merge_tt >::end_here | ( | bool | same_ports = false |
) | [inline] |
Uses current node as an end node of the fork.
The parameter same_ports controls the number of dataports created at merge nodes, see gmFork::end().
| int gmFork< split_tt, branch_tt, merge_tt >::merge | ( | const string & | name_, | |
| gmSelector | input = gmNODE_PREV, |
|||
| const link_type & | t = gmHardLink(), |
|||
| int | srcport = -1, |
|||
| bool | same_ports = false | |||
| ) | [inline] |
Finishes current branch by creating a merge node.
First 4 parameters and the return value are the same as for gmManager::mark_node(), except for the name rule: if the name_ is empty, the node is named '<fork_name>.merge(N)',where N is the branch number. As usual, the return value (nonzero for processing request in the worker mode, 0 otherwise) may be analyzed to trigger merge node exection. If input is gmNODE_AUTO and there is a split node for the current branch, then a datalink of type branch_tt is created between the split node and the merge node of the branch, ignoring the supplied link type. If end nodes already exist for this fork, the merge node is immediately linked to all of them with merge_tt data link (or hard link when split_tt is void). If template parameter merge_tt is not void, the created node will have output dataports. The number of these dataports is controlled by same_ports parameter. If it is true, then all end nodes will be linked from the same (0th) dataport of the merge node. If it is false, then each of the end nodes will be linked from a separate dataport of the merge node. In this case the merge node will have an output dataport for each end node (indexed form 0). The dataports are accesible in the usual way by gmManager::node_output<>(portid) function. If this function is not called for the branch, then the merge node coincides with the split node.
| int gmFork< split_tt, branch_tt, merge_tt >::merge | ( | const string & | name = "", |
|
| gmSelector | input = gmNODE_AUTO, |
|||
| bool | same_ports = false | |||
| ) | [inline] |
Automatic/Hard link version of gmFork::merge<>().
If input is gmNODE_AUTO, then a datalink of type branch_tt is created between the split node and the merge node of the branch. Otherwise hard link(s) to the specified input node(s) are created.
| void gmFork< split_tt, branch_tt, merge_tt >::merge_here | ( | bool | same_ports = false |
) | [inline] |
Finishes current branch without creating a new node.
Uses the current node as a merge node, creating output links. No input links are created. Same data ports as for gmFork::merge() are available.
| void gmFork< split_tt, branch_tt, merge_tt >::set_name | ( | const string & | name_ = "" |
) | [inline] |
Sets/changes the name of the fork.
By default or when the name is empty constructs the name 'forkN', where N is the count of currently existing forks.
| int gmFork< split_tt, branch_tt, merge_tt >::split | ( | const string & | name_ = "" |
) | [inline] |
Starts a new branch by creating a split node and linking it to the fork begin node with split_tt data link (or hard link when split_tt is void).
If split_tt is not void, one input data port of split_tt data is accessible by gmManager::node_input<>(0) function and contains the split data placed in the Nth output of the begin node, where N is the curren branch Id starting from zero. Alternatively, the link data may be obtained by using gmFork::vsplit_in() function, allowing more accurate worker mode type control. If the name is empty the node is named '<fork_name>.split(N)', where N is the branch number. The return value (nonzero for processing request in the worker mode, 0 otherwise) may be analyzed to trigger begin node exection. If split() is called before gmFork::begin(), gmFork::begin_here() is called for the current node.
| void gmFork< split_tt, branch_tt, merge_tt >::split_here | ( | ) | [inline] |
Starts a branch without creating a new node.
Uses the current node as a split node and links it to the fork begin node with split_tt data link (or hard link when split_tt is void). Same data port as for gmFork::split() is available.
| split_t& gmFork< split_tt, branch_tt, merge_tt >::vbegin_out | ( | int | branchid | ) | const [inline] |
Returns a reference to split_tt to put the value of split data for branch branchid.
May be called at begin node only in worker mode. If called at wrong node or split_tt is void, a warning is given at worker mode runtime and a temporary reference for which no data transfer is possible is returned.
| const merge_t& gmFork< split_tt, branch_tt, merge_tt >::vend_in | ( | int | branchid | ) | const [inline] |
Returns a reference to merge_tt to get the value of merge data for branch branchid.
May be called at end nodes only in worker mode. If called at wrong node or merge_tt is void, a warning is given at worker mode runtime and a temporary reference with garbage data is returned.
| const branch_t& gmFork< split_tt, branch_tt, merge_tt >::vmerge_in | ( | ) | const [inline] |
Returns a reference to branch_tt to get the value of branch data for current branch.
May be called at merge node (or at split node when there is no merge node) only in worker mode. If called at wrong node or branch_tt is void, a warning is given at worker mode runtime and a temporary reference with garbage data is returned.
| merge_t& gmFork< split_tt, branch_tt, merge_tt >::vmerge_out | ( | int | portid = 0 |
) | [inline] |
Returns a reference to merge_tt to put the value of merge data for current branch.
May be called at merge node (or at split node when there is no merge node) only in worker mode. If called at wrong node or merge_tt is void, a warning is given at worker mode runtime and a temporary reference for which no data transfer is possible is returned.
| portid | is a port number to put the data, usually corresponding to the end node this data is supplied to. See description of same_ports parameter of the gmFork::merge function for detais. |
| const split_t& gmFork< split_tt, branch_tt, merge_tt >::vsplit_in | ( | ) | const [inline] |
Returns a reference to split_tt to get the value of split data for current branch.
May be called at split node only in worker mode. If called at wrong node or split_tt is void, a warning is given at worker mode runtime and a temporary reference with garbage data is returned.
| branch_t& gmFork< split_tt, branch_tt, merge_tt >::vsplit_out | ( | ) | [inline] |
Returns a reference to branch_tt to put the value of split data for current branch.
May be called at split node only in worker mode. If called at wrong node or branch_tt is void, a warning is given at worker mode runtime and a temporary reference for which no data transfer is possible is returned.
1.7.1