Commit 4e934ca9 by Michael Schmid

FonsecaNelis test works now

parent 24eebe3e
...@@ -22,7 +22,7 @@ public class App { ...@@ -22,7 +22,7 @@ public class App {
TestEnvironment te = new TestEnvironment(); TestEnvironment te = new TestEnvironment();
Set<ResultCollector<AbstractTest<DagTask>>> tests = te.registerTests( Set<ResultCollector<AbstractTest<DagTask>>> tests = te.registerTests(
Arrays.asList(new SchmidMottok(p), new MelaniButtazzo(p), new FonsecaNelis(p))); Arrays.asList(new SchmidMottok(p), /* new MelaniButtazzo(p), */ new FonsecaNelis(p)));
te.runExperiments(builder, tests, p, 500); te.runExperiments(builder, tests, p, 500);
} }
......
package mvd.jester.model; package mvd.jester.model;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -188,6 +189,12 @@ public class DagTask implements Task { ...@@ -188,6 +189,12 @@ public class DagTask implements Task {
forkNodes.add(j); forkNodes.add(j);
} }
} }
for (Job j : forkNodes) {
if (jobDag.outDegreeOf(j) <= 1) {
int test = 3;
}
}
} }
public static DirectedAcyclicGraph<Job, DefaultEdge> createNFJGraph( public static DirectedAcyclicGraph<Job, DefaultEdge> createNFJGraph(
...@@ -259,13 +266,14 @@ public class DagTask implements Task { ...@@ -259,13 +266,14 @@ public class DagTask implements Task {
if (source.isPresent() && sink.isPresent()) { if (source.isPresent() && sink.isPresent()) {
Job current = source.get(); Job current = source.get();
DagUtils.treeDec(jobDag, null, current, tree, forkNodes, joinNodes, sink.get()); DagUtils.constructTree(jobDag, null, current, tree, forkNodes, joinNodes,
sink.get());
} }
return tree; return tree;
} }
private static Node<Job> treeDec(DirectedAcyclicGraph<Job, DefaultEdge> jobDag, private static Node<Job> constructTree(DirectedAcyclicGraph<Job, DefaultEdge> jobDag,
Node<Job> parentNode, Job currentJob, BinaryDecompositionTree<Job> tree, Node<Job> parentNode, Job currentJob, BinaryDecompositionTree<Job> tree,
LinkedList<Job> forkVertices, LinkedList<Job> joinVertices, Job sinkJob) { LinkedList<Job> forkVertices, LinkedList<Job> joinVertices, Job sinkJob) {
if (forkVertices.contains(currentJob)) { if (forkVertices.contains(currentJob)) {
...@@ -282,7 +290,7 @@ public class DagTask implements Task { ...@@ -282,7 +290,7 @@ public class DagTask implements Task {
Node<Job> seqJoinNode = Node<Job> seqJoinNode =
seqForkNode.setRightNode(new Node<Job>(seqForkNode, NodeType.SEQ)); seqForkNode.setRightNode(new Node<Job>(seqForkNode, NodeType.SEQ));
Node<Job> subTreeOfJoin = treeDec(jobDag, seqJoinNode, joinJob, tree, Node<Job> subTreeOfJoin = constructTree(jobDag, seqJoinNode, joinJob, tree,
forkVertices, joinVertices, sinkJob); forkVertices, joinVertices, sinkJob);
seqJoinNode.setRightNode(subTreeOfJoin); seqJoinNode.setRightNode(subTreeOfJoin);
...@@ -296,11 +304,14 @@ public class DagTask implements Task { ...@@ -296,11 +304,14 @@ public class DagTask implements Task {
Node<Job> successorParent = parContinuationNode; Node<Job> successorParent = parContinuationNode;
List<Job> successors = Graphs.successorListOf(jobDag, currentJob); List<Job> successors = Graphs.successorListOf(jobDag, currentJob);
if (successors.size() == 1) {
int test = 3;
}
// create leftSide of joinNode // create leftSide of joinNode
for (int i = 0; i < successors.size(); ++i) { for (int i = 0; i < successors.size(); ++i) {
Job succ = successors.get(i); Job succ = successors.get(i);
Node<Job> thisNode = treeDec(jobDag, successorParent, succ, tree, forkVertices, Node<Job> thisNode = constructTree(jobDag, successorParent, succ, tree,
joinVertices, sinkJob); forkVertices, joinVertices, sinkJob);
if (i == successors.size() - 1) { if (i == successors.size() - 1) {
successorParent.setRightNode(thisNode); successorParent.setRightNode(thisNode);
} else if (i == successors.size() - 2) { } else if (i == successors.size() - 2) {
...@@ -323,7 +334,7 @@ public class DagTask implements Task { ...@@ -323,7 +334,7 @@ public class DagTask implements Task {
tree.setRoot(seqJobNode); tree.setRoot(seqJobNode);
} }
seqJobNode.setLeftNode(new Node<Job>(seqJobNode, currentJob)); seqJobNode.setLeftNode(new Node<Job>(seqJobNode, currentJob));
Node<Job> contNode = treeDec(jobDag, seqJobNode, successor, tree, Node<Job> contNode = constructTree(jobDag, seqJobNode, successor, tree,
forkVertices, joinVertices, sinkJob); forkVertices, joinVertices, sinkJob);
seqJobNode.setRightNode(contNode); seqJobNode.setRightNode(contNode);
return seqJobNode; return seqJobNode;
...@@ -337,69 +348,6 @@ public class DagTask implements Task { ...@@ -337,69 +348,6 @@ public class DagTask implements Task {
} }
} }
// private static Node<Job> constructTree(DirectedAcyclicGraph<Job, DefaultEdge> jobDag,
// Node<Job> parent, Job currentFork, BinaryDecompositionTree<Job> tree,
// LinkedList<Job> forkVertices, LinkedList<Job> joinVertices, Job sink) {
// if (forkVertices.contains(currentFork)) {
// Job join = findJoin(jobDag, currentFork, sink, joinVertices);
// Node<Job> forkNode = new Node<Job>(parent, NodeType.SEQ);
// if (tree.isEmpty()) {
// tree.setRoot(forkNode);
// }
// forkNode.setLeftNode(new Node<Job>(forkNode, currentFork));
// final Node<Job> continuationNode;
// if (!tree.contains(join)) {
// forkNode.setRightNode(new Node<Job>(forkNode, NodeType.SEQ));
// Node<Job> joinNode = forkNode.getRightNode();
// Iterator<Job> successorIterator =
// Graphs.successorListOf(jobDag, join).iterator();
// if (successorIterator.hasNext()) {
// Job successor = successorIterator.next();
// if (!tree.contains(successor)) {
// joinNode.setRightNode(new Node<>(joinNode, NodeType.SEQ));
// Node<Job> successorNode = joinNode.getRightNode();
// successorNode.setLeftNode(new Node<>(successorNode, join));
// Node<Job> subTree = constructTree(jobDag, successorNode, successor,
// tree, forkVertices, joinVertices, sink);
// successorNode.setRightNode(subTree);
// } else {
// joinNode.setRightNode(new Node<>(joinNode, join));
// }
// } else {
// joinNode.setRightNode(new Node<>(joinNode, join));
// }
// joinNode.setLeftNode(new Node<>(joinNode, NodeType.PAR));
// continuationNode = joinNode.getLeftNode();
// } else {
// forkNode.setRightNode(new Node<>(forkNode, NodeType.PAR));
// continuationNode = forkNode.getRightNode();
// }
// Node<Job> successorParent = continuationNode;
// List<Job> successors = Graphs.successorListOf(jobDag, currentFork);
// // create leftSide of joinNode
// for (int i = 0; i < successors.size(); ++i) {
// Job succ = successors.get(i);
// Node<Job> thisNode = constructTree(jobDag, successorParent, succ, tree,
// forkVertices, joinVertices, sink);
// if (i == successors.size() - 1) {
// successorParent.setRightNode(thisNode);
// } else if (i == successors.size() - 2) {
// successorParent.setLeftNode(thisNode);
// } else {
// successorParent.setLeftNode(thisNode);
// successorParent.setRightNode(new Node<>(successorParent, NodeType.PAR));
// successorParent = successorParent.getRightNode();
// }
// }
// return forkNode;
// } else {
// return new Node<>(parent, currentFork);
// }
// }
public static boolean checkNFJProperty(DirectedAcyclicGraph<Job, DefaultEdge> jobDag) { public static boolean checkNFJProperty(DirectedAcyclicGraph<Job, DefaultEdge> jobDag) {
LinkedList<Job> joinNodes = new LinkedList<>(); LinkedList<Job> joinNodes = new LinkedList<>();
LinkedList<Job> forkNodes = new LinkedList<>(); LinkedList<Job> forkNodes = new LinkedList<>();
...@@ -453,15 +401,6 @@ public class DagTask implements Task { ...@@ -453,15 +401,6 @@ public class DagTask implements Task {
if (inbetweenJobs.containsAll(successorOfFork)) { if (inbetweenJobs.containsAll(successorOfFork)) {
return j; return j;
} }
// final Set<DefaultEdge> edgeSet = new HashSet<>();
// AllDirectedPaths<Job, DefaultEdge> finder = new AllDirectedPaths<>(jobDag);
// finder.getAllPaths(forkNode, j, true, null)
// .forEach(g -> edgeSet.addAll(g.getEdgeList()));
// Set<DefaultEdge> outgoingEdges = jobDag.outgoingEdgesOf(forkNode);
// if (edgeSet.containsAll(outgoingEdges)) {
// return j;
// }
} }
return sink; return sink;
...@@ -502,6 +441,10 @@ public class DagTask implements Task { ...@@ -502,6 +441,10 @@ public class DagTask implements Task {
private static GraphEndPoints traverseNodes(DirectedAcyclicGraph<Job, DefaultEdge> jobDag, private static GraphEndPoints traverseNodes(DirectedAcyclicGraph<Job, DefaultEdge> jobDag,
Node<Job> node) { Node<Job> node) {
if (node.getNodeType() != NodeType.LEAF
&& (node.getLeftNode() == null || node.getRightNode() == null)) {
int test = 3;
}
switch (node.getNodeType()) { switch (node.getNodeType()) {
case LEAF: { case LEAF: {
Job j = node.getObject(); Job j = node.getObject();
......
package mvd.jester.model;
public class TreeJob {
private long wcet;
private final Job job;
public TreeJob(Job job) {
this.wcet = job.getWcet();
this.job = job;
}
/**
* @return the job
*/
public Job getJob() {
return job;
}
/**
* @return the wcet
*/
public long getWcet() {
return wcet;
}
/**
* @param wcet the wcet to set
*/
public void setWcet(long wcet) {
this.wcet = wcet;
}
}
package mvd.jester.tests; package mvd.jester.tests;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import javax.print.attribute.standard.JobName;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.math.LongMath; import com.google.common.math.LongMath;
import org.jgrapht.experimental.dag.DirectedAcyclicGraph; import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.traverse.BreadthFirstIterator;
import mvd.jester.info.SchedulingInfo; import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.TerminationInfo; import mvd.jester.info.TerminationInfo;
import mvd.jester.info.TerminationInfo.Level; import mvd.jester.info.TerminationInfo.Level;
...@@ -21,10 +25,13 @@ import mvd.jester.model.Job; ...@@ -21,10 +25,13 @@ import mvd.jester.model.Job;
import mvd.jester.model.Segment; import mvd.jester.model.Segment;
import mvd.jester.model.SortedTaskSet; import mvd.jester.model.SortedTaskSet;
import mvd.jester.model.Task; import mvd.jester.model.Task;
import mvd.jester.model.TreeJob;
import mvd.jester.model.DagTask.DagUtils; import mvd.jester.model.DagTask.DagUtils;
import mvd.jester.priority.PriorityManager; import mvd.jester.priority.PriorityManager;
import mvd.jester.priority.RateMonotonic; import mvd.jester.priority.RateMonotonic;
import mvd.jester.utils.BinaryDecompositionTree; import mvd.jester.utils.BinaryDecompositionTree;
import mvd.jester.utils.BinaryDecompositionTree.Node;
import mvd.jester.utils.BinaryDecompositionTree.NodeType;
public class FonsecaNelis extends AbstractTest<DagTask> { public class FonsecaNelis extends AbstractTest<DagTask> {
...@@ -61,24 +68,82 @@ public class FonsecaNelis extends AbstractTest<DagTask> { ...@@ -61,24 +68,82 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
private void createNFJandDecompositionTree(SortedTaskSet<DagTask> tasks) { private void createNFJandDecompositionTree(SortedTaskSet<DagTask> tasks) {
for (DagTask t : tasks) { for (DagTask t : tasks) {
DirectedAcyclicGraph<Job, DefaultEdge> jobDag = t.getJobDag(); DirectedAcyclicGraph<Job, DefaultEdge> jobDag = t.getJobDag();
LinkedList<Job> joinNodes = new LinkedList<>();
LinkedList<Job> forkNodes = new LinkedList<>(); DirectedAcyclicGraph<Job, DefaultEdge> nfjJobDag = DagUtils.createNFJGraph(jobDag);
BinaryDecompositionTree<Job> tree = DagUtils.createDecompositionTree(nfjJobDag);
BreadthFirstIterator<Job, DefaultEdge> breadthFirstIterator =
new BreadthFirstIterator<>(jobDag); sortedSegments.put(t, constructCarryOutDistribution(nfjJobDag, tree));
while (breadthFirstIterator.hasNext()) { }
Job j = breadthFirstIterator.next(); }
if (jobDag.inDegreeOf(j) > 1) {
joinNodes.add(j); private Set<Segment> constructCarryOutDistribution(
} DirectedAcyclicGraph<Job, DefaultEdge> nfjDag, BinaryDecompositionTree<Job> tree) {
if (jobDag.outDegreeOf(j) > 1) { Set<Segment> carryOutWorkload = new LinkedHashSet<>();
forkNodes.add(j); BinaryDecompositionTree<TreeJob> modifiedTree = transformTree(tree);
boolean isEmpty = false;
do {
Set<TreeJob> parallelJobs = getMaximumParallelism(modifiedTree.getRootNode());
Optional<TreeJob> min =
parallelJobs.stream().min((p1, p2) -> Long.compare(p1.getWcet(), p2.getWcet()));
if (min.isPresent()) {
long width = min.get().getWcet();
carryOutWorkload.add(new Segment(width, parallelJobs.size()));
for (TreeJob p : parallelJobs) {
p.setWcet(p.getWcet() - width);
} }
} else {
break;
}
isEmpty = parallelJobs.isEmpty();
} while (!isEmpty);
return carryOutWorkload;
}
private BinaryDecompositionTree<TreeJob> transformTree(BinaryDecompositionTree<Job> tree) {
BinaryDecompositionTree<TreeJob> modifiedTree = new BinaryDecompositionTree<>();
Node<TreeJob> root = transformNode(null, tree.getRootNode());
modifiedTree.setRoot(root);
return modifiedTree;
}
private Node<TreeJob> transformNode(Node<TreeJob> parent, Node<Job> node) {
if (node.getNodeType() != NodeType.LEAF
&& (node.getLeftNode() == null || node.getRightNode() == null)) {
int test = 3;
}
if (node.getNodeType().equals(NodeType.LEAF)) {
return new Node<TreeJob>(parent, new TreeJob(node.getObject()));
} else {
Node<TreeJob> modifiedNode = new Node<TreeJob>(null, node.getNodeType());
modifiedNode.setLeftNode(transformNode(modifiedNode, node.getLeftNode()));
modifiedNode.setRightNode(transformNode(modifiedNode, node.getRightNode()));
return modifiedNode;
}
}
private Set<TreeJob> getMaximumParallelism(Node<TreeJob> node) {
NodeType nodeType = node.getNodeType();
if (nodeType.equals(NodeType.PAR)) {
Set<TreeJob> left = getMaximumParallelism(node.getLeftNode());
Set<TreeJob> right = getMaximumParallelism(node.getRightNode());
return Sets.union(left, right);
} else if (nodeType.equals(NodeType.SEQ)) {
Set<TreeJob> left = getMaximumParallelism(node.getLeftNode());
Set<TreeJob> right = getMaximumParallelism(node.getRightNode());
if (left.size() >= right.size()) {
return left;
} else {
return right;
}
} else {
if (node.getObject().getWcet() > 0) {
return new HashSet<>(Arrays.asList(node.getObject()));
} else {
return new HashSet<>();
} }
DirectedAcyclicGraph<Job, DefaultEdge> modifiedJobDag =
DagUtils.createNFJGraph(jobDag, forkNodes, joinNodes);
BinaryDecompositionTree<Job> tree =
DagUtils.createDecompositionTree(modifiedJobDag, forkNodes, joinNodes);
} }
} }
......
...@@ -31,12 +31,13 @@ public class BinaryDecompositionTree<N> { ...@@ -31,12 +31,13 @@ public class BinaryDecompositionTree<N> {
private final Node<T> parentNode; private final Node<T> parentNode;
private Node<T> leftNode; private Node<T> leftNode;
private Node<T> rightNode; private Node<T> rightNode;
private NodeType nodeType; private final NodeType nodeType;
private T object; private final T object;
public Node(Node<T> parentNode, NodeType nodeType) { public Node(Node<T> parentNode, NodeType nodeType) {
this.parentNode = parentNode; this.parentNode = parentNode;
this.nodeType = nodeType; this.nodeType = nodeType;
this.object = null;
} }
public boolean contains(T object) { public boolean contains(T object) {
......
package mvd.jester.model; package mvd.jester.model;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.concurrent.ThreadLocalRandom;
import org.jgrapht.Graphs; import org.jgrapht.Graphs;
import org.jgrapht.experimental.dag.DirectedAcyclicGraph; import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.DefaultEdge;
...@@ -48,7 +49,8 @@ public class TestDagUtils { ...@@ -48,7 +49,8 @@ public class TestDagUtils {
@DisplayName("Check if Decomposition Tree is created correctly for NFJ Dag.") @DisplayName("Check if Decomposition Tree is created correctly for NFJ Dag.")
void checkDecompositionTreeCreation() { void checkDecompositionTreeCreation() {
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
DagTaskBuilder b = new DagTaskBuilder(); long numberOfProcessors = ThreadLocalRandom.current().nextLong(4, 16);
DagTaskBuilder b = new DagTaskBuilder().setNumberOfProcessors(numberOfProcessors);
DagTask t = b.generateTask(); DagTask t = b.generateTask();
DirectedAcyclicGraph<Job, DefaultEdge> jobDag = t.getJobDag(); DirectedAcyclicGraph<Job, DefaultEdge> jobDag = t.getJobDag();
DirectedAcyclicGraph<Job, DefaultEdge> nfjJobDag = DagUtils.createNFJGraph(jobDag); DirectedAcyclicGraph<Job, DefaultEdge> nfjJobDag = DagUtils.createNFJGraph(jobDag);
......
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 sign in to comment