// Dump a level worth of doubles from various grids. /****************************************************************************** CHANGE LOG. 4 Dec 98: Creation. ******************************************************************************/ import java.io.FileOutputStream; import java.io.PrintStream; import java.io.IOException; class Dump { static PrintStream dumpout = null; static private Counter count = broadcast new Counter() from 0; static void init() { if (dumpout == null) { try { dumpout = new PrintStream(new FileOutputStream("dump")); } catch (Throwable x) { System.err.println("Error opening file for dumping"); } } } static void cleanup() { } static void dump() { dump(""); } static void dump(String s) { if (dumpout == null) return; for (int l = 0; l < AMR.nLevels; l++) { BoxedList_double_3d_ r = new BoxedList_double_3d_(), p = new BoxedList_double_3d_(); String q = "level " + l; foreach (proc in AMR.processes.domain()) { Level level = AMR.processes[proc].levels[l]; foreach (i in level.patches.domain()) { r.push(level.patches[i].residual); p.push(level.patches[i].phi.restrict(level.patches[i].domain)); System.out.println("Dumping residual " + s + q + " " + Util.stringify(r.first().domain())); System.out.println("Dumping phi " + s + q + " " + Util.stringify(p.first().domain())); } } dumpDoubleGridOverGeneralDomain(r.toList(), "residual " + s + q); dumpDoubleGridOverGeneralDomain(p.toList(), "phi " + s + q); } } static void dump(double [3d] x, String s, PrintStream f) { dumpDoubleGridOverGeneralDomain(new List_double_3d_(x), s, f); } static void dump(double [3d] x, String s) { PrintStream f; int n = count.postincr(); System.out.println("Dumping to dump" + n); try { f = new PrintStream(new FileOutputStream("dump" + n)); } catch (Throwable t) { System.err.println("Error opening file for dumping"); System.exit(-3); } dump(x, s, f); f.close(); } static void dumpDoubleGridOverGeneralDomain(List_double_3d_ l, String s) { dumpDoubleGridOverGeneralDomain(l, s, dumpout); } static void dumpDoubleGridOverGeneralDomain(List_double_3d_ l, String s, PrintStream f) { int i = 0, size; List_double_3d_ q; Point<3> [1d] local a; double [1d] local b; f.println(s); if (l == null) return; for (q = l; q != null; q = q.rest()) size += q.first().domain().size(); System.out.println(s + " has total size " + size); a = new Point<3> [0 : size - 1]; b = new double [0 : size - 1]; for (q = l; q != null; q = q.rest()) { double [3d] z = q.first(); foreach (p in z.domain()) { a[i] = p; b[i] = z[p]; i++; } } sortPointsAndDoubles(a, b); for (i = 0; i < size; i++) f.println(Util.stringifyP3(a[i]) + ": " + b[i]); } /* Sorts a and b based on the ordering of a. */ /* Assumes a and b are stride 1 and have the same domain. */ static void sortPointsAndDoubles(Point<3> [1d] local a, double [1d] local b) { Point<3> temp; int l0 = a.domain().min()[1], r0 = a.domain().max()[1]; BoxedList_int loToDo = new BoxedList_int(l0); BoxedList_int hiToDo = new BoxedList_int(r0); while (!loToDo.isEmpty()) { int l = loToDo.pop(); int r = hiToDo.pop(); if ((AMR.debug & 4) != 0) System.out.println("Popped " + l + " to " + r + " off todo list"); while (true) { if (r <= l) { /* zero or one elements: do nothing */ break; } else if (r == l + 1) { /* two elements */ if (Util.greater(a[l], a[r])) swapPointAndDouble(a, b, l, r); break; } else { boolean done = false; /* more than two elements */ int i, j; Point<3> v; /* the partition element */ if ((AMR.debug & 4) != 0) System.out.println("Sorting " + l + " to " + r); /* partition element = median of 3 elements */ { int m = (r + l) / 2; int pick = r; if (Util.less(a[l], a[m]) && Util.less(a[m], a[r]) || Util.greater(a[l], a[m]) && Util.greater(a[m], a[r])) pick = m; else if (Util.less(a[m], a[l]) && Util.less(a[l], a[r]) || Util.greater(a[m], a[l]) && Util.greater(a[l], a[r])) pick = l; if (pick != r) swapPointAndDouble(a, b, r, pick); } v = a[r]; if ((AMR.debug & 4) != 0) System.out.println("Partition on " + Util.stringify(v)); i = l - 1; j = r; while (!done) { while (++i <= r && Util.less(a[i], v)) // System.out.println("a[" + i + "] = " + Util.stringify(a[i])) ; while (--j >= l && Util.greater(a[j], v)) // System.out.println("a[" + j + "] = " + Util.stringify(a[j])) ; done = j <= i; // System.out.print(done ? "done" : "not done"); // System.out.print(", a[" + i + "] = " + Util.stringify(a[i])); // System.out.println(", a[" + j + "] = " + Util.stringify(a[j])); if (!done && !Util.less(a[i], v) && !Util.greater(a[j], v)) { swapPointAndDouble(a, b, i, j); if ((AMR.debug & 8) != 0) { System.out.print("swap: now "); System.out.print("a[" + i + "] = " + Util.stringify(a[i])); System.out.println(", a[" + j + "] = " + Util.stringify(a[j])); } } } if (j >= l && j + 1 <= r) { for (int t = l; t <= j; t++) if (Util.greater(a[t], v)) { System.out.print("low partition failed: "); System.out.println("a[" + t + "] = " + Util.stringify(a[t])); } for (int t = j + 1; t <= r; t++) if (Util.less(a[t], v)) { System.out.print("high partition failed: "); System.out.println("a[" + t + "] = " + Util.stringify(a[t])); } if ((AMR.debug & 4) != 0) System.out.println("Done partitioning " + l + " to " + r); /* Do l to j later; do j+1 to r next */ loToDo.push(l); hiToDo.push(j); l = j + 1; } else { /* Partitioning failed to make the problem smaller; */ /* Peel off partition element itself to make it smaller. */ if ((AMR.debug & 4) != 0) System.out.println("peeling"); if (j < l) { swapPointAndDouble(a, b, l, r); while (a[l] == v) l++; } else while (a[r] == v) r--; } } } } /* Check it */ boolean failure = false; for (int t = l0; t < r0; t++) if (Util.greater(a[t], a[t + 1])) failure = true; if (failure) { System.out.println("failure sorting " + l0 + " to " + r0); for (int t = l0; t <= r0; t++) System.err.println(t + ": " + Util.stringify(a[t])); System.exit(-1); } } static void swapPointAndDouble(Point<3> [1d] local a, double [1d] local b, int i, int j) { Point<3> tp = a[j]; double td = b[j]; a[j] = a[i]; b[j] = b[i]; a[i] = tp; b[i] = td; } }