Attention une mise à jour du serveur va être effectuée le lundi 17 mai entre 13h et 13h30. Cette mise à jour va générer une interruption du service de quelques minutes.

Commit 0b1e6d24 authored by EYRAUD-DUBOIS Lionel's avatar EYRAUD-DUBOIS Lionel

Many bugfixes. Indep seems to work now.

parent b7cf3ce8
......@@ -5,6 +5,7 @@
#include <vector>
#include <set>
#include <string>
#include <iostream>
using namespace std;
......@@ -13,34 +14,50 @@ typedef set<int, rankCompare> rankSet;
class IB_ActionOnIdle : public SchedAction {
protected:
vector<rankSet> allocated;
vector<double> scheduledLoad;
Instance& instance;
rankSet unassignedTasks;
//Not sure what the correct structure is.
IndepAllocator &allocator;
bool hasChanged = true;
vector<double> endtimesWorkers;
public:
IB_ActionOnIdle(Instance& ins, rankSet queueProto, IndepAllocator &alloc)
: allocated(ins.nbWorkerTypes, queueProto), scheduledLoad(ins.nbWorkerTypes, 0),
instance(ins), unassignedTasks(queueProto), allocator(alloc) {
: allocated(ins.nbWorkerTypes, queueProto), instance(ins), unassignedTasks(queueProto),
allocator(alloc), endtimesWorkers(ins.totalWorkers, 0) {
}
void onSchedule(int task, int worker, double start, double end) {
int t = getType(task, instance.nbWorkers, NULL);
int t = getType(worker, instance.nbWorkers, NULL);
cout << "Erasing task " << task << " from type " << t << endl;
allocated[t].erase(task);
scheduledLoad[t] += instance.execTimes[t][instance.taskTypes[task]];
// scheduledLoad[t] += instance.execTimes[t][instance.taskTypes[task]];
endtimesWorkers[worker] = end;
}
void onTaskPush(int task) {
unassignedTasks.insert(task);
hasChanged = true;
}
int chooseTask(int wType) {
int chooseTask(int wType, double now) {
cout << "Choosing task for " << wType << ", allocated = " << allocated[wType] << endl;
cout << " now = " << now << ", ETW = " << endtimesWorkers << endl;
auto task = allocated[wType].begin();
if(task == allocated[wType].end()) {
if((task == allocated[wType].end()) && hasChanged) {
// Worker type t is idle, call alloc->compute
vector<int> readyTasks(unassignedTasks.begin(), unassignedTasks.end());
for(auto type = allocated.begin(); type != allocated.end(); type++) {
readyTasks.insert(readyTasks.end(), type->begin(), type->end());
type->clear();
}
vector<double> scheduledLoad(instance.nbWorkerTypes, 0);
int j = 0;
for(int t = 0; t < instance.nbWorkerTypes; t++) {
for(int k = 0; k < instance.nbWorkers[t]; k++, j++) {
scheduledLoad[t] += std::max(0.0, endtimesWorkers[j] - now);
}
}
cout << " SchedLoad: " << scheduledLoad << endl;
vector<vector<int> > result = allocator.compute(instance, readyTasks, scheduledLoad);
int i = 0;
for(auto&& v:result) {
......@@ -48,10 +65,10 @@ public:
i++;
}
unassignedTasks.clear();
hasChanged = false;
task = allocated[wType].begin();
if(task == allocated[wType].end()) return -1;
}
if(task == allocated[wType].end()) return -1;
return *task;
}
};
......
......@@ -12,7 +12,7 @@ using namespace std;
// returns minimum CPU load
double IndepDP2::tryGuess(Instance& instance, std::vector<int> taskSet, double maxGPUload, double maxlen,
IndepResult result, bool getResult) {
IndepResult &result, bool getResult) {
// CPUload(i, g) := smallest load on CPU from the first i tasks,
// with at most g load on GPU
// So need to discretize the GPU load ? Yes. Paper says with a ratio of lambda/3n
......@@ -23,20 +23,26 @@ double IndepDP2::tryGuess(Instance& instance, std::vector<int> taskSet, double m
result[0].clear();
result[1].clear();
}
if(maxGPUload < 0) maxGPUload = 1;
double ratio = maxGPUload / (3.0 * taskSet.size());
double ratio = maxGPUload / (30.0 * taskSet.size());
vector<int> discreteGPUtimings(instance.nbTaskTypes);
for(int i = 0; i < instance.nbTaskTypes; i++)
discreteGPUtimings[i] = instance.execTimes[1][i] / ratio;
const int N = maxGPUload / ratio;
discreteGPUtimings[i] = ceil(instance.execTimes[1][i] / ratio);
const int N = ceil(maxGPUload / ratio);
/* for(auto && t : taskSet)
N += discreteGPUtimings[instance.taskTypes[t]]; */
int length = getResult ? taskSet.size() + 1 : 1;
double CPUload[length][N];
double CPUload[length][N+1];
cout << "TryGuess: maxGLoad = " << maxGPUload << ", ratio = " << ratio << " N= " << N << " gR: " << getResult << " mL " << maxlen << endl;
int index = 0;
for(int i = 0; i <= N; i++)
CPUload[index][i] = 0;
for(int t : taskSet) {
cout << "tryGuess: doing task " << t << " TS: " << taskSet << endl;
// cout << "tryGuess: doing task " << t << " TS: " << taskSet << endl;
int taskType = instance.taskTypes[t];
int nextIndex = getResult ? index+1: index;
for(int l = N; l >= 0; l--) {
......@@ -50,7 +56,7 @@ double IndepDP2::tryGuess(Instance& instance, std::vector<int> taskSet, double m
CPUload[nextIndex][l] = newLoad;
}
if(getResult) index++;
cout << "tryGuess: still doing task " << t << ", index = " << index << " TS: " << taskSet << endl;
// cout << "tryGuess: still doing task " << t << ", index = " << index << " TS: " << taskSet << endl;
}
double value = CPUload[index][N];
......@@ -59,10 +65,10 @@ double IndepDP2::tryGuess(Instance& instance, std::vector<int> taskSet, double m
for(; index > 0; index--) {
int taskType = instance.taskTypes[taskSet[index-1]];
if(CPUload[index][gLoad] == CPUload[index-1][gLoad] + instance.execTimes[0][taskType])
result[0].push_back(index-1);
result[0].push_back(taskSet[index-1]);
else {
gLoad -= discreteGPUtimings[taskType];
result[1].push_back(index-1);
result[1].push_back(taskSet[index-1]);
}
}
}
......@@ -77,6 +83,14 @@ IndepResult IndepDP2::compute(Instance& instance, vector<int> taskSet, vector<do
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 << "IndepDP2: called with TS=" << taskSet << " and loads=" << loads << endl;
}
if(taskSet.size() == 0)
return result;
......@@ -101,17 +115,17 @@ IndepResult IndepDP2::compute(Instance& instance, vector<int> taskSet, vector<do
}
for(int i = 0; i < instance.nbTaskTypes; i++) {
TypeData &d = taskTypes[i];
d.CPUtime = instance.execTimes[0][i];
d.GPUtime = instance.execTimes[1][i];
d.ratio = taskTypes[i].CPUtime / taskTypes[i].GPUtime;
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)
low = max(low, min(d.CPUtime, d.GPUtime));
low = max(low, min(instance.execTimes[0][i], instance.execTimes[1][i]));
}
sort(taskTypes.begin(), taskTypes.end(), [&] (TypeData a, TypeData b) {
return (a.ratio > b.ratio);
});
double CPUload = loads[0], GPUload = loads[1];
double CPUload = loads[0] / nbCPU, GPUload = loads[1] / nbGPU;
int g = 0; int c = instance.nbTaskTypes - 1;
while(g != c) {
TypeData & d = taskTypes[g]; TypeData &e = taskTypes[c];
......@@ -134,9 +148,13 @@ IndepResult IndepDP2::compute(Instance& instance, vector<int> taskSet, vector<do
firstguess = 1.15*area;
}
double target = firstguess;
double r = tryGuess(instance, taskSet, target - loads[1], target, result, target == low);
if(r <= target*(1+ epsilon))
double r = tryGuess(instance, taskSet, target * nbGPU - loads[1], target, result, target == low);
if(verbosity >= 4)
cout << "IndepDP2: firstguess = "<< firstguess << ", area = " << area << ", result = " << r << " mkspan = " << (r+loads[0])/ nbCPU << endl;
if((r + loads[0])/nbCPU <= target*(1+ epsilon))
up = firstguess;
else
low = firstguess;
......@@ -148,14 +166,17 @@ IndepResult IndepDP2::compute(Instance& instance, vector<int> taskSet, vector<do
else
target = 1.15*low;
double r = tryGuess(instance, taskSet, target - loads[1], target, result, (target - low) <= 3*epsilon*low);
if(r <= target * (1+ epsilon))
double r = tryGuess(instance, taskSet, target * nbGPU - loads[1], target, result, abs(target - low) <= 3*epsilon*low);
if(verbosity >= 4)
cout << "IndepDP2: TARGET = "<< target << ", result = " << r << " mkspan= " << (r+loads[0])/ nbCPU << endl;
if((r + loads[0]) /nbCPU <= target * (1+ epsilon))
up = target;
else
low = target;
}
cout << "Result of IndepDP2: " << result << endl;
if(verbosity >= 4)
cout << "Result of IndepDP2: " << result << endl;
return result;
}
......@@ -9,7 +9,7 @@ class IndepDP2 : public IndepAllocator {
protected:
double tryGuess(Instance &, std::vector<int> taskSet, double maxGPUload, double maxlen,
IndepResult result, bool getResult);
IndepResult & result, bool getResult);
double epsilon = 0.01;
public:
......
......@@ -52,7 +52,7 @@ double ListAlgorithm::compute(Instance& ins, SchedAction* action) {
vector<double> endtimesWorkers(nbWorkers, 0);
vector<double> endtimesTasks(n, -1);
vector<bool> leaveIdle(nbWorkers, false);
vector<bool> leaveIdle(ins.nbWorkerTypes, false);
vector<bool> finishedTasks(n, false);
vector<int> nbDep(n, 0);
......@@ -77,16 +77,24 @@ double ListAlgorithm::compute(Instance& ins, SchedAction* action) {
int t = getType(idle, ins.nbWorkers, &index);
int chosenTask;
if((action != NULL) && ((chosenTask = action->chooseTask(t)) != SCHEDACTION_NONE)) {
if(chosenTask < 0)
leaveIdle[idle] = true;
if((action != NULL) && ((chosenTask = action->chooseTask(t, currentTime)) != SCHEDACTION_NONE)) {
if(chosenTask < 0) {
if(verbosity >= 5)
cout << "List: leaving type " << t << " idle." << endl;
leaveIdle[t] = true;
}
} else {
chosenTask = *(readyTasks.begin());
}
if(chosenTask >= 0)
{
readyTasks.erase(chosenTask);
if(chosenTask >= 0) {
auto chosenTaskIt = readyTasks.find(chosenTask);
if(chosenTaskIt == readyTasks.end()) {
cerr << "List: chosenTask " << chosenTask << " not present in readyTasks " << readyTasks << endl;
throw(1);
}
readyTasks.erase(chosenTaskIt);
double finishTime = currentTime + ins.execTimes[t][ins.taskTypes[chosenTask]];
if(verbosity >= 1)
cout << "LIST " << chosenTask << " " << ins.taskTypes[chosenTask] << " " << currentTime << " " << finishTime << " " << idle << " " << t << endl;
......@@ -99,12 +107,16 @@ double ListAlgorithm::compute(Instance& ins, SchedAction* action) {
}
double nextTime = currentTime;
idle = -1;
for(i = 0; i < nbWorkers; i++)
if(leaveIdle[i] == false)
if((idle == -1) || (endtimesWorkers[i] < nextTime))
{ idle = i; nextTime = endtimesWorkers[i];
}
idle = -1; i = 0;
if(verbosity >= 5)
cout << "List: looking for idle proc. LI: " << leaveIdle <<", ETW: " << endtimesWorkers << endl;
for(int k = 0; k < ins.nbWorkerTypes; k++)
for(int j = 0; j < ins.nbWorkers[k]; j++, i++)
if((leaveIdle[k] == false) || endtimesWorkers[i] > currentTime)
if((idle == -1) || (endtimesWorkers[i] < nextTime))
{
idle = i; nextTime = endtimesWorkers[i];
}
if(idle == -1) {
cerr << "Found no eligible worker. Ready set size = " << readyTasks.size() << endl;
throw(-1);
......@@ -122,7 +134,7 @@ double ListAlgorithm::compute(Instance& ins, SchedAction* action) {
for(j = 0; j < (int) revDependencies[i].size(); j++) {
int k = revDependencies[i][j];
nbDep[k]--;
if(verbosity >= 3)
if(verbosity >= 7)
cout << " Dependent task: " << k << " remaining dependencies: " << nbDep[k] << endl;
if(nbDep[k] == 0){
auto r = readyTasks.insert(k);
......@@ -131,8 +143,8 @@ double ListAlgorithm::compute(Instance& ins, SchedAction* action) {
throw(-1);
}
if(action != NULL) {
action->onTaskPush(i);
for(int l = 0; l < nbWorkers; l++)
action->onTaskPush(k);
for(int l = 0; l < ins.nbWorkerTypes; l++)
leaveIdle[l] = false;
}
}
......
......@@ -15,10 +15,10 @@ void ActionSequence::onTaskPush(int t) {
for (std::vector<SchedAction*>::iterator it = actions.begin() ; it != actions.end(); ++it)
(*it)->onTaskPush(t);
}
int ActionSequence::chooseTask(int wType) {
int ActionSequence::chooseTask(int wType, double now) {
int tmp;
for (std::vector<SchedAction*>::iterator it = actions.begin() ; it != actions.end(); ++it)
if( (tmp = (*it)->chooseTask(wType)) != SCHEDACTION_NONE)
if( (tmp = (*it)->chooseTask(wType, now)) != SCHEDACTION_NONE)
return tmp;
return SCHEDACTION_NONE;
}
......
......@@ -10,7 +10,7 @@
class SchedAction {
public:
virtual void onSchedule(int task, int worker, double startTime, double endTime) { }
virtual int chooseTask(int wType) {return SCHEDACTION_NONE; }
virtual int chooseTask(int wType, double now) {return SCHEDACTION_NONE; }
virtual void onTaskPush(int task) { }
};
......@@ -22,7 +22,7 @@ class ActionSequence : public SchedAction {
void add(SchedAction *a);
void onSchedule(int i, int w, double s, double f);
void onTaskPush(int t);
int chooseTask(int wType);
int chooseTask(int wType, double now);
};
class ExportToFile : public SchedAction {
......
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