1 package edu.berkeley.fleet.dataflow;
2 import edu.berkeley.fleet.loops.*;
3 import edu.berkeley.fleet.api.*;
4 import edu.berkeley.fleet.fpga.*;
7 public class MergeSort {
8 public static long[] mergeSort(FleetProcess fp, Fleet fleet,
9 long[] vals, int vals_length, int stride_length,
10 Ship memoryShip1, Ship memoryShip2) throws Exception {
13 BitVector[] mem = new BitVector[vals_length];
14 for(int i=0; i<mem.length; i++) mem[i] = new BitVector(fleet.getWordWidth()).set(vals[i]);
15 MemoryUtils.writeMem(fp, memoryShip1, 0, mem);
18 //////////////////////////////////////////////////////////////////////////////
20 DataFlowGraph proc = new DataFlowGraph(fleet);
21 DebugNode dm = new DebugNode(proc);
23 int end_of_data = vals_length;
24 int num_strides = end_of_data / (stride_length * 2);
26 MemoryNode mm = new MemoryNode(proc, memoryShip1);
27 SortedMergeNode sm = new SortedMergeNode(proc);
29 // So far: we have four spare Counter ships; one can be used for resetting
30 for(int i=0; i<2; i++) {
32 DownCounterNode c0 = new DownCounterNode(proc);
33 DownCounterNode c1 = new DownCounterNode(proc);
35 c0.start.connect(new ForeverNode(proc, stride_length).out);
36 c0.incr.connect(new ForeverNode(proc, 1).out);
38 c1.start.connect(new OnceNode(proc, end_of_data + i*stride_length).out);
39 c1.incr.connect(new OnceNode(proc, stride_length*2).out);
41 RepeatNode r1 = new RepeatNode(proc);
42 r1.val.connect(c1.out);
43 r1.count.connect(new ForeverNode(proc, stride_length).out);
45 AluNode alu = new AluNode(proc);
46 alu.in1.connect(r1.out);
47 alu.in2.connect(c0.out);
48 alu.inOp.connect(new ForeverNode(proc, ((Node.DockInPort)alu.inOp).getConstant("ADD")).out);
49 alu.out.connect(i==0 ? mm.inAddrRead1 : mm.inAddrRead2);
51 PunctuatorNode punc = new PunctuatorNode(proc, -1);
52 punc.count.connect(new ForeverNode(proc, stride_length).out);
53 punc.val.connect(i==0 ? mm.outRead1 : mm.outRead2);
54 punc.out.connect(i==0 ? sm.in1 : sm.in2);
57 UnPunctuatorNode unpunc = new UnPunctuatorNode(proc);
58 unpunc.val.connect(sm.out);
59 unpunc.count.connect(new ForeverNode(proc, 2*stride_length).out);
61 DownCounterNode cw = new DownCounterNode(proc);
62 cw.start.connect(new OnceNode(proc, end_of_data).out);
63 cw.incr.connect(new OnceNode(proc, 1).out);
65 MemoryNode mm2 = new MemoryNode(proc, memoryShip2);
66 mm2.inAddrWrite.connect(cw.out);
67 mm2.inDataWrite.connect(unpunc.out);
68 mm2.outWrite.connect(dm.in);
70 //////////////////////////////////////////////////////////////////////////////
72 Context ctx = new Context(fp.getFleet());
73 ctx.setAutoflush(true);
75 ArrayList<Instruction> ai = new ArrayList<Instruction>();
78 for(Instruction ins : ai) {
79 //System.out.println(ins);
80 fp.sendInstruction(ins);
84 for(int i=0; i<vals_length; i++) {
85 System.out.print("\rreading back... " + i+"/"+vals_length+" ");
86 BitVector rec = fp.recvWord();
87 System.out.print(" (prev result: " + rec + " = " + rec.toLong() + ")");
89 System.out.println("\rdone. ");
91 //if (true) return ret;
93 Context ctx2 = new Context(fp.getFleet());
94 Dock debugIn = fleet.getShip("Debug",0).getDock("in");
96 fp.sendToken(debugIn.getInstructionDestination());
99 LoopFactory lf = new LoopFactory(ctx2, debugIn, 0);
101 lf.abortLoopIfTorpedoPresent();
110 Ship counter = proc.pool.allocateShip("Counter");
112 for(int phase=0; phase<=3; phase++) {
113 System.out.println("== phase "+phase+" ==================================================================");
114 ctx2 = new Context(fp.getFleet());
116 Destination ackDestination = counter.getDock("in2").getDataDestination();
117 int expected_tokens = proc.reset(ctx2, phase, ackDestination);
119 Context ctx3 = new Context(fp.getFleet());
120 lf = new LoopFactory(ctx3, counter.getDock("inOp"), 1);
121 lf.literal("DROP_C1_V2");
125 lf = new LoopFactory(ctx3, counter.getDock("in1"), 1);
126 lf.literal(expected_tokens-1);
130 lf = new LoopFactory(ctx3, counter.getDock("in2"), 0);
131 lf.abortLoopIfTorpedoPresent();
134 lf = new LoopFactory(ctx3, counter.getDock("out"), 1);
136 lf.sendToken(counter.getDock("in2").getInstructionDestination()); // HACK: we don't check to make sure this hits
137 lf.sendToken(debugIn.getDataDestination());
138 ctx3.dispatch(fp); // HACK: we don't check to make sure that this is "firmly in place"
140 for(Dock dock : DataFlowGraph.torpedoes) fp.sendToken(dock.getInstructionDestination());
143 System.out.println("flushed");
146 System.out.println("phase done");
148 System.out.println();
151 fp.sendToken(debugIn.getInstructionDestination());
154 //System.out.println("verifying cleanup:");
155 //CleanupUtils.verifyClean(fp);
157 System.out.println("reading back:");
160 ret = new long[vals_length];
161 BitVector[] mem = new BitVector[vals_length];
162 MemoryUtils.readMem(fp, memoryShip2, 0, mem);
163 for(int i=0; i<ret.length; i++) ret[i] = mem[i].toLong();
169 public static void main(String[] s) throws Exception {
170 Fleet fleet = new Fpga();
171 //Fleet fleet = new Interpreter(false);
173 Random random = new Random(System.currentTimeMillis());
174 long[] vals = new long[256];
175 for(int i=0; i<vals.length; i++) {
176 vals[i] = Math.abs(random.nextInt());
179 Ship mem1 = fleet.getShip("Memory", 0);
180 Ship mem2 = fleet.getShip("Memory", 1);
181 //Ship mem2 = fleet.getShip("DDR2", 0);
187 fp = fleet.run(new Instruction[0]);
188 MemoryUtils.writeMem(fp, mem1, 0, vals);
189 int vals_length = vals.length;
191 // Disable readback/writeback inside the loop
194 while(stride < vals_length) {
196 // reset the FleetProcess
197 //fp.terminate(); fp = null;
199 System.out.println("stride " + stride);
201 // if we reset the FleetProcess, restart it
202 if (fp==null) fp = fleet.run(new Instruction[0]);
205 vals = MergeSort.mergeSort(fp, fleet, vals, vals_length, stride, mem1, mem2);
207 // verify the cleanup
208 //CleanupUtils.verifyClean(fp);
210 Ship mem = mem1; mem1=mem2; mem2=mem;
213 System.out.println();
216 BitVector[] bvs = new BitVector[vals_length];
217 MemoryUtils.readMem(fp, mem1, 0, bvs);
218 System.out.println("results:");
219 for(int i=0; i<vals_length; i++)
220 System.out.println(bvs[i].toLong());