Skip to content

Commit

Permalink
Add Union Operator; Update AST (#69)
Browse files Browse the repository at this point in the history
### Background

#55 discusses a need for a modified AST that distinguishes between
**set-to-stream** and **stream-to-stream** policies, and furthermore
distinguishes between **sets** and **streams**. Within that, we discuss
the need for a `Union` operator, which effectively 'merges several
classes into one'. This is critical in the construction of Set-to-Stream
transformers, to allow such polices to arbitrate independent of queue
distinctions.

### Overview

My work on the type system in #63 allowed us to realize that we could
turn typechecking into essentially an abstraction, and have our `set`
and `stream` types inferred at parsing-time itself – that is to say,
with a tweak to the AST and extending it to the parser as well. That's
the first part part of the PR, which entails adding in the `Union`
constructor to the AST, and partitioning it into the `set` and `stream`
types.

### Caveat And Explanation

@polybeandip and I discussed how far we thought this change should
extend. On one hand, modifying `Ast.t` contractually requires us to
modify `Policy.t`. An alternative, though, is to simply establish a
correspondence `Ast.t -> Policy.t`. For simplicity and to preserve the
work done in `control`, we have kept `Policy.t` in its original form,
and adapted that correspondence.

In turn, this required modifying almost all of our programs such that
they would be syntactically correct w.rt. the new AST structure and
parsing mechanisms. In addition, a few extra 'reversions' to allow for
parsed programs to be correctly evaluated in `control`.

---------

Co-authored-by: grp loaner <grploaner@users-MacBook-Air.local>
  • Loading branch information
KabirSamsi and grp loaner authored Nov 6, 2024
1 parent 9517033 commit b9e6d58
Show file tree
Hide file tree
Showing 32 changed files with 132 additions and 73 deletions.
4 changes: 2 additions & 2 deletions progs/incorrect/duplicate_classes.sched
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
classes A, B;

var = rr[A, B];
final = fifo[var, B]; // B is used twice
var = fifo[union[A, B]];
final = rr[var, fifo[B]]; // B is used twice

return final
2 changes: 1 addition & 1 deletion progs/incorrect/duplicate_samepol.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes A, B;

x = fifo[A, A];
x = fifo[union[A, A]];

return x
5 changes: 5 additions & 0 deletions progs/incorrect/set_hierarchical.sched
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
classes A, B;

combined = rr[union[A, B]];

return combined
6 changes: 6 additions & 0 deletions progs/incorrect/set_multiple.sched
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
classes A, B;

//FIFO cannot be applied to multiple classes; they must be unioned first.
combined = fifo[A, B];

return combined
2 changes: 1 addition & 1 deletion progs/incorrect/unbound_var.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes X, Y, Z;

foo = strict[X, Y, Z];
foo = strict[fifo[X], fifo[Y], fifo[Z]];

return policy // user probably meant to return `foo`
4 changes: 2 additions & 2 deletions progs/incorrect/unbound_var_hier.sched
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
classes BX, BY, RP, RT;

b_policy = fifo[BX, BY];
r_policy = rr[RP, RT];
b_policy = fifo[union[BX, BY]];
r_policy = rr[fifo[RP], fifo[RT]];
policy = rr[b_policy, r_polic]; // user made a typo, meant to reference `r_policy`

return policy
2 changes: 1 addition & 1 deletion progs/incorrect/undeclared_classes.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes X, Y;

pol = strict[X, Z]; // `Z` is undeclared, only `X` and `Y` may be used
pol = strict[fifo[X], fifo[Z]]; // `Z` is undeclared, only `X` and `Y` may be used

return pol
6 changes: 3 additions & 3 deletions progs/incorrect/unused_variable.sched
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
classes A, B, C;

pol_1 = rr[A, B];
pol_2 = rr[B, C];
ans = strict[pol_1, C];
pol_1 = rr[fifo[A], fifo[B]];
pol_2 = rr[fifo[B], fifo[C]];
ans = strict[pol_1, fifo[C]];

return ans
5 changes: 2 additions & 3 deletions progs/non_work_conserving/leaky_2_classes.sched
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
classes A, B;

policy = leakybucket [[A, B], width=5, buffer=10];
policy = leakybucket [[fifo[A], fifo[B]], width=5, buffer=10];
// Interleave packets from flows A and B, allowing at most
// 5 packets to be processed per time cycle,
// and at most 10 packets to be in a buffer at once

return policy

return policy
2 changes: 1 addition & 1 deletion progs/non_work_conserving/rcsp_4_classes.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes A, B, C, D;

policy = rcsp [A, B, C, D];
policy = rcsp [fifo[A], fifo[B], fifo[C], fifo[D]];

return policy
4 changes: 2 additions & 2 deletions progs/non_work_conserving/sg_3_classes.sched
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
classes A, B, C;

sub_policy1 = stopandgo[[A, B], width=10];
sub_policy2 = stopandgo[[C], width=10];
sub_policy1 = stopandgo[[fifo[A], fifo[B]], width=10];
sub_policy2 = stopandgo[[fifo[C]], width=10];
policy = stopandgo [[sub_policy1, sub_policy2], width=5];

//Interleaves two sub-policies, with windows of length 10,
Expand Down
4 changes: 2 additions & 2 deletions progs/non_work_conserving/token_2_rr_children.sched
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
classes A, B, C, D;

sub1 = rr [A, B];
sub2 = rr [C, D];
sub1 = rr [fifo[A], fifo[B]];
sub2 = rr [fifo[C], fifo[D]];

policy = tokenbucket [[sub1, sub2], width=20, time=50];

Expand Down
2 changes: 1 addition & 1 deletion progs/work_conserving/drop_a_class.sched
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
classes A, B;

policy = A;
policy = fifo[A];

return policy

Expand Down
2 changes: 1 addition & 1 deletion progs/work_conserving/fifo_1_class.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes A;

policy = A;
policy = fifo[A];

return policy
2 changes: 1 addition & 1 deletion progs/work_conserving/fifo_1_class_sugar.sched
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
classes A;

policy = A;
policy = fifo[A];
// Sample test comment

return policy
5 changes: 5 additions & 0 deletions progs/work_conserving/fifo_2_class_union.sched
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
classes A, B;

policy = fifo[union[A, B]];

return policy
2 changes: 1 addition & 1 deletion progs/work_conserving/fifo_n_classes.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes A, B, C;

policy = fifo[A, B, C];
policy = fifo[union[A, B, C]];

return policy
2 changes: 1 addition & 1 deletion progs/work_conserving/rr_1_class.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes A;

policy = rr[A];
policy = rr[fifo[A]];

return policy
2 changes: 1 addition & 1 deletion progs/work_conserving/rr_2_classes.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes A, B;

policy = rr[A, B];
policy = rr[fifo[union[A, B]]];

return policy
4 changes: 2 additions & 2 deletions progs/work_conserving/rr_hier.sched
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ classes B, RP, RT;
// RP packets are destined for Pittsburgh
// RT packets are destined for Toronto

r_policy = rr[RP, RT];
policy = rr[B, r_policy];
r_policy = rr[fifo[RP], fifo[RT]];
policy = rr[fifo[B], r_policy];

return policy

Expand Down
4 changes: 2 additions & 2 deletions progs/work_conserving/rr_hier_merge_sugar.sched
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ classes BX, BY, RP, RT;
// RP packets are destined for Pittsburgh
// RT packets are destined for Toronto

b_policy = fifo[BX, BY];
r_policy = rr[RP, RT];
b_policy = fifo[union[BX, BY]];
r_policy = rr[fifo[RP], fifo[RT]];
policy = rr[b_policy, r_policy];

return policy
Expand Down
4 changes: 2 additions & 2 deletions progs/work_conserving/rr_hier_sugar.sched
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ classes B, RP, RT;
// RP packets are destined for Pittsburgh
// RT packets are destined for Toronto

r_policy = rr[RP, RT];
policy = rr[B, r_policy];
r_policy = rr[fifo[RP], fifo[RT]];
policy = rr[fifo[B], r_policy];

return policy

Expand Down
4 changes: 2 additions & 2 deletions progs/work_conserving/rr_n_class_hier.sched
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
classes A, B, CU, CV, CW, CX;

c_policy = rr[rr[CU, CV], rr[CW, CX]];
policy = rr[A, B, c_policy];
c_policy = rr[rr[fifo[CU], fifo[CV]], rr[fifo[CW], fifo[CX]]];
policy = rr[fifo[A], fifo[B], c_policy];

return policy

Expand Down
2 changes: 1 addition & 1 deletion progs/work_conserving/rr_n_classes.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes A, B, C;

policy = rr[A, B, C];
policy = rr[fifo[A], fifo[B], fifo[C]];

return policy
4 changes: 2 additions & 2 deletions progs/work_conserving/rr_strict_n_classes_hier.sched
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
classes A, B, CU, CV, CW, CX;

c_policy = rr[rr[CU, CV], strict[CW, CX]];
policy = strict[A, B, c_policy];
c_policy = rr[rr[fifo[CU], fifo[CV]], strict[fifo[CW], fifo[CX]]];
policy = strict[fifo[A], fifo[B], c_policy];

return policy

Expand Down
2 changes: 1 addition & 1 deletion progs/work_conserving/strict_n_classes.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes A, B, C;

policy = strict[C, B, A];
policy = strict[fifo[C], fifo[B], fifo[A]];

return policy
2 changes: 1 addition & 1 deletion progs/work_conserving/wfq_n_classes.sched
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
classes A, B, C;

policy = wfq[(A, 0.1), (B, 0.2), (C, 0.3)];
policy = wfq[(fifo[A], 1), (fifo[B], 2), (fifo[C], 3)];

return policy
32 changes: 20 additions & 12 deletions rio/frontend/ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,29 @@ type clss = string
type var = string

(* Changes to this type must also be reflected in `Policy.t` in policy.ml *)
type policy =
type set =
| Class of clss
| Fifo of policy list
| RoundRobin of policy list
| Strict of policy list
| WeightedFair of (policy * float) list
| EarliestDeadline of policy list
| ShortestJobNext of policy list
| ShortestRemaining of policy list
| RateControlled of policy list
| LeakyBucket of policy list * int * int
| TokenBucket of policy list * int * int
| StopAndGo of policy list * int
| Union of set list

type stream =
(* Set-to-Stream *)
| Fifo of set
| EarliestDeadline of set
| ShortestJobNext of set
| ShortestRemaining of set
(* Stream-To-Stream *)
| RoundRobin of stream list
| Strict of stream list
| WeightedFair of (stream * int) list
(* Non-Work Conserving *)
| RateControlled of stream list
| LeakyBucket of stream list * int * int
| TokenBucket of stream list * int * int
| StopAndGo of stream list * int
(* Variables *)
| Var of var

type policy = stream
type declare = clss list
type assignment = var * policy
type return = policy
Expand Down
2 changes: 1 addition & 1 deletion rio/frontend/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ rule token = parse
| ")" { RPAREN }
| "return" { RETURN }
| "classes" { CLASSES }
| "union" { UNION }
| "width" { WIDTH }
| "buffer" { BUFFER }
| "time" { TIME }
Expand All @@ -40,7 +41,6 @@ rule token = parse
| id as v { VAR(v) }
| bigid as i { CLSS(i) }
| int { INT (int_of_string (Lexing.lexeme lexbuf)) }
| float { FLOAT (float_of_string (Lexing.lexeme lexbuf)) }
| eof { EOF }


Expand Down
21 changes: 13 additions & 8 deletions rio/frontend/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@

%token <string> VAR
%token <string> CLSS
%token <float> FLOAT
%token <int> INT
%token EQUALS
%token LBRACKET
Expand All @@ -43,6 +42,7 @@
%token RPAREN
%token RETURN
%token CLASSES
%token UNION
%token COMMA
%token SEMICOLON
%token EOF
Expand All @@ -67,15 +67,19 @@

%%

set:
| CLSS { Class($1) }
| UNION LBRACKET; pl = setlist; RBRACKET { Union pl }

/* Policies */
policy:
| FIFO LBRACKET; pl = arglist; RBRACKET { Fifo pl }
| STRICT LBRACKET; pl = arglist; RBRACKET { Strict pl }
| FIFO LBRACKET; pl = set; RBRACKET { Fifo pl }
| EDF LBRACKET; pl = set; RBRACKET { EarliestDeadline pl }
| SJN LBRACKET; pl = set; RBRACKET { ShortestJobNext pl }
| SRTF LBRACKET; pl = set; RBRACKET { ShortestRemaining pl }
| RR LBRACKET; pl = arglist; RBRACKET { RoundRobin pl }
| STRICT LBRACKET; pl = arglist; RBRACKET { Strict pl }
| WFQ LBRACKET; pl = weighted_arglist; RBRACKET { WeightedFair pl }
| EDF LBRACKET; pl = arglist; RBRACKET { EarliestDeadline pl }
| SJN LBRACKET; pl = arglist; RBRACKET { ShortestJobNext pl }
| SRTF LBRACKET; pl = arglist; RBRACKET { ShortestRemaining pl }
| RCSP LBRACKET; pl = arglist; RBRACKET { RateControlled pl }

| LEAKY LBRACKET; LBRACKET;
Expand All @@ -92,14 +96,15 @@ policy:
pl = arglist; RBRACKET; COMMA;
WIDTH EQUALS; t = INT; RBRACKET { StopAndGo (pl, t) }

| CLSS { Class($1) }
| VAR { Var($1) }
setlist:
| pl = separated_list(COMMA, set) { pl }
arglist:
| pl = separated_list(COMMA, policy) { pl }
weighted_arglist:
| pl = separated_list(COMMA, weighted_arg) { pl }
weighted_arg:
| LPAREN; arg = separated_pair(policy, COMMA, FLOAT); RPAREN { arg }
| LPAREN; arg = separated_pair(policy, COMMA, INT); RPAREN { arg }

/* Declarations, assignments and returns */
internalcomp :
Expand Down
Loading

0 comments on commit b9e6d58

Please sign in to comment.