00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.benchmarks.timit;
00032
00033 import java.io.ByteArrayOutputStream;
00034 import java.io.ObjectOutputStream;
00035 import java.text.DecimalFormat;
00036 import java.text.DecimalFormatSymbols;
00037
00038 import org.apache.commons.cli.BasicParser;
00039 import org.apache.commons.cli.CommandLine;
00040 import org.apache.commons.cli.HelpFormatter;
00041 import org.apache.commons.cli.Options;
00042 import org.apache.commons.cli.ParseException;
00043 import org.jdom.Element;
00044 import org.objectweb.proactive.ActiveObjectCreationException;
00045 import org.objectweb.proactive.ProActive;
00046 import org.objectweb.proactive.benchmarks.timit.config.Benchmark;
00047 import org.objectweb.proactive.benchmarks.timit.config.ConfigChart;
00048 import org.objectweb.proactive.benchmarks.timit.config.ConfigReader;
00049 import org.objectweb.proactive.benchmarks.timit.config.Serie;
00050 import org.objectweb.proactive.benchmarks.timit.result.BenchmarkResultWriter;
00051 import org.objectweb.proactive.benchmarks.timit.result.SerieResultWriter;
00052 import org.objectweb.proactive.benchmarks.timit.util.BenchmarkStatistics;
00053 import org.objectweb.proactive.benchmarks.timit.util.Startable;
00054 import org.objectweb.proactive.benchmarks.timit.util.TimItManager;
00055 import org.objectweb.proactive.benchmarks.timit.util.TimItReductor;
00056 import org.objectweb.proactive.benchmarks.timit.util.XMLHelper;
00057 import org.objectweb.proactive.benchmarks.timit.util.charts.Utilities;
00058 import org.objectweb.proactive.core.node.NodeException;
00059
00075 public class TimIt {
00076
00077 public static final DecimalFormat df = new DecimalFormat("##0.000",
00078 new DecimalFormatSymbols(java.util.Locale.US));
00079
00080 private static final String VERSION = "1.0";
00081
00082 private static final int MAX_TIMEOUT_ERRORS = 3;
00083
00084 private static final int WAIT_AFTER_ERROR = 5000;
00085
00086 private static TimItReductor timitReductor;
00087
00088 private static Timeout timeoutThread;
00089
00090 private static boolean timeoutError;
00091
00092 private static int totalTimeoutErrors;
00093
00100 public static void main(String[] args) {
00101 try {
00102 Options opt = new Options();
00103 opt.addOption("c", "config", true,
00104 "Specify the configuration file to use");
00105 opt
00106 .addOption("h", "help", false,
00107 "Print help for this application");
00108 opt
00109 .addOption("g", "generate-charts", true,
00110 "Generate charts from merged result file without running benchmarks");
00111 opt
00112 .addOption("m", "merge", true,
00113 "Produce a merged result file from benchmarks results files");
00114 opt.addOption("v", "version", false, "Returns the TimIt version");
00115
00116 BasicParser parser = new BasicParser();
00117 CommandLine cl = parser.parse(opt, args);
00118
00119 if (cl.hasOption('c')) {
00120 if (cl.hasOption('g')) {
00121 generateCharts(cl.getOptionValue('c'), cl
00122 .getOptionValue('g'));
00123
00124 } else if (cl.hasOption('m')) {
00125 mergeResults(cl.getOptionValue('c'), cl
00126 .getOptionValues('g'));
00127
00128 } else {
00129 TimIt.timeoutThread = new Timeout();
00130 TimIt.timeoutThread.start();
00131 createTimItReductor();
00132 runBenchmarkSuite(cl.getOptionValue('c'));
00133 TimIt.timeoutThread.terminate();
00134 }
00135 } else if (cl.hasOption('v')) {
00136 System.out.println(getVersion());
00137
00138 } else {
00139 HelpFormatter help = new HelpFormatter();
00140 help.printHelp("TimIt options", opt);
00141 }
00142
00143 } catch (ParseException e) {
00144 e.printStackTrace();
00145 System.exit(1);
00146 }
00147 System.exit(0);
00148 }
00149
00159 private static void generateCharts(String configFile, String finalFile) {
00160 ConfigReader config = new ConfigReader(configFile);
00161 Serie[] serie = config.getSeries();
00162
00163 for (Serie element : serie) {
00164 ConfigChart[] chart = element.getCharts();
00165 Utilities.generatingCharts(XMLHelper.readFile(finalFile)
00166 .getRootElement(), null, chart);
00167 }
00168 }
00169
00179 private static void mergeResults(String configFile, String[] resultFiles) {
00180 ConfigReader config = new ConfigReader(configFile);
00181 Serie[] serie = config.getSeries();
00182
00183 for (Serie element : serie) {
00184 ConfigChart[] chart = element.getCharts();
00185 SerieResultWriter serieResults = new SerieResultWriter(element
00186 .get("result"));
00187 Benchmark[] bench = element.getBenchmarks();
00188
00189 for (int j = 0; j < bench.length; j++) {
00190 Benchmark benchmark = bench[j];
00191 Element eResult = XMLHelper.readFile(resultFiles[j])
00192 .getRootElement();
00193 int warmup = Integer.valueOf(benchmark.get("warmup"));
00194 int nbRuns = Integer.valueOf(benchmark.get("run")) + warmup;
00195 serieResults.addResult(eResult, benchmark.get("name"), nbRuns,
00196 TimIt.totalTimeoutErrors);
00197 }
00198 Utilities.generatingCharts(serieResults.getRoot(), null, chart);
00199 }
00200 }
00201
00206 private static void createTimItReductor() {
00207 try {
00208 TimIt.timitReductor = (TimItReductor) ProActive.newActive(
00209 TimItReductor.class.getName(), new Object[] {});
00210 TimItManager.getInstance().setTimitReductor(TimIt.timitReductor);
00211 } catch (ActiveObjectCreationException e) {
00212 e.printStackTrace();
00213 } catch (NodeException e) {
00214 e.printStackTrace();
00215 }
00216 }
00217
00224 private static void runBenchmarkSuite(String configfile) {
00225 try {
00226 ConfigReader config = new ConfigReader(configfile);
00227 Serie[] serie = config.getSeries();
00228 int timeoutErrorCount = TimIt.MAX_TIMEOUT_ERRORS;
00229
00230 for (Serie element : serie) {
00231
00232
00233
00234 ConfigChart[] chart = element.getCharts();
00235 Benchmark[] bench = element.getBenchmarks();
00236 Class runClass = Class.forName(element.get("class"));
00237 Startable startable = (Startable) runClass.newInstance();
00238 message(1, "RUN SERIE " + runClass.getSimpleName() + " ["
00239 + element.get("result") + "]");
00240
00241 SerieResultWriter serieResults =
00242 new SerieResultWriter(element.get("result"));
00243
00244 BenchmarkStatistics bstats = null;
00245 TimIt.totalTimeoutErrors = 0;
00246
00247 for (Benchmark b : bench) {
00248
00249
00250
00251 String name = b.get("name");
00252 String outDesc = b.get("descriptorGenerated");
00253 message(2, "RUN BENCHMARK " + name + " [" + b.get("output")
00254 + "]");
00255 BenchmarkResultWriter benchResults = new BenchmarkResultWriter(
00256 b.get("output"));
00257 if (outDesc.length() > 0) {
00258 XMLHelper.generateDescriptor(
00259 element.get("descriptorBase"),
00260 config.getGlobalVariables(),
00261 b.getVariables(), outDesc);
00262 }
00263 int warmup = Integer.valueOf(b.get("warmup"));
00264 int nbRuns = Integer.valueOf(b.get("run")) + warmup;
00265 TimIt.timeoutThread.setNewBenchmark(Long.valueOf(b
00266 .get("timeout")) * 1000, startable);
00267 timeoutErrorCount = TimIt.MAX_TIMEOUT_ERRORS;
00268
00269 for (int run = 1; run <= nbRuns; run++) {
00270
00271
00272
00273 if( nbRuns <= 50
00274 || (nbRuns<=100 && run % 2 == 0)
00275 || (nbRuns>100 && nbRuns<=1000 && run % 10 == 0)
00276 || (nbRuns>1000 && run % ((int)(nbRuns/0.05)) == 0)
00277 ) {
00278 message(3, "RUN " + run + " ON " + nbRuns
00279 + ((run <= warmup) ? " [WARMUP]" : ""));
00280 }
00281 TimIt.timeoutError = false;
00282 TimIt.timeoutThread.newRun();
00283 try {
00284 startable.start(b.get("parameters").split(" "));
00285 } catch( Exception e ) {
00286 e.printStackTrace();
00287 if( --timeoutErrorCount <= 0 ) {
00288 System.err.println(
00289 "Too many exceptions for this benchmark, skip it");
00290 XMLHelper.errorLog(element.get("errorfile"),
00291 "Too many exceptions ("
00292 + TimIt.MAX_TIMEOUT_ERRORS
00293 + ") for this benchmark "
00294 + " (" + b.get("name")
00295 + ") : " + e.getMessage()
00296 + "\n Skip it.");
00297 TimIt.timeoutError = true;
00298 TimIt.sleep(WAIT_AFTER_ERROR);
00299 break;
00300 } else {
00301 System.err.println("An exception occur... retrying...");
00302 XMLHelper.errorLog(element.get("errorfile"),
00303 "An exception occur : " + e.getMessage()
00304 + "... retrying..." );
00305 TimIt.sleep(WAIT_AFTER_ERROR);
00306 run--;
00307 continue;
00308 }
00309 }
00310 bstats = TimIt.timitReductor.getStatistics();
00311 TimIt.timitReductor.clean();
00312 TimItReductor.ready();
00313 ProActive.waitFor(bstats);
00314
00315 if (TimIt.timeoutError) {
00316 TimIt.totalTimeoutErrors++;
00317 XMLHelper.errorLog(element.get("errorfile"),
00318 "Timeout for benchmark '" + b.get("name")
00319 + "'" + " args=["
00320 + b.get("parameters") + "]"
00321 + " on run " + run);
00322 if (--timeoutErrorCount <= 0) {
00323 System.err.println(
00324 "Too many timeout errors for this benchmark, skip it");
00325 XMLHelper.errorLog(element.get("errorfile"),
00326 "Too many timeout errors ("
00327 + TimIt.MAX_TIMEOUT_ERRORS
00328 + ") for this benchmark "
00329 + " (" + b.get("name")
00330 + "), skip it.");
00331 TimIt.sleep(WAIT_AFTER_ERROR);
00332 break;
00333 }
00334 run--;
00335 continue;
00336 }
00337 TimIt.timeoutThread.ok();
00338
00339 if (run > warmup) {
00340 benchResults.addResult(bstats, name + " [" + run
00341 + "/" + nbRuns + "]");
00342 if( b.get("writeEveryRun").equalsIgnoreCase("true") ) {
00343 benchResults.writeResult();
00344 }
00345 }
00346 startable.kill();
00347 }
00348 if (TimIt.timeoutError) {
00349 continue;
00350 }
00351 startable.masterKill();
00352 threadsCleaning();
00353 benchResults.writeResult();
00354 if( b.get("removeExtremums").equalsIgnoreCase("true") ) {
00355 benchResults.removeExtremums();
00356 }
00357 serieResults.addResult(benchResults.getRoot(), b
00358 .get("name"), nbRuns, TimIt.totalTimeoutErrors);
00359 }
00360
00361
00362
00363 Utilities.generatingCharts(serieResults.getRoot(), bstats,
00364 chart);
00365 }
00366 } catch (ClassNotFoundException e) {
00367 e.printStackTrace();
00368 } catch (InstantiationException e) {
00369 e.printStackTrace();
00370 } catch (IllegalAccessException e) {
00371 e.printStackTrace();
00372 }
00373 message(1, "Done.");
00374 }
00375
00379 private static void threadsCleaning() {
00380 ThreadGroup tg = Thread.currentThread().getThreadGroup().getParent();
00381 Thread[] threads = new Thread[200];
00382 int len = tg.enumerate(threads,true);
00383 int nbKilled = 0;
00384 for( int i=0; i<len; i++ ) {
00385 Thread ct = threads[i];
00386 if( ct.getName().indexOf("RMI RenewClean") >= 0
00387 || ct.getName().indexOf("ThreadInThePool") >= 0
00388 ) {
00389 nbKilled++;
00390 ct.stop();
00391 }
00392 }
00393 System.err.println(nbKilled + " thread(s) stopped on " + len);
00394 }
00395
00405 public static void message(int level, String msg) {
00406 switch (level) {
00407 case 1:
00408 System.out.println("\n\n**** " + msg + " ****\n");
00409 break;
00410 case 2:
00411 System.out.println("\n**** " + msg + " ****\n");
00412 break;
00413 case 3:
00414 System.out.println("\n**** " + msg + " ****");
00415 break;
00416 default:
00417 System.out.println("**** " + msg + " ****");
00418 }
00419 }
00420
00428 public static int getObjectSize(Object object) {
00429 if (object == null) {
00430 return 0;
00431 }
00432 try {
00433 ByteArrayOutputStream baos = new ByteArrayOutputStream();
00434 ObjectOutputStream oos = new ObjectOutputStream(baos);
00435 oos.writeObject(object);
00436 byte[] bytes = baos.toByteArray();
00437 oos.close();
00438 baos.close();
00439 return bytes.length;
00440 } catch (Exception e) {
00441 e.printStackTrace();
00442 }
00443 return -1;
00444 }
00445
00449 public static String getVersion() {
00450 return "TimIt " + TimIt.VERSION;
00451 }
00452
00459 public static void sleep(long millis) {
00460 try {
00461 Thread.sleep(millis);
00462 } catch (InterruptedException e) {
00463 e.printStackTrace();
00464 }
00465 }
00466
00470 private static class Timeout extends Thread {
00471 private long timeout;
00472
00473 private Startable startableObject;
00474
00475 private boolean terminated, error, newRun, ok;
00476
00477 public Timeout() {
00478 this.terminated = true;
00479 this.newRun = false;
00480 }
00481
00482 synchronized public void setNewBenchmark(long timeout, Startable obj) {
00483 this.timeout = timeout;
00484 this.startableObject = obj;
00485 }
00486
00487 public void newRun() {
00488 synchronized (this) {
00489 if (!this.newRun) {
00490 this.newRun = true;
00491 this.notifyAll();
00492 }
00493 this.error = true;
00494 }
00495 }
00496
00497 public void ok() {
00498 synchronized (this) {
00499 this.newRun = false;
00500 this.error = false;
00501 this.ok = true;
00502 this.notifyAll();
00503 }
00504 }
00505
00506 public void terminate() {
00507 synchronized (this) {
00508 this.terminated = true;
00509 this.error = false;
00510 this.notifyAll();
00511 }
00512 }
00513
00514 public void run() {
00515 try {
00516 synchronized (this) {
00517 while (this.terminated) {
00518 if (this.newRun) {
00519 this.wait(this.timeout);
00520 } else {
00521 this.wait();
00522 continue;
00523 }
00524
00525 if (this.error && !this.ok) {
00526 message(2, "TIMEOUT !!! RESTART THE RUN");
00527 TimIt.timeoutError = true;
00528 this.startableObject.kill();
00529 TimItReductor.stop();
00530 }
00531 this.ok = false;
00532 }
00533 }
00534
00535 } catch (InterruptedException e) {
00536 }
00537 }
00538 }
00539 }