Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
las3_pub
/
jester
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
a15a466e
authored
May 19, 2020
by
Michael Schmid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added binary decomp tree and some changes on tests
parent
cdffd7ee
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
515 additions
and
74 deletions
+515
-74
src/main/java/mvd/jester/model/DagTask.java
+220
-33
src/main/java/mvd/jester/model/SystemSetup.java
+1
-2
src/main/java/mvd/jester/tests/FonsecaNelis.java
+21
-7
src/main/java/mvd/jester/utils/BinaryDecompositionTree.java
+107
-0
src/test/java/mvd/jester/model/TestDagUtils.java
+138
-0
src/test/java/mvd/jester/model/TestSegment.java
+0
-1
src/test/java/mvd/jester/model/TestSystemSetup.java
+28
-31
No files found.
src/main/java/mvd/jester/model/DagTask.java
View file @
a15a466e
package
mvd
.
jester
.
model
;
package
mvd
.
jester
.
model
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.LinkedHashSet
;
import
java.util.LinkedList
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.Set
;
import
com.google.common.collect.Iterables
;
import
com.google.common.collect.Sets
;
import
org.jgrapht.Graphs
;
import
org.jgrapht.Graphs
;
import
org.jgrapht.alg.shortestpath.AllDirectedPaths
;
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.utils.BinaryDecompositionTree
;
import
mvd.jester.utils.BinaryDecompositionTree.Node
;
import
mvd.jester.utils.BinaryDecompositionTree.NodeType
;
public
class
DagTask
implements
Task
{
public
class
DagTask
implements
Task
{
...
@@ -115,6 +122,10 @@ public class DagTask implements Task {
...
@@ -115,6 +122,10 @@ public class DagTask implements Task {
public
static
long
calculateCriticalPath
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
public
static
long
calculateCriticalPath
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
long
criticalPath
=
0
;
long
criticalPath
=
0
;
// BreadthFirstIterator<Job, DefaultEdge> breadthFirstIterator =
// new BreadthFirstIterator<>(jobDag);
// while (breadthFirstIterator.hasNext()) {
// Job job = breadthFirstIterator.next();
for
(
Job
job
:
jobDag
)
{
for
(
Job
job
:
jobDag
)
{
Set
<
DefaultEdge
>
edges
=
jobDag
.
incomingEdgesOf
(
job
);
Set
<
DefaultEdge
>
edges
=
jobDag
.
incomingEdgesOf
(
job
);
long
longestRelativeCompletionTime
=
0
;
long
longestRelativeCompletionTime
=
0
;
...
@@ -161,25 +172,37 @@ public class DagTask implements Task {
...
@@ -161,25 +172,37 @@ public class DagTask implements Task {
public
static
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
createNFJGraph
(
public
static
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
createNFJGraph
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
modifiedJobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
Graphs
.
addGraph
(
modifiedJobDag
,
jobDag
);
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
List
<
Job
>
forkNodes
=
new
LinkedList
<>();
LinkedList
<
Job
>
forkNodes
=
new
LinkedList
<>();
collectForksAndJoins
(
jobDag
,
forkNodes
,
joinNodes
);
return
createNFJGraph
(
jobDag
,
forkNodes
,
joinNodes
);
}
BreadthFirstIterator
<
Job
,
DefaultEdge
>
breadthFirstIterator
=
public
static
void
collectForksAndJoins
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
new
BreadthFirstIterator
<>(
modifiedJobDag
);
LinkedList
<
Job
>
forkNodes
,
LinkedList
<
Job
>
joinNodes
)
{
while
(
breadthFirstIterator
.
hasNext
())
{
for
(
Job
j
:
jobDag
)
{
Job
j
=
breadthFirstIterator
.
next
();
if
(
jobDag
.
inDegreeOf
(
j
)
>
1
)
{
if
(
modifiedJobDag
.
inDegreeOf
(
j
)
>
1
)
{
joinNodes
.
add
(
j
);
joinNodes
.
add
(
j
);
}
}
if
(
modifiedJ
obDag
.
outDegreeOf
(
j
)
>
1
)
{
if
(
j
obDag
.
outDegreeOf
(
j
)
>
1
)
{
forkNodes
.
add
(
j
);
forkNodes
.
add
(
j
);
}
}
}
}
}
Job
sink
=
joinNodes
.
getLast
();
public
static
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
createNFJGraph
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
LinkedList
<
Job
>
forkNodes
,
LinkedList
<
Job
>
joinNodes
)
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
modifiedJobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
Graphs
.
addGraph
(
modifiedJobDag
,
jobDag
);
if
(!(
joinNodes
.
size
()
>
1
))
{
return
modifiedJobDag
;
}
final
Job
sink
=
joinNodes
.
getLast
();
for
(
Job
j
:
joinNodes
)
{
for
(
Job
j
:
joinNodes
)
{
Set
<
DefaultEdge
>
edgeSet
=
new
HashSet
<>(
modifiedJobDag
.
incomingEdgesOf
(
j
));
Set
<
DefaultEdge
>
edgeSet
=
new
HashSet
<>(
modifiedJobDag
.
incomingEdgesOf
(
j
));
...
@@ -201,34 +224,107 @@ public class DagTask implements Task {
...
@@ -201,34 +224,107 @@ public class DagTask implements Task {
break
;
break
;
}
}
}
}
// Find fork node f following the path along this edge e
// if f has successor that is not ancestor of j -> e is conflicting edge
// get sorcetarget of e
// remove e
// if sourcetarget has no successor -> connect sourcetraget to sink
// if indegree = 1 -> break;
}
}
// if (!DagUtils.checkProperty1(modifiedJobDag)) {
// throw new RuntimeException("abs");
// }
return
modifiedJobDag
;
return
modifiedJobDag
;
}
}
private
static
boolean
checkProperty1
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
public
static
BinaryDecompositionTree
<
Job
>
createDecompositionTree
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
List
<
Job
>
forkNodes
=
new
LinkedList
<>();
Li
nkedLi
st
<
Job
>
forkNodes
=
new
LinkedList
<>();
BreadthFirstIterator
<
Job
,
DefaultEdge
>
breadthFirstIterator
=
collectForksAndJoins
(
jobDag
,
forkNodes
,
joinNodes
);
new
BreadthFirstIterator
<>(
jobDag
);
return
createDecompositionTree
(
jobDag
,
forkNodes
,
joinNodes
);
while
(
breadthFirstIterator
.
hasNext
())
{
}
Job
j
=
breadthFirstIterator
.
next
();
if
(
jobDag
.
inDegreeOf
(
j
)
>
1
)
{
public
static
BinaryDecompositionTree
<
Job
>
createDecompositionTree
(
joinNodes
.
add
(
j
);
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
LinkedList
<
Job
>
forkNodes
,
LinkedList
<
Job
>
joinNodes
)
{
Job
source
=
forkNodes
.
getFirst
();
Job
sink
=
joinNodes
.
getLast
();
Job
current
=
source
;
BinaryDecompositionTree
<
Job
>
tree
=
new
BinaryDecompositionTree
<>();
DagUtils
.
constructTree
(
jobDag
,
null
,
current
,
tree
,
forkNodes
,
joinNodes
,
sink
);
return
tree
;
}
private
static
Node
<
Job
>
constructTree
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
Node
<
Job
>
parent
,
Job
current
,
BinaryDecompositionTree
<
Job
>
tree
,
LinkedList
<
Job
>
forkVertices
,
LinkedList
<
Job
>
joinVertices
,
Job
sink
)
{
if
(
forkVertices
.
contains
(
current
))
{
Job
join
=
findJoin
(
jobDag
,
current
,
sink
,
joinVertices
);
if
(
jobDag
.
outDegreeOf
(
join
)
>
1
)
{
throw
new
RuntimeException
(
"Join und Fork in Einem! Ohoh!"
);
}
}
if
(
jobDag
.
outDegreeOf
(
j
)
>
1
)
{
forkNodes
.
add
(
j
);
Node
<
Job
>
forkNode
=
new
Node
<
Job
>(
parent
,
NodeType
.
SEQ
);
if
(
tree
.
isEmpty
())
{
tree
.
setRoot
(
forkNode
);
}
}
forkNode
.
setLeftNode
(
new
Node
<
Job
>(
forkNode
,
current
));
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
,
current
);
// 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
,
current
);
}
}
public
static
boolean
checkNFJProperty
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
LinkedList
<
Job
>
forkNodes
=
new
LinkedList
<>();
collectForksAndJoins
(
jobDag
,
forkNodes
,
joinNodes
);
if
(!(
joinNodes
.
size
()
>
1
))
{
return
true
;
}
}
for
(
Job
j
:
joinNodes
)
{
for
(
Job
j
:
joinNodes
)
{
...
@@ -257,14 +353,29 @@ public class DagTask implements Task {
...
@@ -257,14 +353,29 @@ public class DagTask implements Task {
return
false
;
return
false
;
}
}
private
static
Job
findJoin
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
Job
forkNode
,
Job
sink
,
List
<
Job
>
joinNodes
)
{
for
(
Job
j
:
joinNodes
)
{
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
;
}
private
static
boolean
checkForFork
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
private
static
boolean
checkForFork
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
Job
joinNode
,
List
<
Job
>
forkNodes
,
Job
job
)
{
Job
joinNode
,
List
<
Job
>
forkNodes
,
Job
job
)
{
List
<
Job
>
pred
=
Graphs
.
predecessorListOf
(
jobDag
,
job
);
List
<
Job
>
pred
=
Graphs
.
predecessorListOf
(
jobDag
,
job
);
for
(
Job
p
:
pred
)
{
for
(
Job
p
:
pred
)
{
if
(
forkNodes
.
contains
(
p
))
{
if
(
forkNodes
.
contains
(
p
))
{
for
(
DefaultEdge
successorEdge
:
jobDag
.
outgoingEdgesOf
(
p
))
{
for
(
Job
successor
:
Graphs
.
successorListOf
(
jobDag
,
p
))
{
Job
successor
=
jobDag
.
getEdgeSource
(
successorEdge
);
if
(
jobDag
.
getAncestors
(
jobDag
,
joinNode
).
contains
(
successor
))
{
if
(
jobDag
.
getAncestors
(
jobDag
,
joinNode
).
contains
(
successor
))
{
return
false
;
return
false
;
}
}
...
@@ -277,5 +388,81 @@ public class DagTask implements Task {
...
@@ -277,5 +388,81 @@ public class DagTask implements Task {
return
true
;
return
true
;
}
}
public
static
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
createNFJfromDecompositionTree
(
BinaryDecompositionTree
<
Job
>
tree
)
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
traverseNodes
(
jobDag
,
tree
.
getRootNode
(),
TraversalOrder
.
LEFT
);
return
jobDag
;
}
private
static
Set
<
Job
>
traverseNodes
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
Node
<
Job
>
node
,
TraversalOrder
order
)
{
switch
(
node
.
getNodeType
())
{
case
LEAF:
{
Job
j
=
node
.
getObject
();
jobDag
.
addVertex
(
j
);
return
new
HashSet
<
Job
>(
Arrays
.
asList
(
j
));
}
case
SEQ:
{
Set
<
Job
>
left
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
(),
TraversalOrder
.
LEFT
);
Set
<
Job
>
right
=
traverseNodes
(
jobDag
,
node
.
getRightNode
(),
TraversalOrder
.
RIGHT
);
try
{
for
(
Job
l
:
left
)
{
for
(
Job
r
:
right
)
{
jobDag
.
addDagEdge
(
l
,
r
);
}
}
}
catch
(
Exception
e
)
{
}
if
(
order
==
TraversalOrder
.
LEFT
)
{
Set
<
Job
>
openEndJobs
=
new
HashSet
<>();
for
(
Job
j
:
right
)
{
if
(
jobDag
.
outDegreeOf
(
j
)
==
0
)
{
openEndJobs
.
add
(
j
);
}
for
(
Job
d
:
jobDag
.
getDescendants
(
jobDag
,
j
))
{
if
(
jobDag
.
outDegreeOf
(
d
)
==
0
)
{
openEndJobs
.
add
(
d
);
}
}
}
return
openEndJobs
;
}
else
{
return
left
;
}
// return order == TraversalOrder.LEFT ? right : left; // left -> right; right
// ->
}
case
PAR:
{
Set
<
Job
>
left
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
(),
order
);
Set
<
Job
>
right
=
traverseNodes
(
jobDag
,
node
.
getRightNode
(),
order
);
return
Sets
.
newHashSet
(
Iterables
.
concat
(
left
,
right
));
}
default
:
break
;
}
return
new
HashSet
<>();
}
private
class
GraphEndPoints
{
public
Set
<
Job
>
left
;
public
Set
<
Job
>
right
;
public
GraphEndPoints
(
Set
<
Job
>
left
,
Set
<
Job
>
right
)
{
this
.
left
=
left
;
this
.
right
=
right
;
}
}
private
enum
TraversalOrder
{
LEFT
,
RIGHT
}
}
}
}
}
src/main/java/mvd/jester/model/SystemSetup.java
View file @
a15a466e
...
@@ -211,7 +211,7 @@ public class SystemSetup<T extends Task> {
...
@@ -211,7 +211,7 @@ public class SystemSetup<T extends Task> {
private
long
p_par
=
80
;
private
long
p_par
=
80
;
private
long
p_add
=
20
;
private
long
p_add
=
20
;
p
rivate
double
getBeta
()
{
p
ublic
double
getBeta
()
{
return
0.035
*
numberOfProcessors
;
return
0.035
*
numberOfProcessors
;
}
}
...
@@ -253,7 +253,6 @@ public class SystemSetup<T extends Task> {
...
@@ -253,7 +253,6 @@ public class SystemSetup<T extends Task> {
fork
(
jobDag
,
Optional
.
of
(
j
),
this
.
depth
);
fork
(
jobDag
,
Optional
.
of
(
j
),
this
.
depth
);
randomEdges
(
jobDag
);
randomEdges
(
jobDag
);
final
long
workload
=
DagUtils
.
calculateWorkload
(
jobDag
);
final
long
workload
=
DagUtils
.
calculateWorkload
(
jobDag
);
final
long
criticalPath
=
DagUtils
.
calculateCriticalPath
(
jobDag
);
final
long
criticalPath
=
DagUtils
.
calculateCriticalPath
(
jobDag
);
...
...
src/main/java/mvd/jester/tests/FonsecaNelis.java
View file @
a15a466e
...
@@ -4,6 +4,7 @@ import java.math.RoundingMode;
...
@@ -4,6 +4,7 @@ import java.math.RoundingMode;
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.LinkedList
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.Set
;
...
@@ -11,6 +12,7 @@ import com.google.common.collect.Lists;
...
@@ -11,6 +12,7 @@ import com.google.common.collect.Lists;
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
;
...
@@ -22,6 +24,7 @@ import mvd.jester.model.Task;
...
@@ -22,6 +24,7 @@ import mvd.jester.model.Task;
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
;
public
class
FonsecaNelis
extends
AbstractTest
<
DagTask
>
{
public
class
FonsecaNelis
extends
AbstractTest
<
DagTask
>
{
...
@@ -57,14 +60,25 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
...
@@ -57,14 +60,25 @@ 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
();
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
LinkedList
<
Job
>
forkNodes
=
new
LinkedList
<>();
BreadthFirstIterator
<
Job
,
DefaultEdge
>
breadthFirstIterator
=
new
BreadthFirstIterator
<>(
jobDag
);
while
(
breadthFirstIterator
.
hasNext
())
{
Job
j
=
breadthFirstIterator
.
next
();
if
(
jobDag
.
inDegreeOf
(
j
)
>
1
)
{
joinNodes
.
add
(
j
);
}
if
(
jobDag
.
outDegreeOf
(
j
)
>
1
)
{
forkNodes
.
add
(
j
);
}
}
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
modifiedJobDag
=
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
modifiedJobDag
=
DagUtils
.
createNFJGraph
(
t
.
getJobDag
());
DagUtils
.
createNFJGraph
(
jobDag
,
forkNodes
,
joinNodes
);
// List<Segment> sortedSegment = new LinkedList<>(t.getWorkloadDistribution());
BinaryDecompositionTree
<
Job
>
tree
=
// Collections.sort(sortedSegment,
DagUtils
.
createDecompositionTree
(
modifiedJobDag
,
forkNodes
,
joinNodes
);
// (s1, s2) -> (int) (s2.getNumberOfJobs() - s1.getNumberOfJobs()));
// Set<Segment> sortedSet = new LinkedHashSet<>(sortedSegment);
// sortedSegments.put(t, sortedSet);
}
}
}
}
...
...
src/main/java/mvd/jester/utils/BinaryDecompositionTree.java
0 → 100644
View file @
a15a466e
package
mvd
.
jester
.
utils
;
public
class
BinaryDecompositionTree
<
N
>
{
private
Node
<
N
>
root
;
public
BinaryDecompositionTree
()
{
}
public
Node
<
N
>
getRootNode
()
{
return
root
;
}
public
boolean
contains
(
N
object
)
{
return
root
.
contains
(
object
);
}
public
boolean
isEmpty
()
{
return
root
==
null
;
}
public
void
setRoot
(
Node
<
N
>
root
)
{
this
.
root
=
root
;
}
public
static
class
Node
<
T
>
{
private
final
Node
<
T
>
parentNode
;
private
Node
<
T
>
leftNode
;
private
Node
<
T
>
rightNode
;
private
NodeType
nodeType
;
private
T
object
;
public
Node
(
Node
<
T
>
parentNode
,
NodeType
nodeType
)
{
this
.
parentNode
=
parentNode
;
this
.
nodeType
=
nodeType
;
}
public
boolean
contains
(
T
object
)
{
if
(
nodeType
.
equals
(
NodeType
.
LEAF
))
{
return
this
.
object
==
object
;
}
else
{
boolean
leftContains
=
false
;
boolean
rightContains
=
false
;
if
(
leftNode
!=
null
)
{
leftContains
=
leftNode
.
contains
(
object
);
}
if
(
rightNode
!=
null
)
{
rightContains
=
rightNode
.
contains
(
object
);
}
return
leftContains
||
rightContains
;
}
}
public
Node
(
Node
<
T
>
parentNode
,
T
object
)
{
this
.
parentNode
=
parentNode
;
this
.
nodeType
=
NodeType
.
LEAF
;
this
.
object
=
object
;
}
/**
* @return the parentNode
*/
public
Node
<
T
>
getParentNode
()
{
return
parentNode
;
}
public
NodeType
getNodeType
()
{
return
nodeType
;
}
public
T
getObject
()
{
return
object
;
}
/**
* @param leftNode the leftNode to set
*/
public
void
setLeftNode
(
Node
<
T
>
leftNode
)
{
this
.
leftNode
=
leftNode
;
}
/**
* @return the leftNode
*/
public
Node
<
T
>
getLeftNode
()
{
return
leftNode
;
}
/**
* @param rightNode the rightNode to set
*/
public
void
setRightNode
(
Node
<
T
>
rightNode
)
{
this
.
rightNode
=
rightNode
;
}
/**
* @return the rightNode
*/
public
Node
<
T
>
getRightNode
()
{
return
rightNode
;
}
}
public
enum
NodeType
{
SEQ
,
PAR
,
LEAF
}
}
src/test/java/mvd/jester/model/TestDagUtils.java
0 → 100644
View file @
a15a466e
package
mvd
.
jester
.
model
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.graph.DefaultEdge
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
mvd.jester.model.DagTask.DagUtils
;
import
mvd.jester.model.SystemSetup.DagTaskBuilder
;
import
mvd.jester.utils.BinaryDecompositionTree
;
public
class
TestDagUtils
{
@Test
@DisplayName
(
"Test if a NFJ Graph is created correctly."
)
public
void
checkNFJCreation
()
{
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
DagTaskBuilder
builder
=
new
DagTaskBuilder
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
builder
.
generateTask
().
getJobDag
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
modifiedJobDag
=
DagUtils
.
createNFJGraph
(
jobDag
);
assertTrue
(
DagUtils
.
checkNFJProperty
(
modifiedJobDag
));
}
}
@Test
@DisplayName
(
"Test if dynamic segments are constructed correctly."
)
public
void
checkPathLength
()
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
createJobDag
();
long
criticalPath
=
DagUtils
.
calculateCriticalPath
(
jobDag
);
for
(
Job
j
:
jobDag
)
{
assertTrue
(
j
.
getRelativeCompletionTime
()
<=
criticalPath
);
}
for
(
DefaultEdge
e
:
jobDag
.
edgeSet
())
{
Job
source
=
jobDag
.
getEdgeSource
(
e
);
Job
target
=
jobDag
.
getEdgeTarget
(
e
);
assertTrue
(
source
.
getRelativeCompletionTime
()
<
target
.
getRelativeCompletionTime
());
}
assertTrue
(
criticalPath
==
155
);
}
@Test
@DisplayName
(
"Check if Decomposition Tree is created correctly for NFJ Dag."
)
void
checkDecompositionTreeCreation
()
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
createJobDag
();
BinaryDecompositionTree
<
Job
>
tree
=
DagUtils
.
createDecompositionTree
(
jobDag
);
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDagFromTree
=
DagUtils
.
createNFJfromDecompositionTree
(
tree
);
assertTrue
(
jobDag
.
equals
(
jobDagFromTree
));
}
private
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
createJobDag
()
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
Job
source
=
new
Job
(
20
);
Job
pathA
=
new
Job
(
10
);
Job
pathB
=
new
Job
(
30
);
Job
pathC
=
new
Job
(
40
);
Job
child1OfA
=
new
Job
(
5
);
Job
child2OfA
=
new
Job
(
15
);
Job
child3OfA
=
new
Job
(
5
);
Job
childsOfAJoin
=
new
Job
(
10
);
Job
child1OfC
=
new
Job
(
5
);
Job
child2OfC
=
new
Job
(
10
);
Job
child3OfC
=
new
Job
(
15
);
Job
child4OfC
=
new
Job
(
20
);
Job
firstJoin
=
new
Job
(
20
);
Job
intermediateFork
=
new
Job
(
10
);
Job
forkChild1
=
new
Job
(
5
);
Job
forkChild2
=
new
Job
(
10
);
Job
forkChild3
=
new
Job
(
15
);
Job
sink
=
new
Job
(
30
);
try
{
jobDag
.
addVertex
(
source
);
jobDag
.
addVertex
(
pathA
);
jobDag
.
addVertex
(
pathB
);
jobDag
.
addVertex
(
pathC
);
jobDag
.
addVertex
(
child1OfA
);
jobDag
.
addVertex
(
child2OfA
);
jobDag
.
addVertex
(
child3OfA
);
jobDag
.
addVertex
(
childsOfAJoin
);
jobDag
.
addVertex
(
child1OfC
);
jobDag
.
addVertex
(
child2OfC
);
jobDag
.
addVertex
(
child3OfC
);
jobDag
.
addVertex
(
child4OfC
);
jobDag
.
addVertex
(
firstJoin
);
jobDag
.
addVertex
(
intermediateFork
);
jobDag
.
addVertex
(
forkChild1
);
jobDag
.
addVertex
(
forkChild2
);
jobDag
.
addVertex
(
forkChild3
);
jobDag
.
addVertex
(
sink
);
jobDag
.
addDagEdge
(
source
,
pathA
);
jobDag
.
addDagEdge
(
pathA
,
child1OfA
);
jobDag
.
addDagEdge
(
pathA
,
child2OfA
);
jobDag
.
addDagEdge
(
pathA
,
child3OfA
);
jobDag
.
addDagEdge
(
child1OfA
,
childsOfAJoin
);
jobDag
.
addDagEdge
(
child2OfA
,
childsOfAJoin
);
jobDag
.
addDagEdge
(
child3OfA
,
childsOfAJoin
);
jobDag
.
addDagEdge
(
childsOfAJoin
,
firstJoin
);
jobDag
.
addDagEdge
(
source
,
pathB
);
jobDag
.
addDagEdge
(
pathB
,
firstJoin
);
jobDag
.
addDagEdge
(
source
,
pathC
);
jobDag
.
addDagEdge
(
pathC
,
child1OfC
);
jobDag
.
addDagEdge
(
pathC
,
child2OfC
);
jobDag
.
addDagEdge
(
pathC
,
child3OfC
);
jobDag
.
addDagEdge
(
pathC
,
child4OfC
);
jobDag
.
addDagEdge
(
child1OfC
,
firstJoin
);
jobDag
.
addDagEdge
(
child2OfC
,
firstJoin
);
jobDag
.
addDagEdge
(
child3OfC
,
firstJoin
);
jobDag
.
addDagEdge
(
child4OfC
,
firstJoin
);
jobDag
.
addDagEdge
(
firstJoin
,
intermediateFork
);
jobDag
.
addDagEdge
(
intermediateFork
,
forkChild1
);
jobDag
.
addDagEdge
(
intermediateFork
,
forkChild2
);
jobDag
.
addDagEdge
(
intermediateFork
,
forkChild3
);
jobDag
.
addDagEdge
(
forkChild1
,
sink
);
jobDag
.
addDagEdge
(
forkChild2
,
sink
);
jobDag
.
addDagEdge
(
forkChild3
,
sink
);
}
catch
(
Exception
e
)
{
}
return
jobDag
;
}
}
src/test/java/mvd/jester/model/TestSegment.java
View file @
a15a466e
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
com.google.common.math.LongMath
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Test
;
...
...
src/test/java/mvd/jester/model/TestSystemSetup.java
View file @
a15a466e
...
@@ -2,18 +2,10 @@ package mvd.jester.model;
...
@@ -2,18 +2,10 @@ package mvd.jester.model;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
java.awt.Color
;
import
java.awt.image.BufferedImage
;
import
java.io.File
;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.concurrent.ThreadLocalRandom
;
import
java.util.concurrent.ThreadLocalRandom
;
import
javax.imageio.ImageIO
;
import
com.google.common.math.DoubleMath
;
import
com.google.common.math.DoubleMath
;
import
com.mxgraph.layout.mxCircleLayout
;
import
com.mxgraph.layout.mxIGraphLayout
;
import
com.mxgraph.util.mxCellRenderer
;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.ext.JGraphXAdapter
;
import
org.jgrapht.graph.DefaultEdge
;
import
org.jgrapht.graph.DefaultEdge
;
import
org.junit.Rule
;
import
org.junit.Rule
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.DisplayName
;
...
@@ -86,40 +78,45 @@ public class TestSystemSetup {
...
@@ -86,40 +78,45 @@ public class TestSystemSetup {
@Test
@Test
@DisplayName
(
"Check if DagTaskBuilder works correctly"
)
@DisplayName
(
"Check if DagTaskBuilder works correctly"
)
void
testDagTaskBuilder
()
{
void
testDagTaskBuilder
()
{
DagTaskBuilder
builder
=
new
DagTaskBuilder
();
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
j
=
builder
.
generateTask
().
getJobDag
();
DagTaskBuilder
builder
=
new
DagTaskBuilder
();
DagTask
task
=
builder
.
generateTask
();
JGraphXAdapter
<
Job
,
DefaultEdge
>
graphAdapter
=
new
JGraphXAdapter
<
Job
,
DefaultEdge
>(
j
);
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
task
.
getJobDag
();
mxIGraphLayout
layout
=
new
mxCircleLayout
(
graphAdapter
);
layout
.
execute
(
graphAdapter
.
getDefaultParent
());
BufferedImage
image
=
assertTrue
(
task
.
getCriticalPath
()
<=
task
.
getPeriod
());
mxCellRenderer
.
createBufferedImage
(
graphAdapter
,
null
,
2
,
Color
.
WHITE
,
true
,
null
);
assertTrue
(
task
.
getPeriod
()
<=
(
long
)
(
task
.
getWorkload
()
/
builder
.
getBeta
())
);
File
imgFile
=
new
File
(
"src/test/resources/graph.png"
);
for
(
Job
j
:
jobDag
)
{
try
{
assertTrue
(
1
<=
j
.
getWcet
()
&&
j
.
getWcet
()
<=
100
);
ImageIO
.
write
(
image
,
"PNG"
,
imgFile
);
assertTrue
(
j
.
getRelativeCompletionTime
()
<=
task
.
getCriticalPath
());
}
catch
(
Exception
e
)
{
if
(
jobDag
.
outDegreeOf
(
j
)
==
0
)
{
assertTrue
(
j
.
getRelativeCompletionTime
()
==
task
.
getCriticalPath
());
}
}
for
(
DefaultEdge
e
:
jobDag
.
edgeSet
())
{
Job
source
=
jobDag
.
getEdgeSource
(
e
);
Job
target
=
jobDag
.
getEdgeTarget
(
e
);
assertTrue
(
source
.
getRelativeCompletionTime
()
<
target
.
getRelativeCompletionTime
());
}
}
}
assertTrue
(
imgFile
.
exists
());
}
}
@Test
@Test
@DisplayName
(
"Check if utilization works correctly."
)
@DisplayName
(
"Check if utilization works correctly."
)
void
testUtil
()
{
void
testUtil
()
{
for
(
double
d
=
0.25
;
d
<
4
;
d
+=
0.25
)
{
for
(
int
i
=
0
;
i
<
5
;
++
i
)
{
DagTaskBuilder
builder
=
new
DagTaskBuilder
();
for
(
double
d
=
0.25
;
d
<
4
;
d
+=
0.25
)
{
Set
<
DagTask
>
taskSet
=
builder
.
generateTaskSet
(
d
);
DagTaskBuilder
builder
=
new
DagTaskBuilder
();
double
taskSetUtil
=
0
;
Set
<
DagTask
>
taskSet
=
builder
.
generateTaskSet
(
d
);
for
(
DagTask
t
:
taskSet
)
{
double
taskSetUtil
=
0
;
taskSetUtil
+=
t
.
getUtilization
();
for
(
DagTask
t
:
taskSet
)
{
}
taskSetUtil
+=
t
.
getUtilization
();
}
assertTrue
(
DoubleMath
.
fuzzyEquals
(
taskSetUtil
,
d
,
0.002
));
assertTrue
(
DoubleMath
.
fuzzyEquals
(
taskSetUtil
,
d
,
0.002
));
}
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment