Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow send actions that are conditionally executed #1273

Closed
jclark opened this issue Nov 7, 2023 · 4 comments · Fixed by #1303
Closed

Allow send actions that are conditionally executed #1273

jclark opened this issue Nov 7, 2023 · 4 comments · Fixed by #1303
Assignees
Milestone

Comments

@jclark
Copy link
Collaborator

jclark commented Nov 7, 2023

The specification requires that whenever a worker is executed and execution does not fail, then the same sequence of send actions is executed. Sends in a conditional context are very limited: they are only allowed when both branches execute and send the same value. The current implementation does not allow sends in a conditional context at all.

We want to fix this for #1271 by changing the specification semantics so that sends can happen within a conditional context in a much more flexible way. For cases supported by the implementation, the semantics should be unchanged.

@jclark jclark changed the title Conditional send action and alternate receive action Allow send actions that are conditionally executed Nov 10, 2023
@lochana-chathura
Copy link
Member

lochana-chathura commented Nov 23, 2023

public function main() {
    worker w1 {
        if true {
            // <channel_w1w3_2.close()> 
            2 -> w3; // channel: w1w3_1 
        } else {
            3 -> w3; // channel: w1w3_2 
        }
        4 -> w3; // channel: w1w3_3
    }


    // Case 1
    worker w3 {
        _ = <- w1; // both w1w3_1 and w1w3_2 match here.
        _ = <- w1; // w1w3_3 matches here
    }

   // Case 2
    worker w3 {
        _ = <- w1; // w1w3_1 matches here
        _ = <- w1; // w1w3_2 matches with NoMessageError
        _ = <- w1; // w1w3_3 matches here
    }

   // Case 3
    worker w3 {
        _ = <- w1; // w1w3_1 matches here
        _ = <- w1|w1; // both w1w3_2 and w1w3_3 match here
    }

   // Case 4
    worker w3 {
        _ = <- w1|w2; // both w1w3_1 and w1w3_2 match here
        _ = <- w1; // w1w3_3 matches here
    }

   // Case 5
    worker w3 {
        _ = <- w1|w2|w3;
    }
}

From the above 5 scenarios, what are the valid cases? All sends have a receiver (i'th send in w1 is associated with the i'th channel in w3) except in the first case.

@jclark
Copy link
Collaborator Author

jclark commented Nov 23, 2023

The new concept is that you match up actions (in the syntax tree). Each alternative in an alternate receive matches one send action. So:

  1. Not ok
  2. OK
  3. OK (an alternate receive uses one slot for each alternate)
  4. OK (you mean w1|w1, right?)
  5. OK (you mean w1|w1|w1, right)

We might want to give errors for receives that are guaranteed to give a NoMessage.

@lochana-chathura
Copy link
Member

Consider the below code:

code (click to expand)
public function main() {
   worker w2 {
       _ = <- w1; // result: [case1, case2] = [1, NoMsgErr]
       _ = <- w1; // result: [case1, case2] = [NoMsgErr, 1]
       _ = <- w1; // result: [case1, case2] = [2, NoMsgErr]
       _ = <- w1; // result: [case1, case2]=  [NoMsgErr, 2]
       _ = <- w1; // result: [case1, case2]=  [3, 3]
   }

   boolean bool = true;

   // case 1
    worker w1 {
        if bool {
            1 -> w2; // w1w2:1
            2 -> w2; // w1w2:3
            3 -> w2; // w1w2:5
        } else {
            4 -> w2; // w1w2:2
            5 -> w2; // w1w2:4
        }
    }

   // case 2
    worker w1 {
        if !bool {
            4 -> w2; // w1w2:1
            5 -> w2; // w1w2:3
        } else {
            1 -> w2; // w1w2:2
            2 -> w2; // w1w2:4
            3 -> w2; // w1w2:5
        }
    }
}

Here I am matching up the send actions to receives based on the breadth first approach for if-else. Case 1 and case 2 if-else are the same. However, the receive result is different in both cases(depends on where we start). We need to have a the same result for both case 1 and 2 right?. In that case, how do we match the send-receive pairs?

@jclark
Copy link
Collaborator Author

jclark commented Nov 24, 2023

The matching is very simplistic. The i-th send action is matched with the i-th receive action (apart from complication with alternates). No, 1 and 2 aren't the same. (We could disallow the case where two parallel branches both have a send to the same place if we wanted to.)

@jclark jclark added this to the 2024R2 milestone Feb 15, 2024
@jclark jclark modified the milestones: 2024R2, 2024R1 Mar 28, 2024
@jclark jclark self-assigned this Mar 30, 2024
jclark added a commit that referenced this issue May 9, 2024
New semantics for worker message passing, which allows send actions to be conditionally executed.
Most of the _Worker message passing_ section is rewritten.
Fixes #1273.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants