Commit 018ede3b authored by EYRAUD-DUBOIS Lionel's avatar EYRAUD-DUBOIS Lionel

One more forgotten file

parent 059c20bb
#include "IndepDualGeneric.h"
#include <iostream>
#include <limits>
#include <new>
#include <algorithm>
#include <cmath>
#include "util.h"
using namespace std;
IndepDualGeneric::IndepDualGeneric(const AlgOptions& opt): IndepAllocator(opt) {
verbosity = opt.asInt("verb_dual", verbosity);
epsilon = opt.asDouble("eps", epsilon);
}
// Arbitrary convention: CPU times are index 0, GPU times are index 1. Just a naming thing.
IndepResult IndepDualGeneric::compute(Instance& instance, vector<int> &taskSet, vector<double> &loads) {
// This class could be generalized if needed, but it would require
// another lower bound, so it has a cost. Do it if needed only
if(instance.nbWorkerTypes != 2) {
cerr << "IndepDualGeneric: only implemented for instances with 2 worker types" << endl;
throw(1);
}
IndepResult result(2); // 2 because there are two resource types.
int nbCPU = instance.nbWorkers[0];
int nbGPU = instance.nbWorkers[1];
if(verbosity >= 4) {
cout << "IndepDualGeneric: called with TS=" << taskSet << " and loads=" << loads << endl;
// cout << " CPU times: ";
// for(int i : taskSet) cout << instance.execType(0, i) << " ";
// cout << endl;
// cout << " GPU times: ";
// for(int i : taskSet) cout << instance.execType(1, i) << " ";
// cout << endl;
}
if(taskSet.size() == 0)
return result;
double minload = min(loads[0], loads[1]);
loads[0] -= minload;
loads[1] -= minload;
double low = lowerBoundTwoResource(instance, taskSet, loads[0], loads[1]);
double up = std::numeric_limits<double>::infinity();
double target;
bool haveResult = false;
while(abs(up - low) > epsilon*low) {
if(up != std::numeric_limits<double>::infinity())
target = (up + low) / 2;
else
target = 1.15*low;
bool askForResult = abs(target - low) <= 3*epsilon*low;
double r = tryGuess(instance, taskSet, loads, target, result, askForResult);
if(verbosity >= 6)
cout << "IndepDualGeneric: TARGET = "<< target << ", result = " << r << " mkspan= " << r/ nbCPU << endl;
if((r != -1) && (r/nbCPU <= target * (1+ epsilon))) {
up = target;
haveResult = askForResult;
}
else {
low = target;
}
}
if(! haveResult) {
double r = tryGuess(instance, taskSet, loads, up, result, true);
if(verbosity >= 6)
cout << "IndepDualGeneric: TARGET = "<< up << ", result = " << r << " mkspan= " << (r+loads[0])/ nbCPU << endl;
}
return result;
}
double lowerBoundTwoResource(Instance& instance, vector<int> taskSet,
double CPUload, double GPUload) {
if(instance.nbWorkerTypes != 2) {
cerr << "lowerBoundTwoResources: only implemented for instances with 2 worker types" << endl;
throw(1);
}
int nbCPU = instance.nbWorkers[0];
int nbGPU = instance.nbWorkers[1];
double longest = 0;
struct TypeData {
int nbTasks;
double CPUtime;
double GPUtime;
double ratio;
};
vector<TypeData> taskTypes(instance.nbTaskTypes);
for(auto &&t: taskSet) {
taskTypes[instance.taskTypes[t]].nbTasks++;
}
for(int i = 0; i < instance.nbTaskTypes; i++) {
TypeData &d = taskTypes[i];
d.CPUtime = instance.execTimes[0][i] / nbCPU;
d.GPUtime = instance.execTimes[1][i] / nbGPU;
d.ratio = instance.execTimes[0][i] / instance.execTimes[1][i];
if(d.nbTasks > 0)
longest = max(longest,
min(instance.execTimes[0][i], instance.execTimes[1][i]));
}
sort(taskTypes.begin(), taskTypes.end(), [&] (TypeData a, TypeData b) {
return (a.ratio > b.ratio);
});
double CPUlen = CPUload / nbCPU, GPUlen = GPUload / nbGPU;
int g = 0; int c = instance.nbTaskTypes - 1;
while(g != c) {
TypeData & d = taskTypes[g]; TypeData &e = taskTypes[c];
if(GPUlen + d.nbTasks * d.GPUtime <= CPUlen + e.nbTasks * e.CPUtime) {
GPUlen += d.nbTasks * d.GPUtime;
g++;
} else {
CPUlen += e.nbTasks * e.CPUtime;
c--;
}
}
TypeData &d = taskTypes[g];
double remCPU = d.nbTasks * d.CPUtime;
double remGPU = d.nbTasks * d.GPUtime;
double area;
if(remCPU + CPUlen <= GPUlen)
area = GPUlen ;
else if(remGPU + GPUlen <= CPUlen)
area = CPUlen;
else
area = (CPUlen*remGPU +remGPU * remCPU + GPUlen * remCPU) / (remCPU + remGPU);
// cout << "LB: " << area << " " << longest << " " << remCPU << " " << remGPU << " " << CPUlen << " " << GPUlen << " " << g << " " << c << endl;
/*for(auto &&t: taskTypes) {
cout << " " << t.nbTasks << " " << t.CPUtime << " " << t.GPUtime <<" " << t.ratio << endl;
} */
return max(area, longest);
}
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 to comment