Skip to content

Commit

Permalink
[runtime][variables] Work on the variables infrastructure: space to r…
Browse files Browse the repository at this point in the history
…egister variable, scheduler to register event, and the different accesses to variables (read, write, readwrite.
  • Loading branch information
ptal committed Sep 24, 2018
1 parent 54a7d8d commit 0dd2641
Show file tree
Hide file tree
Showing 22 changed files with 822 additions and 311 deletions.
29 changes: 29 additions & 0 deletions data/test/compile-fail/E0033_10.bonsai.java
@@ -0,0 +1,29 @@
// Copyright 2018 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[error(E0033, 1, 0)]

package test;

public class E0033_10
{
public proc test() =
single_time LMax x = new LMax(0);
par
// The result of x |= 3 depends on `f(readwrite x)`, but it can only be scheduled after `g(write x)`
|| f(readwrite x)
|| when x |= 3 then g(write x) end
end
end
}
Expand Up @@ -16,19 +16,19 @@


import bonsai.runtime.synchronous.interfaces.*; import bonsai.runtime.synchronous.interfaces.*;


public abstract class Instruction implements Program public abstract class ASTNode implements Schedulable
{ {
private Program parent; protected Schedulable parent;


public Instruction() { public ASTNode() {
parent = null; parent = null;
} }


public void setParent(Program parent) { public void setParent(Schedulable parent) {
this.parent = parent; this.parent = parent;
} }


public void wakeUp(Program from) { public void schedule(Schedulable from) {
parent.wakeUp(from); parent.schedule(from);
} }
} }
81 changes: 81 additions & 0 deletions runtime/src/main/java/bonsai/runtime/synchronous/Environment.java
@@ -0,0 +1,81 @@
// Copyright 2016 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bonsai.runtime.synchronous;

import java.util.*;
import java.util.function.*;
import bonsai.runtime.core.*;
import bonsai.runtime.synchronous.variables.*;
import bonsai.runtime.synchronous.interfaces.*;
import bonsai.runtime.synchronous.statements.SpaceStmt;

public class Environment<Queue extends Queueing<Future>>
{
private Space space;
private Queue queue;
private Scheduler scheduler;

public Environment(Queue queue)
{
this.queue = queue;
space = new Space();
scheduler = new Scheduler();
}

/// We create and push the branches created in the current instant onto the queue.
/// It corresponds to `push: Store(L3) -> L4` in the lattice hierarchy.
/// Caution: this function must always be called even with an empty set of branches.
/// Rational: this function marks the end of an instant, and therefore internal data might be reinitialized.
/// @see Future
public void pushBranches(/* ArrayList<SpaceStmt> branches */) {
// ArrayList<Future> futures = Future.createFutures(branches, varsST, varsWL);
// queue.push(futures);
}

public Optional<Future> pop() {
// if(!queue.isEmpty()) {
// Future future = queue.pop();
// future.restoreWL(varsWL);
// return Optional.of(future);
// }
// else {
return Optional.empty();
// }
}

public boolean isEmpty() {
return queue.isEmpty();
}

public int queueSize() {
return queue.size();
}

// private HashMap<String, Variable> vars() {
// return vars;
// }

public Variable lookUpVar(String name) {
return space.lookUpVar(name);
}

public void subscribe(Event event, Schedulable program) {
scheduler.subscribe(event, program);
}

public void schedule(Event event) {
scheduler.schedule(event);
}
}
57 changes: 57 additions & 0 deletions runtime/src/main/java/bonsai/runtime/synchronous/Event.java
@@ -0,0 +1,57 @@
// Copyright 2018 Pierre Talbot

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bonsai.runtime.synchronous;

import bonsai.runtime.synchronous.variables.Variable;

enum EventKind {
CAN_READ,
CAN_READWRITE
}

public class Event {
private EventKind kind;
private Integer uid;

public Event(EventKind kind, Integer uid) {
this.kind = kind;
this.uid = uid;
}

public static Event makeCanRead(Variable var) {
return new Event(EventKind.CAN_READ, var.uid());
}

public static Event makeCanReadWrite(Variable var) {
return new Event(EventKind.CAN_READWRITE, var.uid());
}

public int hashCode() {
return uid + ((kind == EventKind.CAN_READ) ? 0: 1000000);
}

public boolean equals(Object obj) {
if (obj == null) {
return false;
}
else if (getClass() != obj.getClass()) {
return false;
}
else {
Event e = (Event) obj;
return kind == e.kind && uid == e.uid;
}
}
}
@@ -1,4 +1,4 @@
// Copyright 2017 Pierre Talbot (IRCAM) // Copyright 2018 Pierre Talbot (IRCAM)


// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
Expand All @@ -17,29 +17,30 @@
import java.util.*; import java.util.*;
import bonsai.runtime.synchronous.statements.*; import bonsai.runtime.synchronous.statements.*;


public class Result { public class ExprResult {
private CompletionCode code; private Optional<Object> result;
private ArrayList<SpaceStmt> branches;


public Result(CompletionCode code, ArrayList<SpaceStmt> branches) { public ExprResult(Object result) {
this.code = code; this.result = Optional.of(result);
this.branches = branches;
} }


public Result(CompletionCode code, SpaceStmt branch) { public ExprResult() {
this(code); this.result = Optional.empty();
this.branches.add(branch);
} }


public Result(CompletionCode code) { public boolean isSuspended() {
this(code, new ArrayList()); return !result.isPresent();
} }


public CompletionCode code() { public Object unwrap() {
return code; checkResultNotEmpty();
return result.get();
} }


public ArrayList<SpaceStmt> branches() { public void checkResultNotEmpty() {
return branches; if(isSuspended()) {
throw new NoSuchElementException(
"Try to access the result of an expression but it was suspended, and did not produce any result yet.");
}
} }
} }
82 changes: 41 additions & 41 deletions runtime/src/main/java/bonsai/runtime/synchronous/Future.java
Expand Up @@ -45,49 +45,49 @@ public Program branch() {
return branch; return branch;
} }


// Restore the world line variables present in `varsWL` according to their labels in `snapshotWL`. // // Restore the world line variables present in `varsWL` according to their labels in `snapshotWL`.
public void restoreWL(HashMap<String, StreamVar> varsWL) { // public void restoreWL(HashMap<String, StreamVar> varsWL) {
for(Map.Entry<String, StreamVar> entry : varsWL.entrySet()) { // for(Map.Entry<String, StreamVar> entry : varsWL.entrySet()) {
Object label = snapshotWL.get(entry.getKey()); // Object label = snapshotWL.get(entry.getKey());
entry.getValue().stream().restore(label); // entry.getValue().stream().restore(label);
} // }
} // }


public void swapVarsST(SpaceEnvironment env) { // public void swapVarsST(Environment env) {
snapshotST = env.swapVarsST(snapshotST); // snapshotST = env.swapVarsST(snapshotST);
} // }


/// For each branch generated by a `space` statement, we create a future. // /// For each branch generated by a `space` statement, we create a future.
public static ArrayList<Future> createFutures(ArrayList<SpaceStmt> branches, // public static ArrayList<Future> createFutures(ArrayList<SpaceStmt> branches,
HashMap<String, SingleTimeVar> varsST, HashMap<String, StreamVar> varsWL) // HashMap<String, SingleTimeVar> varsST, HashMap<String, StreamVar> varsWL)
{ // {
HashMap<String, Object> snapshotWL = snapshotWL(varsWL); // HashMap<String, Object> snapshotWL = snapshotWL(varsWL);
ArrayList<Future> store = new ArrayList(); // ArrayList<Future> store = new ArrayList();
for(SpaceStmt b : branches) { // for(SpaceStmt b : branches) {
store.add(new Future(b, snapshotST(b, varsST), snapshotWL)); // store.add(new Future(b, snapshotST(b, varsST), snapshotWL));
} // }
return store; // return store;
} // }


// We create a snapshot of the world line variables by calling `label` on each of these variables. // // We create a snapshot of the world line variables by calling `label` on each of these variables.
// The labels are stored in the `HashMap` that is returned. // // The labels are stored in the `HashMap` that is returned.
private static HashMap<String, Object> snapshotWL(HashMap<String, StreamVar> varsWL) { // private static HashMap<String, Object> snapshotWL(HashMap<String, StreamVar> varsWL) {
HashMap<String, Object> snapshotWL = new HashMap(); // HashMap<String, Object> snapshotWL = new HashMap();
for (StreamVar var : varsWL.values()) { // for (StreamVar var : varsWL.values()) {
snapshotWL.put(var.uid(), var.stream().label()); // snapshotWL.put(var.uid(), var.stream().label());
} // }
return snapshotWL; // return snapshotWL;
} // }


// We capture the single time variables of a branch, and store them into a `HashMap` that is returned. // // We capture the single time variables of a branch, and store them into a `HashMap` that is returned.
// Note that we do not store a copy of the variable, but a reference (see @snapshotST). // // Note that we do not store a copy of the variable, but a reference (see @snapshotST).
private static HashMap<String, SingleTimeVar> snapshotST(SpaceStmt branch, // private static HashMap<String, SingleTimeVar> snapshotST(SpaceStmt branch,
HashMap<String, SingleTimeVar> varsST) // HashMap<String, SingleTimeVar> varsST)
{ // {
HashMap<String, SingleTimeVar> snapshotST = new HashMap(); // HashMap<String, SingleTimeVar> snapshotST = new HashMap();
for (String varUID: branch.singleTimeClosure()) { // for (String varUID: branch.singleTimeClosure()) {
snapshotST.put(varUID, varsST.get(varUID)); // snapshotST.put(varUID, varsST.get(varUID));
} // }
return snapshotST; // return snapshotST;
} // }
} }
44 changes: 44 additions & 0 deletions runtime/src/main/java/bonsai/runtime/synchronous/Scheduler.java
@@ -0,0 +1,44 @@
// Copyright 2018 Pierre Talbot

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bonsai.runtime.synchronous;

import java.util.*;
import java.util.function.*;
import bonsai.runtime.core.*;
import bonsai.runtime.synchronous.variables.*;
import bonsai.runtime.synchronous.interfaces.*;

public class Scheduler
{
private HashMap<Event, ArrayList<Schedulable>> waitingQueue;

public Scheduler() {
waitingQueue = new HashMap();
}

public void subscribe(Event event, Schedulable program) {
waitingQueue
.computeIfAbsent(event, k -> new ArrayList<>())
.add(program);
}

public void schedule(Event event) {
ArrayList<Schedulable> programs = waitingQueue.get(event);
for (Schedulable s: programs) {
s.schedule(null);
}
programs.clear();
}
}

0 comments on commit 0dd2641

Please sign in to comment.