co.turnus.analysis.buffers.MpcBoundedSchedulingCliLauncher.java Source code

Java tutorial

Introduction

Here is the source code for co.turnus.analysis.buffers.MpcBoundedSchedulingCliLauncher.java

Source

/* 
 * 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;
    }

}