...
 
Commits (3)
......@@ -10,7 +10,10 @@ class IndepDP3Demi : public IndepDualGeneric {
protected:
double tryGuess(Instance &, std::vector<int> taskSet, std::vector<double>& loads,
double target, IndepResult & result, bool getResult);
double discretizationConstant = 3.0;
double discretizationConstant = 3.0;
#ifdef WITH_CPLEX
bool solveWithCplex;
#endif
public:
IndepDP3Demi(const AlgOptions& opt);
......
......@@ -6,11 +6,24 @@
#include <cmath>
#include "util.h"
#ifdef WITH_CPLEX
#include <ilcplex/ilocplex.h>
ILOSTLBEGIN
#endif
using namespace std;
IndepDP3Demi::IndepDP3Demi(const AlgOptions& opt): IndepDualGeneric(opt) {
discretizationConstant = opt.asDouble("disc", discretizationConstant);
discretizationConstant = opt.asDouble("disc", discretizationConstant);
#ifdef WITH_CPLEX
solveWithCplex = opt.asString("cplex", "false") == "true";
#else
if(opt.isPresent("cplex"))
cerr << "Warning: DP3demi: pmtool compiled without cplex support, ignoring 'cplex' option." << endl;
#endif
}
......@@ -31,6 +44,61 @@ double IndepDP3Demi::tryGuess(Instance& instance, std::vector<int> taskSet, vect
double maxGPUload = target * nbGPU - existingGPUload;
if(maxGPUload < 0) maxGPUload = 1;
#ifdef WITH_CPLEX
if(solveWithCplex) {
IloEnv env;
IloModel model = IloModel(env);
IloNumVarArray affect(env, taskSet.size(), 0.0, 1.0, ILOINT); // 0 means on CPU, 1 on GPU
IloExpr nbTasksWithLargeCPUTime(env);
IloExpr nbTasksWithLargeGPUTime(env);
IloExpr totalCPULoad(env);
IloExpr totalGPULoad(env);
for(int i = 0; i < taskSet.size(); ++i) {
int t = taskSet[i];
int taskType = instance.taskTypes[t];
const double exec0 = instance.execTimes[0][taskType];
const double exec1 = instance.execTimes[1][taskType];
if(exec0 > target / 2)
nbTasksWithLargeCPUTime += (1-affect[i]);
if(exec1 > target/2)
nbTasksWithLargeGPUTime += affect[i];
totalCPULoad += (1-affect[i])*exec0;
totalGPULoad += affect[i]*exec1;
}
model.add(nbTasksWithLargeCPUTime <= nbCPU);
model.add(nbTasksWithLargeGPUTime <= nbGPU);
model.add(totalGPULoad <= maxGPUload);
model.add(IloMinimize(env, totalCPULoad));
IloCplex modelCplex = IloCplex(model);
if(verbosity <= 8)
modelCplex.setOut(env.getNullStream());
IloBool feasible = modelCplex.solve();
if(! feasible)
return std::numeric_limits<double>::infinity();
double value = modelCplex.getObjValue();
if(getResult) {
result[0].clear();
result[1].clear();
IloNumArray affectValues(env);
modelCplex.getValues(affectValues, affect);
for(int i = 0; i < taskSet.size(); ++i)
if(affectValues[i] > 0.5)
result[1].push_back(i);
else
result[0].push_back(i);
}
return value + existingCPUload;
}
#endif
double ratio = target / (discretizationConstant * taskSet.size());
vector<int> discreteGPUtimings(instance.nbTaskTypes);
......@@ -61,7 +129,7 @@ double IndepDP3Demi::tryGuess(Instance& instance, std::vector<int> taskSet, vect
for(int i = 1; i < length; i++)
CPUload[i] = CPUload[i-1] + stateSpaceSize;
#define getTabValue(tab, l, m, k) (tab[l + (N+1)*m + (N+1)*(maxMu+1)*k])
#define getTabValue(tab, l, m, k) (tab[l + (N+1)*(m) + (N+1)*(maxMu+1)*(k)])
if(verbosity >= 7)
......@@ -78,12 +146,15 @@ double IndepDP3Demi::tryGuess(Instance& instance, std::vector<int> taskSet, vect
const double exec1 = instance.execTimes[1][taskType];
const int discreteGPUtime = discreteGPUtimings[taskType];
const int muOffset = exec0 > target ? 1 : 0;
const int nuOffset = exec1 > target ? 1 : 0;
const int muOffset = exec0 > (target/2) ? 1 : 0;
const int nuOffset = exec1 > (target/2) ? 1 : 0;
if(exec0 > target && exec1 > target)
return -1; // Problem is not feasible: task t cannot be placed on any resource
if(verbosity >= 8)
cout << "Task " << t << " dGPUTime="<< discreteGPUtime << " exec0=" << exec0 << " muOffset="<<muOffset << " nuOffset="<<nuOffset << endl;
if((exec0 <= target) && (exec1 <= target)) { // Task t can be placed on both resources
for(int mu = maxMu; mu >= muOffset; --mu) {
for(int nu = maxNu; nu >= nuOffset; --nu) {
......@@ -151,22 +222,29 @@ double IndepDP3Demi::tryGuess(Instance& instance, std::vector<int> taskSet, vect
}
}
index = nextIndex;
}
index = nextIndex;
if(verbosity >= 8) {
cout << "DP3Demi: state after task " << t << endl;
for(int mu = 0; mu <= maxMu; ++mu)
for(int nu = 0; nu <= maxNu; ++nu) {
cout << " ";
for(int l = 0; l <= N; ++l)
cout << " " << getTabValue(CPUload[index], l, mu, nu);
cout << endl;
}
}
double value = getTabValue(CPUload[index], N, maxMu, maxNu);
if(value == std::numeric_limits<double>::infinity()) {
// Problem not feasible.
return -1;
}
double value = getTabValue(CPUload[index], N, maxMu, maxNu);
if(verbosity >= 7)
cerr << "DP3demi: final value is " << value << endl;
int gLoad = N;
int mu = maxMu;
int nu = maxNu;
if(getResult) {
if(getResult && (value != std::numeric_limits<double>::infinity())) {
result[0].clear();
result[1].clear();
......