Java tutorial
/* * TURNUS, the co-exploration framework * * Copyright (C) 2014 EPFL SCI STI MM * * This file is part of TURNUS. * * TURNUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * TURNUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with TURNUS. If not, see <http://www.gnu.org/licenses/>. * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining it * with Eclipse (or a modified version of Eclipse or an Eclipse plugin or * an Eclipse library), containing parts covered by the terms of the * Eclipse Public License (EPL), the licensors of this Program grant you * additional permission to convey the resulting work. Corresponding Source * for a non-source form of such a combination shall include the source code * for the parts of Eclipse libraries used as well as that of the covered work. * */ package co.turnus.analysis.buffers; import static co.turnus.analysis.AnalysisOptions.BXDF; import static co.turnus.analysis.AnalysisOptions.OUTPUT_PATH; import static co.turnus.analysis.AnalysisOptions.TRACE_PROJECT; import static co.turnus.analysis.AnalysisOptions.VERBOSE; import static co.turnus.analysis.AnalysisOptions.XLS; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.BIT_ACCURATE; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.HC_MAX; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.HC_MIN; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.HC_NUM; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.QUICK_CUT; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.RECOVERY; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.TRACE_CUT_DEGREE_MAX; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.TRACE_CUT_DEGREE_MIN; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.TRACE_CUT_DEGREE_NUM; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.TRACE_CUT_STEPS_MAX; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.TRACE_CUT_STEPS_MIN; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.TRACE_CUT_STEPS_NUM; import static co.turnus.analysis.buffers.MpcBoundedSchedulingOptions.ZERO_STARTING_POINT; import java.io.File; import java.util.Date; import java.util.UUID; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.configuration.BaseConfiguration; import org.apache.commons.configuration.Configuration; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import co.turnus.TurnusExtension; import co.turnus.analysis.AnalysisActivator; import co.turnus.analysis.bottlenecks.AlgorithmicBottlenecksCliLauncher; import co.turnus.analysis.buffers.MpcBoundedScheduling; import co.turnus.analysis.data.DataFactory; import co.turnus.analysis.data.Report; import co.turnus.analysis.data.buffers.BufferMinimizationData; import co.turnus.analysis.data.buffers.io.XlsBufferMinimizationDataWriter; import co.turnus.analysis.data.buffers.io.XmlBufferMinimizationDataWriter; import co.turnus.trace.TraceProject; import co.turnus.util.EcoreHelper; import co.turnus.util.TurnusLogger; import co.turnus.util.TurnusLogger.TurnusLevel; /** * * @author Simone Casale-Brunet casalebrunet@ieee.org * @author Massimo Canale massimo.canale@polito.it * */ @SuppressWarnings("static-access") public class MpcBoundedSchedulingCliLauncher { private static final Options cliOptions = new Options(); static { cliOptions.addOption("t", true, "trace project directory"); cliOptions.addOption("o", true, "output root directory"); cliOptions.addOption("s", false, "scale the horizons cut according to the number of actors"); cliOptions.addOption("q", false, "use a quick cut approach for analysing the trace graph"); cliOptions.addOption("z", false, "use a zero starting point (all buffers set initially at zero)"); cliOptions.addOption("b", false, "bit accurate: use the number of bits instead the number of tokens"); cliOptions.addOption("xls", true, "xls report file name (without extension)"); cliOptions.addOption("bxdf", true, "bxdf file (without extension) generated for each configuration (with an id)"); cliOptions.addOption("v", false, "activate the logger verbosity: all messages from TURNUS are printed"); cliOptions.addOption("r", false, "use the mpc deadlock recovery mode instead of the avoidance mode"); cliOptions.addOption(OptionBuilder.withArgName("min> <points> <max").withValueSeparator(' ').hasArgs(3) .withDescription("maximum trace cut steps").create("s")); cliOptions.addOption(OptionBuilder.withArgName("min> <points> <max").withValueSeparator(' ').hasArgs(3) .withDescription("maximum trace cut degree").create("d")); cliOptions.addOption(OptionBuilder.withArgName("min> <points> <max").withValueSeparator(' ').hasArgs(3) .withDescription("control horizon").create("c")); } public static void main(String[] args) { try { CommandLineParser parser = new GnuParser(); CommandLine cmd = parser.parse(cliOptions, args); Configuration config = parseCommandLine(cmd); // init models AnalysisActivator.init(); // set logger verbosity if (config.getBoolean(VERBOSE, false)) { TurnusLogger.setLevel(TurnusLevel.ALL); } File tDir = new File(config.getString(TRACE_PROJECT)); TraceProject project = TraceProject.load(tDir); MpcBoundedScheduling mpc = new MpcBoundedScheduling(project); mpc.setConfiguration(config); BufferMinimizationData data = mpc.run(); TurnusLogger.info("Storing results..."); File outPath = new File(config.getString(OUTPUT_PATH)); // store the analysis report String uuid = UUID.randomUUID().toString(); File rFile = new File(outPath, uuid + "." + TurnusExtension.REPORT); Report report = DataFactory.eINSTANCE.createReport(); report.setDate(new Date()); report.setComment("Report with only Bounded Buffer Scheduling results analysis"); report.getDataSet().add(data); EcoreHelper.storeEObject(report, new ResourceSetImpl(), rFile); TurnusLogger.info("TURNUS report stored in " + rFile); // store formatted reports String xlsName = config.getString(XLS, ""); if (!xlsName.isEmpty()) { File xlsFile = new File(outPath, xlsName + ".xls"); new XlsBufferMinimizationDataWriter().write(data, xlsFile); TurnusLogger.info("XLS report stored in " + xlsFile); } String bxdfName = config.getString(BXDF, ""); if (!bxdfName.isEmpty()) { File bxdfFile = new File(outPath, bxdfName + ".bxdf"); new XmlBufferMinimizationDataWriter().write(data, bxdfFile); TurnusLogger.info("BXDF files (one for each configuration) " + "stored in " + outPath); } TurnusLogger.info("Analysis Done!"); } catch (ParseException e) { TurnusLogger.error(e.getMessage()); HelpFormatter formatter = new HelpFormatter(); formatter.printHelp(AlgorithmicBottlenecksCliLauncher.class.getSimpleName(), cliOptions); } catch (Exception e) { TurnusLogger.error(e.getMessage()); } } private static Configuration parseCommandLine(CommandLine cmd) throws ParseException { Configuration config = new BaseConfiguration(); StringBuffer s = new StringBuffer(); config.setProperty(VERBOSE, cmd.hasOption("v")); if (!cmd.hasOption("t")) { s.append("Trace project directory not specified. "); } else { String fileName = cmd.getOptionValue("t", ""); File file = new File(fileName); if (file == null || !file.exists()) { s.append("Trace project does not exists. "); } else { config.setProperty(TRACE_PROJECT, fileName); } } if (!cmd.hasOption("o")) { s.append("Output directory not specified. "); } else { String fileName = cmd.getOptionValue("o", ""); File file = new File(fileName); if (file == null || !file.exists()) { s.append("Output directory does not exists. "); } else { config.setProperty(OUTPUT_PATH, fileName); } } if (cmd.hasOption("xls")) { String fileName = cmd.getOptionValue("xls", ""); if (fileName == null || fileName.isEmpty()) { s.append("XLS file name is not correct. "); } else { config.setProperty(XLS, fileName); } } if (cmd.hasOption("bxdf")) { String fileName = cmd.getOptionValue("bxdf", ""); if (fileName == null || fileName.isEmpty()) { s.append("BXDF file name is not correct. "); } else { config.setProperty(BXDF, fileName); } } if (!cmd.hasOption("s") && !cmd.hasOption("d")) { s.append("please choose at least one option for the trace cut (max steps or max degree) "); } if (cmd.hasOption("s")) { String[] sArray = cmd.getOptionValues("s"); if (sArray.length == 1) { int value = Integer.parseInt(sArray[0]); config.addProperty(TRACE_CUT_STEPS_MIN, value); config.addProperty(TRACE_CUT_STEPS_MAX, value); config.addProperty(TRACE_CUT_STEPS_NUM, 1); } else if (sArray.length == 2) { int min = Integer.parseInt(sArray[0]); int max = Integer.parseInt(sArray[1]); config.addProperty(TRACE_CUT_STEPS_MIN, min); config.addProperty(TRACE_CUT_STEPS_MAX, max); config.addProperty(TRACE_CUT_STEPS_NUM, max - min + 1); } else { int min = Integer.parseInt(sArray[0]); int points = Integer.parseInt(sArray[1]); int max = Integer.parseInt(sArray[2]); config.addProperty(TRACE_CUT_STEPS_MIN, min); config.addProperty(TRACE_CUT_STEPS_NUM, points); config.addProperty(TRACE_CUT_STEPS_MAX, max); } } if (cmd.hasOption("d")) { String[] sArray = cmd.getOptionValues("d"); if (sArray.length == 1) { int value = Integer.parseInt(sArray[0]); config.addProperty(TRACE_CUT_DEGREE_MIN, value); config.addProperty(TRACE_CUT_DEGREE_MAX, value); config.addProperty(TRACE_CUT_DEGREE_NUM, 1); } else if (sArray.length == 2) { int min = Integer.parseInt(sArray[0]); int max = Integer.parseInt(sArray[1]); config.addProperty(TRACE_CUT_DEGREE_MIN, min); config.addProperty(TRACE_CUT_DEGREE_MAX, max); config.addProperty(TRACE_CUT_DEGREE_NUM, max - min + 1); } else { int min = Integer.parseInt(sArray[0]); int points = Integer.parseInt(sArray[1]); int max = Integer.parseInt(sArray[2]); config.addProperty(TRACE_CUT_DEGREE_MIN, min); config.addProperty(TRACE_CUT_DEGREE_NUM, points); config.addProperty(TRACE_CUT_DEGREE_MAX, max); } } if (cmd.hasOption("c")) { String[] sArray = cmd.getOptionValues("c"); if (sArray.length == 1) { int value = Integer.parseInt(sArray[0]); config.addProperty(HC_MIN, value); config.addProperty(HC_MAX, value); config.addProperty(HC_NUM, 1); } else if (sArray.length == 2) { int min = Integer.parseInt(sArray[0]); int max = Integer.parseInt(sArray[1]); config.addProperty(HC_MIN, min); config.addProperty(HC_MAX, max); config.addProperty(HC_NUM, max - min + 1); } else { int min = Integer.parseInt(sArray[0]); int points = Integer.parseInt(sArray[1]); int max = Integer.parseInt(sArray[2]); config.addProperty(HC_MIN, min); config.addProperty(HC_NUM, points); config.addProperty(HC_MAX, max); } } else { s.append("the control horizon has not been choosed"); } boolean recovery = cmd.hasOption("r"); config.setProperty(RECOVERY, recovery); boolean bitAccurate = cmd.hasOption("b"); config.setProperty(BIT_ACCURATE, bitAccurate); boolean zeroStartingPoint = cmd.hasOption("z"); config.setProperty(ZERO_STARTING_POINT, zeroStartingPoint); boolean quickCut = cmd.hasOption("q"); config.setProperty(QUICK_CUT, quickCut); String error = s.toString(); if (!error.isEmpty()) { throw new ParseException(error); } return config; } }