123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- package de.tu_darmstadt.informatik.tk.scopviz.metrics;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileReader;
- import java.util.Arrays;
- import java.util.LinkedList;
- import java.util.stream.Collectors;
- import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug;
- import de.tu_darmstadt.informatik.tk.scopviz.graphs.MappingGraphManager;
- import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyEdge;
- import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph;
- import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyNode;
- import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
- import de.tu_darmstadt.informatik.tk.scopviz.metrics.interfaces.ScopvizGraphMetric;
- import javafx.stage.FileChooser;
- import javafx.util.Pair;
- /**
- * Class to compute the placement cost Metric. Placement Cost is defined as the
- * sum of the costs of individual mapping placements. These Costs are specified
- * in operator node - underlay node pairs and are loaded from an external file
- * during setup.
- *
- * @author Jan Enders
- * @version 1.0
- *
- */
- public class PlacementCostMetric implements ScopvizGraphMetric {
- /**
- * The prefix used to mark the line containing all the relevant operator
- * node IDs.
- */
- private static final String OPERATOR_ID_PREFIX = "operatorIDs:";
- /**
- * The Prefix used to mark the line containing all the relevant underlay
- * node IDs.
- */
- private static final String UNDERLAY_ID_PREFIX = "underlayIDs:";
- /** The text to display in case of an error during computation. */
- private static final Pair<String, String> ERROR_MESSAGE = new Pair<String, String>("Error",
- "ERROR: check Debug logs");
- /** The text to display if the Setup has not yet been done. */
- private static final Pair<String, String> SETUP_NEEDED = new Pair<String, String>("Setup required!",
- "Setup required!");
- /** The Cost Matrix. */
- private double[][] costs;
- /** The operator node IDs specified in the cost data. */
- private LinkedList<String> operatorIDs = new LinkedList<String>();
- /** The underlay node IDs specified in the cost data. */
- private LinkedList<String> underlayIDs = new LinkedList<String>();
- /** Whether or not the Setup has been done yet. */
- private boolean setupDone = false;
- /** Flag for when an error occurs during computation */
- private boolean error = false;
- @Override
- public boolean isSetupRequired() {
- return true;
- }
- @Override
- public String getName() {
- return "Placement Cost";
- }
- @Override
- public void setup() {
- // Pick File from File Chooser
- FileChooser fileChooser = new FileChooser();
- fileChooser.setTitle("Select Placement Cost Data");
- File file = fileChooser.showOpenDialog(Main.getInstance().getPrimaryStage());
- if (file != null) {
- String fileName = file.getPath();
- try {
- // Read File Line by Line
- BufferedReader reader = new BufferedReader(new FileReader(fileName));
- String line;
- int lineCounter = 0;
- while ((line = reader.readLine()) != null) {
- lineCounter = processLine(line, lineCounter);
- }
- reader.close();
- setupDone = true;
- } catch (Exception e) {
- Debug.out("ERROR while trying to read File!");
- error = true;
- }
- }
- }
- @Override
- public LinkedList<Pair<String, String>> calculate(MyGraph g) {
- LinkedList<Pair<String, String>> results = new LinkedList<Pair<String, String>>();
- double placementCostSum = 0;
- // If an Error occurred, show error message
- if (error) {
- results.add(ERROR_MESSAGE);
- error = false;
- }
- // If Setup has not yet been successfully done, show error message
- if (!setupDone) {
- results.add(SETUP_NEEDED);
- } else {
- LinkedList<MyEdge> mappingEdges = new LinkedList<MyEdge>(g.<MyEdge>getEdgeSet().stream()
- .filter(e -> (((Boolean) e.getAttribute(MappingGraphManager.ATTRIBUTE_KEY_MAPPING)) == true))
- .collect(Collectors.toList()));
- for (MyEdge e : mappingEdges) {
- placementCostSum += placementCost(e.getNode0(), e.getNode1());
- }
- results.add(new Pair<String, String>("Overall Cost", "" + placementCostSum));
- }
- return results;
- }
- /**
- * Processes a single line of the input Data.
- *
- * @param line
- * The line to process
- * @param lineCounter
- * The counter of actual lines that has been read so far
- * @return the possibly increased line counter
- */
- private int processLine(String line, int lineCounter) {
- // Discard Comments and empty lines
- if (line.startsWith("%") || line.equals("")) {
- return lineCounter;
- }
- // Read Operator Node ID list
- if (line.startsWith(OPERATOR_ID_PREFIX)) {
- operatorIDs = new LinkedList<String>();
- String data = line.substring(OPERATOR_ID_PREFIX.length()).trim();
- String[] opIDs = data.split(",");
- for (String s : opIDs) {
- operatorIDs.add(s.trim());
- }
- // Read Underlay Node ID list
- } else if (line.startsWith(UNDERLAY_ID_PREFIX)) {
- underlayIDs = new LinkedList<String>();
- String data = line.substring(UNDERLAY_ID_PREFIX.length()).trim();
- String[] ulIDs = data.split(",");
- for (String s : ulIDs) {
- underlayIDs.add(s.trim());
- }
- } else {
- // When both lists have been read, create cost array with correct
- // size
- if (lineCounter == 2) {
- costs = new double[operatorIDs.size()][underlayIDs.size()];
- }
- // Parse comma separated data
- int dataRow = lineCounter - 2;
- String[] data = line.split(",");
- double[] convertedData = Arrays.asList(data).stream().mapToDouble(s -> Double.parseDouble(s)).toArray();
- costs[dataRow] = Arrays.copyOf(convertedData, costs[dataRow].length);
- }
- return lineCounter + 1;
- }
- /**
- * Fethes the placement cost of a specific Coupling of Operator node and
- * Underlay Node.
- *
- * @param operator
- * The Operator node
- * @param target
- * The Underlay node it is mapped to
- * @return The placement cost
- */
- private double placementCost(MyNode operator, MyNode target) {
- if (costs == null) {
- Debug.out(
- "Tried to read Costs from nonexistant Cost Matrix. Please run Setup before trying to Compute the Metric!");
- error = true;
- return 0;
- }
- String operatorID = operator.getId().substring(MappingGraphManager.OPERATOR.length()).trim();
- String underlayID = target.getId().substring(MappingGraphManager.UNDERLAY.length()).trim();
- int x = operatorIDs.indexOf(operatorID);
- int y = underlayIDs.indexOf(underlayID);
- if (x < 0 || y < 0) {
- Debug.out("Either operator node ID " + operatorID + " or underlay node ID " + underlayID
- + " do not exist in the cost data!");
- error = true;
- return 0;
- }
- return costs[x][y];
- }
- }
|