when using the Timer ship, invoke collectWord() twice just to be safe
[fleet.git] / src / edu / berkeley / fleet / dataflow / SortingDemo.java
1 package edu.berkeley.fleet.dataflow;
2 import java.util.*;
3 import java.io.*;
4 import edu.berkeley.fleet.loops.*;
5 import edu.berkeley.fleet.api.*;
6 import edu.berkeley.fleet.fpga.*;
7 import org.ibex.graphics.*;
8
9 public class SortingDemo {
10
11     public static void main(String[] s) throws Exception {
12         //mergeSort(1024*64, 4, "Dvi",
13         mergeSort(1024*128, 4, "Dvi",
14                   4194304
15                   );
16                   //548*478);
17     }
18
19     /** demo */
20     public static void main0(String[] s) throws Exception {
21         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("stats.txt")));
22         //int inflight = 1;
23         for(int inflight=1; inflight <= 8; inflight++)
24         for(int count = 32; count < 2097152; count *= 2) {
25             System.out.println("==============================================================================");
26             System.out.println("count="+count);
27             System.out.println("inflight="+inflight);
28             //long time = timeit(count, inflight);
29             long time = mergeSort(count, inflight, "DDR2", 0);
30             pw.println(inflight + ", " + count + ", " + time);
31             pw.flush();
32         }
33     }
34
35     public static long timeit(int count, int inflight) throws Exception {
36         Fleet fleet = new Fpga();
37         FleetProcess fp = fleet.run(new Instruction[0]);
38         ShipPool pool = new ShipPool(fleet);
39         //Program program = new Program(pool.allocateShip("Memory"));
40         CodeBag cb = new CodeBag(fleet);
41
42         Ship counter1 = pool.allocateShip("Counter");
43         Ship counter2 = pool.allocateShip("Counter");
44
45         Ship timer    = pool.allocateShip("Timer");
46         Ship debug    = pool.allocateShip("Debug");
47
48         LoopFactory lf;
49
50         lf = cb.loopFactory(debug.getDock("in"), 2);
51         lf.recvWord();
52         lf.deliver();
53
54
55         // First counter //////////////////////////////////////////////////////////////////////////////
56
57         lf = cb.loopFactory(counter1.getDock("in1"), 1);
58         lf.recvToken();
59         lf.literal(count);
60         lf.deliver();
61
62         lf = cb.loopFactory(counter1.getDock("in2"), 1);
63         lf.literal(1);
64         lf.deliver();
65
66         lf = cb.loopFactory(counter1.getDock("inOp"), 1);
67         lf.literal("COUNT");
68         lf.deliver();
69
70         lf = cb.loopFactory(counter1.getDock("out"), 0);
71         lf.recvToken();
72         lf.collectWord();
73         lf.sendWord(counter2.getDock("in2"));
74
75
76         // Second counter //////////////////////////////////////////////////////////////////////////////
77
78         lf = cb.loopFactory(counter2.getDock("in1"), 1);
79         lf.literal(count);
80         lf.deliver();
81         lf.literal(1);
82         lf.deliver();
83         lf.literal(1);
84         lf.deliver();
85
86         lf = cb.loopFactory(counter2.getDock("in2"), 1);
87         for(int i=0; i<inflight; i++)
88             lf.sendToken(counter1.getDock("out"));
89         lf = lf.makeNext(0);
90         lf.recvWord();
91         lf.sendToken(counter1.getDock("out"));
92         lf.deliver();
93
94         lf = cb.loopFactory(counter2.getDock("inOp"), 1);
95         lf.literal("DROP_C1_V2");
96         lf.deliver();
97         lf.literal("PASS_C1_V1");
98         lf.deliver();
99
100         lf = cb.loopFactory(counter2.getDock("out"), 1);
101         lf.collectWord();
102         lf.sendToken(timer.getDock("out"));
103
104
105         // Timer //////////////////////////////////////////////////////////////////////////////
106
107         lf = cb.loopFactory(timer.getDock("out"), 1);
108         // collect twice just to be safe
109         lf.collectWord();
110         lf.collectWord();
111         lf.sendToken(counter1.getDock("in1"));
112         lf.sendWord(debug.getDock("in"));
113         lf.recvToken();
114         // collect twice just to be safe
115         lf.collectWord();
116         lf.collectWord();
117         lf.sendWord(debug.getDock("in"));
118
119         FpgaDock out = (FpgaDock)counter1.getDock("out");
120         FpgaDock in  = (FpgaDock)counter2.getDock("in2");
121         System.out.println("distance is " + out.getPathLength((FpgaDestination)in.getDataDestination()));
122         System.out.println("reverse distance is " + in.getPathLength((FpgaDestination)out.getDataDestination()));
123
124         for(Instruction i : cb.emit()) System.out.println(i);
125         cb.dispatch(fp, true);
126         long time1 = fp.recvWord().toLong();
127         System.out.println("got " + time1);
128         long time2 = fp.recvWord().toLong();
129         System.out.println("got " + time2);
130         System.out.println("diff=" + (time2-time1));
131
132         fp.terminate();
133
134         return (time2-time1);
135     }
136
137     public static long mergeSort(int vals_length, int inflight, String shipType, int clearAmount) throws Exception {
138         Node.CAPACITY = inflight;
139
140         Fleet fleet = new Fpga();
141         FleetProcess fp = fleet.run(new Instruction[0]);
142         ShipPool pool = new ShipPool(fleet);
143         Ship mem1 = pool.allocateShip(shipType);
144
145
146         if (clearAmount > 0)
147             randomizeMemory(fp, pool, mem1, 0, clearAmount, false);
148
149         //randomizeMemory(fp, pool, mem1, 0, vals_length, true);
150
151         BitVector[] bvs = new BitVector[vals_length];
152
153         long index = 0;
154         Picture p = new Picture(new FileInputStream("campus.png"));
155         for(int y=0; y<(478/2); y++)
156             for(int x=0; x<544; x++) {
157                 if (index >= vals_length) break;
158                 int pixel = (x>=p.width) ? 0 : p.data[p.width*y+x];
159                 long r = (pixel>>0)  & 0xff;
160                 long g = (pixel>>8)  & 0xff;
161                 long b = (pixel>>16) & 0xff;
162                 r >>= 2;
163                 g >>= 2;
164                 b >>= 2;
165                 //r = ~(-1L<<6);
166                 //g = ~(-1L<<6);
167                 //b = ~(-1L<<6);
168                 bvs[(int)index] = new BitVector(fleet.getWordWidth()).set( r | (g<<6) | (b<<12) | (index<<18) );
169                 index++;
170             }
171
172         for(; index<vals_length; index++) {
173             long tag = index<<18;
174             bvs[(int)index] = new BitVector(fleet.getWordWidth()).set( tag );
175         }
176
177         System.out.println("final index " + index);
178
179         Random random = new Random(System.currentTimeMillis());
180         for(int i=0; i<bvs.length*10; i++) {
181             int from = Math.abs(random.nextInt()) % bvs.length;
182             int to   = Math.abs(random.nextInt()) % bvs.length;
183             BitVector bv = bvs[from];
184             bvs[from] = bvs[to];
185             bvs[to] = bv;
186         }
187
188         int offset = 40;
189         MemoryUtils.writeMem(fp, pool, mem1, 40, bvs);
190
191         Ship mem = pool.allocateShip("Memory");
192         Program program = new Program(mem);
193         CodeBag cb_ = new MergeSort(fleet, program, pool, 2, mem1, mem1).makeInstance(offset, vals_length);
194         cb_.seal();
195         Ship button = pool.allocateShip("Button");
196         CodeBag cb = new CodeBag(fleet, program);
197         LoopFactory lf = cb.loopFactory(button.getDock("out"), 1);
198         lf.collectWord();
199         lf.literal(cb_.getDescriptor());
200         lf.sendWord(program.getCBDDestination());
201         cb.seal();
202
203         ShipPool pool2 = new ShipPool(fp.getFleet());
204         pool2.allocateShip(program.memoryShip);
205         // FIXME
206         long ret = program.run(fp, cb, pool2);
207         pool2.releaseShip(program.memoryShip);
208
209         //long ret = 0;
210         // verify the cleanup?
211         //CleanupUtils.verifyClean(fp);
212         //MemoryUtils.readMem(fp, new ShipPool(fp.getFleet()), mem1, 0, bvs);
213
214         BitVector[] bvx = new BitVector[1024];
215         pool.allocateShip(mem);
216         MemoryUtils.readMem(fp, new ShipPool(fp.getFleet()), mem1, 0, bvx);
217         for(int i=0; i<bvx.length; i++)
218             System.out.println(bvx[i]);
219         /*
220         System.out.println("results:");
221         for(int i=0; i<vals_length-1; i++)
222             if ( (bvs[i].toLong() & ~(-1L<<18)) != ~(-1L<<18))
223                 System.out.println(bvs[i]);
224         */
225         /*
226         for(int i=0; i<vals_length-1; i++) {
227             if (bvs[i].toLong() > bvs[i+1].toLong())
228                 System.out.println("sort failure at "+i+":\n  "+bvs[i]+"\n  "+bvs[i+1]);
229         }
230         */
231         fp.terminate();
232         return ret;
233     }
234
235     //static int offset = 32;
236     //static int offset = 544*2;
237     //static int offset = 544;
238
239     public static void randomizeMemory(FleetProcess fp, ShipPool pool_, Ship memory, long start, long length, boolean randomize) {
240         ShipPool pool = new ShipPool(pool_);
241         Ship mem = pool.allocateShip("Memory");
242         Program prog = new Program(mem);
243
244         DataFlowGraph dfg = new DataFlowGraph(fp.getFleet(), pool);
245         DownCounterNode dcn = new DownCounterNode(dfg);
246         dcn.start.connectOnce(length);
247         dcn.incr.connectOnce(1);
248
249         AluNode alu = new AluNode(dfg, "ADD");
250         alu.in1.connectForever(start);
251         alu.in2.connect(dcn.out);
252
253         MemoryNode mn = new MemoryNode(dfg, memory);
254         mn.inAddrWrite.connect(alu.out);
255
256         AluNode aluAnd = new AluNode(dfg, "AND");
257         if (randomize) {
258             aluAnd.in1.connect(new RandomNode(dfg).out);
259         } else {
260             //aluAnd.in1.connectForever( ~(-1L<<36) );
261             aluAnd.in1.connectForever( 0 );
262         }
263         aluAnd.in2.connectForever( ~(-1<<18) );
264         mn.inDataWrite.connect(aluAnd.out);
265         
266         UnPunctuatorNode discard = new UnPunctuatorNode(dfg, true);
267         discard.count.connectOnce(length);
268         discard.val.connect(mn.outWrite);
269         DoneNode done = new DoneNode(dfg, prog);
270         discard.out.connect(done.in);
271
272         CodeBag cb = new CodeBag(fp.getFleet(), prog);
273         dfg.build(cb);
274         cb.seal();
275
276         CodeBag cb2 = new CodeBag(fp.getFleet(), prog);
277         Ship button = fp.getFleet().getShip("Button",0);
278
279         LoopFactory lf = cb2.loopFactory(button.getDock("out"), 1);
280         //lf.collectWord();
281         lf.literal(prog.getEndProgramCodeBag().getDescriptor());
282         lf.sendWord(done.getDestinationToSendNextCodeBagDescriptorTo());
283         lf.literal(cb.getDescriptor());
284         lf.sendWord(prog.getCBDDestination());
285         cb2.seal();
286
287         System.out.println("dispatching randomization codebag...");
288         prog.run(fp, cb2, pool);
289         System.out.println("  randomization done.");
290         pool.releaseAll();
291     }
292
293 }