Files
SAPFOR/Sapfor/_src/Predictor/PredictorModel.cpp

1174 lines
41 KiB
C++
Raw Normal View History

2023-09-14 19:43:13 +03:00
#include "../Utils/leak_detector.h"
//#define _CRT_SECURE_NO_WARNINGS
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#ifdef _MSC_VER
#include <io.h>
#else
#include <sys/types.h>
#include <dirent.h>
#endif
#include "../Distribution/Distribution.h"
#include "../Distribution/DvmhDirective.h"
#include "../GraphLoop/graph_loops.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "PredictorInterface.h"
#include "PredictorModel.h"
using std::vector;
using std::map;
using std::set;
using std::to_string;
static void setVectorCallRet(FuncCall *f)
{
// <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vcall_time <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
f->vcall_time.resize(currentVM->getProcCount());
for (int k = 0; k < currentVM->getProcCount(); ++k)
f->vcall_time[k] = f->call_time / currentVM->getProcPower(k);
f->vret_time.resize(currentVM->getProcCount());
for (int k = 0; k < currentVM->getProcCount(); ++k)
f->vret_time[k] = f->ret_time / currentVM->getProcPower(k);
}
static int printInterval(Interval *inter)
{
for (int proc_no = 0; proc_no < MPSProcCount(); ++proc_no)
{
printf("proc[%d].Execution_time = %.8f\n", proc_no, inter->GetProcPred(proc_no, _Execution_time));
printf("proc[%d].CPU_time = %.8f\n", proc_no, inter->GetProcPred(proc_no, _CPU_time));
printf("proc[%d].CPU_time_usr = %.8f and 2x=%.8f\n", proc_no, inter->GetProcPred(proc_no, _CPU_time_usr), 2 * inter->GetProcPred(proc_no, _CPU_time_usr));
printf("proc[%d].CPU_time_sys = %.8f\n", proc_no, inter->GetProcPred(proc_no, _CPU_time_sys));
printf("proc[%d].Lost_time = %.8f\n", proc_no, inter->GetProcPred(proc_no, _Lost_time));
printf("proc[%d].Insuff_parallelism_usr = %.8f\n", proc_no, inter->GetProcPred(proc_no, _Insuff_parallelism_usr));
printf("proc[%d].Insuff_parallelism_sys = %.8f\n", proc_no, inter->GetProcPred(proc_no, _Insuff_parallelism_sys));
printf("proc[%d].Communication = %.8f\n", proc_no, inter->GetProcPred(proc_no, _Communication));
printf("proc[%d].Idle = %.8f\n", proc_no, inter->GetProcPred(proc_no, _Idle));
printf("\n");
}
return 0;
}
//====================================== model ====================================================================
//==============
static long arrayAddr = 1;
static long arrayAddrPtr = 10000;
static long ids = 1;
static long loopIds = 1;
static long redShIds = 1;
static long remIds = 1;
static map<DIST::Array*, long> mapArrayAddrs;
static map<DIST::Array*, long> mapArrayAddrsPtr;
static map<DIST::Array*, long> mapIds;
static map<LoopGraph*, long> mapLoopIds;
template<typename T>
static long getId(T object, map<T, long> &dict, long &counter)
{
auto it = dict.find(object);
if (it == dict.end())
dict[object] = counter++;
return dict[object];
}
static int Model_distr(DIST::Array *array, const DistrVariant *distrVar, FILE *printOut = NULL)
{
long cur_amv, cur_ps = 999; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> cur_amv_ptr (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> = cur_amv)
string debug = "";
{
FuncCall f;
f.func_id = crtamv_;
crtamv_Info *tmp_params = new crtamv_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = getId(array, mapIds, ids); //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cur_amv = tmp_params->ID;
tmp_params->AM_ID = cur_amv; //possible not
auto sizes = array->GetSizes();
tmp_params->SizeArray.resize(sizes.size());
const int rank = (int)sizes.size();
for (int i = rank - 1; i >= 0; --i)
tmp_params->SizeArray[rank - 1 - i] = sizes[i].second - sizes[i].first + 1;
tmp_params->StaticSign = 0; //possible not
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
if (printOut)
{
debug += "crtamv SizeArray=";
for (int i = 0; i < tmp_params->SizeArray.size(); ++i)
debug += " " + to_string(tmp_params->SizeArray[i]);
debug += "\n";
}
f.crtamv();
}
{
FuncCall f;
f.func_id = distr_;
distr_Info *tmp_params = new distr_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = cur_amv;
tmp_params->PSRef = cur_ps;
tmp_params->AxisArray.resize(0);
tmp_params->DistrParamArray.resize(0);
for (int i = 0; i < array->GetDimSize(); ++i)
{
if (distrVar->distRule[i] == dist::BLOCK)
{
tmp_params->AxisArray.push_back(array->GetDimSize() - i);
tmp_params->DistrParamArray.push_back(0); //possible not
}
}
if (printOut)
{
debug += "distr AxisArray=";
for (int i = 0; i < tmp_params->AxisArray.size(); ++i)
debug += " " + to_string(tmp_params->AxisArray[i]);
debug += "\n";
}
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.distr();
}
{
FuncCall f;
f.func_id = crtda_;
crtda_Info* tmp_params = new crtda_Info;
f.call_params = (void *)tmp_params; // point to parameters
const int rank = array->GetDimSize();
tmp_params->ArrayHeader = getId(array, mapArrayAddrs, arrayAddr);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->ArrayHandlePtr = getId(array, mapArrayAddrsPtr, arrayAddrPtr);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->ReDistrSign = 0; //poss not 3
tmp_params->StaticSign = 0; //poss not
tmp_params->TypeSize = array->GetTypeSize();
tmp_params->SizeArray.resize(rank);
tmp_params->LowShdWidthArray.resize(rank);
tmp_params->HiShdWidthArray.resize(rank);
auto sizes = array->GetSizes();
auto shadow = array->GetShadowSpec();
for (int i = rank - 1; i >= 0; --i)
{
tmp_params->SizeArray[rank - 1 - i] = sizes[i].second - sizes[i].first + 1;
tmp_params->LowShdWidthArray[rank - 1 - i] = shadow[i].first;
tmp_params->HiShdWidthArray[rank - 1 - i] = shadow[i].second;
}
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
if (printOut)
{
debug += "d crtda " + array->GetName() + "addr=" + to_string(tmp_params->ArrayHeader) + "\n";
debug += "d crtda SizeArray=";
for (int i = 0; i < tmp_params->SizeArray.size(); ++i)
debug += " " + to_string(tmp_params->SizeArray[i]);
debug += "\n";
debug += "d crtda LowShdWidthArray=";
for (int i = 0; i < tmp_params->LowShdWidthArray.size(); ++i)
debug += " " + to_string(tmp_params->LowShdWidthArray[i]);
debug += "\n";
debug += "d crtda HiShdWidthArray=";
for (int i = 0; i < tmp_params->HiShdWidthArray.size(); ++i)
debug += " " + to_string(tmp_params->HiShdWidthArray[i]);
debug += "\n";
}
f.crtda();
}
{
FuncCall f;
f.func_id = align_;
align_Info* tmp_params = new align_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ArrayHeader = getId(array, mapArrayAddrs, arrayAddr);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->ArrayHandlePtr = getId(array, mapArrayAddrsPtr, arrayAddrPtr);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->PatternRef = cur_amv;
tmp_params->PatternRefPtr = cur_amv;
tmp_params->PatternType = 1; //AMView
tmp_params->AxisArray.resize(array->GetDimSize());
tmp_params->CoeffArray.resize(array->GetDimSize());
tmp_params->ConstArray.resize(array->GetDimSize());
const int rank = array->GetDimSize();
for (int i = 0; i < rank; ++i)
{
tmp_params->AxisArray[i] = i + 1;
if (distrVar->distRule[rank - 1 - i] == dist::BLOCK)
tmp_params->ConstArray[i] = 0 - array->GetSizes()[rank - 1 - i].first;
else
tmp_params->ConstArray[i] = 0;
tmp_params->CoeffArray[i] = 1;
}
if (printOut)
{
debug += "d align AxisArray=";
for (int i = 0; i < tmp_params->AxisArray.size(); ++i)
debug += " " + to_string(tmp_params->AxisArray[i]);
debug += "\n";
}
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.align();
}
if (printOut)
fprintf(printOut, "%s", debug.c_str());
return 0;
}
static int Model_align(DIST::Array *array, const int regId, FILE *printOut = NULL)
{
DIST::Array *templ = array->GetTemplateArray(regId);
auto rule = array->GetAlignRulesWithTemplate(regId);
auto links = array->GetLinksWithTemplate(regId);
const int rank = array->GetDimSize();
string debug = "";
{
FuncCall f;
f.func_id = crtda_;
crtda_Info* tmp_params = new crtda_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ArrayHeader = getId(array, mapArrayAddrs, arrayAddr);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->ArrayHandlePtr = getId(array, mapArrayAddrsPtr, arrayAddrPtr);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->ReDistrSign = 0;
tmp_params->StaticSign = 0; //poss not
tmp_params->TypeSize = array->GetTypeSize(); //ch!!!
tmp_params->SizeArray.resize(rank);
tmp_params->LowShdWidthArray.resize(rank);
tmp_params->HiShdWidthArray.resize(rank);
auto shadow = array->GetShadowSpec();
debug += "v1->rank=" + to_string(rank) + " s->rank=" + to_string(shadow.size()) + "\n";
debug += "Sh_low ";
for (int i = 0; i < shadow.size(); ++i)
debug += " " + to_string(shadow[i].first);
debug += "\n";
debug += "Sh_high ";
for (int i = 0; i < shadow.size(); ++i)
debug += " " + to_string(shadow[i].second);
debug += "\n";
auto sizes = array->GetSizes();
for (int i = rank - 1; i >= 0; --i)
{
tmp_params->SizeArray[rank - 1 - i] = sizes[i].second - sizes[i].first + 1;
tmp_params->LowShdWidthArray[rank - 1 - i] = shadow[i].first;
tmp_params->HiShdWidthArray[rank - 1 - i] = shadow[i].second;
}
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
debug += "a crtda SizeArray=";
for (int i = 0; i < tmp_params->SizeArray.size(); ++i)
debug += " " + to_string(tmp_params->SizeArray[i]);
debug += "\n";
debug += "a crtda LowShdWidthArray=";
for (int i = 0; i < tmp_params->LowShdWidthArray.size(); ++i)
debug += " " + to_string(tmp_params->LowShdWidthArray[i]);
debug += "\n";
debug += "a crtda HiShdWidthArray=";
for (int i = 0; i < tmp_params->HiShdWidthArray.size(); ++i)
debug += " " + to_string(tmp_params->HiShdWidthArray[i]);
debug += "\n";
f.crtda();
}
{
FuncCall f;
f.func_id = align_;
align_Info* tmp_params = new align_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ArrayHeader = getId(array, mapArrayAddrs, arrayAddr);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->ArrayHandlePtr = getId(array, mapArrayAddrsPtr, arrayAddrPtr);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->PatternRef = getId(templ, mapArrayAddrsPtr, arrayAddrPtr); //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->PatternRefPtr = getId(templ, mapArrayAddrs, arrayAddr); //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->PatternType = 2; //Distr
tmp_params->AxisArray.resize(rank);
tmp_params->CoeffArray.resize(rank);
tmp_params->ConstArray.resize(rank);
for (int i = 0; i < rank; ++i)
{
if (links[rank - 1 - i] == -1)
{
tmp_params->AxisArray[i] = -1;
tmp_params->CoeffArray[i] = 0;
tmp_params->ConstArray[i] = 0;
}
else
{
tmp_params->AxisArray[i] = i + 1;
tmp_params->CoeffArray[i] = rule[rank - 1 - i].first;
tmp_params->ConstArray[i] = rule[rank - 1 - i].second - array->GetSizes()[rank - 1 - i].first;
}
}
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
debug += "a align AxisArray=";
for (int i = 0; i < tmp_params->AxisArray.size(); ++i)
debug += " " + to_string(tmp_params->AxisArray[i]);
debug += "\n";
f.align();
}
if (printOut)
fprintf(printOut, "%s", debug.c_str());
return 0;
}
double Model_Single_Rem(const pair<DIST::Array*, vector<long>> &dirRem)
{
long RID = -1;
FuncCall f;
f.func_id = crtrbp_;
crtrbp_Info* tmp_params = new crtrbp_Info;
f.call_params = (void *)tmp_params; // point to parameters
RID = tmp_params->ID = (remIds++);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->RemArrayHeader = getId(dirRem.first, mapArrayAddrs, arrayAddr);
tmp_params->StaticSign = 0; //may be not always
tmp_params->PSRef = 0;
tmp_params->IsLocal = 0;
tmp_params->CoordArray = dirRem.second; //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.crtrbp();
return f.ret_time + f.call_time;
}
static int findPosInParallel(vector<string> &parallel, const string &find)
{
int ret = -1;
for (int z = 0; z < parallel.size(); ++z)
if (parallel[z] == find)
return z + 1;
return ret;
}
static bool shadowExist(vector<pair<pair<string, string>, vector<pair<int, int>>>> &shadows)
{
for (auto &sh : shadows)
for (auto &elem : sh.second)
if (elem.first != 0 || elem.second != 0)
return true;
return false;
}
//==============
static int Model_par(LoopGraph *loop, ParallelDirective *directive, const set<DIST::Array*> &allArrays, FILE *printOut = NULL)
{
long LR = -1, RID = -1, RIDG = -1, SHG = -1, SHG1 = -1, SHG2 = -1, REMID = -1;
string debug = "";
//TODO: count of reduction elems
if (directive->reduction.size() || directive->reductionLoc.size()) //REDUCTION
{
{
FuncCall f;
f.func_id = crtrg_;
crtrg_Info* tmp_params = new crtrg_Info;
f.call_params = (void *)tmp_params; // point to parameters
RID = (redShIds++);
tmp_params->ID = RID;//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.crtrg();
}
RIDG = (redShIds++);
for (auto &redG : directive->reduction)
{
for (auto &red : redG.second)
{
FuncCall f;
f.func_id = crtred_;
crtred_Info* tmp_params = new crtred_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = RIDG; //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->LocElmLength = 0;
tmp_params->RedArrayLength = 1; // count of elem
tmp_params->RedArrayType = 1; // INT TYPE
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.crtred();
}
}
for (auto &redG : directive->reductionLoc)
{
for (auto &red : redG.second)
{
FuncCall f;
f.func_id = crtred_;
crtred_Info* tmp_params = new crtred_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = RIDG; //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->LocElmLength = std::get<2>(red); // count of loc elem
tmp_params->RedArrayLength = 1; // count of elem
tmp_params->RedArrayType = 1; // INT TYPE
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.crtred();
}
}
}
//PARLOOP
{
FuncCall f;
f.func_id = crtpl_;
crtpl_Info* tmp_params = new crtpl_Info;
f.call_params = (void *)tmp_params; // point to parameters
LR = tmp_params->ID = getId(loop, mapLoopIds, loopIds);
tmp_params->Rank = directive->parallel.size();
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.crtpl();
}
// TODO: add CORNER
if (shadowExist(directive->shadowRenew)) //SHADOW RENEW
{
{
FuncCall f;
f.func_id = crtshg_;
crtshg_Info *tmp_params = new crtshg_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ShadowGroupRef = (redShIds++);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SHG = tmp_params->ShadowGroupRef;
tmp_params->StaticSign = 0; //poss not
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.crtshg();
}
auto arraysInDir = fillArraysFromDir(loop->loop);
for (int j = 0; j < directive->shadowRenew.size(); ++j)
{
DIST::Array *shArray = NULL;
for (auto &elem : arraysInDir)
if (elem->GetName() == directive->shadowRenew[j].first.second)
shArray = elem;
checkNull(shArray, __FILE__, __LINE__);
FuncCall f;
f.func_id = inssh_;
inssh_Info* tmp_params = new inssh_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ShadowGroupRef = SHG;
tmp_params->ArrayHandlePtr = getId(shArray, mapArrayAddrsPtr, arrayAddrPtr);
tmp_params->ArrayHeader = getId(shArray, mapArrayAddrs, arrayAddr);
tmp_params->FullShdSign = 0; //CORNER
tmp_params->HiShdWidthArray.resize(0);
tmp_params->LowShdWidthArray.resize(0);
const int rank = shArray->GetDimSize();
for (int z = 0; z < rank; ++z)
{
tmp_params->HiShdWidthArray.push_back(directive->shadowRenew[j].second[rank - 1 - z].second);
tmp_params->LowShdWidthArray.push_back(directive->shadowRenew[j].second[rank - 1 - z].first);
}
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
debug += "ins_sh " + shArray->GetShortName() + " ArrayPtr=" + to_string(tmp_params->ArrayHeader) + "\n";
f.inssh();
}
{
FuncCall f;
f.func_id = strtsh_;
strtsh_Info* tmp_params = new strtsh_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = SHG;
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.strtsh();
}
{
FuncCall f;
f.func_id = waitsh_;
waitsh_Info* tmp_params = new waitsh_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = SHG;
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.waitsh();
}
}
if (shadowExist(directive->across)) // ACROSS
{
{
FuncCall f;
f.func_id = crtshg_;
crtshg_Info* tmp_params = new crtshg_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ShadowGroupRef = (redShIds++);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SHG1 = tmp_params->ShadowGroupRef;
tmp_params->StaticSign = 0; //poss not
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.crtshg();
}
auto arraysInDir = fillArraysFromDir(loop->loop);
for (int j = 0; j < directive->across.size(); ++j)
{
DIST::Array *acArray = NULL;
for (auto &elem : arraysInDir)
if (elem->GetName() == directive->across[j].first.second)
acArray = elem;
checkNull(acArray, __FILE__, __LINE__);
FuncCall f;
f.func_id = insshd_;
inssh_Info* tmp_params = new inssh_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ShadowGroupRef = SHG1;
tmp_params->ArrayHandlePtr = getId(acArray, mapArrayAddrsPtr, arrayAddrPtr);
tmp_params->ArrayHeader = getId(acArray, mapArrayAddrs, arrayAddr);
tmp_params->MaxShdCount = 1; //poss not
tmp_params->HiShdWidthArray.resize(0);
tmp_params->LowShdWidthArray.resize(0);
tmp_params->ShdSignArray.resize(0);
const int rank = acArray->GetDimSize();
for (int z = 0; z < rank; ++z)
{
tmp_params->HiShdWidthArray.push_back(0);
tmp_params->LowShdWidthArray.push_back(directive->across[j].second[rank - 1 - z].first);
tmp_params->ShdSignArray.push_back(3); //poss not
}
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.insshd();
}
{
FuncCall f;
f.func_id = crtshg_;
crtshg_Info* tmp_params = new crtshg_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ShadowGroupRef = (redShIds++);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SHG2 = tmp_params->ShadowGroupRef;
tmp_params->StaticSign = 0; //poss not
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.crtshg();
}
for (int j = 0; j < directive->across.size(); ++j)
{
DIST::Array *acArray = NULL;
for (auto &elem : arraysInDir)
if (elem->GetName() == directive->across[j].first.second)
acArray = elem;
checkNull(acArray, __FILE__, __LINE__);
FuncCall f;
f.func_id = insshd_;
inssh_Info* tmp_params = new inssh_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ShadowGroupRef = SHG2;
tmp_params->ArrayHandlePtr = getId(acArray, mapArrayAddrsPtr, arrayAddrPtr);
tmp_params->ArrayHeader = getId(acArray, mapArrayAddrs, arrayAddr);
tmp_params->MaxShdCount = 1; //poss not
tmp_params->HiShdWidthArray.resize(0);
tmp_params->LowShdWidthArray.resize(0);
tmp_params->ShdSignArray.resize(0);
const int rank = acArray->GetDimSize();
for (int z = 0; z < rank; ++z)
{
tmp_params->HiShdWidthArray.push_back(directive->across[j].second[rank - 1 - z].second);
tmp_params->LowShdWidthArray.push_back(0);
tmp_params->ShdSignArray.push_back(5);
}
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.insshd();
}
}
//PARLOOP
{
FuncCall f;
f.func_id = mappl_;
mappl_Info* tmp_params = new mappl_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->LoopRef = LR; //<2F><><EFBFBD> <20><><EFBFBD> <20> <20> crtpl
tmp_params->PatternRef = getId(directive->arrayRef, mapArrayAddrsPtr, arrayAddrPtr); //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->PatternRefPtr = getId(directive->arrayRef, mapArrayAddrs, arrayAddr); //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->PatternType = 2; //DisArray
const int rank = directive->arrayRef->GetDimSize();
tmp_params->AxisArray.resize(rank);
tmp_params->CoeffArray.resize(rank);
tmp_params->ConstArray.resize(rank);
for (int i = 0; i < rank; ++i)
{
if (directive->on[i].first == "*")
{
tmp_params->AxisArray[rank - 1 - i] = -1;
tmp_params->CoeffArray[rank - 1 - i] = 0;
tmp_params->ConstArray[rank - 1 - i] = 0;
}
else
{
tmp_params->AxisArray[rank - 1 - i] = findPosInParallel(directive->parallel, directive->on[i].first);
tmp_params->CoeffArray[rank - 1 - i] = directive->on[i].second.first;
tmp_params->ConstArray[rank - 1 - i] = directive->on[i].second.second;
}
}
const int loopRank = directive->parallel.size();
tmp_params->InInitIndexArray.resize(loopRank);
tmp_params->InLastIndexArray.resize(loopRank);
tmp_params->InStepArray.resize(loopRank);
LoopGraph *currL = loop;
for (int i = 0; i < loopRank; ++i, currL = currL->children[0])
{
tmp_params->InInitIndexArray[i] = currL->startVal;
tmp_params->InLastIndexArray[i] = currL->endVal;
tmp_params->InStepArray[i] = currL->stepVal;
if (i == loopRank - 1)
break;
if (currL->children.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
debug += "mappl AxisArray=";
for (int i = 0; i < tmp_params->AxisArray.size(); ++i)
debug += " " + to_string(tmp_params->AxisArray[i]);
debug += "\n";
f.mappl();
}
if (directive->reduction.size() | directive->reductionLoc.size()) //REDUCTION
{
FuncCall f;
f.func_id = insred_;
insred_Info* tmp_params = new insred_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->RG_ID = RID;//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmp_params->RV_ID = RIDG;//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.insred();
}
if (shadowExist(directive->across)) //ACROSS
{
FuncCall f;
f.func_id = across_;
across_Info* tmp_params = new across_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->AcrossType = 0; //poss not
tmp_params->NewShadowGroupRef = SHG1;
tmp_params->OldShadowGroupRef = SHG2;
tmp_params->PipeLinePar = 0; //poss not
tmp_params->CondPipeLine = 0; //poss not
tmp_params->ErrPipeLine = 9; //poss not
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.across();
}
// vector<int> -> -1 == full, 0 == one elem
map<DIST::Array*, vector<long>> remoteAccess = fillRemoteInParallel(loop->loop);
if (remoteAccess.size())
{
auto arraysInDir = fillArraysFromDir(loop->loop);
for (auto &rem : remoteAccess)
{
DIST::Array *remArray = rem.first;
{
FuncCall f;
f.func_id = crtrbl_;
crtrbl_Info* tmp_params = new crtrbl_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->BufferHeader = (remIds++);//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
REMID = tmp_params->BufferHeader;
tmp_params->RemArrayHeader = getId(remArray, mapArrayAddrs, arrayAddr);
const int rank = remArray->GetDimSize();
tmp_params->AxisArray.resize(rank);
tmp_params->CoeffArray.resize(rank);
tmp_params->ConstArray.resize(rank);
for (int i = 0; i < rank; ++i)
{
if (rem.second[i] == 0)
{
tmp_params->AxisArray[rank - 1 - i] = 0;
tmp_params->CoeffArray[rank - 1 - i] = 0;
tmp_params->ConstArray[rank - 1 - i] = 0;
}
else //if (rem.second[i] == 1)
{
tmp_params->AxisArray[rank - 1 - i] = -1;
tmp_params->CoeffArray[rank - 1 - i] = -1;
tmp_params->ConstArray[rank - 1 - i] = -1;
}
}
tmp_params->LoopRef = LR; //may be always equal lastLR:
tmp_params->StaticSign = 0; //may be not always
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.crtrbl();
}
{
FuncCall f;
f.func_id = loadrb_;
loadrb_Info* tmp_params = new loadrb_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = REMID;
tmp_params->RenewSign = 1; //may be always
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.loadrb();
}
{
FuncCall f;
f.func_id = waitrb_;
waitrb_Info* tmp_params = new waitrb_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = REMID;
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.waitrb();
}
}
}
//PARLOOP
{
FuncCall f;
f.func_id = dopl_;
dopl_full_Info *tmp_params = new dopl_full_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = LR; //<2F><><EFBFBD> <20><><EFBFBD> <20> <20> crtpl
tmp_params->ReturnVar = 1;
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.dopl();
}
{
FuncCall f;
f.func_id = dopl_;
dopl_full_Info* tmp_params = new dopl_full_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = LR;//<2F><><EFBFBD> <20><><EFBFBD> <20> <20> crtpl
tmp_params->ReturnVar = 0;
f.call_time = loop->executionTimeInSec; // call time, c->time - <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>!
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.dopl();
}
{
FuncCall f;
f.func_id = endpl_;
endpl_Info* tmp_params = new endpl_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = LR; //<2F><><EFBFBD> <20><><EFBFBD> <20> <20> crtpl
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.endpl();
}
if (directive->reduction.size() || directive->reductionLoc.size()) //REDUCTION
{
{
FuncCall f;
f.func_id = strtrd_;
strtrd_Info* tmp_params = new strtrd_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = RID;//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.strtrd();
}
{
FuncCall f;
f.func_id = waitrd_;
waitrd_Info* tmp_params = new waitrd_Info;
f.call_params = (void *)tmp_params; // point to parameters
tmp_params->ID = RID;//<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
f.call_time = 0.00000100; // call time
f.ret_time = 0.00000100; // return time
setVectorCallRet(&f);
f.waitrd();
}
}
if (printOut)
fprintf(printOut, "%s", debug.c_str());
return 0;
}
static int multiply(const vector<long> &array_)
{
int res = 1;
for (long i = 0; i < array_.size(); ++i)
res *= array_[i];
return res;
}
static vector<long> get_divisors(long N)
{
vector<long> res;
res.push_back(N);
if (N > 1)
{
int k = N / 2;
for (long i = k; i > 1; --i)
if (N % i == 0)
res.push_back(i);
res.push_back(1);
}
return res;
}
static void recGen(vector<long> divisors, vector<long> &matrix, size_t index, int procNum, vector<vector<long>> &result)
{
if (index < matrix.size())
{
for (size_t i = 0; i < divisors.size(); i++)
{
matrix[index] = divisors[i];
recGen(divisors, matrix, index + 1, procNum, result);
}
}
else
{
if (multiply(matrix) == procNum)
result.push_back(matrix);
}
}
static vector<vector<long>> generate_matrixes(int procNum, int dim)
{
vector<vector<long>> result;
vector<long> divisors = get_divisors(procNum);
vector<long> matrix(dim);
recGen(divisors, matrix, 0, procNum, result);
return result;
}
static void addTimeMessage(map<string, vector<Messages>> &messagesByFile, const string file, const int line)
{
/*wstring messg;
__spf_printToLongBuf(messg, L"Can not find execution time for this loop, try to get times statistic");
messagesByFile[file].push_back(Messages(ERROR, line, messg, 3019));*/
__spf_print(1, "%s on line %d\n", "Can not find execution time for this loop, try to get times statistic", line);
}
vector<vector<long>> getTopologies(const int procNum, const int maxSizeDist)
{
return generate_matrixes(procNum, maxSizeDist);
}
int predictScheme(ParallelRegion *reg, const vector<pair<DIST::Array*, const DistrVariant*>> &distVar,
const set<DIST::Array*> &allArrays, const map<LoopGraph*, ParallelDirective*> &dirsToPredict,
map<string, vector<SpfInterval*>> &intervals, map<string, vector<Messages>> &messagesByFile,
const vector<std::tuple<DIST::Array*, vector<long>, pair<string, int>>> &allSingleRemotes,
const int maxSizeDist, const int procNum)
{
map<string, map<SgStatement*, SpfInterval*>> intervalsBySt;
for (auto &byFile : intervals)
{
map<int, SpfInterval*> tmp;
createMapOfinterval(tmp, byFile.second);
for (auto &interval : tmp)
intervalsBySt[byFile.first][interval.second->begin] = interval.second;
}
int errCode = 0;
MinSizesOfAM.clear();
MinSizesOfAM.resize(maxSizeDist);
std::fill(MinSizesOfAM.begin(), MinSizesOfAM.end(), 0);
map<string, map<int, SpfInterval*>> mapOfIntervals;
for (auto &inter : intervals)
createMapOfinterval(mapOfIntervals[inter.first], inter.second);
vector<vector<long>> allTolopogies = generate_matrixes(procNum, maxSizeDist);
for (int topIdx = 0; topIdx < allTolopogies.size(); ++topIdx)
{
//TStart and TByte in mkS,
ps = new PS(mach_ETHERNET, 1, 7.0, 0.001, procNum); //0.001 == 1Gb/s
//ps = new PS(mach_ETHERNET, 1, 0.0, 0.0, procNum); //fastest communications
//set configuration of PS
ps->setTopology(allTolopogies[topIdx]);
vector<long> lb;
vector<long> ASizeArray;
mach_Type AMType;
int AnumChanels = 1;
double Ascale = 1.0;
double ATStart;
double ATByte;
double AProcPower;
vector<double> AvProcPower;
ps->nextPS(lb, ASizeArray, AMType, AnumChanels, Ascale, ATStart, ATByte, AProcPower, AvProcPower);
rootVM = new VM(ASizeArray, AMType, AnumChanels, Ascale, ATStart / 1000000.0, ATByte / 1000000.0, AProcPower, AvProcPower);
currentVM = rootVM;
rootProcCount = rootVM->getProcCount();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
procElapsedTime = new double[rootProcCount];
for (int i = 0; i < rootProcCount; ++i)
procElapsedTime[i] = 0.0;
for (auto &dir : dirsToPredict)
{
if (dir.first->executionTimeInSec == -1.0)
{
addTimeMessage(messagesByFile, dir.first->fileName, dir.first->lineNum);
errCode = -1;
continue;
}
auto itByFile = mapOfIntervals.find(dir.first->fileName);
if (itByFile == mapOfIntervals.end())
{
addTimeMessage(messagesByFile, dir.first->fileName, dir.first->lineNum);
errCode = -1;
continue;
}
auto itInterval = itByFile->second.find(dir.first->lineNum);
if (itInterval == itByFile->second.end())
{
addTimeMessage(messagesByFile, dir.first->fileName, dir.first->lineNum);
errCode = -1;
continue;
}
//printf("loop %d exec time = %f\n", dir.first->lineNum, CurrInterval->GetExecTime());
}
if (errCode != -1)
{
for (auto &elem : distVar)
{
DIST::Array *array = elem.first;
const DistrVariant *var = elem.second;
auto sizes = array->GetSizes();
int countBlock = 0;
for (int z = 0, dim = 0; z < var->distRule.size(); ++z)
{
if (var->distRule[z] == dist::BLOCK)
{
MinSizesOfAM[dim] = std::max(MinSizesOfAM[dim], (long)(sizes[z].second - sizes[z].first + 1));
dim++;
}
}
}
for (auto &var : distVar)
Model_distr(var.first, var.second);
for (auto &array : allArrays)
if (!array->IsTemplate() && !array->IsLoopArray())
Model_align(array, reg->GetId());
for (auto &dir : dirsToPredict)
{
auto itByFile = mapOfIntervals.find(dir.first->fileName);
auto itInterval = itByFile->second.find(dir.first->lineNum);
CurrInterval = new Interval(0);
Model_par(dir.first, dir.second, allArrays);
CurrInterval->CalcIdleAndImbalance();
CurrInterval->Integrate();
itInterval->second->predictedTimes[topIdx] = CurrInterval->GetExecTime() * itInterval->second->exec_count;
delete CurrInterval;
//printf("loop %d exec time = %f\n", dir.first->lineNum, CurrInterval->GetExecTime());
}
for (auto &singleRem : allSingleRemotes)
{
pair<string, int> place = get<2>(singleRem);
DIST::Array *array = get<0>(singleRem);
auto coords = get<1>(singleRem);
auto itFile = intervalsBySt.find(place.first);
if (itFile == intervalsBySt.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto nearestInt = findNearestDown(itFile->second, SgStatement::getStatementByFileAndLine(place.first, place.second));
CurrInterval = new Interval(0);
auto tmpPair = make_pair(array, coords);
double singleRemTime = Model_Single_Rem(tmpPair);
delete CurrInterval;
nearestInt->predictedRemoteTimes[topIdx] = singleRemTime * nearestInt->exec_count;
}
}
delete rootVM;
delete ps;
if (errCode != 0)
break;
}
return errCode;
}