/** * */ package vroom.optimization.online.jmsa.benchmarking; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Arrays; import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import org.apache.log4j.Layout; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.apache.log4j.WriterAppender; import vroom.common.heuristics.cw.CWLogging; import vroom.common.heuristics.utils.HeuristicsLogging; import vroom.common.heuristics.vls.VLSLogging; import vroom.common.modeling.dataModel.IVRPSolution; import vroom.common.modeling.dataModel.Solution; import vroom.common.modeling.io.NovoaPersistenceHelper; import vroom.common.modeling.io.NovoaPersistenceHelper.DemandDistribution; import vroom.common.utilities.StatCollector; import vroom.common.utilities.StatCollector.Label; import vroom.common.utilities.Stopwatch; import vroom.common.utilities.Utilities; import vroom.common.utilities.callbacks.CallbackStack; import vroom.common.utilities.logging.LogPrintStream; import vroom.common.utilities.logging.LoggerHelper; import vroom.optimization.online.jmsa.MSABase; import vroom.optimization.online.jmsa.MSAGlobalParameters; import vroom.optimization.online.jmsa.MSASequential; import vroom.optimization.online.jmsa.benchmarking.NovoaRun.ReturnStatus; import vroom.optimization.online.jmsa.utils.MSALogging; import vroom.optimization.online.jmsa.vrp.VRPParameterKeys; import vroom.optimization.online.jmsa.vrp.vrpsd.VRPSDConsensus; /** * <code>NovoaBenchmarking</code> * <p> * Creation date: May 10, 2010 - 5:05:14 PM. * * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a * href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a * href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a> * @version 1.0 */ public class NovoaBenchmarking implements Runnable { public static int sAttemps = 5; public static NovoaPersistenceHelper.DemandDistribution sDistribution = DemandDistribution.UNIFORM; /** * Path of the file containing the default values for the {@link MSAGlobalParameters} */ public static String sDefaultsFile = "./data/NovoaDefaults.conf"; /** * Getter for this class logger * * @return the logger associated with this class */ public static LoggerHelper getLogger() { return LoggerHelper.getLogger(NovoaBenchmarking.class); } /** A per run time limit (in min) */ public static int sRunTimeLimit = 15; /** * The Class <code>BenchmarkRun</code> is used for a single run of MSA on a Novoa instance * <p> * Creation date: Oct 8, 2010 - 12:01:15 PM. * * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a * href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a * href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp" >SLP</a> * @version 1.0 */ public class BenchmarkRun implements Runnable { /** <code>[run, set, size, num, cap]</code> */ private final Integer[] runInfo; /** The seeds. */ private final long[] seeds; /** The params. */ private final MSAGlobalParameters params; /** The comment. */ private final String comment; /** * Creates a new <code>BenchmarkRun</code> * * @param run * : <code>[run, set, size, num, cap]</code> * @param params * @param comment */ public BenchmarkRun(Integer[] run, MSAGlobalParameters params, String comment) { runInfo = run; this.params = params; this.comment = comment; seeds = getSeeds(getRun(), getSize(), getRep(), getCap(), getSet()); } private int getRun() { return runInfo[0]; } private int getSize() { return runInfo[2]; } private int getRep() { return runInfo[3]; } private int getCap() { return runInfo[4]; } private int getSet() { return runInfo[1]; } /** * Collect statistics. * * @param novoa * the novoa * @param perfInf * the perfect information cost */ protected void collectStats(NovoaRun novoa, double perfInf) { Solution<?> solution = (Solution<?>) novoa.getMsa().getCurrentSolution(); int failures = novoa.getInstance().getRequestCount() - getSize(); double cost = novoa.getStatus() == ReturnStatus.NORMAL ? solution.getCost() : -1; double gap = novoa.getStatus() == ReturnStatus.NORMAL ? (cost - perfInf) / perfInf : -1; mStatsCollector.collect(Integer.valueOf(getRun()), novoa.getInstance().getName(), getSize(), (int) novoa.getInstance().getFleet().getVehicle().getCapacity(), Double.valueOf(novoa.getMsa().getTimer().readTimeS()), Double.valueOf(cost), Double.valueOf(perfInf), Integer.valueOf(failures), Double.valueOf(novoa.getTravelInvertSpeed()), comment, Arrays.toString(seeds), novoa.getStatus().toString(), Double.valueOf(gap)); } /* * (non-Javadoc) * @see java.lang.Runnable#run() */ @Override public void run() { boolean completed = false; int attempts = 0; NovoaRun novoa = null; double perfInf = -1; if (sComparePerfInf) { perfInf = mPerfInf.solvePerfectInformation(getRun(), getSize(), getRep(), getCap(), getSet(), 60 * 5, false, true, sDistribution); } Stopwatch timer = new Stopwatch(); while (!completed && attempts < sAttemps) { attempts++; timer.restart(); try { novoa = new NovoaRun(getSet(), getSize(), getRep(), getCap(), getRun(), params, sDistribution); System.gc(); } catch (IOException e) { getLogger().exception("NovoaBenchmarking.BenchmarkRun.run", e); } if (sFastRun) { novoa.setTravelInvertSpeed(1); } Runtime runtime = Runtime.getRuntime(); long maxMemory = runtime.maxMemory() / (1024 * 1024); long allocatedMemory = runtime.totalMemory() / (1024 * 1024); long freeMemory = runtime.freeMemory() / (1024 * 1024); double p = (100f * mProgress) / mTotalRuns; long expectedTime = (long) (mTimer.readTimeMS() * (((double) mTotalRuns) / mProgress - 1)); StringBuilder log = new StringBuilder(); log.append("-------------------------------------"); log.append(String.format("\n Instance: %s run #%s (%s) %.2f (etc: %s) %s", novoa .getInstance().getName(), getRun(), Thread.currentThread().getName(), p, Utilities.Time.millisecondsToString(expectedTime, 3, false, false), new Date(System.currentTimeMillis()))); log.append(String.format("\n > Comment : %s", comment)); log.append(String.format("\n > Memory (f/a/m/tf): %sm/%sm/%sm/%sm", freeMemory, allocatedMemory, maxMemory, (freeMemory + maxMemory - allocatedMemory))); log.append("\n-------------------------------------"); print(log.toString()); try { novoa.setTimeLimit(sRunTimeLimit); novoa.run(); completed = novoa.getStatus() == ReturnStatus.NORMAL; } catch (Exception e) { novoa.getMsa().stop(); getLogger().exception("NovoaBenchmarking.BenchmarkRun.run", e); } IVRPSolution<?> solution = (IVRPSolution<?>) novoa.getMsa().getCurrentSolution(); timer.stop(); p = (100f * mProgress) / mTotalRuns; log = new StringBuilder(); log.append("-------------------------------------"); log.append(String.format("\n Instance: %s run #%s (%s) %.2f (etc: %s) %s", novoa .getInstance().getName(), getRun(), Thread.currentThread().getName(), p, Utilities.Time.millisecondsToString(expectedTime, 3, false, false), new Date(System.currentTimeMillis()))); log.append(String.format("\n > Comment : %s", comment)); log.append(String.format("\n > Run Time: %smin (status: %s)", timer.readTimeS() / 60, novoa.getStatusString())); log.append(String.format("\n > Solution: %s", solution)); log.append(String.format("\n > PerfInf : %s (gap: %.2f)", perfInf, (solution.getCost() - perfInf) / perfInf * 100)); log.append(String.format("\n > Feasible: %s", mChecker.checkSolution(solution))); // Free memory if (!completed) { if (attempts < sAttemps) log.append(String.format("\n > SIMULATION FAILED, NEW ATTEMPT (%s/%s)", attempts, sAttemps)); else log.append(String.format( "\n > SIMULATION FAILED AFTER %s ATTEMPT(S), ABORTING ", attempts)); } log.append("\n-------------------------------------"); print(log.toString()); } collectStats(novoa, perfInf); if (completed) { synchronized (mRunList) { mRunList.remove(runInfo); } writePendingRuns(); } mProgress++; novoa = null; System.gc(); } @Override public String toString() { return String.format("NovoaRun: set:%s size:%s rep:%s cap:%s run:%s", getSet(), getSize(), getRep(), getCap(), getRun()); } } /** * A factory for creating NovoaBenchmarkThread objects. */ public static class NovoaBenchmarkThreadFactory implements ThreadFactory { /** The Thread id. */ private static int sThreadId = 0; /** The Group. */ private static ThreadGroup sGroup = new ThreadGroup(Thread.currentThread() .getThreadGroup(), "NovoaBenchmarks"); /* * (non-Javadoc) * @see java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable) */ @Override public Thread newThread(Runnable r) { sThreadId++; ThreadGroup group = new ThreadGroup(sGroup, String.format("BenchGroup-" + sThreadId, sThreadId)); return new Thread(group, r, "BenchThread-" + sThreadId); } } /** * <code>NovoaBenchmarkParameters</code> encapsulate information about a particular set of runs. */ public static class NovoaBenchmarkSettings { protected final MSAGlobalParameters mGlobalParameters; protected final String mComment; public NovoaBenchmarkSettings(MSAGlobalParameters globalParameters, String comment) { super(); mGlobalParameters = globalParameters; mComment = comment; } } /** The default logger layout. */ public static Layout DEFAULT_LOGGER_LAYOUT = new PatternLayout( "%d{dd/MM HH:mm:ss} %-15c %-5p [%-10t] : %m%n"); /** * Gets the default parameters from file {@link #sDefaultsFile} * * @return the default parameters */ public static MSAGlobalParameters getDefaultParameters() { VRPParameterKeys.registerRequiredParameters(); MSAGlobalParameters params = new MSAGlobalParameters(); try { params.loadParameters(new File(sDefaultsFile)); } catch (Exception e) { getLogger().exception( "NovoaBenchmarking.getDefaultParameters, loading defaults defined in NovoaRun", e); params = new MSAGlobalParameters(); NovoaRun.loadDefaultParameters(params); } return params; } /** * Creates a unique first seed from the given parameters. * * @param run * max value: 1000 * @param size * max value 200 * @param rep * max value 5 * @param cap * max value 2 * @param set * max value 2 * @return a unique first seed for the given parameters */ public static long getFirstSeed(int run, int size, int rep, int cap, int set) { int lset = 1; int lsize = 0; int hsize = 200; int lrep = 1; int hrep = 5; int lcap = 0; int hcap = 2; int lrun = 0; int hrun = 10000; long firstSeed = set - lset; firstSeed *= hsize - lsize + 1; firstSeed += size - lsize; firstSeed *= hrep - lrep + 1; firstSeed += rep - lrep; firstSeed *= hcap - lcap + 1; firstSeed += cap - lcap; firstSeed *= hrun - lrun + 1; firstSeed += run - lrun; // Check if the seed is valid if (firstSeed > MSABase.MAX_LAST_SEEDS - 6) { MSALogging .getSetupLogger() .warn("NovoaBenchmarking.getFirstSeed first seed is greater than the limit defined for MRG32ka (%s>%s)", firstSeed, MSABase.MAX_LAST_SEEDS - 6); } // Use modulo operation to prevent exception in SSJ return (firstSeed * 6l) % (MSABase.MAX_LAST_SEEDS - 6l); // return firstSeed * 6l; } /** * Creates a set of seeds from the given parameters. * * @param run * max value: 1000 * @param size * max value 200 * @param rep * max value 5 * @param cap * max value 2 * @param set * max value 2 * @return a set of seeds from the given parameters * @see #getFirstSeed(int, int, int, int, int) */ public static long[] getSeeds(int run, int size, int rep, int cap, int set) { long seed = getFirstSeed(run, size, rep, cap, set); return new long[] { seed, seed + 1, seed + 2, seed + 3, seed + 4, seed + 5 }; } /** * @param run * @param size * @param rep * @param cap * @param set * @return */ public static String getInstanceCode(int run, int size, int rep, int cap, int set) { return getInstanceCode(run, size, rep, cap, set, sDistribution); } /** * @param run * @param size * @param rep * @param cap * @param set * @param distribution * @return */ public static String getInstanceCode(int run, int size, int rep, int cap, int set, DemandDistribution distribution) { String base = String.format("%sc%s-%s", NovoaPersistenceHelper.getInstanceName(size, set, rep).replaceFirst(".dat", ""), NovoaPersistenceHelper.getCapacity(size, set, cap), run); if (distribution == DemandDistribution.UNIFORM) { return base; } else { return String.format("%s-%s", base, distribution.toString().substring(0, 2)); } } /** * The main method. * * @param args * <ul> * <li>-e [sizes] [sets] nruns</li> * <li>-f instance_file</li> * <li>-i configuration_file</li> * <li>-t number_of_threads</li> * <li>-c file_comment</li> * <li>-d distribution [UNIFORM,NORMAL]</li> * </ul> * @see NovoaRun#NovoaRun(int, int, int, int, long[]) */ public static void main(String[] args) { VRPParameterKeys.registerRequiredParameters(); LoggerHelper.setupRootLogger(LoggerHelper.LEVEL_ERROR, LoggerHelper.LEVEL_ERROR, false); LinkedList<NovoaBenchmarkSettings> settings = new LinkedList<NovoaBenchmarkSettings>(); MSAGlobalParameters p = getDefaultParameters(); p.set(MSAGlobalParameters.SOLUTION_BUILDER_CLASS, VRPSDConsensus.class); settings.add(new NovoaBenchmarkSettings(p, "C")); // p = getDefaultParameters(); // p.set(MSAGlobalParameters.SOLUTION_BUILDER_CLASS, // VRPSDSmartConsensus.class); // settings.add(new NovoaBenchmarkSettings(p, "SmartC")); Runtime.getRuntime().availableProcessors(); NovoaBenchmarking benchmark = null; String comment = "na"; String benchFile = null, configFiles = null; int[] sizes = null; int[] sets = null; int nRuns = -1, nThreads = Runtime.getRuntime().availableProcessors(); int i = 0; try { while (i < args.length) { // A benchmark file is used if (args[i].equals("-f") && i < args.length - 1) { i++; benchFile = args[i++]; } // Explicit runs definition else if (args[i].equals("-e") && i < args.length - 3) { i++; sizes = vroom.common.utilities.Utilities.toIntArray(args[i++]); sets = vroom.common.utilities.Utilities.toIntArray(args[i++]); nRuns = Integer.parseInt(args[i++]); } // Configuration files else if (args[i].equals("-i") && i < args.length - 1) { i++; configFiles = args[i++]; } // Number of threads else if (args[i].equals("-t") && i < args.length - 1) { i++; nThreads = Integer.parseInt(args[i++]); } // Comment else if (args[i].equals("-c") && i < args.length - 1) { i++; comment = args[i++]; } // Distribution else if (args[i].equals("-d") && i < args.length - 1) { i++; sDistribution = DemandDistribution.valueOf(args[i++]); } // Time limit else if (args[i].equals("-l") && i < args.length - 1) { i++; sRunTimeLimit = Integer.parseInt(args[i++]); } else { i++; } } } catch (NumberFormatException e) { System.out.println("Wrong arguments"); printUsage(); System.exit(1); } // Configuration files if (configFiles != null) { settings.clear(); if (configFiles.startsWith("[")) { String[] files = configFiles.replaceAll("[", "").replaceAll("]", "").split(","); for (String f : files) { System.out.print(" Loading configuration file " + f); MSAGlobalParameters params = getDefaultParameters(); try { File configFile = new File(f); params.loadParameters(configFile); settings.add(new NovoaBenchmarkSettings(params, f)); System.out.printf(" : OK\n"); } catch (Exception e) { System.out.printf(" : EROOR - %s\n", e.getClass().getSimpleName()); getLogger().exception("NovoaBenchmarking.main", e); } } } else { MSAGlobalParameters params = getDefaultParameters(); try { System.out.print(" Loading configuration file " + configFiles); params.loadParameters(new File(configFiles)); Object o = params.get(VRPParameterKeys.ACTUAL_REQUEST_CLASS); System.out.println(o); settings.add(new NovoaBenchmarkSettings(params, configFiles)); System.out.printf(" : OK\n"); o = params.get(VRPParameterKeys.ACTUAL_REQUEST_CLASS); System.out.println(o); } catch (Exception e) { System.out.printf(" : EROOR - %s\n", e.getClass().getSimpleName()); getLogger().exception("NovoaBenchmarking.main", e); System.exit(1); } } } else { } // Benchmark file if (benchFile != null) { try { System.out.println(" Loading benchmark file " + benchFile); benchmark = new NovoaBenchmarking(benchFile, comment, settings); } catch (IOException e) { getLogger().exception("NovoaBenchmarking.main", e); } } // Explicit definition else if (sizes != null) { try { System.out.printf(" Benchmarks: sets:%s sizes:%s nRuns:%s", Arrays.toString(sets), Arrays.toString(sizes), nRuns); benchmark = new NovoaBenchmarking(sizes, sets, nRuns, comment, settings); } catch (IOException e) { getLogger().exception("NovoaBenchmarking.main", e); } } else { System.out.println("Wrong arguments"); printUsage(); } if (benchmark != null) { benchmark.mThreadCount = Math.min(nThreads, Runtime.getRuntime().availableProcessors()); benchmark.run(); } else { System.exit(1); } } /** * Prints the main method usage (argument list) */ private static void printUsage() { System.out.println("Arguments: "); System.out.println(" At one of the two:"); System.out.println(" -f benchFile : benchmark file"); System.out.println(" -e [sizes] [sets] nruns : benchmark definitions"); System.out.println(" Optional:"); System.out.println(" -i configFile : configuration file"); System.out.println(" -t num : number of threads"); System.out.println(" -c comment : comment for the log/stats files"); System.out.println(" -d distribution : demand distribution [NORMAL,UNIFORM]"); } /** * Print a message * * @param format * the format * @param args * the args */ protected static void print(String format, Object... args) { String string = String.format(format, args); System.out.println(string); } /** The Progress. */ private int mTotalRuns, mProgress; /** The Timer. */ private final Stopwatch mTimer; /** * The string that will be used to create the output file path: <br/> * <code>"%1$s/stats_%2$ty%2$tm%2$td_%2$tk-%2$tM.csv"</code> which will be converted to: <br/> * <code>outputPath/stats_yymmdd_hh-mm.csv</code> */ public static final String OUTPUT_FILE_FORMAT_STRING = "%1$s/%2$s_stats-%3$s.csv"; /** * The string that will be used to create the pending run file: <br/> * <code>"%1$s/stats_%2$ty%2$tm%2$td_%2$tk-%2$tM.csv"</code> which will be converted to: <br/> * <code>data/pending_yymmdd_hh-mm.csv</code> */ public static final String PENDING_FILE_FORMAT_STRING = "%1$s/%2$s_pending-%3$s.csv"; /** The Constant LABELS. */ public static final Label<?>[] LABELS = new Label<?>[] { new Label<Integer>("run_id", Integer.class), new Label<String>("instance_name", String.class), new Label<Integer>("size", Integer.class), new Label<Integer>("vehicle_capacity", Integer.class), new Label<Double>("running_time", Double.class), new Label<Double>("cost", Double.class), new Label<Double>("perf_inf", Double.class), new Label<Integer>("failures", Integer.class), new Label<Double>("speed", Double.class), new Label<String>("comment", String.class), new Label<String>("seeds", String.class), new Label<String>("status", String.class), new Label<Double>("gap_pi", Double.class) }; /** The Stats collector. */ private final StatCollector mStatsCollector; /** The Stat file. */ private final String mStatFile; /** The Constant STAT_FILES_PATH. */ public static final String STAT_FILES_PATH = "./results"; /** The Constant LOG_FILES_PATH. */ public static final String LOG_FILES_PATH = "./log"; /** The number of threads used in the benchmarks. */ private int mThreadCount = Runtime .getRuntime() .availableProcessors(); /** <code>true</code> if the running times should be shortened. */ public static boolean sFastRun = false; /** * <code>true</code> if an exact algorithm should be run to compare with perfect information. */ public static boolean sComparePerfInf = true; /** A time limit for the perfect information solver. */ public static int sPerfInfTimeLimit = 300; /** * The string that will be used to create the log file path: <br/> * <code>"%1$s/stats_%2$ty%2$tm%2$td_%2$tk-%2$tM.csv"</code> wich will be converted to: <br/> * <code>outputPath/stats_yymmdd_hh-mm.csv</code> */ public static final String LOG_FILE_FORMAT_STRING = "%1$s/%2$s_log-%3$s.log"; /** The Constant ERR_FILE_FORMAT_STRING. */ public static final String ERR_FILE_FORMAT_STRING = "%1$s/%2$s_errors-%3$s.log"; /** The Checker. */ private final SolutionChecker mChecker = new SolutionChecker(); /** The Perf inf. */ private final PerfectInformationSolver mPerfInf; /** The Executor. */ private ExecutorService mExecutor; /** The err. */ private final LogPrintStream out, err; /** The Run list. */ private final LinkedList<Integer[]> mRunList; /** The file containing a list of pending runs */ private final File mPendingFile; private final List<NovoaBenchmarkSettings> mSettings; /** * Sets the number of thread used for benchmarking * * @param threadCount */ public void setThreadCount(int threadCount) { mThreadCount = threadCount; } /** * Gets the thread count. * * @return the number of thread used for benchmarking */ public int getThreadCount() { return mThreadCount; } /** * Instantiates a new novoa benchmarking. * * @param benchFile * the bench file containing the run information * @param fileComment * the file comment * @param settings * a list of settings for the benchmarks * @throws IOException * Signals that an I/O exception has occurred. */ public NovoaBenchmarking(String benchFile, String fileComment, List<NovoaBenchmarkSettings> settings) throws IOException { this(fileComment, settings); BufferedReader in = new BufferedReader(new FileReader(benchFile)); // Skip first line (headers) String line = in.readLine(); line = in.readLine(); int lineId = 1; while (line != null) { line = line.replaceAll("\\s*", ""); String[] runInfo = line.split(";|,|\\s"); if (runInfo.length != 5) { in.close(); throw new IOException( String.format( "Error while parsing line %s, should be in format run,set,size,rep,cap (%s)", lineId, line)); } int set = Integer.valueOf(runInfo[1]); int size = Integer.valueOf(runInfo[2]); int cap = Integer.valueOf(runInfo[4]); cap = NovoaPersistenceHelper.getCapacityIdx(size, set, cap); mRunList.add(new Integer[] { Integer.valueOf(runInfo[0]), set, size, Integer.valueOf(runInfo[3]), cap }); line = in.readLine(); lineId++; } in.close(); writePendingRuns(); } /** * Instantiates a new novoa benchmarking. * * @param sizes * the sizes * @param sets * the sets * @param numRuns * the num runs * @param fileComment * the file comment * @param settings * a list of settings for the benchmarks * @throws IOException * Signals that an I/O exception has occurred. */ public NovoaBenchmarking(int[] sizes, int[] sets, int numRuns, String fileComment, List<NovoaBenchmarkSettings> settings) throws IOException { this(fileComment, settings); for (int set : sets) { for (int size : sizes) { for (int cap = 0; cap < 2; cap++) { for (int num = 1; num <= 5; num++) { for (int run = 0; run < numRuns; run++) { mRunList.add(new Integer[] { run, set, size, num, cap }); } } } } } writePendingRuns(); } /** * Instantiates a new novoa benchmarking. * * @param fileComment * the file comment * @throws IOException * Signals that an I/O exception has occurred. */ protected NovoaBenchmarking(String fileComment, List<NovoaBenchmarkSettings> settings) throws IOException { LoggerHelper.DEFAULT_CONSOLE_LAYOUT = DEFAULT_LOGGER_LAYOUT; @SuppressWarnings({ "unchecked", "rawtypes" }) MSABase msa = new MSASequential(null, getDefaultParameters()); String comment = String.format("Date: %s\nDemand distribution: %s\nMSA:\n%s\n\n", new Date( System.currentTimeMillis()), sDistribution, msa.getComponentsDescription()); print(comment); String date = String.format("%1$ty%1$tm%1$td_%1$tk-%1$tM", new Date(System.currentTimeMillis())); mStatFile = String.format(OUTPUT_FILE_FORMAT_STRING, STAT_FILES_PATH, date, fileComment); mStatsCollector = new StatCollector(new File(mStatFile), true, false, comment, LABELS); out = new LogPrintStream(new File(String.format(LOG_FILE_FORMAT_STRING, LOG_FILES_PATH, date, fileComment)), System.out); err = new LogPrintStream(new File(String.format(ERR_FILE_FORMAT_STRING, LOG_FILES_PATH, date, fileComment)), System.err); System.setOut(out); System.setErr(err); mPerfInf = new PerfectInformationSolver(); mTimer = new Stopwatch(); mRunList = new LinkedList<Integer[]>(); mPendingFile = new File(String.format(PENDING_FILE_FORMAT_STRING, STAT_FILES_PATH, date, fileComment)); mSettings = settings; setupLoggers(); } /** * Write the list of pending runs in a file */ private synchronized void writePendingRuns() { try { BufferedWriter out = new BufferedWriter(new FileWriter(mPendingFile, false)); out.write("run;set;size;rep;cap\n"); synchronized (mRunList) { for (Integer[] run : mRunList) { out.write(String.format("%s;%s;%s;%s;%s\n", run[0], run[1], run[2], run[3], NovoaPersistenceHelper.getCapacity(run[2], run[1], run[4]))); } } out.flush(); out.close(); } catch (IOException e) { getLogger().exception("NovoaBenchmarking.writePendingRuns", e); } } /* * (non-Javadoc) * @see java.lang.Runnable#run() */ @Override public void run() { print("#=====================================#"); print("# Running Novoa Benchmarks #"); print("#=====================================#"); print(" Output file : " + mStatFile); print(" Pending file : " + mPendingFile); print(" Threads : %s on %s available processors", mThreadCount, Runtime.getRuntime() .availableProcessors()); print(" Max memory : %sm", Runtime.getRuntime().maxMemory() / (1024 * 1024)); print(" # Runs : %s", mRunList.size() * mSettings.size()); print("#=====================================#"); mTimer.start(); mTotalRuns = mRunList.size() * mSettings.size(); // mExecutor = Executors.newFixedThreadPool(getThreadCount(), new // NovoaBenchmarkThreadFactory()); mExecutor = Executors.newFixedThreadPool(1, new NovoaBenchmarkThreadFactory()); for (Integer[] run : mRunList) { for (NovoaBenchmarkSettings s : mSettings) { s.mGlobalParameters.set(MSAGlobalParameters.MAX_THREADS, getThreadCount()); s.mGlobalParameters.set(MSAGlobalParameters.MIN_THREADS, getThreadCount()); mExecutor.execute(new BenchmarkRun(run, s.mGlobalParameters, s.mComment)); } } mExecutor.shutdown(); synchronized (this) { try { this.wait(1000); } catch (InterruptedException e) { getLogger().exception("NovoaBenchmarking.run", e); } } print("Active Threads:"); Thread[] activeThreads = new Thread[Thread.currentThread().getThreadGroup().activeCount() + 5]; Thread.enumerate(activeThreads); for (Thread thread : activeThreads) { if (thread != null) { print("[%s] \t %s", thread.getThreadGroup().getName(), thread.getName()); } } try { mExecutor.awaitTermination(365, TimeUnit.DAYS); CallbackStack.stopAllThreads(); mTimer.stop(); print("#=====================================#"); print("# FINISHED #"); print("#=====================================#"); print("# Running time:%s", mTimer.readTimeString()); print(" Waiting 60sec for callbacks to finish"); CallbackStack.stopAllThreads(); // Wait 1 minute for the callbacks to finish synchronized (this) { try { this.wait(60000); // Force the VM to stop System.exit(0); } catch (InterruptedException e) { getLogger().exception("NovoaBenchmarking.run", e); } } } catch (InterruptedException e) { getLogger().exception("NovoaBenchmarking.run", e); } System.err.println("MSA Procedure did not terminated as expected"); System.exit(1); } /** * Setup the main loggers for Novoa benchmarking routine. */ public void setupLoggers() { LoggerHelper.setupRootLogger(LoggerHelper.LEVEL_WARN, LoggerHelper.LEVEL_WARN, true); // Configuring loggers Logger.getRootLogger().setLevel(LoggerHelper.LEVEL_WARN); // MSA MSALogging.getBaseLogger().setLevel(LoggerHelper.LEVEL_WARN); // CW CWLogging.getBaseLogger().setLevel(LoggerHelper.LEVEL_WARN); // VLS VLSLogging.getBaseLogger().setLevel(LoggerHelper.LEVEL_WARN); // Heuristics HeuristicsLogging.getBaseLogger().setLevel(LoggerHelper.LEVEL_WARN); WriterAppender logAppender = new WriterAppender(DEFAULT_LOGGER_LAYOUT, err); logAppender.setThreshold(LoggerHelper.LEVEL_WARN); logAppender.setImmediateFlush(true); Logger.getRootLogger().removeAllAppenders(); Logger.getRootLogger().addAppender(logAppender); } }