import x10.x10rt.X10RT; import x10.core.fun.*; import x10.rtt.*; import java.io.*; public class Basic { private static class RunnableWithBuf implements Serializable, x10.serialization.X10JavaSerializable { public static final int Ping = 1; public static final int Pong = 2; public static final int Quit = 3; private int id; private RunnableWithBuf() { } public RunnableWithBuf(int id) { this.id = id; } public void run(byte[] buf) { switch (id) { case Ping: Basic.recv_msg_ping(buf); break; case Pong: Basic.recv_msg_pong(buf); break; case Quit: Basic.recv_quit(buf); break; } } public static RunnableWithBuf $_deserialize_body(RunnableWithBuf _obj, x10.serialization.X10JavaDeserializer deserializer) throws java.io.IOException { _obj.id = deserializer.readInt(); return _obj; } public static RunnableWithBuf $_deserializer(x10.serialization.X10JavaDeserializer deserializer) throws java.io.IOException { RunnableWithBuf _obj = new RunnableWithBuf(); deserializer.record_reference(_obj); return $_deserialize_body(_obj, deserializer); } public void $_serialize(x10.serialization.X10JavaSerializer serializer) throws java.io.IOException { serializer.write(this.id); } } static RunnableWithBuf Ping, Pong, Quit; static { Ping = new RunnableWithBuf(RunnableWithBuf.Ping); Pong = new RunnableWithBuf(RunnableWithBuf.Pong); Quit = new RunnableWithBuf(RunnableWithBuf.Quit); } byte[] buf; int len = 1024; boolean validate = false; static int pongs_outstanding = 0; static boolean finished = false; static void recv_msg_ping(byte[] buf) { //System.err.println(X10RT.here()+": Received a ping message"); sendMsg(0, Pong, buf, buf.length); } static void recv_msg_pong(byte[] buf) { //System.err.println(X10RT.here()+": Received a pong message"); pongs_outstanding--; } static void recv_quit(byte[] buf) { //System.err.println(X10RT.here()+": Received a quit message"); finished = true; } public void show_help(java.io.PrintStream out, String name) { if (X10RT.here() != 0) return; out.println("Usage: " + name + " <args>"); out.print ("-h (--help) "); out.println("this message"); out.print ("-l (--length) <n> "); out.println("size of individual message"); out.print ("-w (--window) <n> "); out.println("number of pongs to wait for in parallel (window size)"); out.print ("-i (--iterations) <n> "); out.println("top-level iterations (round trips)"); out.print ("-v (--validate) "); out.println("check whether messages are mangled in transit"); out.print ("-p (--put) "); out.println("use x10rt_send_put instead of x10rt_send_msg"); out.print ("-g (--get) "); out.println("use x10rt_send_get instead of x10rt_send_msg"); out.print ("-a (--auto) "); out.println("test a variety of --length and --window"); } long run_test(int iters, int window, int len) { return run_test(iters, window, len, false); } long run_test(int iters, int window, int len, boolean put) { return run_test(iters, window, len, put, false); } long run_test(int iters, int window, int len, boolean put, boolean get) { long nanos = -System.nanoTime(); for (int i = 0; i < iters; ++i) { for (int j = 0; j < window; ++j) { for (int k = 1; k < X10RT.numPlaces(); ++k) { sendMsg(k, Ping, buf, len); pongs_outstanding++; } } while (pongs_outstanding > 0) X10RT.probe(); } nanos += System.nanoTime(); return nanos; } public void run(String[] argv) { if (X10RT.numPlaces()==1) { System.err.println("This is a communications test so needs at least 2 hosts."); System.exit(EXIT_FAILURE); } int iterations = 32; int window = 100; boolean put = false; boolean get = false; boolean automatic = false; for (int i = 0; i < argv.length; ++i) { if (!strcmp(argv[i], "--help")) { show_help(System.out, getClass().getName()); System.exit(EXIT_SUCCESS); } else if (!strcmp(argv[i], "-h")) { show_help(System.err, getClass().getName()); System.exit(EXIT_SUCCESS); } else if (!strcmp(argv[i], "--length")) { len = strtoul(argv[++i]); } else if (!strcmp(argv[i], "-l")) { len = strtoul(argv[++i]); } else if (!strcmp(argv[i], "--window")) { window = strtoul(argv[++i]); } else if (!strcmp(argv[i], "-w")) { window = strtoul(argv[++i]); } else if (!strcmp(argv[i], "--iterations")) { iterations = strtoul(argv[++i]); } else if (!strcmp(argv[i], "-i")) { iterations = strtoul(argv[++i]); } else if (!strcmp(argv[i], "--validate")) { validate = true; } else if (!strcmp(argv[i], "-v")) { validate = true; } else if (!strcmp(argv[i], "--auto")) { automatic = true; } else if (!strcmp(argv[i], "-a")) { automatic = true; } else if (!strcmp(argv[i], "--put")) { put = true; } else if (!strcmp(argv[i], "-p")) { put = true; } else if (!strcmp(argv[i], "--get")) { get = true; } else if (!strcmp(argv[i], "-g")) { get = true; } else { if (X10RT.here() == 0) { System.err.println("Didn't understand: \"" + argv[i] + "\""); show_help(System.err, getClass().getName()); } System.exit(EXIT_FAILURE); } } if (put || get) { if (X10RT.here() == 0) { System.err.println("Put and get are not supported."); } System.exit(EXIT_FAILURE); } if (put && get) { if (X10RT.here() == 0) { System.err.println("You can't specify both put and get."); show_help(System.err, getClass().getName()); } System.exit(EXIT_FAILURE); } { int sz = len < 1024*1024 ? 1024*1024 : len; buf = new byte[sz]; for (int i = 0; i < sz; ++i) { buf[i] = (byte) (i & 0xFF); } } if (X10RT.here() == 0) { // warm up for (int i=0; i < 16; ++i) { run_test(1, 1, 1024, false, false); run_test(1, 1, 1024, true, false); run_test(1, 1, 1024, true, true); } } if (X10RT.here() == 0) { if (automatic) { System.out.print(" "); for (int j = 1; j <= 16; ++j) { System.out.printf("%5d", j); } System.out.println(" b/w (MB)"); for (int l = 0; l<512*1024; l=(l*2)>0?(l*2):1) { System.out.printf("%8d", l); double micros = 0; for (int j = 1; j <= 16; ++j) { micros = run_test(iterations/j, j, l, put, get) / 1E3 / (iterations/j*j) / 2 / (X10RT.numPlaces() - 1); System.out.printf("%6.3f ", micros); } System.out.printf("%.3f\n", l/micros); } } else { double micros = run_test(iterations, window, len, put, get) / 1E3 / (iterations*window) / 2 / (X10RT.numPlaces() - 1); System.out.println("Half roundtrip time: " + micros + " us Bandwidth: " + (len/micros) + " MB/s"); } for (int i = 1; i < X10RT.numPlaces(); ++i) { sendMsg(i, Quit, null, 0); } finished = true; } while (!finished) X10RT.probe(); } private static class Handler implements VoidFun_0_0 { public RunnableWithBuf id; public byte[] buf; private Handler() { } public Handler(RunnableWithBuf id, byte[] buf, int len) { this.id = id; byte[] newbuf = buf; if (len > 0 && buf.length != len) { newbuf = new byte[len]; System.arraycopy(buf, 0, newbuf, 0, len); } this.buf = newbuf; } public void $apply() { id.run(buf); } public RuntimeType<?> $getRTT() { return x10.core.Any.$RTT; } public Type<?> $getParam(int i) { throw new IllegalArgumentException(); } public static Handler $_deserialize_body(Handler _obj, x10.serialization.X10JavaDeserializer deserializer) throws java.io.IOException { _obj.id = (RunnableWithBuf) deserializer.readRef(); _obj.buf = deserializer.readByteArray(); return _obj; } public static Handler $_deserializer(x10.serialization.X10JavaDeserializer deserializer) throws java.io.IOException { Handler _obj = new Handler(); deserializer.record_reference(_obj); return $_deserialize_body(_obj, deserializer); } public void $_serialize(x10.serialization.X10JavaSerializer serializer) throws java.io.IOException { serializer.write((x10.serialization.X10JavaSerializable) this.id); if (this.buf == null) { serializer.write((Object) this.buf); } else { serializer.write(this.buf); } } } // serialization helper public static void sendMsg(int place, RunnableWithBuf runner, byte[] buf, int len) { try { VoidFun_0_0 body = new Handler(runner, buf, len); x10.serialization.X10JavaSerializer serializer = new x10.serialization.X10JavaSerializer(); serializer.write((x10.serialization.X10JavaSerializable) body); byte[] msg = serializer.toMessage(); int msgLen = msg.length; //System.err.println(X10RT.here()+": About to send a message to place "+place); x10.x10rt.MessageHandlers.runClosureAtSend(place, msgLen, msg); //System.err.println(X10RT.here()+": Sent a message to place "+place); } catch (java.io.IOException e){ e.printStackTrace(); } } // stdlib simulation stuff public static final int EXIT_SUCCESS = 1; public static final int EXIT_FAILURE = 1; public static boolean strcmp(String a, String b) { return !a.equals(b); } public static int strtoul(String s) { return Integer.parseInt(s); } public static void main(String[] argv) { int n = X10RT.numPlaces(); int i = X10RT.here(); System.out.println("There are "+n+" Nodes and I am Node "+i); new Basic().run(argv); } } // vim:tabstop=4:shiftwidth=4:expandtab