#include <iomanip>
#include <iostream>
#include <vector>
#include "algotester_generator.h"
using namespace std;
const int BURST_NUM_MIN = 2;
const int BURST_NUM_MAX = 100;
const double TAU_MIN = 0.01;
const double TAU_MAX = 1;
const int QUERY_NUM_MIN = 10;
const int QUERY_NUM_MAX = 1000;
const int IO_MIN = 10;
const int IO_MAX = 1000;
const int COMPUTE_UNITS_MIN = 2;
const int COMPUTE_UNITS_MAX = 10;
const int BILLION = 1000'000'000;
struct ModelParams
{
int hiddenDim;
int layerNum;
long long modelParamNum;
};
const int MODELS_NUMBER = 5;
ModelParams models[MODELS_NUMBER] =
{
{4096, 32, 6700000000ll},
{5120, 50, 13000000000ll},
{6656, 60, 32500000000ll},
{8192, 80, 65200000000ll},
{12288, 96, 175000000000ll}
};
struct ComputeUnit
{
int deviceNum;
long long computatingAbility;
long long memoryCapacity;
long long memoryBandwidth;
long long commBandwidth;
};
const int COMPUTE_UNIT_NUMBER = 5;
ComputeUnit availableComputeUnits[COMPUTE_UNIT_NUMBER] =
{
{8, 156500000000000, 64000000000, 800000000000, 28000000000},
{8, 140000000000000, 32000000000, 400000000000, 28000000000},
{8, 131000000000000, 32000000000, 600000000000, 15000000000},
{8, 333500000000000, 80000000000, 1000000000000, 150000000000},
{8, 1000000000000000, 80000000000, 1500000000000, 225000000000}
};
vector<ComputeUnit> getComputeUnits(AlgotesterGenerator gen)
{
int machineNum = gen.randInt(COMPUTE_UNITS_MIN, COMPUTE_UNITS_MAX);
vector<ComputeUnit> computeUnits(machineNum);
for (int i = 0; i < machineNum; i++)
{
computeUnits[i] = availableComputeUnits[gen.randInt(COMPUTE_UNIT_NUMBER)];
}
return computeUnits;
}
struct QueryParams
{
double alpha;
double beta;
double gamma;
int burstNum;
vector<int> queryNumList;
vector<double> tauList;
vector<vector<int> > queryIList;
vector<vector<int> > queryOList;
};
const int SCENARIOS_NUMBER = 6;
double scenarios[SCENARIOS_NUMBER][8] =
{
{500, 200, 300, 50, 200, 50, 0.075, 0.01},
{400, 180, 70, 20, 400, 50, 0.38, 0.05},
{100, 40, 4000, 1500, 400, 40, 0.38, 0.05},
{200, 90, 200, 100, 4000, 1000, 0.45, 0.02},
{300, 140, 4000, 1500, 4000, 1500, 0.38, 0.05},
{250, 100, 110, 40, 1000, 1, 0.075, 0.01}
};
double clip(double val, double min, double max)
{
if (val < min) return min;
if (val > max) return max;
return val;
}
double round(double val, int magn)
{
return ((int) (val * magn)) / (double)magn;
}
QueryParams getQueryParams(AlgotesterGenerator& gen)
{
auto params = scenarios[gen.randInt(SCENARIOS_NUMBER)];
double alpha, beta, gamma;
while(true)
{
gamma = round(gen.randDoubleNormal(params[6], params[7]), 1000);
beta = round(gen.randDoubleNormal(params[6], params[7]), 1000);
alpha = 1 - gamma - beta;
if (gamma < 0 || gamma > 1) continue;
if (beta < 0 || beta > 1) continue;
if (alpha < 0 || alpha > 1) continue;
break;
}
int burstNum = gen.randInt(BURST_NUM_MIN, BURST_NUM_MAX);
vector<double> tauList(burstNum);
vector<int> queryNumList(burstNum);
vector<vector<int> > queryIList(burstNum);
vector<vector<int> > queryOList(burstNum);
for (int i = 0; i < burstNum; i++)
{
tauList[i] = i == burstNum - 1 ? 0 : gen.randDouble(TAU_MIN, TAU_MAX);
queryNumList[i] = clip(gen.randDoubleNormal(params[0], params[1]), QUERY_NUM_MIN, QUERY_NUM_MAX);
vector<int> iList(queryNumList[i]);
vector<int> oList(queryNumList[i]);
for (int j = 0; j < queryNumList[i]; j++)
{
iList[j] = clip(gen.randDoubleNormal(params[2], params[3]), IO_MIN, IO_MAX);
oList[j] = clip(gen.randDoubleNormal(params[2], params[3]), IO_MIN, IO_MAX);
}
queryIList[i] = iList;
queryOList[i] = oList;
}
return
{
alpha,
beta,
gamma,
burstNum,
queryNumList,
tauList,
queryIList,
queryOList
};
}
int main(int argc, char* argv[])
{
//ios::sync_with_stdio(false); cin.tie(0);
auto gen = initGenerator(argc, argv);
while(true)
{
auto model = models[gen.randInt(MODELS_NUMBER)];
auto queryParams = getQueryParams(gen);
auto computeUnits = getComputeUnits(gen);
bool isValid = true;
for (int i = 0; i < queryParams.burstNum; i++)
{
for (int j = 0; j < queryParams.queryNumList[i]; j++)
{
for (int k = 0; k < (int)computeUnits.size(); k++)
{
long long left = computeUnits[k].memoryCapacity * computeUnits[k].deviceNum;
long long right = 2 * model.modelParamNum + 4ll * model.layerNum * model.hiddenDim * (queryParams.queryIList[i][j] + queryParams.queryOList[i][j]);
if (left < right) isValid = false;
}
}
}
if (!isValid) continue;
cout<<setprecision(3)<<fixed;
cout << model.layerNum << ' ' << model.hiddenDim << ' ' << model.modelParamNum << endl;
cout << queryParams.alpha << ' ' << queryParams.beta << ' ' << queryParams.gamma << endl;
cout << computeUnits.size() << ' ' << queryParams.burstNum << endl;
for (int i = 0; i < (int)computeUnits.size(); i++)
{
cout << computeUnits[i].deviceNum << ' ' <<computeUnits[i].computatingAbility / BILLION << ' ' << computeUnits[i].memoryCapacity / BILLION << ' ' << computeUnits[i].memoryBandwidth / BILLION << ' ' << computeUnits[i].commBandwidth / BILLION << endl;
}
for (int i = 0; i < queryParams.burstNum; i++)
{
cout << queryParams.queryNumList[i] << ' ' << queryParams.tauList[i] << endl;
for (int j = 0; j < queryParams.queryNumList[i]; j++)
{
cout << queryParams.queryIList[i][j];
if (j != queryParams.queryNumList[i] - 1) cout<<' ';
}
cout<<endl;
for (int j = 0; j < queryParams.queryNumList[i]; j++)
{
cout << queryParams.queryOList[i][j];
if (j != queryParams.queryNumList[i] - 1) cout<<' ';
}
cout<<endl;
}
break;
}
return 0;
}