Commit 5ccf5525 authored by Sebastian Vollbrecht's avatar Sebastian Vollbrecht

Began working on an InfeasibleMinII-FeasibleII property (for fixed numbers of...

Began working on an InfeasibleMinII-FeasibleII property (for fixed numbers of infeasible II candidates).
parent 89e2b3ee
/*
* Copyright 2018 Sebastian Vollbrecht, Julian Oppermann
* Embedded Systems and Applications Group, TU Darmstadt
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package graphgen.generator.components.properties.minII.combined;
import graphgen.enums.ModuloSchedulingFormulation;
import graphgen.generator.components.properties.minII.infeasible.InfeasibleMinIICycleProperty;
import graphgen.graph.ResourceNode;
import graphgen.util.SchedulingUtils;
import modsched.Edge;
import java.util.HashSet;
import java.util.Set;
/**
* This property can be used to define the distance of the first <i>feasible</i> II to a defined MinII.
*
* @author Sebastian Vollbrecht
*/
public class InfeasibleMinIIFeasibleIIProperty extends InfeasibleMinIICycleProperty {
private final ModuloSchedulingFormulation formulation;
/**
* Creates a new infeasible MinII & feasible II property which ensures that the specified MinII and the number of
* subsequent given timesteps will be (and remain) infeasible during graph creation. The delay and distance
* parameters will be used for the RecMinII-ensuring backedges. The backedge parameters are set to 1 in this
* constructor. The infeasible timesteps parameter denotes how many timesteps should be infeasible, starting at the
* MinII's timestep (inclusive).
*
* @param minII the MinII to ensure
* @param infeasibleTimesteps the number of infeasible timesteps
* @param formulation the ILP formulation to use to determine edge and backedge validity for the (MinII +
* infeasible timesteps)-th timestep
* @throws IllegalArgumentException if the MinII is not greater than zero, if the backedge delay is less than zero
* or if the backedge distance is not greater than zero
*/
public InfeasibleMinIIFeasibleIIProperty(int minII, int infeasibleTimesteps,
ModuloSchedulingFormulation formulation) {
this(minII, 1, 1, infeasibleTimesteps, formulation);
}
/**
* Creates a new infeasible MinII & feasible II property which ensures that the specified MinII and the number of
* given timesteps will be (and remain) infeasible during graph creation. The delay and distance parameters will be
* used for the RecMinII-ensuring backedges. The infeasible timesteps parameter denotes how many timesteps should be
* infeasible, starting at the MinII's timestep (inclusive).
*
* @param minII the MinII to ensure
* @param backedgeDelay the delay of the RecMinII-ensuring backedges
* @param backedgeDistance the distance of the RecMinII-ensuring backedges
* @param infeasibleTimesteps the number of infeasible timesteps
* @param formulation the ILP formulation to use to determine edge and backedge validity for the (MinII +
* infeasible timesteps)-th timestep
* @throws IllegalArgumentException if the MinII is not greater than zero, if the backedge delay is less than zero
* or if the backedge distance is not greater than zero
*/
public InfeasibleMinIIFeasibleIIProperty(int minII, int backedgeDelay, int backedgeDistance,
int infeasibleTimesteps, ModuloSchedulingFormulation formulation) {
super(minII, backedgeDelay, backedgeDistance, infeasibleTimesteps);
this.formulation = formulation;
}
@Override
public boolean isEdgeValid(ResourceNode src, ResourceNode dst, int delay) {
return isBackedgeValid(src, dst, delay, 0);
}
@Override
public boolean isBackedgeValid(ResourceNode src, ResourceNode dst, int delay, int distance) {
Set<Edge<ResourceNode>> tmpEdges = new HashSet<>(edgeCreator.edgeView());
tmpEdges.add(new Edge<>(src, dst, delay, distance));
if (SchedulingUtils.getRecMinII(nodes, tmpEdges) > minII) {
return false;
}
int firstFeasibleII = minII + infeasibleIIs;
for (int II = minII; II < firstFeasibleII; II++) {
assert !SchedulingUtils.isFeasible(nodes, tmpEdges, formulation, II, II);
}
return SchedulingUtils.schedule(nodes, tmpEdges, "", formulation, 1, minII, firstFeasibleII)
.getII() == firstFeasibleII;
}
}
......@@ -62,6 +62,7 @@ public class Main {
// CaseStudyCASES2018.generate();
// RandomGraphs.generate();
}
/**
......
......@@ -40,6 +40,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.Callable;
......@@ -294,8 +295,9 @@ public class SchedulingUtils {
for (Edge<ResourceNode> edge : incoming.get(node)) {
if (edge.isBackedge())
if (edge.isBackedge()) {
continue;
}
ResourceNode src = edge.getSrc();
......@@ -319,16 +321,46 @@ public class SchedulingUtils {
}
int maxII = 0;
for (Entry<ResourceNode, Integer> timeEntry : earliestPossibleTimes.entrySet()) {
/*
* The additional call to Math.max(...) makes sure that 'end' nodes with delay
* 0 don't lead to the next iteration beginning in the end node's timeslot.
*/
maxII = Math.max(timeEntry.getValue() + Math.max(timeEntry.getKey().getDelay(), 1), maxII);
}
/*
* Because the computation of the MaxII does not take into account the
* inter-iteration-dependencies imposed by the backedges, it might be smaller
* than the RecMinII of the graph. Therefore, the greater value of both II
* bounds should be returned.
* Check whether the current MaxII fulfills every single backedge dependency by
* calculating how far away the backedge's source and destination nodes would be
* placed in the non-modulo schedule. If they are too close together, the MaxII
* needs to be increased accordingly.
*/
int maxII = layers.getLastLayer().stream().map(graph::getNode)
.mapToInt(n -> earliestPossibleTimes.get(n) + n.getDelay()).max().orElse(0);
for (Edge<ResourceNode> backedge : JavaUtils
.asSet(graph.edges.stream().filter(EdgeType.BACKWARD::matchesEdge))) {
ResourceNode src = backedge.getSrc();
ResourceNode dst = backedge.getDst();
int srcTime = earliestPossibleTimes.get(src);
int dstTime = earliestPossibleTimes.get(dst);
/*
* The resulting time denotes the time of the destination node in the next
* iteration.
*/
int resultingTimeDelta = (dstTime + maxII) - srcTime;
int neededTimeDelta = (src.getDelay() + backedge.getDelay()) / backedge.getDistance();
int delta = neededTimeDelta - resultingTimeDelta;
if (delta > 0) {
maxII += delta;
}
}
return Math.max(maxII, getMinII(graph));
return maxII;
}
......@@ -369,7 +401,7 @@ public class SchedulingUtils {
}
}
resourceUsagePerSlot.get(nodeSlot).put(res, resourceUsagePerSlot.get(nodeSlot).get(res) + 1);
JavaUtils.insertOrIncValue(resourceUsagePerSlot.get(nodeSlot), res);
nodeTimes.put(node, nodeSlot);
}
......
......@@ -554,6 +554,45 @@ public class SchedulingUtilsTest {
assertEquals(13, SchedulingUtils.getMaxII(graph));
}
@Test
public void testMaxII2() {
Resource limited = new Resource("adder", 1, 1);
Resource unlimited = new Resource("unlimited", 0);
ResourceNode n0 = new ResourceNode(0, unlimited);
ResourceNode n1 = new ResourceNode(1, unlimited);
ResourceNode n2 = new ResourceNode(2, limited);
ResourceNode n3 = new ResourceNode(3, limited);
ResourceNode n4 = new ResourceNode(4, limited);
ResourceNode n5 = new ResourceNode(5, unlimited);
Set<ResourceNode> nodes = JavaUtils.asSet(n0, n1, n2, n3, n4, n5);
Set<Edge<ResourceNode>> edges = new HashSet<>();
edges.add(new Edge<>(n0, n1, 0, 0));
edges.add(new Edge<>(n0, n2, 0, 0));
edges.add(new Edge<>(n0, n3, 0, 0));
edges.add(new Edge<>(n1, n4, 0, 0));
edges.add(new Edge<>(n2, n5, 1, 0));
edges.add(new Edge<>(n3, n5, 1, 0));
edges.add(new Edge<>(n4, n5, 1, 0));
Edge<ResourceNode> edge = new Edge<>(n5, n0, 1, 1);
edges.add(edge);
//assertEquals(5, SchedulingUtils.getMaxII(new Graph<>(nodes, edges)));
edges.remove(edge);
edge = new Edge<>(n5, n0, 50, 1);
edges.add(edge);
assertEquals(54, SchedulingUtils.getMaxII(new Graph<>(nodes, edges)));
edges.remove(edge);
edge = new Edge<>(n5, n0, 50, 2);
edges.add(edge);
assertEquals(29, SchedulingUtils.getMaxII(new Graph<>(nodes, edges)));
}
@Test
public void minIIGreaterMaxIIProblematicOne1() {
......
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