overhaul resetting logic in Process.java, it now works with the fpga!
authormegacz <adam@megacz.com>
Thu, 12 Mar 2009 22:23:15 +0000 (15:23 -0700)
committermegacz <adam@megacz.com>
Thu, 12 Mar 2009 22:23:15 +0000 (15:23 -0700)
src/edu/berkeley/fleet/ir/Process.java

index 017b17f..9decf30 100644 (file)
@@ -13,8 +13,8 @@ import static edu.berkeley.fleet.util.BitManipulations.*;
 
 
 /*
- - refactor the cleanup into the subclasses of Port (phase1, phase2, etc)
- */
+  - refactor the cleanup into the subclasses of Port (phase1, phase2, etc)
+*/
 
 // does peer.recvWord() have to honor the currently-set predicate?
 
@@ -27,6 +27,7 @@ import static edu.berkeley.fleet.util.BitManipulations.*;
 
 public class Process {
 
+
     public static int reset_count = 0;
     public static HashSet<Dock> torpedoes = new HashSet<Dock>();
 
@@ -44,15 +45,93 @@ public class Process {
         for(Module mod : modules)
             mod.build(ctx);
     }
-    public void reset(Context ctx, int phase) {
+    public void reset(Context ctx, int phase, Destination ackDestination) {
         reset_count = 0;
         torpedoes.clear();
         for(Module mod : modules)
-            mod.reset(ctx, phase);
+            mod.reset(ctx, phase, ackDestination);
     }
 
     public class Module {
 
+        void doReset(Context ctx, int phase, Dock dock, Port peer, Destination ackDestination, boolean peerUsed) {
+            if (dock.getShip().getType().equals("Debug")) return;
+
+            switch(phase) {
+
+                // Phase 0: torpedo every output dock, put it in
+                // collecting mode.  Cannot combine with phase 1,
+                // because until output docks are in vacuum mode we
+                // cannot be sure that the tokens to the input docks
+                // will eventually succeed.  This may cause the
+                // instructions sent after the tokens to back up into
+                // the switch fabric.
+                case 0: {
+                    if (!dock.isInputDock()) {
+                        torpedoes.add(dock);
+                        Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+                        lf.sendToken(ackDestination);
+                        lf = lf.makeNext(0);
+                        lf.abortLoopIfTorpedoPresent();
+                        lf.collectWord();
+                        reset_count++;
+                    }
+                    break;
+                }
+
+                // Phase 1: torpedo every input dock, put it in loopback mode
+                case 1: {
+                    if (dock.isInputDock()) {
+                        torpedoes.add(dock);
+                        Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+                        lf.sendToken(ackDestination);
+
+                        // FIXME: this won't work right for ports that
+                        // get "shared" by two senders (for example,
+                        // inAddrRead1/2)
+
+                        if (peerUsed && peer!=null) {
+                            lf = lf.makeNext(0);
+                            lf.abortLoopIfTorpedoPresent();
+                            ((OutPort)peer).recvWord(lf);
+                            ((OutPort)peer).sendToken(lf);
+                        }
+                        reset_count++;
+                    }
+                    break;
+                }
+
+                // Phase 2: torpedo every output dock, have it absorb tokens
+                case 2: {
+                    if (!dock.isInputDock()) {
+                        torpedoes.add(dock);
+                        Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+                        if (peer != null)
+                            for(int i=0; i<((InPort)peer).getTokensToAbsorb(); i++)
+                                lf.recvToken();
+                        lf.sendToken(ackDestination);
+                        reset_count++;
+                    }
+                    break;
+                }
+
+                // Phase 3: torpedo every input dock, and we're done
+                case 3: {
+                    if (dock.isInputDock()) {
+                        if (peerUsed && peer!=null) {
+                            torpedoes.add(dock);
+                        }
+                        Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+                        lf.sendToken(ackDestination);
+                        reset_count++;
+                    }
+                    break;
+                }
+
+
+            }
+        }
+
         public Module() {
             Process.this.modules.add(this);
         }
@@ -63,7 +142,9 @@ public class Process {
         public OutPort getOutPort(String name) { return (OutPort)ports.get(name); }
         
         public void build(Context ctx) { for(Port p : ports.values()) p.build(ctx); }
-        public void reset(Context ctx, int phase) { for(Port p : ports.values()) p.reset(ctx, phase); }
+        public void reset(Context ctx, int phase, Destination ackDestination) {
+            for(Port p : ports.values()) p.reset(ctx, phase, ackDestination);
+        }
 
         public abstract class Port {
             public final String name;
@@ -73,7 +154,7 @@ public class Process {
                 Module.this.ports.put(name,this);
             }
             public abstract void build(Context ctx);
-            public abstract void reset(Context ctx, int phase);
+            public abstract void reset(Context ctx, int phase, Destination ackDestination);
         }
 
         public abstract class InPort extends Port {
@@ -138,34 +219,8 @@ public class Process {
                 for(int i=0; i<pattern.length; i++) if (pattern[i]==null) return true;
                 return false;
             }
-            public void reset(Context ctx, int phase) {
-                if (dock.getShip().getType().equals("Debug")) {
-                    return;
-                }
-                switch(phase) {
-                    case 0: {
-                        torpedoes.add(dock);
-                        break;
-                    }
-                    case 2: {
-                        reset_count++;
-                        Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
-                        lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
-                        if (peerUsed()) {
-                            lf = lf.makeNext(0);
-                            lf.abortLoopIfTorpedoPresent();
-                            peer.recvWord(lf);
-                            peer.sendToken(lf);
-                        }
-                        break;
-                    }
-                    case 3: {
-                        if (peerUsed()) {
-                            torpedoes.add(dock);
-                        }
-                        break;
-                    }
-                }
+            public void reset(Context ctx, int phase, Destination ackDestination) {
+                doReset(ctx, phase, dock, peer, ackDestination, peerUsed());
             }
             protected void build(Context ctx, Context.LoopFactory lf) {
                 int inflight = (count != 0 && count < getInflight()) ? count : getInflight();
@@ -215,40 +270,8 @@ public class Process {
                 lf.collectWord();
                 peer.sendWord(lf);
             }
-            public void reset(Context ctx, int phase) {
-
-                // set this to true to get a more "fine grained" report of the shutdown process
-                boolean extratokens = false;
-
-                switch(phase) {
-                    case 0: {
-                        torpedoes.add(dock);
-                        break;
-                    }
-                    case 1: {
-                        Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
-                        if (peer != null) {
-                            for(int i=0; i<peer.getTokensToAbsorb(); i++) {
-                                lf.recvToken();
-                                if (extratokens) lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
-                            }
-                        }
-                        lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
-                        lf = lf.makeNext(0);
-                        lf.abortLoopIfTorpedoPresent();
-                        lf.collectWord();
-                        break;
-                    }
-                    case 2: {
-                        reset_count++;
-                        if (extratokens && peer != null) reset_count += peer.getTokensToAbsorb();
-                        break;
-                    }
-                    case 3: {
-                        torpedoes.add(dock);
-                        break;
-                    }
-                }
+            public void reset(Context ctx, int phase, Destination ackDestination) {
+                doReset(ctx, phase, dock, peer, ackDestination, true);
             }
         }
     }
@@ -261,8 +284,7 @@ public class Process {
     }
 
     /**
-     *  For every datum transmitted to in, pass it along to out and
-     *  deliver the constant at out.  Flow control in<->out is
+     *  Deliver the constant at out forever.  Flow control in<->out is
      *  maintained, but out is not flow-controlled, so be sure
      *  that every datum sent there is consumed synchronously wiht
      *  data items sent to out.
@@ -273,7 +295,7 @@ public class Process {
                 public void sendToken(Context.LoopFactory lf) { }
                 public void recvWord(Context.LoopFactory lf) { }
                 public void build(Context ctx) { }
-                public void reset(Context ctx, int phase) { }
+                public void reset(Context ctx, int phase, Destination ackDestination) { }
                 public void setPeer(InPort peer) {
                     this.peer = peer;
                     DockInPort pip = ((DockInPort)peer);
@@ -293,7 +315,7 @@ public class Process {
                 public void sendToken(Context.LoopFactory lf) { }
                 public void recvWord(Context.LoopFactory lf) { }
                 public void build(Context ctx) { }
-                public void reset(Context ctx, int phase) { }
+                public void reset(Context ctx, int phase, Destination ackDestination) { }
                 public void setPeer(InPort peer) {
                     this.peer = peer;
                     DockInPort pip = ((DockInPort)peer);
@@ -408,17 +430,8 @@ public class Process {
                     public void sendWord(Context.LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(0)); }
                     public void build(Context ctx) { }
                     public int getTokensToAbsorb() { return outRead1.peer.getTokensToAbsorb(); }
-                    public void reset(Context ctx, int phase) {
-                        switch(phase) {
-                            case 0:
-                                torpedoes.add(ship.getDock("inAddrRead"));
-                                break;
-                            case 2:
-                                reset_count++;
-                                Context.LoopFactory lf = ctx.new LoopFactory(ship.getDock("inAddrRead"), 1);
-                                lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
-                                break;
-                        }
+                    public void reset(Context ctx, int phase, Destination ackDestination) {
+                        doReset(ctx, phase, ship.getDock("inAddrRead"), null, ackDestination, false);
                     }
                 };
             this.inAddrRead2  = new InPort("inAddrRead2") {
@@ -426,19 +439,19 @@ public class Process {
                     public void sendWord(Context.LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(1)); }
                     public void build(Context ctx) { }
                     public int getTokensToAbsorb() { return outRead2.peer.getTokensToAbsorb(); }
-                    public void reset(Context ctx, int phase) { }
+                    public void reset(Context ctx, int phase, Destination ackDestination) { }
                 };
             this.outRead1 = new OutPort("outRead1") {
                     public void sendToken(Context.LoopFactory lf) { inAddrRead1.peer.sendToken(lf); }
                     public void recvWord(Context.LoopFactory lf) { lf.recvWord(); }
                     public void build(Context ctx) { }
-                    public void reset(Context ctx, int phase) { }
+                    public void reset(Context ctx, int phase, Destination ackDestination) { }
                 };
             this.outRead2 = new OutPort("outRead2") {
                     public void sendToken(Context.LoopFactory lf) { inAddrRead2.peer.sendToken(lf); }
                     public void recvWord(Context.LoopFactory lf) { lf.recvWord(); }
                     public void build(Context ctx) { }
-                    public void reset(Context ctx, int phase) { }
+                    public void reset(Context ctx, int phase, Destination ackDestination) { }
                 };
             this.outWrite = new DockOutPort("out", ship.getDock("out")) {
                     protected void build(Context ctx, Context.LoopFactory lf) {
@@ -490,6 +503,8 @@ public class Process {
 
     public static void main(String[] s) throws Exception {
         Fleet fleet = new Fpga();
+        //Fleet fleet = new Interpreter(false);
+
         Random random = new Random(System.currentTimeMillis());
         long[] vals = new long[256];
         for(int i=0; i<vals.length; i++) {
@@ -498,6 +513,7 @@ public class Process {
 
         Ship mem1 = fleet.getShip("Memory", 0);
         Ship mem2 = fleet.getShip("Memory", 1);
+        //Ship mem2 = fleet.getShip("DDR2", 0);
 
         FleetProcess fp;
         int stride = 1;
@@ -539,6 +555,7 @@ public class Process {
             System.out.println(bvs[i].toLong());
     }
 
+    // FIXME: check for "lingering" torpedoes?
     public static void verifyClean(FleetProcess fp) {
         Ship debug   = fp.getFleet().getShip("Debug", 0);
         Dock debugIn = debug.getDock("in");
@@ -552,9 +569,7 @@ public class Process {
         lf.deliver();
         lf.literal(5);
         lf.deliver();
-        ArrayList<Instruction> ai = new ArrayList<Instruction>();
-        ctx.emit(ai);
-        for(Instruction ins : ai) fp.sendInstruction(ins);
+        Gadgets.dispatch(fp, ctx);
         fp.flush();
 
         System.out.println("checking debug.in");
@@ -588,6 +603,10 @@ public class Process {
                     lf.sendToken(dock.getDataDestination(), new BitVector(1).set(reverse ? 1 : 0));
                     lf.sendToken(dock.getDataDestination(), new BitVector(1).set(reverse ? 0 : 1));
                     lf = lf.makeNext(2);
+
+                    // if a torpedo was lying in wait, the problem will be manifest as a "freezup"
+                    lf.abortLoopIfTorpedoPresent();
+
                     lf.recvToken();
                     lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
                     lf.setPredicate(Predicate.NotFlagA);
@@ -596,9 +615,7 @@ public class Process {
                     lf.sendToken(debugIn.getDataDestination(), new BitVector(1).set(1));
                     lf.setPredicate(null);
 
-                    ai = new ArrayList<Instruction>();
-                    ctx.emit(ai);
-                    for(Instruction ins : ai) fp.sendInstruction(ins);
+                    Gadgets.dispatch(fp, ctx);
                     fp.flush();
 
                     long kk;
@@ -614,7 +631,6 @@ public class Process {
                 }
     }
 
-    // FIXME: numbers seem to get duplicated when stride=2
     public static long[] mergeSort(FleetProcess fp, Fleet fleet,
                                    long[] vals, int vals_length, int stride_length,
                                    Ship memoryShip1, Ship memoryShip2) throws Exception {
@@ -639,10 +655,8 @@ public class Process {
         // So far: we have four spare Counter ships; one can be used for resetting
         for(int i=0; i<2; i++) {
 
-            RepeatModule r1 = proc.new RepeatModule();
             DownCounterModule c0 = proc.new DownCounterModule();
             DownCounterModule c1 = proc.new DownCounterModule();
-            AluModule alu = proc.new AluModule();
 
             c0.start.connect(proc.new ForeverModule(stride_length).out);
             c0.incr.connect(proc.new ForeverModule(1).out);
@@ -650,12 +664,14 @@ public class Process {
             c1.start.connect(proc.new OnceModule(end_of_data + i*stride_length).out);
             c1.incr.connect(proc.new OnceModule(stride_length*2).out);
 
+            RepeatModule r1 = proc.new RepeatModule();
             r1.val.connect(c1.out);
             r1.count.connect(proc.new ForeverModule(stride_length).out);
 
+            AluModule alu = proc.new AluModule();
             alu.in1.connect(r1.out);
             alu.in2.connect(c0.out);
-            alu.inOp.connect(proc.new ForeverModule(2 /* ADD */).out);
+            alu.inOp.connect(proc.new ForeverModule(2).out);  // ADD
             alu.out.connect(i==0 ? mm.inAddrRead1 : mm.inAddrRead2);
 
             PunctuatorModule punc = proc.new PunctuatorModule(-1);
@@ -664,7 +680,6 @@ public class Process {
             punc.out.connect(i==0 ? sm.in1 : sm.in2);
         }
 
-        
         UnPunctuatorModule unpunc = proc.new UnPunctuatorModule();
         unpunc.val.connect(sm.out);
         unpunc.count.connect(proc.new ForeverModule(2*stride_length).out);
@@ -677,7 +692,7 @@ public class Process {
         mm2.inAddrWrite.connect(cw.out);
         mm2.inDataWrite.connect(unpunc.out);
         mm2.outWrite.connect(dm.in);
+
         //////////////////////////////////////////////////////////////////////////////
 
         Context ctx = new Context(fp.getFleet());
@@ -694,7 +709,8 @@ public class Process {
 
         for(int i=0; i<vals_length; i++) {
             System.out.print("\rreading back... " + i+"/"+vals_length+"  ");
-            System.out.print(" (prev result: " + fp.recvWord() + ")");
+            BitVector rec = fp.recvWord();
+            System.out.print(" (prev result: " + rec + " = " + rec.toLong() + ")");
         }
         System.out.println("\rdone.                                                                    ");
 
@@ -704,6 +720,7 @@ public class Process {
         Dock debugIn = fleet.getShip("Debug",0).getDock("in");
         Dock fred = debugIn;
         fp.sendToken(debugIn.getInstructionDestination());
+        fp.flush();
 
         Context.LoopFactory lf = ctx2.new LoopFactory(debugIn, 0);
         lf.literal(0);
@@ -711,47 +728,59 @@ public class Process {
         lf.recvToken();
         lf.deliver();
 
-        ctx2.emit(ai = new ArrayList<Instruction>());
-        for(Instruction ins : ai)
-            fp.sendInstruction(ins);
+        Gadgets.dispatch(fp, ctx2);
         fp.flush();
 
         int count = 0;
 
+        Ship counter = proc.pool.allocateShip("Counter");
+
         for(int phase=0; phase<=3; phase++) {
             System.out.println("== phase "+phase+" ==================================================================");
             ctx2 = new Context(fp.getFleet());
-            proc.reset(ctx2, phase);
-
-            final Semaphore sem = new Semaphore(0);
-            final FleetProcess fpf = fp;
-            final int phasef = phase;
-            new Thread() {
-                public void run() {
-                    for(int ii=0; ii<reset_count; ii++) {
-                        System.out.print("\r phase "+phasef+" ==> " + (ii+1) + " / " + reset_count);
-                        fpf.recvWord();
-                    }
-                    sem.release();
-                }}.start();
+
+            Destination ackDestination = counter.getDock("in2").getDataDestination();
+            proc.reset(ctx2, phase, ackDestination);
+
+            Context ctx3 = new Context(fp.getFleet());
+            lf = ctx3.new LoopFactory(counter.getDock("inOp"), 1);
+            lf.literal(9);
+            lf.deliver();
+            lf.literal(5);
+            lf.deliver();
+            lf = ctx3.new LoopFactory(counter.getDock("in1"), 1);
+            lf.literal(reset_count-1);
+            lf.deliver();
+            lf.literal(1);
+            lf.deliver();
+            lf = ctx3.new LoopFactory(counter.getDock("in2"), 0);
+            lf.abortLoopIfTorpedoPresent();
+            lf.recvWord();
+            lf.deliver();
+            lf = ctx3.new LoopFactory(counter.getDock("out"), 1);
+            lf.collectWord();
+            lf.sendToken(counter.getDock("in2").getInstructionDestination());  // HACK: we don't check to make sure this hits
+            lf.sendToken(debugIn.getDataDestination());
+            Gadgets.dispatch(fp, ctx3);  // HACK: we don't check to make sure that this is "firmly in place"
 
             for(Dock dock : torpedoes) fp.sendToken(dock.getInstructionDestination());
-            ctx2.emit(ai = new ArrayList<Instruction>());
-            for(Instruction ins : ai) fp.sendInstruction(ins);
+            Gadgets.dispatch(fp, ctx2);
             fp.flush();
-
-            sem.acquire();
             System.out.println("flushed");
 
+            fp.recvWord();
+            System.out.println("phase done");
+
             System.out.println();
         }
 
         fp.sendToken(debugIn.getInstructionDestination());
         fp.flush();
 
-        System.out.println("verifying cleanup:");
+        //System.out.println("verifying cleanup:");
         //verifyClean(fp);
 
+        System.out.println("reading back:");
         long[] ret = null;
         if (vals != null) {
             ret = new long[vals_length];