go: fleeterpreter.jar
java -Xmx500m -cp lib/edu.berkeley.sbp.jar:fleeterpreter.jar edu.berkeley.fleet.FleetParser
-run: fleeterpreter.jar
- java -Xmx500m -cp lib/edu.berkeley.sbp.jar:fleeterpreter.jar edu.berkeley.fleet.FleetParser < test.fleet
+code: fleeterpreter.jar
+ java -Xmx500m -cp lib/edu.berkeley.sbp.jar:fleeterpreter.jar edu.berkeley.fleet.FleetParser --dump-code < demo.fleet
+
+fabric: fleeterpreter.jar
+ java -Xmx500m -cp lib/edu.berkeley.sbp.jar:fleeterpreter.jar edu.berkeley.fleet.FleetParser --dump-fabric < demo.fleet
applet: fleeterpreter.jar
java -Xmx500m -cp lib/edu.berkeley.sbp.jar:fleeterpreter.jar edu.berkeley.fleet.FleetApplet < test.fleet
#include "demo.ships"
-// NOTE: "accept" is a synonym for "move" it is less confusing in the case
-// of inboxes, but is otherwise identical
-
-//////////////////////////////////////////////////////////////////////////////
-// The following three instructions simply produce one hundred "3"s
-// and put them into fifo "a". Ignore the switch-fabric clogging
-// issue here; this is just setup for the rest of the code.
-
- 3 -> helper.in
- copy helper.out -[10]-> source.in
- discard helper.out -> ()
-
-
-//////////////////////////////////////////////////////////////////////////////
-// set up a counting move of 10 items from source.out to dest.in, but require
-// flow control tokens (10 items is too many to send at once)
-
- triggered move source.out -[10]-> dest.in
-
-
-//////////////////////////////////////////////////////////////////////////////
-// The next instruction tears down the "default" standing move on dest.in
-// and uses the resulting tokens to prime source.out's pump. Once that
-// has been kicked off, any subsequent incoming items will generate tokens
-// which are sent back to the source outbox
-
- nop+ack dest.in -[3]-> source.out
- accept+ack dest.in -[7]-> source.out
- accept dest.in -[3]-> source.out
- nop+ack dest.in -> fetch.release // then release the fetch
- accept dest.in -[*]-> () // and return the fabric to normal
-
-{ tokensource.out -> halt.in } -> fetch.codebag // termination codebag
+//3 -> adder1.a
+3 -> debug.data
#import edu.berkeley.fleet.ships
-#ship helper : FifoShip
-#ship source : FifoShip
-#ship dest : FifoShip
-#ship halt : HaltShip
-#ship fetch : FetchShip
-#ship tokensource : TokenSourceShip
+#ship debug : DebugShip
+#ship adder1 : AdderShip
+#ship adder2 : AdderShip
package edu.berkeley.fleet;
import java.util.*;
+import java.io.*;
/** a codebag */
public class CodeBag {
return parent.getCodeBag(name);
}
+ public void dump(OutputStream os, int data) throws Exception {
+ os.write((byte)data);
+ System.out.print(data+" ");
+ }
+ public void dump(Fleet fleet) throws Exception {
+ OutputStream os = new FileOutputStream("fleet.bin");
+ for(Dispatchable d : dispatchables) {
+ if (d instanceof Instruction) {
+ Instruction inst = (Instruction)d;
+ dump(os, inst.source.resolve(fleet).instr_bits);
+ dump(os, inst.source.resolve(fleet).instr_addr);
+ dump(os, 5);
+ dump(os, 10); // input+output
+ dump(os, inst.destination.resolve(fleet).bits);
+ dump(os, inst.destination.resolve(fleet).addr);
+ dump(os, 0);
+ System.out.println();
+ } else if (d instanceof Literal.LiteralDatum) {
+ Literal.LiteralDatum ld = (Literal.LiteralDatum)d;
+ dump(os, ld.destination.resolve(fleet).instr_bits);
+ dump(os, ld.destination.resolve(fleet).instr_addr);
+ dump(os, 5);
+ dump(os, 2);
+ dump(os, 32);
+ dump(os, ld.data);
+ dump(os, 0);
+ System.out.println();
+ }
+ }
+ os.flush();
+ os.close();
+ }
+
public String toString() {
if (name != null) return name;
StringBuffer ret = new StringBuffer();
import edu.berkeley.sbp.util.*;
import java.util.*;
import java.io.*;
+import edu.berkeley.fleet.ships.*;
public class Fleet {
public int[] mem = new int[0];
public ArrayList<String> imports = new ArrayList<String>();
+ public ArrayList<Ship> shiplist = new ArrayList<Ship>();
public HashMap<String,Ship> ships = new HashMap<String,Ship>();
public void go() {
Log.data(data+"", source, dest);
dest.addDataFromFabric(data);
}
+
+ public void dumpFabric(boolean quiet) {
+ // FIXME: this is really ugly: the order of port declarations in
+ // the XXXShip.java file must match the order in the .balsa file!
+
+ ArrayList instructionports = new ArrayList<Port>();
+ for(Ship ship : shiplist)
+ for(Port port : ship.portlist)
+ instructionports.add(port);
+ FabricTree instructions =
+ new FabricTree((Port[])instructionports.toArray(new Port[0]),
+ "horn",
+ "instruction");
+
+ ArrayList inputports = new ArrayList<Port>();
+ for(Ship ship : shiplist)
+ for(Port port : ship.portlist)
+ if (port instanceof Inbox)
+ inputports.add(port);
+ FabricTree inputs =
+ new FabricTree((Port[])inputports.toArray(new Port[0]),
+ "horn",
+ "dest");
+
+ ArrayList outputports = new ArrayList<Port>();
+ for(Ship ship : shiplist)
+ for(Port port : ship.portlist)
+ if (port instanceof Outbox && !(port.getShip() instanceof DebugShip))
+ outputports.add(port);
+ FabricTree outputs =
+ new FabricTree((Port[])outputports.toArray(new Port[0]),
+ "funnel",
+ "source");
+
+ if (quiet) return;
+ System.out.println("import [balsa.sim.portio]");
+ System.out.println("import [xbit]");
+ System.out.println("import [funnel]");
+ System.out.println("import [horn]");
+ System.out.println("import [par2ser]");
+ System.out.println("import [ser2par]");
+
+ HashSet<Class> added = new HashSet<Class>();
+ for(Ship ship : shiplist)
+ if (!added.contains(ship.getClass())) {
+ added.add(ship.getClass());
+ System.out.println("import ["+ship.getBalsaName()+"]");
+ }
+
+ System.out.println("procedure fabric(input top_in:XBit; output top_out:XBit)");
+ System.out.println("is");
+ System.out.println(" channel source_debug_out : XBit");
+ instructions.dumpChannels(true);
+ outputs.dumpChannels(true);
+ inputs.dumpChannels(true);
+ System.out.println("begin");
+ System.out.println(" loop source -> dest end");
+ System.out.println(" || loop top_in -> instruction end");
+ System.out.println(" || loop source_debug_out -> top_out end");
+ System.out.println("");
+ instructions.dumpChannels(false);
+ System.out.println("");
+ outputs.dumpChannels(false);
+ System.out.println("");
+ inputs.dumpChannels(false);
+ System.out.println("");
+ for(Ship ship : shiplist) {
+ System.out.print(" || ");
+ System.out.print(ship.getBalsaName());
+ System.out.print("(");
+ boolean first = true;
+ for(Port port : ship.portlist) {
+ if (!first) System.out.print(", ");
+ first = false;
+ System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName());
+ System.out.print(",");
+ if (port instanceof Inbox)
+ System.out.print("dest_"+port.getShip().getName()+"_"+port.getName());
+ else
+ System.out.print("source_"+port.getShip().getName()+"_"+port.getName());
+ System.out.print(" ");
+ }
+ System.out.println(")");
+ }
+ System.out.println("end");
+ }
+
+ private static class FabricTree {
+ int master_idx = 1;
+ String prefix;
+ Node root;
+ public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
+ public FabricTree(Port[] ports, String component, String prefix) {
+ this.prefix = prefix;
+ root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
+ }
+ private Object mkNode(String name, String component, Port[] ports, int start, int end, int addr, int bits) {
+ if (end-start == 0) return null;
+ if (end-start == 1) {
+ Port p = ports[start];
+ if (prefix.equals("instruction")) {
+ p.instr_addr = addr;
+ p.instr_bits = bits;
+ } else {
+ p.addr = addr;
+ p.bits = bits;
+ }
+ return p;
+ }
+ int len = end-start;
+ return new Node(name,
+ component,
+ mkNode(name+"_0", component, ports, start, start+len/2, (addr<<1)|0, bits+1),
+ mkNode(name+"_1", component, ports, start+len/2, end, (addr<<1)|1, bits+1),
+ addr,
+ bits);
+ }
+ private String describe(String prefix, Object o) {
+ if (o==null) return null;
+ if (o instanceof Port) {
+ Port p = (Port)o;
+ return prefix+"_"+p.getShip().getName()+"_"+p.getName();
+ }
+ if (o instanceof Node) {
+ return ((Node)o).describe(prefix);
+ }
+ return null;
+ }
+ private class Node {
+ Object left;
+ Object right;
+ String name;
+ String component;
+ int addr;
+ int bits;
+ public Node(String name, String component, Object left, Object right, int addr, int bits) {
+ this.left = left;
+ this.right = right;
+ this.name = name;
+ this.component = component;
+ this.addr = addr;
+ this.bits = bits;
+ }
+ public void dumpChannels(int indentamount, boolean decl) {
+ String indent = "";
+ for(int i=0; i<indentamount; i++) indent += " ";
+ if (decl) {
+ System.out.println(" channel "+indent+describe(prefix)+" : XBit");
+ } else {
+ System.out.println(" || "+indent+
+ component+"("+describe(prefix)+
+ ", "+FabricTree.this.describe(prefix, left)+
+ ", "+FabricTree.this.describe(prefix, right)+")");
+ }
+ dumpChannels(left, indentamount+1, decl);
+ dumpChannels(right, indentamount+1, decl);
+ }
+ public void dumpChannels(Object o, int indentamount, boolean decl) {
+ if (o==null) return;
+ if (o instanceof Node) {
+ ((Node)o).dumpChannels(indentamount, decl);
+ } else {
+ String indent = "";
+ for(int i=0; i<indentamount; i++) indent += " ";
+ if (decl)
+ System.out.println(" channel "+indent+FabricTree.this.describe(prefix,o)+" :XBit");
+ }
+ }
+ public String describe(String prefix) {
+ return prefix+name;
+ }
+ }
+ }
+
}
*/
public class FleetParser {
+ public static boolean dump_fabric = false;
+ public static boolean dump_code = false;
+
public static void main(String[] s) throws Exception {
for(int i=0; i<s.length; i++) {
if (s[i].startsWith("--color=")) {
Log.ansi_color = false;
continue;
}
+ } else if (s[i].startsWith("--dump-fabric")) {
+ dump_fabric = true;
+ continue;
+ } else if (s[i].startsWith("--dump-code")) {
+ dump_code = true;
+ continue;
+
} else if (s[i].startsWith("--inboxes=")) {
String val = s[i].substring(s[i].indexOf('=')+1);
if (val.equals("configured")) {
}
System.out.println("Fleeterpreter usage:");
System.out.println("");
+ System.out.println(" --dump-fabric");
+ System.out.println(" --dump-code");
System.out.println(" --color={on|off}");
System.out.println(" --inboxes={configured|unconfigured}");
System.out.println(" --memory={hide|show}");
}
public void done() {
- if (rootCodeBag != null) {
+ if (dump_fabric) {
+ fleet.dumpFabric(false);
+
+ } else if (dump_code) {
+ fleet.dumpFabric(true);
+ try {
+ rootCodeBag.dump(fleet);
+ } catch (Exception e) { throw new RuntimeException(e); }
+
+ } else if (rootCodeBag != null) {
if (debugMemory) { fleet.dumpMem(); }
System.out.println(rootCodeBag);
rootCodeBag.dispatch(fleet);
public class Literal {
public static class LiteralDatum extends Dispatchable {
- private int data;
- private PortReference destination;
+ int data;
+ PortReference destination;
private boolean isCodeBag;
private int count;
public LiteralDatum(int data, PortReference destination, boolean isCodeBag) { this(data, destination, isCodeBag, 1); }
public String toString() { return ship+"."+name; }
abstract void shutdown();
+
+ public String getName() { return name; }
+
+ int bits;
+ int addr;
+ int instr_bits;
+ int instr_addr;
}
/** a ship, which belongs to a fleet and which may have many ports */
public abstract class Ship {
+ ArrayList<Port> portlist = new ArrayList<Port>();
private HashMap<String,Port> ports = new HashMap<String,Port>();
private String name;
public Ship(Fleet fleet, String name) {
this.name = name;
this.fleet = fleet;
+ fleet.shiplist.add(this);
fleet.ships.put(name, this);
}
return p;
}
+ public String getBalsaName() { return name; }
+ public String getName() { return name; }
public String toString() { return name; }
public Fleet getFleet() { return fleet; }
}
void addPort(String name, Port port) {
+ portlist.add(port);
ports.put(name, port);
}
--- /dev/null
+package edu.berkeley.fleet.ships;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * @author Adam Megacz <megacz@cs.berkeley.edu>
+ */
+public class AdderShip extends Ship {
+
+ private int link;
+
+ DataInbox a = new DataInbox(this, "a");
+ DataInbox b = new DataInbox(this, "b");
+ DataOutbox out = new DataOutbox(this, "out");
+
+ public String getBalsaName() { return "adder"; }
+
+ public AdderShip(Fleet fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (!out.readyForDataFromShip()) return;
+ if (!a.dataReadyForShip()) return;
+ if (!b.dataReadyForShip()) return;
+
+ int inA = a.removeDataForShip();
+ int inB = b.removeDataForShip();
+ int result = inA + inB;
+
+ out.addDataFromShip(result);
+ }
+}
public class DebugShip extends Ship {
- TokenInbox token = new TokenInbox(this, "token");
+ //TokenInbox token = new TokenInbox(this, "token");
DataInbox data = new DataInbox(this, "data");
+ DataOutbox out = new DataOutbox(this, "out");
+
+ public String getBalsaName() { return "debug"; }
public DebugShip(Fleet fleet, String name) {
super(fleet, name);
}
public void service() {
+ /*
if (token.tokenReadyForShip()) {
Log.println(Log.invert(" DEBUG: got a token"+Log.clreol()));
token.removeTokenForShip();
}
+ */
if (data.dataReadyForShip())
Log.println(Log.invert(" DEBUG: got a datum: " + data.removeDataForShip()+Log.clreol()));
}