Skip to content
Snippets Groups Projects
Commit ec357396 authored by Johannes Mey's avatar Johannes Mey
Browse files

add support for multiplicities for resources.

parent b43c5ddf
No related branches found
No related tags found
No related merge requests found
......@@ -215,10 +215,21 @@ ResourceTypeRef resource_type_ref =
;
Resource resource =
RESOURCE name.n COLON resource_type_ref.r LB_CURLY RB_CURLY
RESOURCE name.n COLON resource_type_ref.r MULT INTEGER.amount LB_CURLY RB_CURLY
{:
return new MultiResource(n, r, new List<>(), new List<>(), Integer.parseInt(amount));
:}
| RESOURCE name.n COLON resource_type_ref.r LB_CURLY RB_CURLY
{:
return new Resource(n, r, new List<>(), new List<>());
:}
| RESOURCE name.n COLON resource_type_ref.r MULT INTEGER.amount LB_CURLY resource_body.b RB_CURLY
{:
b.setName(n);
b.setType(r);
b.setAmount(Integer.parseInt(amount));
return b;
:}
| RESOURCE name.n COLON resource_type_ref.r LB_CURLY resource_body.b RB_CURLY
{:
b.setName(n);
......@@ -227,11 +238,11 @@ Resource resource =
:}
;
Resource resource_body =
MultiResource resource_body =
resource.r resource_body.b {: insertZero(b.getSubResourceList(), r); return b; :}
| current_resource_value.v resource_body.b {: insertZero(b.getCurrentResourceValueList(), v); return b; :}
| resource.r {: return new Resource(null, null, new List<>(r), new List<>()); :}
| current_resource_value.v {: return new Resource(null, null, new List<>(), new List<>(v)); :}
| resource.r {: return new MultiResource(null, null, new List<>(r), new List<>(), 1); :}
| current_resource_value.v {: return new MultiResource(null, null, new List<>(), new List<>(v), 1); :}
;
CurrentResourceValue current_resource_value =
......
aspect Checking {
public void Solution.explain() {
// TODO fix for multiresource
Set<Request> requestSet = new HashSet<>();
Map<Resource, Assignment> resourceSet = new HashMap<>();
logger.info(this.toString());
......
......@@ -2,7 +2,7 @@ aspect Checking {
syn boolean Solution.isValid() {
Set<Request> requestSet = new HashSet<>();
Set<Resource> resourceSet = new HashSet<>();
Map<Resource, Integer> resourceMap = new HashMap<>();
// check assignments
Iterator<Assignment> assignmentIterator = this.assignmentIterator();
......@@ -15,10 +15,12 @@ aspect Checking {
assignment.getRequest().getTarget().getRef()) {
requestSet.add(assignment.getRequest());
}
if (resourceSet.contains(assignment.getResource())) {
int num = resourceMap.getOrDefault(assignment.getResource(), 0);
resourceMap.put(assignment.getResource(), num + 1);
if (resourceMap.get(assignment.getResource()) > assignment.getResource().amount()) {
return false;
}
resourceSet.add(assignment.getResource());
}
}
......
MultiResource:Resource ::= <Amount:int> ;
\ No newline at end of file
aspect AI {
syn boolean Resource.isMultiResource() = false;
eq MultiResource.isMultiResource() = true;
syn int Resource.amount() = 1;
eq MultiResource.amount() = getAmount();
}
\ No newline at end of file
......@@ -54,7 +54,7 @@ aspect ILP {
IlpConstraint resourceConstraint = resourceConstraints.get(resource);
if (resourceConstraint == null) {
resourceConstraint = new IlpConstraint("one_on_" + resource.getIlpName(), new IlpLeftHandSide(),
ClauseComparator.LE, 1);
ClauseComparator.LE, resource.amount());
resourceConstraints.put(resource, resourceConstraint);
}
if (result == null) {
......
......@@ -44,7 +44,7 @@ public class SimpleSolver implements BenchmarkableSolver {
assignment.setResourceMapping(mapping);
}
private int checkAssignment(Solution solution, List<Solution> solutions, List<Assignment> assignments, List<Set<Resource>> possibleResources, int index, Stack<Resource> usedResources) {
private int checkAssignment(Solution solution, List<Solution> solutions, List<Assignment> assignments, List<Set<Resource>> possibleResources, int index, Map<Resource, Integer> usedResources) {
int checkCounter = 0;
Assignment assignment = assignments.get(index);
......@@ -54,9 +54,12 @@ public class SimpleSolver implements BenchmarkableSolver {
return checkCounter;
}
if (usedResources.contains(resource)) continue;
int currentNumber = usedResources.getOrDefault(resource, 0);
if (currentNumber >= resource.amount()) continue;
assignResource(assignment, resource);
usedResources.push(resource);
usedResources.put(resource, currentNumber + 1);
checkCounter++;
if (index == assignments.size() - 1) {
if (solution.isValid()) {
......@@ -71,7 +74,7 @@ public class SimpleSolver implements BenchmarkableSolver {
} else {
checkCounter += checkAssignment(solution, solutions, assignments, possibleResources, index + 1, usedResources);
}
usedResources.pop();
usedResources.put(resource, currentNumber);
}
return checkCounter;
}
......@@ -123,7 +126,7 @@ public class SimpleSolver implements BenchmarkableSolver {
possibleResources.add(resourceList);
}
numAssignments += checkAssignment(currentSolution, solutions, assignments, possibleResources, 0, new Stack<>());
numAssignments += checkAssignment(currentSolution, solutions, assignments, possibleResources, 0, new HashMap<>());
}
if (stopWatch.time(TimeUnit.MILLISECONDS) > maxSolvingTime) {
......
......@@ -165,4 +165,13 @@ public abstract class HandwrittenTestSuite {
modelAndSolution.getSecondElement().computeObjective(), 0.01);
}
@Test
public void test_multi_01() throws IOException, Parser.Exception, SolvingException {
Tuple<Root, Solution> modelAndSolution = loadAndSolve("test_multi_01.txt");
assertValidSolution(modelAndSolution);
Assignment config_0i0m0 = assertAssignment(modelAndSolution, 0, "config_0i0m0", "r0");
Assignment config_1i0m0 = assertAssignment(modelAndSolution, 0, "config_1i0m0", "r0");
assertComponentRequirement(config_0i0m0,"other", config_1i0m0);
}
}
// One request, two simple components, first requires second one
// Expected solution
// config_0i0m0 -> r0 + cpu0_0
// config_1i0m0 -> r1 + cpu0_1
container resource type ComputeNode {
resource type CPU {
property frequency [Hz]
property load [%]
}
property flops [ops/s]
}
resource r0:ComputeNode * 5 {
resource cpu0_0:CPU {
frequency = 2930
load = 30
}
flops = 293000
}
meta size
property energy [J]
property quality [%]
component c0 {
using property quality
contract config_0i0m0 {
// can run only on r0
requires component other of type c1
requires resource compute_resource_0 of type ComputeNode with {
cpu_1 of type CPU
}
requiring other.quality >= 95
requiring compute_resource_0.cpu_1.frequency >= 2159
providing quality = 300
providing energy = ((0.59*(size^2))+(0.89*compute_resource_0.flops))
}
contract config_0i0m1 {
// not satisfied at all
requires component other of type c1
requires resource compute_resource_0 of type ComputeNode with {
cpu_1 of type CPU
}
requiring other.quality >= 95
requiring compute_resource_0.cpu_1.frequency >= 14159
providing quality = 90
providing energy = ((0.11*(size^2))+(0.94*compute_resource_0.flops))
}
}
component c1 {
using property quality
contract config_1i0m0 {
// can run on both, r0 and r1
requires resource compute_resource_0 of type ComputeNode with {
cpu_1 of type CPU
}
requiring compute_resource_0.cpu_1.load <= 80
// fulfills c0 requirement
providing quality = 1004
providing energy = ((0.45*(size^2))+(0.34*compute_resource_0.flops))
}
contract config_1i0m1 {
// could run on r1
requires resource compute_resource_0 of type ComputeNode with {
cpu_1 of type CPU
}
requiring compute_resource_0.cpu_1.load <= 20
// does not fulfill c0 requirement
providing quality = 3
providing energy = ((0.25*(size^2))+(0.34*compute_resource_0.flops))
}
contract config_1i0m2 {
// not satisfied at all
requires resource compute_resource_0 of type ComputeNode with {
cpu_1 of type CPU
}
requiring compute_resource_0.cpu_1.load <= 1
providing quality = 200
providing energy = ((0.02*(size^2))+(0.71*compute_resource_0.flops))
}
}
request for c0 {
meta size = 6
requiring quality >= 35
}
minimize sum(energy)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment