CommunicationCostMetric.java 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package de.tu_darmstadt.informatik.tk.scopviz.metrics;
  2. import java.util.LinkedList;
  3. import java.util.stream.Collectors;
  4. import org.graphstream.algorithm.Dijkstra;
  5. import org.graphstream.algorithm.Toolkit;
  6. import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug;
  7. import de.tu_darmstadt.informatik.tk.scopviz.graphs.MappingGraphManager;
  8. import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyEdge;
  9. import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph;
  10. import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyNode;
  11. import de.tu_darmstadt.informatik.tk.scopviz.metrics.interfaces.ScopvizGraphMetric;
  12. import javafx.util.Pair;
  13. /**
  14. * Class to compute the communication cost metric. The Metric is defined as the
  15. * sum of the network traversal costs for each hop in the longest path in the
  16. * operator graph. wARNING: This might not work fully as intended with multiple
  17. * Operator graphs!
  18. *
  19. * @author Jan Enders
  20. * @version 0.9
  21. *
  22. */
  23. // TODO: make this work well with multiple operator graphs
  24. public class CommunicationCostMetric implements ScopvizGraphMetric {
  25. /**
  26. * Message to show if not all Operator nodes have been placed onto the
  27. * underlay
  28. */
  29. private static final Pair<String, String> ERROR_MESSAGE = new Pair<String, String>("Warning",
  30. "Not all Nodes have a valid Mapping");
  31. /** Flag for when an error occurs during computation. */
  32. // TODO: this is not yet being used for output and never reset
  33. private boolean error = false;
  34. @Override
  35. public boolean isSetupRequired() {
  36. return false;
  37. }
  38. @Override
  39. public String getName() {
  40. return "Communication Cost";
  41. }
  42. @Override
  43. public void setup() {
  44. // No Setup required.
  45. }
  46. @Override
  47. public LinkedList<Pair<String, String>> calculate(MyGraph g) {
  48. LinkedList<Pair<String, String>> results = new LinkedList<Pair<String, String>>();
  49. if (error) {
  50. error = false;
  51. results.add(ERROR_MESSAGE);
  52. }
  53. MyGraph operator = new MyGraph("opWithTime");
  54. for (MyNode n : g.<MyNode>getNodeSet()) {
  55. if (n.getAttribute(MappingGraphManager.ATTRIBUTE_KEY_MAPPING_PARENT) == MappingGraphManager.OPERATOR) {
  56. operator.addNode(n.getId());
  57. }
  58. }
  59. for (MyEdge e : g.<MyEdge>getEdgeSet()) {
  60. if (e.getAttribute(MappingGraphManager.ATTRIBUTE_KEY_MAPPING_PARENT) == MappingGraphManager.OPERATOR) {
  61. String newID = e.getId();
  62. double cost = computeCost(e.getNode0(), e.getNode1(), g);
  63. operator.addEdge(newID, e.getNode0().getId(), e.getNode1().getId(), true);
  64. operator.getEdge(newID).addAttribute("cost", cost);
  65. }
  66. }
  67. // TODO: not fully sure if the diameter Method does exactly what we
  68. // want, requires testing
  69. double communicationCost = Toolkit.diameter(operator, "cost", true);
  70. communicationCost = Math.round(communicationCost * 100) / 100;
  71. results.add(new Pair<String, String>("Overall Cost", "" + communicationCost));
  72. return results;
  73. }
  74. /**
  75. * Compute the Network traversal cost for the Communication between two
  76. * given operator nodes.
  77. *
  78. * @param n1
  79. * The first operator node
  80. * @param n2
  81. * The second operator node
  82. * @param g
  83. * the combined mapping graph
  84. * @return the cost
  85. */
  86. private double computeCost(MyNode n1, MyNode n2, MyGraph g) {
  87. double cost = 0;
  88. // find the underlay nodes that the operator nodes are mapped to
  89. LinkedList<MyEdge> mappingEdges = new LinkedList<MyEdge>(g.<MyEdge>getEdgeSet().stream()
  90. .filter(e -> (((Boolean) e.getAttribute(MappingGraphManager.ATTRIBUTE_KEY_MAPPING)) == true))
  91. .collect(Collectors.toList()));
  92. MyNode target1 = null;
  93. MyNode target2 = null;
  94. for (MyEdge e : mappingEdges) {
  95. if (e.getNode0() == n1) {
  96. target1 = e.getNode1();
  97. } else if (e.getNode0() == n2) {
  98. target2 = e.getNode1();
  99. }
  100. }
  101. // Error if not both operator nodes have a valid mapping
  102. if (target1 == null || target2 == null) {
  103. Debug.out("Could not find Mapping target for Operator Node " + n1.getId() + " or " + n2.getId());
  104. error = true;
  105. } else {
  106. // find shortest path between the two underlay nodes
  107. Dijkstra dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null, "weight");
  108. dijkstra.init(g);
  109. dijkstra.setSource(target1);
  110. dijkstra.compute();
  111. cost = dijkstra.getPathLength(target2);
  112. }
  113. return cost;
  114. }
  115. }