Commit b7ee28b1 authored by Sebastian Vollbrecht's avatar Sebastian Vollbrecht

Some renaming, some code movements.

parent 4ab510cb
......@@ -17,9 +17,7 @@
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.SuffixConfiguration;
import graphgen.graph.Resource;
import graphgen.graph.ResourceNode;
import graphgen.util.JavaUtils;
......@@ -30,7 +28,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.stream.IntStream;
public class InfeasibilityInspector {
......@@ -315,29 +312,4 @@ public class InfeasibilityInspector {
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;
import java.util.Set;
import java.util.function.BiFunction;
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 InfeasibleConfiguration infeasibleCfg;
......@@ -47,13 +48,36 @@ public class InfeasibleEdgeInspector implements Initializable {
private SeededRandom rng;
public InfeasibleEdgeInspector(StartConfiguration startCfg, InfeasibleConfiguration infeasibleCfg,
SuffixConfiguration suffixCfg) {
public InfeasibleCycleEdgePlanner(StartConfiguration startCfg, InfeasibleConfiguration infeasibleCfg,
SuffixConfiguration suffixCfg) {
this.startCfg = startCfg;
this.infeasibleCfg = infeasibleCfg;
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() {
Set<PlannedEdge> edges = new HashSet<>();
......@@ -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,
BiFunction<ResourceNode, ResourceNode, Integer> delayComputer) {
......@@ -196,6 +233,16 @@ public class InfeasibleEdgeInspector implements Initializable {
problematicEdges.add(new PlannedEdge(fixedNode, firstSuffixNode, edgeDelay, 0));
} 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);
}
}
......@@ -345,20 +392,6 @@ public class InfeasibleEdgeInspector implements Initializable {
// 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,
Collection<ResourceNode> relevantNodes) {
Map<ResourceNode, PlannedEdge> incomingEdgesByNode = new HashMap<>();
......
......@@ -31,14 +31,14 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
public class InfeasibleNodePlacer implements Initializable {
public class InfeasibleCycleNodePlacer implements Initializable {
private final StartConfiguration startCfg;
private final InfeasibleConfiguration infeasibleCfg;
private SeededRandom rng;
public InfeasibleNodePlacer(StartConfiguration startCfg, InfeasibleConfiguration infeasibleCfg) {
public InfeasibleCycleNodePlacer(StartConfiguration startCfg, InfeasibleConfiguration infeasibleCfg) {
this.startCfg = startCfg;
this.infeasibleCfg = infeasibleCfg;
}
......
......@@ -35,7 +35,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
......@@ -93,7 +92,6 @@ public class InfeasibleMinIIProperty extends Property {
*/
public InfeasibleMinIIProperty(int minII, int backedgeDelay, int backedgeDistance) {
// TODO: test MinII == 0
if (minII <= 0) {
throw new IllegalArgumentException("The MinII must be greater than zero.");
}
......@@ -135,8 +133,7 @@ public class InfeasibleMinIIProperty extends Property {
Set<Edge<ResourceNode>> tmpEdges = new HashSet<>(edgeCreator.edgeView());
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 {
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
* either be the destination node or a zero node of the previous layer.
* 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). */
Set<Integer> possibleTimeslots = InfeasibilityInspector
.getProblematicTimeslots(startCfg, infeasibleCfg, suffixCfg);
Set<Integer> possibleTimeslots = edgePlanner.getProblematicTimeslots();
int problematicTimeslot = JavaUtils.pickRandomElement(possibleTimeslots, rng);
/*
......@@ -182,17 +178,18 @@ public class InfeasibleMinIIProperty extends Property {
* the chosen timeslot. The remaining inner delay will also be distributed over the
* 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()) {
Map<ResourceNode, PlannedEdge> outgoingEdgesByNode = InfeasibleEdgeInspector
Map<ResourceNode, PlannedEdge> outgoingEdgesByNode = InfeasibleCycleEdgePlanner
.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
.getProblematicResource().delay + lastEdgeRepresentative.get().delay;
suffixCfg.setInitialOffset(firstSuffixSlot);
......@@ -207,12 +204,11 @@ public class InfeasibleMinIIProperty extends Property {
* Create the required outgoing edges.
* 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
* nodes themselves) or which will be used as backedge sources.
* nodes themselves).
*/
Predicate<ResourceNode> nodeNeedsOutgoingEdge = n -> plannedEdges.stream()
.noneMatch(e -> e.src == n && e.distance == 0) && !suffixCfg.getBackedgeSources().contains(n);
Set<PlannedEdge> outgoingEdges = edgeInspector
.getOutgoingEdges(problematicTimeslot, nodeNeedsOutgoingEdge, edgeCreator::computeEdgeDelay);
Predicate<ResourceNode> needsOutgoingEdge = n -> plannedEdges.stream().noneMatch(e -> e.src == n);
Set<PlannedEdge> outgoingEdges = edgePlanner
.getOutgoingEdges(problematicTimeslot, needsOutgoingEdge, edgeCreator::computeEdgeDelay);
plannedEdges.addAll(outgoingEdges);
/*
......@@ -221,8 +217,8 @@ public class InfeasibleMinIIProperty extends Property {
plannedEdges.forEach(e -> edgeCreator.createEdge(e.src, e.dst, e.delay));
/*
* Finally, create the backedges going to the destination node, depending on
* whether or not a suffix exists.
* Finally, create the backedges going to the destination node. The backedge
* source selection depends on whether or not a suffix exists.
*/
if (suffixCfg.getSuffixNodes().isEmpty()) {
for (ResourceNode endNode : suffixCfg.getBackedgeSources()) {
......@@ -392,7 +388,7 @@ public class InfeasibleMinIIProperty extends Property {
* could be replaced by zero nodes if a lower problematic node required one to
* be placed in the respective layer.
*/
InfeasibleNodePlacer placer = new InfeasibleNodePlacer(startCfg, infeasibleCfg);
InfeasibleCycleNodePlacer placer = new InfeasibleCycleNodePlacer(startCfg, infeasibleCfg);
placer.init(rng);
for (ResourceNode problematicNode : JavaUtils.asSortedList(infeasibleCfg.getProblematicNodes(), Comparator
......@@ -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;
}
......
......@@ -17,9 +17,8 @@
package graphgen.util;
import org.junit.Test;
import graphgen.datastructures.SeededRandom;
import org.junit.Test;
import java.util.HashSet;
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