use of org.chocosolver.solver.variables.Task in project scheduler by btrplace.
the class CMaxOnline method inject.
@Override
public boolean inject(Parameters ps, ReconfigurationProblem rp) throws SchedulerException {
Model csp = rp.getModel();
if (constraint.getInvolvedNodes().isEmpty()) {
// The constraint is entailed as it contains no node.
return true;
}
if (constraint.isContinuous()) {
CPowerView view = (CPowerView) rp.getView(CPowerView.VIEW_ID);
if (view == null) {
view = new CPowerView();
if (!rp.addView(view)) {
throw new SchedulerModelingException(rp.getSourceModel(), "Unable to attach view '" + CPowerView.VIEW_ID + "'");
}
if (!view.inject(ps, rp)) {
throw new SchedulerModelingException(rp.getSourceModel(), "Unable to inject view '" + CPowerView.VIEW_ID + "'");
}
}
int numberOfTasks = constraint.getInvolvedNodes().size();
int i = 0;
int[] nodeIdx = new int[numberOfTasks];
for (Node n : constraint.getInvolvedNodes()) {
nodeIdx[i++] = rp.getNode(n);
}
IntVar capacity = rp.fixed(constraint.getAmount(), "capacity");
// The state of the node:
IntVar[] heights = new IntVar[numberOfTasks];
IntVar[] starts = new IntVar[numberOfTasks];
IntVar[] ends = new IntVar[numberOfTasks];
// Online duration:
IntVar[] durations = new IntVar[numberOfTasks];
// Online duration is modeled as a task
Task[] taskVars = new Task[numberOfTasks];
for (int idx = 0; idx < nodeIdx.length; idx++) {
Node n = rp.getNode(nodeIdx[idx]);
// ---------------GET PowerStart and PowerEnd of the node------------------
starts[idx] = view.getPowerStart(rp.getNode(n));
ends[idx] = view.getPowerEnd(rp.getNode(n));
// ------------------------------------------------------------------------
durations[idx] = rp.makeUnboundedDuration(rp.makeVarLabel("Dur(", n, ")"));
csp.post(csp.arithm(durations[idx], "<=", rp.getEnd()));
// All tasks have to be scheduled
heights[idx] = csp.intVar(1);
taskVars[idx] = new Task(starts[idx], durations[idx], ends[idx]);
}
csp.post(csp.cumulative(taskVars, heights, capacity, true));
}
// Constraint for discrete model
List<IntVar> nodesState = new ArrayList<>(constraint.getInvolvedNodes().size());
for (Node ni : constraint.getInvolvedNodes()) {
nodesState.add(rp.getNodeAction(ni).getState());
}
IntVar mySum = csp.intVar(rp.makeVarLabel("nbOnline"), 0, constraint.getAmount(), true);
csp.post(csp.sum(nodesState.toArray(new IntVar[nodesState.size()]), "=", mySum));
csp.post(csp.arithm(mySum, "<=", constraint.getAmount()));
return true;
}
use of org.chocosolver.solver.variables.Task in project scheduler by btrplace.
the class CSerialize method inject.
@Override
public boolean inject(Parameters ps, ReconfigurationProblem rp) throws SchedulerException {
// Get the solver
Model csp = rp.getModel();
// Not enough VMs
if (ser.getInvolvedVMs().size() < 2) {
return true;
}
// Get all migrations involved
for (VM vm : ser.getInvolvedVMs()) {
VMTransition vt = rp.getVMAction(vm);
if (vt instanceof RelocatableVM) {
migrationList.add((RelocatableVM) vt);
}
}
// Not enough migrations
if (migrationList.size() < 2) {
return true;
}
// Using a cumulative
List<Task> tasks = new ArrayList<>();
for (RelocatableVM mig : migrationList) {
tasks.add(new Task(mig.getStart(), mig.getDuration(), mig.getEnd()));
}
IntVar[] heights = new IntVar[tasks.size()];
Arrays.fill(heights, csp.intVar(1));
csp.post(csp.cumulative(tasks.toArray(new Task[tasks.size()]), heights, csp.intVar(1), true));
return true;
}
use of org.chocosolver.solver.variables.Task in project scheduler by btrplace.
the class CNetwork method addLinkConstraints.
/**
* Add the cumulative constraints for each link.
*
* Full-duplex links are considered, two cumulative constraints are defined per link by looking at
* the migration direction for each link on the migration path.
*
* @param rp the reconfiguration problem
*/
private void addLinkConstraints(ReconfigurationProblem rp) {
// Links limitation
List<Task> tasksListUp = new ArrayList<>();
List<Task> tasksListDown = new ArrayList<>();
List<IntVar> heightsListUp = new ArrayList<>();
List<IntVar> heightsListDown = new ArrayList<>();
for (Link l : net.getLinks()) {
for (VM vm : rp.getVMs()) {
VMTransition a = rp.getVMAction(vm);
if (a instanceof RelocatableVM && !a.getDSlice().getHoster().isInstantiatedTo(a.getCSlice().getHoster().getValue())) {
Node src = source.getMapping().getVMLocation(vm);
Node dst = rp.getNode(a.getDSlice().getHoster().getValue());
List<Link> path = net.getRouting().getPath(src, dst);
// Check first if the link is on migration path
if (path.contains(l)) {
// Get link direction
LinkDirection linkDirection = net.getRouting().getLinkDirection(src, dst, l);
// UpLink
if (linkDirection == LinkDirection.UPLINK) {
tasksListUp.add(((RelocatableVM) a).getMigrationTask());
heightsListUp.add(((RelocatableVM) a).getBandwidth());
} else // DownLink
{
tasksListDown.add(((RelocatableVM) a).getMigrationTask());
heightsListDown.add(((RelocatableVM) a).getBandwidth());
}
}
}
}
if (!tasksListUp.isEmpty()) {
// Post the cumulative constraint for the current UpLink
csp.post(csp.cumulative(tasksListUp.toArray(new Task[tasksListUp.size()]), heightsListUp.toArray(new IntVar[heightsListUp.size()]), csp.intVar(l.getCapacity()), true));
tasksListUp.clear();
heightsListUp.clear();
}
if (!tasksListDown.isEmpty()) {
// Post the cumulative constraint for the current DownLink
csp.post(csp.cumulative(tasksListDown.toArray(new Task[tasksListDown.size()]), heightsListDown.toArray(new IntVar[heightsListDown.size()]), csp.intVar(l.getCapacity()), true));
tasksListDown.clear();
heightsListDown.clear();
}
}
}
use of org.chocosolver.solver.variables.Task in project scheduler by btrplace.
the class CNetwork method addSwitchConstraints.
/**
* Add the cumulative constraints for each blocking switch (having limited capacity)
*
* @param rp the reconfiguration problem
*/
private void addSwitchConstraints(ReconfigurationProblem rp) {
// Switches capacity limitation
List<Task> tasksList = new ArrayList<>();
List<IntVar> heightsList = new ArrayList<>();
for (Switch sw : net.getSwitches()) {
// Only if the capacity is limited
if (sw.getCapacity() != Integer.MAX_VALUE) {
for (VM vm : rp.getVMs()) {
VMTransition a = rp.getVMAction(vm);
if (a != null && a instanceof RelocatableVM) {
if (a.getDSlice().getHoster().isInstantiated()) {
if (a.getCSlice().getHoster().getValue() != a.getDSlice().getHoster().getValue()) {
Node src = source.getMapping().getVMLocation(vm);
Node dst = rp.getNode(a.getDSlice().getHoster().getValue());
if (!Collections.disjoint(net.getConnectedLinks(sw), net.getRouting().getPath(src, dst))) {
tasksList.add(new Task(a.getStart(), a.getDuration(), a.getEnd()));
heightsList.add(((RelocatableVM) a).getBandwidth());
}
}
}
}
}
if (!tasksList.isEmpty()) {
// Post the cumulative constraint for the current switch
csp.post(csp.cumulative(tasksList.toArray(new Task[tasksList.size()]), heightsList.toArray(new IntVar[heightsList.size()]), csp.intVar(sw.getCapacity()), true));
tasksList.clear();
heightsList.clear();
}
}
}
}
use of org.chocosolver.solver.variables.Task in project scheduler by btrplace.
the class IssuesTest method testIssue5a.
/**
* Another test related to issue #5.
*
* @throws org.btrplace.scheduler.SchedulerException
*/
@Test
public void testIssue5a() throws SchedulerException, ContradictionException {
Model model = new DefaultModel();
Node n1 = model.newNode();
Node n2 = model.newNode();
Node n3 = model.newNode();
VM vm1 = model.newVM();
VM vm2 = model.newVM();
ShareableResource resources = new ShareableResource("vcpu", 1, 1);
resources.setCapacity(n1, 2);
resources.setCapacity(n2, 2);
Mapping map = model.getMapping().on(n1, n2).off(n3).run(n1, vm1, vm2);
model.attach(resources);
ReconfigurationProblem rp = new DefaultReconfigurationProblemBuilder(model).build();
List<IntVar> VMsOnAllNodes = rp.getNbRunningVMs();
int NUMBER_OF_NODE = map.getAllNodes().size();
// Each element is the number of VMs on each node
IntVar[] vmsOnInvolvedNodes = new IntVar[NUMBER_OF_NODE];
BoolVar[] busy = new BoolVar[NUMBER_OF_NODE];
rp.getEnd().updateUpperBound(10, Cause.Null);
int i = 0;
int maxVMs = rp.getSourceModel().getMapping().getAllVMs().size();
for (Node n : map.getAllNodes()) {
vmsOnInvolvedNodes[i] = rp.getModel().intVar("nVMs", -1, maxVMs, true);
IntVar state = rp.getNodeAction(n).getState();
// If the node is offline -> the temporary variable is -1, otherwise, it equals the number of VMs on that node
Constraint elem = rp.getModel().element(vmsOnInvolvedNodes[i], new IntVar[] { rp.getModel().intVar(-1), VMsOnAllNodes.get(rp.getNode(n)) }, state, 0);
rp.getModel().post(elem);
// IF the node is online and hosting VMs -> busy = 1.
busy[i] = rp.getModel().boolVar("busy" + n);
ChocoUtils.postIfOnlyIf(rp, busy[i], rp.getModel().arithm(vmsOnInvolvedNodes[i], ">=", 1));
i++;
}
// idle is equals the number of vmsOnInvolvedNodes with value 0. (The node without VM)
IntVar idle = rp.getModel().intVar("Nidles", 0, NUMBER_OF_NODE, true);
rp.getModel().post(rp.getModel().count(0, vmsOnInvolvedNodes, idle));
// idle should be less than Amount for MaxSN (0, in this case)
rp.getModel().post(rp.getModel().arithm(idle, "<=", 0));
// Extract all the state of the involved nodes (all nodes in this case)
IntVar[] states = new IntVar[NUMBER_OF_NODE];
int j = 0;
for (Node n : map.getAllNodes()) {
states[j++] = rp.getNodeAction(n).getState();
}
// In case the number of VMs is inferior to the number of online nodes, some nodes have to shutdown
// to satisfy the constraint. This could be express as:
// The addition of the idle nodes and busy nodes should be equals the number of online nodes.
IntVar sumStates = rp.getModel().intVar("sumStates", 0, 1000, true);
rp.getModel().post(rp.getModel().sum(states, "=", sumStates));
IntVar sumBusy = rp.getModel().intVar("sumBusy", 0, 1000, true);
rp.getModel().post(rp.getModel().sum(states, "=", sumBusy));
IntVar sumIB = rp.getModel().intVar("ib", 0, 1000, true);
@SuppressWarnings("unused") Task task = new Task(sumBusy, idle, sumIB);
// solver.eq(sumStates, sumIB));
rp.getModel().post(rp.getModel().arithm(sumStates, "=", sumIB));
ReconfigurationPlan plan = rp.solve(0, false);
Assert.assertNotNull(plan);
}
Aggregations