From: jzhou Date: Wed, 28 Jul 2010 00:19:35 +0000 (+0000) Subject: Add TSP benchmark from JOlden for the multicore gc X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=362b19583be9d5dabee7693d2a55303b8f209bb3;p=IRC.git Add TSP benchmark from JOlden for the multicore gc --- diff --git a/Robust/src/Benchmarks/Scheduling/GC/tsp/Makefile b/Robust/src/Benchmarks/Scheduling/GC/tsp/Makefile new file mode 100644 index 00000000..f84382b0 --- /dev/null +++ b/Robust/src/Benchmarks/Scheduling/GC/tsp/Makefile @@ -0,0 +1,4 @@ +BMARK = TSP +PARMS = -c 10000 -m +include ../Makefile.common + diff --git a/Robust/src/Benchmarks/Scheduling/GC/tsp/TSPBench.java b/Robust/src/Benchmarks/Scheduling/GC/tsp/TSPBench.java new file mode 100644 index 00000000..f00f6318 --- /dev/null +++ b/Robust/src/Benchmarks/Scheduling/GC/tsp/TSPBench.java @@ -0,0 +1,23 @@ +/** Bamboo Version + * Ported by: Jin Zhou 07/27/10 + * + * This is ported from the JOlden + * **/ + +task t1(StartupObject s{initialstate}) { + //System.printString("task t1\n"); + + int threadnum = 62; // 56; + int ncities = 4080; + for(int i = 0; i < threadnum; ++i) { + TestRunner tr = new TestRunner(ncities){run}; + } + + taskexit(s{!initialstate}); +} + +task t2(TestRunner tr{run}) { + //System.printString("task t2\n"); + tr.run(); + taskexit(tr{!run}); +} diff --git a/Robust/src/Benchmarks/Scheduling/GC/tsp/TestRunner.java b/Robust/src/Benchmarks/Scheduling/GC/tsp/TestRunner.java new file mode 100644 index 00000000..e9e106d2 --- /dev/null +++ b/Robust/src/Benchmarks/Scheduling/GC/tsp/TestRunner.java @@ -0,0 +1,108 @@ + +//import java.io.*; + +/** + * A Java implementation of the tsp Olden benchmark, the traveling + * salesman problem. + *

+ * + * R. Karp, "Probabilistic analysis of partitioning algorithms for the + * traveling-salesman problem in the plane." Mathematics of Operations Research + * 2(3):209-224, August 1977 + * + **/ +public class TestRunner +{ + flag run; + + /** + * Number of cities in the problem. + **/ + public int cities; + /** + * Set to true if the result should be printed + **/ + //private static boolean printResult = false; + /** + * Set to true to print informative messages + **/ + //private static boolean printMsgs = false; + + public TestRunner(int cities) { + this.cities = cities; + } + + /** + * The main routine which creates a tree and traverses it. + * @param args the arguments to the program + **/ + public void run() + { + /*parseCmdLine(args); + + if (printMsgs) + System.out.println("Building tree of size " + cities); + + long start0 = System.currentTimeMillis();*/ + Tree_tsp t = Tree_tsp.buildTree(this.cities, false, 0.0f, 1.0f, 0.0f, 1.0f); + /*long end0 = System.currentTimeMillis(); + + long start1 = System.currentTimeMillis();*/ + t.tsp(150); + /*long end1 = System.currentTimeMillis(); + + if (printResult) { + // if the user specifies, print the final result + t.printVisitOrder(); + } + + if (printMsgs) { + System.out.println("Tsp build time " + (end0 - start0)/1000.0); + System.out.println("Tsp time " + (end1 - start1)/1000.0); + System.out.println("Tsp total time " + (end1 - start0)/1000.0); + } + System.out.println("Done!");*/ + } + + /** + * Parse the command line options. + * @param args the command line options. + **/ + /*private static final void parseCmdLine(String args[]) + { + int i = 0; + String arg; + + while (i < args.length && args[i].startsWith("-")) { + arg = args[i++]; + + if (arg.equals("-c")) { + if (i < args.length) + cities = new Integer(args[i++]).intValue(); + else throw new Error("-c requires the size of tree"); + } else if (arg.equals("-p")) { + printResult = true; + } else if (arg.equals("-m")) { + printMsgs = true; + } else if (arg.equals("-h")) { + usage(); + } + } + if (cities == 0) usage(); + }*/ + + /** + * The usage routine which describes the program options. + **/ + /*private static final void usage() + { + System.err.println("usage: java TSP -c [-p] [-m] [-h]"); + System.err.println(" -c number of cities (rounds up to the next power of 2 minus 1)"); + System.err.println(" -p (print the final result)"); + System.err.println(" -m (print informative messages)"); + System.err.println(" -h (print this message)"); + System.exit(0); + }*/ + +} + diff --git a/Robust/src/Benchmarks/Scheduling/GC/tsp/Tree_tsp.java b/Robust/src/Benchmarks/Scheduling/GC/tsp/Tree_tsp.java new file mode 100644 index 00000000..706ba059 --- /dev/null +++ b/Robust/src/Benchmarks/Scheduling/GC/tsp/Tree_tsp.java @@ -0,0 +1,456 @@ + +//import java.util.Random; + +/** + * A class that represents a node in a binary tree. Each node represents + * a city in the TSP benchmark. + **/ +final class Tree_tsp +{ + /** + * The number of nodes (cities) in this subtree + **/ + private int sz; + /** + * The coordinates that this node represents + **/ + private float x,y; + /** + * Left child of the tree + **/ + private Tree_tsp left; + /** + * Right child of tree + **/ + private Tree_tsp right; + /** + * The next pointer in a linked list of nodes in the subtree. The list + * contains the order of the cities to visit. + **/ + private Tree_tsp next; + /** + * The previous pointer in a linked list of nodes in the subtree. The list + * contains the order of the cities to visit. + **/ + private Tree_tsp prev; + + // used by the random number generator + //private static final float M_E2; // = 7.3890560989306502274; + //private static final float M_E3; // = 20.08553692318766774179; + //private static final float M_E6; // = 403.42879349273512264299; + //private static final float M_E12; // = 162754.79141900392083592475; + + /** + * Construct a Tree node (a city) with the specified size + * @param size the number of nodes in the (sub)tree + * @param x the x coordinate of the city + * @param y the y coordinate of the city + * @param left the left subtree + * @param right the right subtree + **/ + Tree_tsp(int size, float x, float y, Tree_tsp l, Tree_tsp r) + { + /*M_E2 = 7.3890560989306502274f; + M_E3 = 20.08553692318766774179f; + M_E6 = 403.42879349273512264299f; + M_E12 = 162754.79141900392083592475f;*/ + + sz = size; + this.x = x; + this.y = y; + left = l; + right = r; + next = null; + prev = null; + } + + /** + * Find Euclidean distance between this node and the specified node. + * @param b the specified node + * @return the Euclidean distance between two tree nodes. + **/ + float distance(Tree_tsp b) + { + return (Math.sqrtf((float)((x-b.x)*(x-b.x)+(y-b.y)*(y-b.y)))); + } + + /** + * Create a list of tree nodes. Requires root to be the tail of the list. + * Only fills in next field, not prev. + * @return the linked list of nodes + **/ + Tree_tsp makeList() + { + Tree_tsp myleft, myright; + Tree_tsp tleft,tright; + Tree_tsp retval = this; + + // head of left list + if (left != null) + myleft = left.makeList(); + else + myleft = null; + + // head of right list + if (right != null) + myright = right.makeList(); + else + myright = null; + + if (myright != null) { + retval = myright; + right.next = this; + } + + if (myleft != null) { + retval = myleft; + if (myright != null) + left.next = myright; + else + left.next = this; + } + next = null; + + return retval; + } + + /** + * Reverse the linked list. Assumes that there is a dummy "prev" + * node at the beginning. + **/ + void reverse() + { + Tree_tsp prev = this.prev; + prev.next = null; + this.prev = null; + Tree_tsp back = this; + Tree_tsp tmp = this; + // reverse the list for the other nodes + Tree_tsp next; + for (Tree_tsp t = this.next; t != null; back = t, t = next) { + next = t.next; + t.next = back; + back.prev = t; + } + // reverse the list for this node + tmp.next = prev; + prev.prev = tmp; + } + + /** + * Use closest-point heuristic from Cormen, Leiserson, and Rivest. + * @return a + **/ + Tree_tsp conquer() + { + // create the list of nodes + Tree_tsp t = makeList(); + + // Create initial cycle + Tree_tsp cycle = t; + t = t.next; + cycle.next = cycle; + cycle.prev = cycle; + + // Loop over remaining points + Tree_tsp donext; + for (; t != null; t = donext) { + donext = t.next; /* value won't be around later */ + Tree_tsp min = cycle; + float mindist = t.distance(cycle); + for (Tree_tsp tmp = cycle.next; tmp != cycle; tmp=tmp.next) { + float test = tmp.distance(t); + if (test < mindist) { + mindist = test; + min = tmp; + } /* if */ + } /* for tmp... */ + + Tree_tsp next = min.next; + Tree_tsp prev = min.prev; + + float mintonext = min.distance(next); + float mintoprev = min.distance(prev); + float ttonext = t.distance(next); + float ttoprev = t.distance(prev); + + if ((float)(ttoprev - mintoprev) < (float)(ttonext - mintonext)) { + /* insert between min and prev */ + prev.next = t; + t.next = min; + t.prev = prev; + min.prev = t; + } else { + next.prev = t; + t.next = next; + min.next = t; + t.prev = min; + } + } /* for t... */ + + return cycle; + } + + /** + * Merge two cycles as per Karp. + * @param a a subtree with one cycle + * @param b a subtree with the other cycle + **/ + Tree_tsp merge(Tree_tsp a, Tree_tsp b) + { + // Compute location for first cycle + Tree_tsp min = a; + float mindist = distance(a); + Tree_tsp tmp = a; + for (a = a.next; a != tmp; a = a.next) { + float test = distance(a); + if (test < mindist) { + mindist = test; + min = a; + } + } + + Tree_tsp next = min.next; + Tree_tsp prev = min.prev; + float mintonext = min.distance(next); + float mintoprev = min.distance(prev); + float ttonext = distance(next); + float ttoprev = distance(prev); + + Tree_tsp p1, n1; + float tton1, ttop1; + if ((ttoprev - mintoprev) < (ttonext - mintonext)) { + // would insert between min and prev + p1 = prev; + n1 = min; + tton1 = mindist; + ttop1 = ttoprev; + } else { + // would insert between min and next + p1 = min; + n1 = next; + ttop1 = mindist; + tton1 = ttonext; + } + + // Compute location for second cycle + min = b; + mindist = distance(b); + tmp = b; + for (b = b.next; b != tmp; b = b.next) { + float test = distance(b); + if (test < mindist) { + mindist = test; + min = b; + } + } + + next = min.next; + prev = min.prev; + mintonext = min.distance(next); + mintoprev = min.distance(prev); + ttonext = this.distance(next); + ttoprev = this.distance(prev); + + Tree_tsp p2, n2; + float tton2, ttop2; + if ((ttoprev - mintoprev) < (ttonext - mintonext)) { + // would insert between min and prev + p2 = prev; + n2 = min; + tton2 = mindist; + ttop2 = ttoprev; + } else { + // would insert between min andn ext + p2 = min; + n2 = next; + ttop2 = mindist; + tton2 = ttonext; + } + + // Now we have 4 choices to complete: + // 1:t,p1 t,p2 n1,n2 + // 2:t,p1 t,n2 n1,p2 + // 3:t,n1 t,p2 p1,n2 + // 4:t,n1 t,n2 p1,p2 + float n1ton2 = n1.distance(n2); + float n1top2 = n1.distance(p2); + float p1ton2 = p1.distance(n2); + float p1top2 = p1.distance(p2); + + mindist = (float)(ttop1 + ttop2 + n1ton2); + int choice = 1; + + float test = (float)(ttop1 + tton2 + n1top2); + if (test < mindist) { + choice = 2; + mindist = test; + } + + test = tton1 + ttop2 + p1ton2; + if (test < mindist) { + choice = 3; + mindist = test; + } + + test = tton1 + tton2 + p1top2; + if (test < mindist) + choice = 4; + + if (choice == 1) { + //case 1: + // 1:p1,this this,p2 n2,n1 -- reverse 2! + n2.reverse(); + p1.next = this; + this.prev = p1; + this.next = p2; + p2.prev = this; + n2.next = n1; + n1.prev = n2; + //break; + } else if(choice == 2) { + //case 2: + // 2:p1,this this,n2 p2,n1 -- OK + p1.next = this; + this.prev = p1; + this.next = n2; + n2.prev = this; + p2.next = n1; + n1.prev = p2; + //break; + } else if(choice == 3) { + //case 3: + // 3:p2,this this,n1 p1,n2 -- OK + p2.next = this; + this.prev = p2; + this.next = n1; + n1.prev = this; + p1.next = n2; + n2.prev = p1; + //break; + } else if(choice == 4) { + //case 4: + // 4:n1,this this,n2 p2,p1 -- reverse 1! + n1.reverse(); + n1.next = this; + this.prev = n1; + this.next = n2; + n2.prev = this; + p2.next = p1; + p1.prev = p2; + //break; + } + return this; + } + + /** + * Compute TSP for the tree t. Use conquer for problems <= sz + * @param sz the cutoff point for using conquer vs. merge + **/ + Tree_tsp tsp(int sz) + { + if (this.sz <= sz) return conquer(); + + Tree_tsp leftval = left.tsp(sz); + Tree_tsp rightval = right.tsp(sz); + + return merge(leftval, rightval); + } + + /** + * Print the list of cities to visit from the current node. The + * list is the result of computing the TSP problem. + * The list for the root node (city) should contain every other node + * (city). + **/ + /*void printVisitOrder() + { + System.out.println("x = " + x + " y = " + y); + for (Tree_tsp tmp = next; tmp != this; tmp = tmp.next) { + System.out.println("x = " + tmp.x + " y = " + tmp.y); + } + }*/ + + // + // static methods + // + + /** + * Return an estimate of median of n values distributed in [min,max) + * @param min the minimum value + * @param max the maximum value + * @param n + * @return an estimate of median of n values distributed in [min,max) + **/ + private static float median(float min, float max, int n) + { + float M_E2 = 7.3890560989306502274f; + float M_E3 = 20.08553692318766774179f; + float M_E6 = 403.42879349273512264299f; + float M_E12 = 162754.79141900392083592475f; + + // get random value in [0.0, 1.0) + float t = (new Random()).nextFloat(); + + float retval; + if (t > 0.5) { + retval = /*java.lang.*/(float)(Math.log(1.0-(2.0*(M_E12-1)*(t-0.5)/M_E12))/12.0f); + } else { + retval = (float)(-/*java.lang.*/Math.log(1.0-(2.0*(M_E12-1)*t/M_E12))/12.0f); + } + // We now have something distributed on (-1.0,1.0) + retval = (float)((retval+1.0f) * (max-min)/2.0f); + retval = retval + min; + return retval; + } + + /** + * Get float uniformly distributed over [min,max) + * @return float uniformily distributed over [min,max) + **/ + private static float uniform(float min, float max) + { + // get random value between [0.0,1.0) + float retval = (new Random()).nextFloat(); + retval = retval * (max-min); + return retval + min; + } + + /** + * Builds a 2D tree of n nodes in specified range with dir as primary + * axis (false for x, true for y) + * + * @param n the size of the subtree to create + * @param dir the primary axis + * @param min_x the minimum x coordinate + * @param max_x the maximum x coordinate + * @param min_y the minimum y coordinate + * @param max_y the maximum y coordinate + * @return a reference to the root of the subtree + **/ + public static Tree_tsp buildTree(int n, boolean dir, float min_x, + float max_x, float min_y, float max_y) + { + if (n==0) return null; + + Tree_tsp left, right; + float x, y; + if (dir) { + dir = !dir; + float med = median(min_x,max_x,n); + left = buildTree(n/2, dir, min_x, med, min_y, max_y); + right = buildTree(n/2, dir, med, max_x, min_y, max_y); + x = med; + y = uniform(min_y, max_y); + } else { + dir = !dir; + float med = median(min_y,max_y,n); + left = buildTree(n/2, dir, min_x, max_x, min_y, med); + right = buildTree(n/2, dir, min_x, max_x, med, max_y); + y = med; + x = uniform(min_x, max_x); + } + return new Tree_tsp(n, x, y, left, right); + } + +} diff --git a/Robust/src/Benchmarks/Scheduling/GC/tsp/benchmark.py b/Robust/src/Benchmarks/Scheduling/GC/tsp/benchmark.py new file mode 100644 index 00000000..1acab5da --- /dev/null +++ b/Robust/src/Benchmarks/Scheduling/GC/tsp/benchmark.py @@ -0,0 +1,3 @@ +from ashes2.lang.java.JOldenBenchmark import JOldenBenchmark + +benchmark = JOldenBenchmark("tsp", "TSP", params = ("-c", "1000", "-m"))