Commit b7ee28b1 authored by Sebastian Vollbrecht's avatar Sebastian Vollbrecht

Some renaming, some code movements.

parent 4ab510cb
...@@ -17,9 +17,7 @@ ...@@ -17,9 +17,7 @@
package graphgen.generator.components.properties.infeasibleMinII; package graphgen.generator.components.properties.infeasibleMinII;
import graphgen.generator.components.properties.infeasibleMinII.configuration.InfeasibleConfiguration;
import graphgen.generator.components.properties.infeasibleMinII.configuration.StartConfiguration; import graphgen.generator.components.properties.infeasibleMinII.configuration.StartConfiguration;
import graphgen.generator.components.properties.infeasibleMinII.configuration.SuffixConfiguration;
import graphgen.graph.Resource; import graphgen.graph.Resource;
import graphgen.graph.ResourceNode; import graphgen.graph.ResourceNode;
import graphgen.util.JavaUtils; import graphgen.util.JavaUtils;
...@@ -30,7 +28,6 @@ import java.util.Map; ...@@ -30,7 +28,6 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.IntStream;
public class InfeasibilityInspector { public class InfeasibilityInspector {
...@@ -315,29 +312,4 @@ public class InfeasibilityInspector { ...@@ -315,29 +312,4 @@ public class InfeasibilityInspector {
return remainingDelays; return remainingDelays;
} }
public static Set<Integer> getProblematicTimeslots(StartConfiguration startCfg,
InfeasibleConfiguration infeasibleCfg,
SuffixConfiguration suffixCfg) {
Set<Integer> possibleTimeSlots = new HashSet<>();
ResourceNode destinationNode = Objects.requireNonNull(startCfg).getDestinationNode();
if (Objects.requireNonNull(infeasibleCfg).getProblematicNodes().contains(destinationNode)) {
possibleTimeSlots.add(0);
return possibleTimeSlots;
}
if (Objects.requireNonNull(suffixCfg).getSuffixNodes().isEmpty()) {
possibleTimeSlots.add(destinationNode.getDelay() + suffixCfg.getRemainingInnerDelay());
return possibleTimeSlots;
} else {
int firstSlot = destinationNode.getDelay();
int lastSlot = firstSlot + suffixCfg.getRemainingInnerDelay();
return JavaUtils.asSet(IntStream.rangeClosed(firstSlot, lastSlot).boxed());
}
}
} }
...@@ -38,8 +38,9 @@ import java.util.Optional; ...@@ -38,8 +38,9 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.IntStream;
public class InfeasibleEdgeInspector implements Initializable { public class InfeasibleCycleEdgePlanner implements Initializable {
private final StartConfiguration startCfg; private final StartConfiguration startCfg;
private final InfeasibleConfiguration infeasibleCfg; private final InfeasibleConfiguration infeasibleCfg;
...@@ -47,13 +48,36 @@ public class InfeasibleEdgeInspector implements Initializable { ...@@ -47,13 +48,36 @@ public class InfeasibleEdgeInspector implements Initializable {
private SeededRandom rng; private SeededRandom rng;
public InfeasibleEdgeInspector(StartConfiguration startCfg, InfeasibleConfiguration infeasibleCfg, public InfeasibleCycleEdgePlanner(StartConfiguration startCfg, InfeasibleConfiguration infeasibleCfg,
SuffixConfiguration suffixCfg) { SuffixConfiguration suffixCfg) {
this.startCfg = startCfg; this.startCfg = startCfg;
this.infeasibleCfg = infeasibleCfg; this.infeasibleCfg = infeasibleCfg;
this.suffixCfg = suffixCfg; this.suffixCfg = suffixCfg;
} }
public Set<Integer> getProblematicTimeslots() {
Set<Integer> possibleTimeSlots = new HashSet<>();
ResourceNode destinationNode = Objects.requireNonNull(startCfg).getDestinationNode();
if (Objects.requireNonNull(infeasibleCfg).getProblematicNodes().contains(destinationNode)) {
possibleTimeSlots.add(0);
return possibleTimeSlots;
}
if (Objects.requireNonNull(suffixCfg).getSuffixNodes().isEmpty()) {
possibleTimeSlots.add(destinationNode.getDelay() + suffixCfg.getRemainingInnerDelay());
return possibleTimeSlots;
} else {
int firstSlot = destinationNode.getDelay();
int lastSlot = firstSlot + suffixCfg.getRemainingInnerDelay();
return JavaUtils.asSet(IntStream.rangeClosed(firstSlot, lastSlot).boxed());
}
}
public Set<PlannedEdge> getIncomingEdges() { public Set<PlannedEdge> getIncomingEdges() {
Set<PlannedEdge> edges = new HashSet<>(); Set<PlannedEdge> edges = new HashSet<>();
...@@ -121,6 +145,19 @@ public class InfeasibleEdgeInspector implements Initializable { ...@@ -121,6 +145,19 @@ public class InfeasibleEdgeInspector implements Initializable {
} }
private static Set<ResourceNode> getPossiblePredecessors(ResourceNode node, StartConfiguration startCfg,
InfeasibleConfiguration infeasibleCfg) {
int nodeDepth = infeasibleCfg.getLayers().getDepth(node.getId());
if (nodeDepth == startCfg.getDestinationNodeLayer() + 1) {
return JavaUtils.asSet(startCfg.getDestinationNode());
} else {
return infeasibleCfg.getZeroNodesByLayer().get(nodeDepth - 1);
}
}
public Set<PlannedEdge> getOutgoingEdges(int problematicTimeslot, Predicate<ResourceNode> nodeNeedsOutgoingEdge, public Set<PlannedEdge> getOutgoingEdges(int problematicTimeslot, Predicate<ResourceNode> nodeNeedsOutgoingEdge,
BiFunction<ResourceNode, ResourceNode, Integer> delayComputer) { BiFunction<ResourceNode, ResourceNode, Integer> delayComputer) {
...@@ -196,6 +233,16 @@ public class InfeasibleEdgeInspector implements Initializable { ...@@ -196,6 +233,16 @@ public class InfeasibleEdgeInspector implements Initializable {
problematicEdges.add(new PlannedEdge(fixedNode, firstSuffixNode, edgeDelay, 0)); problematicEdges.add(new PlannedEdge(fixedNode, firstSuffixNode, edgeDelay, 0));
} else { } else {
/*
* A problematic node can only become a backedge source if its ASAP time plus
* its delay exactly matches the maximum inner delay. Otherwise the node would
* introduce slack which would destroy the infeasibility. We need to make sure
* that this does not happen.
*/
if (problematicTimeslot + fixedNode.getDelay() != startCfg.getMaxInnerDelay()) {
throw new IllegalStateException("Node " + fixedNode + " cannot be a backedge source node.");
}
suffixCfg.addBackedgeSource(fixedNode); suffixCfg.addBackedgeSource(fixedNode);
} }
} }
...@@ -345,20 +392,6 @@ public class InfeasibleEdgeInspector implements Initializable { ...@@ -345,20 +392,6 @@ public class InfeasibleEdgeInspector implements Initializable {
// Do nothing. // Do nothing.
} }
public static Set<ResourceNode> getPossiblePredecessors(ResourceNode node, StartConfiguration startCfg,
InfeasibleConfiguration infeasibleCfg) {
int nodeDepth = infeasibleCfg.getLayers().getDepth(node.getId());
if (nodeDepth == startCfg.getDestinationNodeLayer() + 1) {
return JavaUtils.asSet(startCfg.getDestinationNode());
} else {
return infeasibleCfg.getZeroNodesByLayer().get(nodeDepth - 1);
}
}
public static Map<ResourceNode, PlannedEdge> getIncomingEdgesMap(Set<PlannedEdge> edges, public static Map<ResourceNode, PlannedEdge> getIncomingEdgesMap(Set<PlannedEdge> edges,
Collection<ResourceNode> relevantNodes) { Collection<ResourceNode> relevantNodes) {
Map<ResourceNode, PlannedEdge> incomingEdgesByNode = new HashMap<>(); Map<ResourceNode, PlannedEdge> incomingEdgesByNode = new HashMap<>();
......
...@@ -31,14 +31,14 @@ import java.util.Objects; ...@@ -31,14 +31,14 @@ import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
public class InfeasibleNodePlacer implements Initializable { public class InfeasibleCycleNodePlacer implements Initializable {
private final StartConfiguration startCfg; private final StartConfiguration startCfg;
private final InfeasibleConfiguration infeasibleCfg; private final InfeasibleConfiguration infeasibleCfg;
private SeededRandom rng; private SeededRandom rng;
public InfeasibleNodePlacer(StartConfiguration startCfg, InfeasibleConfiguration infeasibleCfg) { public InfeasibleCycleNodePlacer(StartConfiguration startCfg, InfeasibleConfiguration infeasibleCfg) {
this.startCfg = startCfg; this.startCfg = startCfg;
this.infeasibleCfg = infeasibleCfg; this.infeasibleCfg = infeasibleCfg;
} }
......
...@@ -35,7 +35,6 @@ import java.util.Collections; ...@@ -35,7 +35,6 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
...@@ -93,7 +92,6 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -93,7 +92,6 @@ public class InfeasibleMinIIProperty extends Property {
*/ */
public InfeasibleMinIIProperty(int minII, int backedgeDelay, int backedgeDistance) { public InfeasibleMinIIProperty(int minII, int backedgeDelay, int backedgeDistance) {
// TODO: test MinII == 0
if (minII <= 0) { if (minII <= 0) {
throw new IllegalArgumentException("The MinII must be greater than zero."); throw new IllegalArgumentException("The MinII must be greater than zero.");
} }
...@@ -135,8 +133,7 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -135,8 +133,7 @@ public class InfeasibleMinIIProperty extends Property {
Set<Edge<ResourceNode>> tmpEdges = new HashSet<>(edgeCreator.edgeView()); Set<Edge<ResourceNode>> tmpEdges = new HashSet<>(edgeCreator.edgeView());
tmpEdges.add(new Edge<>(src, dst, delay, distance)); tmpEdges.add(new Edge<>(src, dst, delay, distance));
// TODO: test == instead of <= return SchedulingUtils.getRecMinII(nodes, tmpEdges) == minII;
return SchedulingUtils.getRecMinII(nodes, tmpEdges) <= minII;
} }
...@@ -162,19 +159,18 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -162,19 +159,18 @@ public class InfeasibleMinIIProperty extends Property {
SuffixConfiguration suffixCfg = chooseSuffixConfiguration(startCfg, infeasibleCfg); SuffixConfiguration suffixCfg = chooseSuffixConfiguration(startCfg, infeasibleCfg);
InfeasibleEdgeInspector edgeInspector = new InfeasibleEdgeInspector(startCfg, infeasibleCfg, suffixCfg);
edgeInspector.init(rng);
/* /*
* We need to create an incoming edge for all fixed nodes. The source node can * We need to create an incoming edge for all fixed nodes. The source node can
* either be the destination node or a zero node of the previous layer. * either be the destination node or a zero node of the previous layer.
* Also create an incoming edge for every suffix node. * Also create an incoming edge for every suffix node.
*/ */
Set<PlannedEdge> plannedEdges = edgeInspector.getIncomingEdges(); InfeasibleCycleEdgePlanner edgePlanner = new InfeasibleCycleEdgePlanner(startCfg, infeasibleCfg, suffixCfg);
edgePlanner.init(rng);
Set<PlannedEdge> plannedEdges = edgePlanner.getIncomingEdges();
/* Choose the timeslot of the problematic nodes (relative to the destination node). */ /* Choose the timeslot of the problematic nodes (relative to the destination node). */
Set<Integer> possibleTimeslots = InfeasibilityInspector Set<Integer> possibleTimeslots = edgePlanner.getProblematicTimeslots();
.getProblematicTimeslots(startCfg, infeasibleCfg, suffixCfg);
int problematicTimeslot = JavaUtils.pickRandomElement(possibleTimeslots, rng); int problematicTimeslot = JavaUtils.pickRandomElement(possibleTimeslots, rng);
/* /*
...@@ -182,17 +178,18 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -182,17 +178,18 @@ public class InfeasibleMinIIProperty extends Property {
* the chosen timeslot. The remaining inner delay will also be distributed over the * the chosen timeslot. The remaining inner delay will also be distributed over the
* non-problematic edges (e.g. the suffix edges). * non-problematic edges (e.g. the suffix edges).
*/ */
Optional<PlannedEdge> lastEdgeRepresentative = edgeInspector.distributeDelay(problematicTimeslot, plannedEdges); Optional<PlannedEdge> lastEdgeRepresentative = edgePlanner.distributeDelay(problematicTimeslot, plannedEdges);
/*
* Adjust the suffix nodes' offsets (i.e. ASAP-wise from the destination node)
* based on the freshly distributed delay of the edges among them. These are
* useful for the creation of the cycle's required outgoing edges below.
*/
if (lastEdgeRepresentative.isPresent()) { if (lastEdgeRepresentative.isPresent()) {
Map<ResourceNode, PlannedEdge> outgoingEdgesByNode = InfeasibleEdgeInspector Map<ResourceNode, PlannedEdge> outgoingEdgesByNode = InfeasibleCycleEdgePlanner
.getOutgoingEdgesMap(plannedEdges, suffixCfg.getSuffixNodes()); .getOutgoingEdgesMap(plannedEdges, suffixCfg.getSuffixNodes());
/*
* Adjust the suffix nodes' offsets (i.e. ASAP-wise from the destination node)
* based on the freshly distributed delay of the edges among them.
*/
int firstSuffixSlot = problematicTimeslot + infeasibleCfg int firstSuffixSlot = problematicTimeslot + infeasibleCfg
.getProblematicResource().delay + lastEdgeRepresentative.get().delay; .getProblematicResource().delay + lastEdgeRepresentative.get().delay;
suffixCfg.setInitialOffset(firstSuffixSlot); suffixCfg.setInitialOffset(firstSuffixSlot);
...@@ -207,12 +204,11 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -207,12 +204,11 @@ public class InfeasibleMinIIProperty extends Property {
* Create the required outgoing edges. * Create the required outgoing edges.
* Note that there is no need to create edges for problematic nodes which have * Note that there is no need to create edges for problematic nodes which have
* been connected to other nodes already (this can happen if they are zero * been connected to other nodes already (this can happen if they are zero
* nodes themselves) or which will be used as backedge sources. * nodes themselves).
*/ */
Predicate<ResourceNode> nodeNeedsOutgoingEdge = n -> plannedEdges.stream() Predicate<ResourceNode> needsOutgoingEdge = n -> plannedEdges.stream().noneMatch(e -> e.src == n);
.noneMatch(e -> e.src == n && e.distance == 0) && !suffixCfg.getBackedgeSources().contains(n); Set<PlannedEdge> outgoingEdges = edgePlanner
Set<PlannedEdge> outgoingEdges = edgeInspector .getOutgoingEdges(problematicTimeslot, needsOutgoingEdge, edgeCreator::computeEdgeDelay);
.getOutgoingEdges(problematicTimeslot, nodeNeedsOutgoingEdge, edgeCreator::computeEdgeDelay);
plannedEdges.addAll(outgoingEdges); plannedEdges.addAll(outgoingEdges);
/* /*
...@@ -221,8 +217,8 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -221,8 +217,8 @@ public class InfeasibleMinIIProperty extends Property {
plannedEdges.forEach(e -> edgeCreator.createEdge(e.src, e.dst, e.delay)); plannedEdges.forEach(e -> edgeCreator.createEdge(e.src, e.dst, e.delay));
/* /*
* Finally, create the backedges going to the destination node, depending on * Finally, create the backedges going to the destination node. The backedge
* whether or not a suffix exists. * source selection depends on whether or not a suffix exists.
*/ */
if (suffixCfg.getSuffixNodes().isEmpty()) { if (suffixCfg.getSuffixNodes().isEmpty()) {
for (ResourceNode endNode : suffixCfg.getBackedgeSources()) { for (ResourceNode endNode : suffixCfg.getBackedgeSources()) {
...@@ -392,7 +388,7 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -392,7 +388,7 @@ public class InfeasibleMinIIProperty extends Property {
* could be replaced by zero nodes if a lower problematic node required one to * could be replaced by zero nodes if a lower problematic node required one to
* be placed in the respective layer. * be placed in the respective layer.
*/ */
InfeasibleNodePlacer placer = new InfeasibleNodePlacer(startCfg, infeasibleCfg); InfeasibleCycleNodePlacer placer = new InfeasibleCycleNodePlacer(startCfg, infeasibleCfg);
placer.init(rng); placer.init(rng);
for (ResourceNode problematicNode : JavaUtils.asSortedList(infeasibleCfg.getProblematicNodes(), Comparator for (ResourceNode problematicNode : JavaUtils.asSortedList(infeasibleCfg.getProblematicNodes(), Comparator
...@@ -462,32 +458,6 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -462,32 +458,6 @@ public class InfeasibleMinIIProperty extends Property {
} }
List<ResourceNode> suffix = suffixCfg.getSuffixNodes();
/*
* If no suffix has been created, all problematic end nodes must become backedge
* sources themselves. Otherwise, the very last suffix node will be used as the
* only backedge's source node.
*
* Special care needs to be taken when the suffix is empty and the problematic
* resource's delay is not zero. In this case, every problematic node needs to
* be the source node of a backedge, as they aren't able to connect to any other
* node without exceeding the RecMinII. If the delay is zero however, the
* 'inner' problematic nodes can still connect to each other, hence only the
* lowest problematic nodes need to become backedge sources.
*/
Set<ResourceNode> backedgeSources = new HashSet<>();
if (suffix.isEmpty()) {
if (infeasibleCfg.getProblematicResource().delay == 0) {
backedgeSources.addAll(infeasibleCfg.getLowestProblematicNodes());
} else {
backedgeSources.addAll(infeasibleCfg.getProblematicNodes());
}
} else {
backedgeSources.add(suffix.get(suffix.size() - 1));
}
return suffixCfg; return suffixCfg;
} }
......
...@@ -17,9 +17,8 @@ ...@@ -17,9 +17,8 @@
package graphgen.util; package graphgen.util;
import org.junit.Test;
import graphgen.datastructures.SeededRandom; import graphgen.datastructures.SeededRandom;
import org.junit.Test;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment