Skip to content

Work in Progress

Forward Socket with Control Flow

Currently when gen_processes() is called, select and commute tasks do not behave properly with SFWD tasks bound directly on their data sockets. Indeed they only rebind the first bound sockets while they should use the explore_thread_rec() function to update the data pointers of every linked SFWD. For now, tasks bound to switchers should be SIO.

Task IDs Update

When push and pull tasks are inserted into the pipeline the update_tasks_id() method is called to assert that the task IDs are still coherent, the task with the greatest ID is used to insert the push task in stages for instance. It uses the following algorithm.

# It is called with min_id = 0 in the pipeline code, min_id is shared between 
# recursive calls and NOT copied because it is a reference
void update_tasks_id(Node n, min_id):
    mark(n)
    for every task t in n:
        t.set_id(min_id)
        min_id += 1
    for every child c of n that is not marked:
        update_tasks_id(c, min_id)

This however can lead to issues. For instance when updating the IDs of a sequence with a switch-case.

Warning

The following is a graph of tasks, and NOT a graph of sub-sequences.

    graph LR;
    A[Task_first ID : 0]-->B[Task Commute ID : 1];
    B[Task Commute ID : 1]-.->C[Task_b1 ID : 2];
    B[Task Commute ID : 1]-.->D[Task_b2 ID : 3];
    B[Task Commute ID : 1]-.->E[Task_b3 ID : 4];
    C[Task_b1 ID : 2]-.->F[Task select ID : 5];
    D[Task_b2 ID : 3]-.->F[Task select ID : 5];
    E[Task_b3 ID : 4]-.->F[Task select ID : 5];
    F[Task select ID : 5]-->G[Task_last ID : 6];

Here is the result of the DFS-id update.

    graph LR;
    A[Task_first ID : 0]-->B[Task Commute ID : 1];
    B[Task Commute ID : 1]-.->C[Task_b1 ID : 2];
    B[Task Commute ID : 1]-.->D[Task_b2 ID : 5];
    B[Task Commute ID : 1]-.->E[Task_b3 ID : 6];
    C[Task_b1 ID : 2]-.->F[Task select ID : 3];
    D[Task_b2 ID : 5]-.->F[Task select ID : 3];
    E[Task_b3 ID : 6]-.->F[Task select ID : 3];
    F[Task select ID : 3]-->G[Task_last ID : 4];

This is not a coherent set of IDs, Task_last should not have an ID inferior than Task_b2 and Task_b3, but due to the nature of the DFS algorithm it was assigned a lesser id because it was reached first, thus Task_b2 was updated later and given a greater id.

The current implementation uses the following algorithm.

# We no longer have a minimum, instead we simply increment each ID by 1
void update_tasks_id(Node n):
    mark(n)
    for every task t in n:
        t.set_id(t.id + 1)
    for every child c of n that is not marked:
        update_tasks_id(c)

Which results in

    graph LR;
    A[Task_first ID : 1]-->B[Task Commute ID : 2];
    B[Task Commute ID : 2]-.->C[Task_b1 ID : 3];
    B[Task Commute ID : 2]-.->D[Task_b2 ID : 4];
    B[Task Commute ID : 2]-.->E[Task_b3 ID : 5];
    C[Task_b1 ID : 3]-.->F[Task select ID : 6];
    D[Task_b2 ID : 4]-.->F[Task select ID : 6];
    E[Task_b3 ID : 5]-.->F[Task select ID : 6];
    F[Task select ID : 6]-->G[Task_last ID : 7];

While this is a coherent set of IDs, we lost control over the min_id, which is less-than-ideal and thus every task has a new ID while they didn't need change. A better long term solution would perhaps be to use the min_id system in order to keep the old numerical values of already existing tasks but this time with a breadth-first type algorithm.

End-of-sequence (commute/select)

Currently a sequence may not end with a switcher task (commute or select), this is problematic for pipelines as this means that individual stages cannot have a commute as their last task. This would require modifications to the last_subsequence() method, as an end-of-sequence commute would still have a children.

Example

As an example, let's try to divide the following sequence into 3 stages

graph LR;
A(SS 1)-.->B(SS select);
B(SS select)-->C(SS 2);
C(SS 2)-->F(SS commute);
F(SS commute)-.->E(SS 3);
E(SS 3)-.->B(SS select);
    F(SS commute)-.->G(SS 4);
graph LR;
A(SS1);
graph LR;
B(SS select)-->C(SS 2);
C(SS 2)-->F(SS commute);
F(SS commute)-.->E(SS 3);
E(SS 3)-.->B(SS select);
graph LR;
G(SS 4);

With our current implementation of the DFS, Stage 2 technically has no final sub-sequence as every single node has at least one child, thus making the insertion of push tasks impossible. A solution would be to introduce a fake task after each commute on their last path during pipeline creations.