org/objectweb/proactive/benchmarks/timit/TimIt.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
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                 // ** Series **
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                     // ** Benchmarks **
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                         // ** Runs **
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; // then continue if timeoutError=true
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; // from previous break
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                 // Charts generation (from serie's file)
00362                 // last bstats is used for unmergable values (like comm events)
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 }

Generated on Mon Jan 22 15:16:04 2007 for ProActive by  doxygen 1.5.1