Files
SAPFOR/Sapfor/_src/DirectiveProcessing/insert_directive.cpp

2426 lines
96 KiB
C++
Raw Normal View History

2023-09-14 19:43:13 +03:00
#include "../Utils/leak_detector.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <assert.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include "dvm.h"
#include "../Distribution/GraphCSR.h"
#include "../Distribution/Arrays.h"
#include "../Distribution/Distribution.h"
#include "../Distribution/DvmhDirective_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../GraphCall/graph_calls_func.h"
#include "../Utils/errors.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "directive_parser.h"
#include "../Utils/SgUtils.h"
#include "../Sapfor.h"
#include "directive_creator.h"
#include "insert_directive.h"
using std::string;
using std::wstring;
using std::vector;
using std::map;
using std::set;
using std::pair;
using std::tuple;
using std::make_pair;
using std::make_tuple;
static const string dvmhModuleName = "dvmh_template_mod";
extern int sharedMemoryParallelization;
2024-03-24 21:24:32 +03:00
2023-09-14 19:43:13 +03:00
//the size of vector indiceates type of DVM_DIR
SgStatement* createStatFromExprs(const vector<Expression*> &exprs)
{
SgStatement *result = NULL;
if (exprs.size() == 3)
result = new SgStatement(DVM_PARALLEL_ON_DIR, NULL, NULL, NULL, NULL, NULL);
else if (exprs.size() == 4)
result = new SgStatement(DVM_REDISTRIBUTE_DIR, NULL, NULL, NULL, NULL, NULL);
else if (exprs.size() == 5)
result = new SgStatement(DVM_REALIGN_DIR, NULL, NULL, NULL, NULL, NULL);
else if (exprs.size() == 6)
result = new SgStatement(DVM_DISTRIBUTE_DIR, NULL, NULL, NULL, NULL, NULL);
else if (exprs.size() == 7)
result = new SgStatement(HPF_TEMPLATE_STAT, NULL, NULL, NULL, NULL, NULL);
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (int i = 0; i < 3; ++i)
if (exprs[i])
result->setExpression(i, *exprs[i]);
return result;
}
static void removeDoubleRealign(vector<vector<Expression*>>& realigns)
{
if (realigns.size() < 2)
return;
vector<bool> save;
for (int z = 0; z < realigns.size(); ++z)
save.push_back(true);
bool changed = false;
for (int z = 1; z < realigns.size(); ++z)
{
for (int zp = 0; zp < z; ++zp)
{
if (!save[zp])
continue;
auto prev = string(realigns[zp][0]->unparse());
auto curr = string(realigns[z][0]->unparse());
if (prev == curr)
{
save[zp] = false;
changed = true;
}
else
{
set<string> listNext;
SgExpression* ex = realigns[z][0];
while (ex)
{
listNext.insert(ex->lhs()->symbol()->identifier());
ex = ex->rhs();
}
ex = realigns[zp][0];
vector<SgExpression*> newExp;
while (ex)
{
if (listNext.find(ex->lhs()->symbol()->identifier()) == listNext.end())
newExp.push_back(ex->lhs());
ex = ex->rhs();
}
if (newExp.size())
realigns[zp][0] = new Expression(makeExprList(newExp));
else
{
save[zp] = false;
changed = true;
}
}
}
}
if (!changed)
return;
vector<vector<Expression*>> newVal;
for (int z = 0; z < realigns.size(); ++z)
if (save[z])
newVal.push_back(realigns[z]);
realigns = newVal;
}
static void filterInsertMap(map<int, vector<vector<Expression*>>> &toInsertMap)
{
for (auto it = toInsertMap.begin(); it != toInsertMap.end(); ++it)
{
vector<vector<Expression*>> newVal;
vector<vector<Expression*>> realign, redis;
for (int z = 0; z < it->second.size(); ++z)
{
if (it->second[z].size() == 4)
redis.push_back(it->second[z]);
else if (it->second[z].size() == 5)
realign.push_back(it->second[z]);
else
newVal.push_back(it->second[z]);
}
//removeDoubleRedistribute
//TODO: deprecated?
for (auto& elem : redis)
newVal.push_back(elem);
//removeDoubleRealign
removeDoubleRealign(realign);
for (auto& elem : realign)
newVal.push_back(elem);
//sort by type
map<int, vector<vector<Expression*>>> toSort;
for (auto &elem : newVal)
toSort[elem.size()].push_back(elem);
newVal.clear();
for (auto itR = toSort.rbegin(); itR != toSort.rend(); itR++)
{
for (auto &elem : itR->second)
newVal.push_back(elem);
}
it->second = newVal;
}
}
static void correctKeyLine(SgFile *file, map<int, vector<vector<Expression*>>> &toInsertMap)
{
set<int> lines;
vector<int> lines_v;
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
{
if (st->lineNumber() > 0 || st->lineNumber() < 0 && st->variant() == FOR_NODE)
lines.insert(st->lineNumber());
if (st->variant() < 0)
st = st->lastNodeOfStmt();
}
for (auto &l : lines)
lines_v.push_back(l);
map<int, vector<vector<Expression*>>> newMap;
for (auto &elem : toInsertMap)
{
if (std::find(lines_v.begin(), lines_v.end(), elem.first) != lines_v.end())
newMap[elem.first] = elem.second;
else
{
int lineNext = -1;
for (int z = 0; z < lines_v.size(); ++z)
{
if (lines_v[z] > elem.first)
{
lineNext = lines_v[z];
break;
}
}
if (lineNext == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
newMap[lineNext] = elem.second;
}
}
toInsertMap = newMap;
}
void removeStatementsFromAllproject(const set<int> &variants)
{
for (int z = 0; z < CurrentProject->numberOfFiles(); ++z)
{
SgFile* file = &CurrentProject->file(z);
SgStatement* stF = file->firstStatement();
vector<SgStatement*> toDel;
for (SgStatement* st = stF; st; st = st->lexNext())
{
const int var = st->variant();
bool templateMod = false;
if (var == MODULE_STMT)
{
string ident = st->symbol()->identifier();
convertToLower(ident);
if (ident == dvmhModuleName)
templateMod = true;
}
bool useMod = false;
if (var == USE_STMT && st->symbol()->identifier() == dvmhModuleName)
useMod = true;
if (variants.find(var) != variants.end() || templateMod || useMod)
toDel.push_back(st);
if (var == MODULE_STMT && templateMod)
st = st->lastNodeOfStmt();
}
for (int k = 0; k < toDel.size(); ++k)
{
//move comment to next statement
if (toDel[k]->comments())
{
char* comms = toDel[k]->comments();
string comments(comms);
toDel[k]->delComments();
SgStatement* next = toDel[k]->lexNext();
if (next)
next->addComment(comments.c_str());
}
toDel[k]->deleteStmt();
}
}
}
// TODO: optimize REDISTR dirs with CFG
void insertDirectiveToFile(SgFile *file, const char *fin_name, const vector<Directive*> &toInsert,
const bool extractDir, vector<Messages> &messagesForFile)
{
map<int, vector<vector<Expression*>>> toInsertMap;
for (int i = 0; i < toInsert.size(); ++i)
{
auto it = toInsertMap.find(toInsert[i]->line);
if (it == toInsertMap.end())
{
vector<vector<Expression*>> tmp;
tmp.push_back(((CreatedDirective*)toInsert[i])->sageData);
toInsertMap.insert(it, make_pair(toInsert[i]->line, tmp));
}
else
it->second.push_back(((CreatedDirective*)toInsert[i])->sageData);
}
filterInsertMap(toInsertMap);
correctKeyLine(file, toInsertMap);
vector<SgStatement*> toDel;
vector<SgStatement*> modulesAndFuncs;
getModulesAndFunctions(file, modulesAndFuncs);
for (int i = 0; i < modulesAndFuncs.size(); ++i)
{
SgStatement *st = modulesAndFuncs[i];
SgStatement *lastNode = st->lastNodeOfStmt();
if (extractDir && st->variant() == MODULE_STMT)
{
if (st->symbol()->identifier() == dvmhModuleName)
{
st->deleteStmt();
continue;
}
}
int numSt = 0;
do
{
if (st->variant() == CONTAINS_STMT)
break;
if (numSt != 0)
st = st->lexNext();
if (st == NULL)
{
messagesForFile.push_back(Messages(ERROR, 1, R128, L"internal error in analysis, parallel directives will not be generated for this file!", 3008));
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
break;
}
if (!strcmp(st->fileName(), fin_name))
{
auto it = toInsertMap.find(st->lineNumber());
if (it != toInsertMap.end())
{
if (extractDir == false)
{
for (int i1 = 0; i1 < it->second.size(); ++i1)
{
SgStatement *dirToInsert = createStatFromExprs((it->second[i1]));
const int varSt = st->variant();
if (varSt == PROC_HEDR || varSt == PROG_HEDR || varSt == FUNC_HEDR || varSt == MODULE_STMT)
st->insertStmtAfter(*dirToInsert, *st);
else
st->insertStmtBefore(*dirToInsert, *(st->controlParent()));
if (st->comments())
{
char *comms = st->comments();
string comments(comms);
st->delComments();
st->lexPrev()->addComment(comments.c_str());
}
}
}
toInsertMap.erase(it);
}
}
if (extractDir)
{
const int var = st->variant();
if (var == DVM_PARALLEL_ON_DIR ||
var == DVM_REDISTRIBUTE_DIR ||
var == DVM_REALIGN_DIR ||
var == DVM_REMOTE_ACCESS_DIR ||
var == DVM_SHADOW_DIR ||
var == DVM_INHERIT_DIR ||
var == DVM_DYNAMIC_DIR ||
(var == USE_STMT && st->lineNumber() < 0) ||
var == HPF_TEMPLATE_STAT ||
var == DVM_ALIGN_DIR ||
var == DVM_DISTRIBUTE_DIR ||
var == DVM_VAR_DECL ||
var == ACC_REGION_DIR || var == ACC_END_REGION_DIR ||
var == ACC_ACTUAL_DIR || var == ACC_GET_ACTUAL_DIR)
{
toDel.push_back(st);
//move comment to next statement
if (st->comments())
{
char *comms = st->comments();
string comments(comms);
st->delComments();
SgStatement *next = st->lexNext();
if (next)
next->addComment(comments.c_str());
}
}
}
numSt++;
} while (st != lastNode);
if (extractDir)
{
for (int k = 0; k < toDel.size(); ++k)
{
if (toDel[k]->lineNumber() > 0) // user directives, skip
; // printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
else
toDel[k]->deleteStmt();
}
}
}
}
static void moveComment(SgStatement *elem, const string addNew = "")
{
string comms = "";
if (elem->comments())
comms = elem->comments();
comms += addNew;
if (comms != "")
{
auto toAddComm = elem;
while (toAddComm)
{
toAddComm = toAddComm->lexNext();
if (toAddComm && !isDVM_stat(toAddComm))
break;
}
if (toAddComm == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
string comms2 = "";
if (toAddComm->comments())
comms2 = toAddComm->comments();
comms += comms2;
if (comms != "")
toAddComm->setComments(comms.c_str());
}
}
static void replaceComment(string &dir, const char *firstChar)
{
const string templ = firstChar + string("DVM$");
size_t offset = 0;
for (; ; )
{
offset = dir.find(templ, offset);
if (offset == string::npos)
break;
else
{
dir.insert(offset + 1, " ");
offset += 6;
}
}
}
void removeDvmDirectives(SgFile *file, const bool toComment)
{
vector<SgStatement*> toDel;
vector<SgStatement*> toTotalDel;
const string currFile = file->filename();
vector<SgStatement*> toProcess;
getModulesAndFunctions(file, toProcess);
for (int i = 0; i < toProcess.size(); ++i)
{
SgStatement *st = toProcess[i];
SgStatement *lastNode = st->lastNodeOfStmt();
while (st != lastNode)
{
if (st == NULL)
{
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
break;
}
if (st->variant() == CONTAINS_STMT)
break;
const int var = st->variant();
if (isDVM_stat(st))
if (st->fileName() == currFile)
toDel.push_back(st);
if ( (var == USE_STMT || var == MODULE_STMT) && st->symbol()->identifier() == string("dvmh_template_mod"))
toTotalDel.push_back(st);
st = st->lexNext();
}
}
if (toComment)
{
for (auto &elem : toDel)
{
moveComment(elem);
elem->delComments();
char *tmp = elem->unparse();
if (tmp == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
string dir(tmp);
convertToUpper(dir);
replaceComment(dir, "!");
replaceComment(dir, "C");
moveComment(elem, dir);
elem->deleteStmt();
}
}
else
{
for (auto &elem : toDel)
{
moveComment(elem);
elem->deleteStmt();
}
}
for (auto& elem : toTotalDel)
{
moveComment(elem);
elem->deleteStmt();
}
}
static inline pair<string, SgExpression*> genBoundsOfDim(const pair<int, int> &intBounds, const pair<Expression*, Expression*> &exprBounds)
{
if (intBounds.first > intBounds.second)
{
if (exprBounds.first == NULL || exprBounds.second == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
else
{
return make_pair(string(exprBounds.first->unparse()) + ":" + string(exprBounds.second->unparse()),
new SgExpression(DDOT, exprBounds.first, exprBounds.second, NULL));
}
}
else
return make_pair(std::to_string(intBounds.first) + ":" + std::to_string(intBounds.second),
new SgExpression(DDOT, new SgValueExp(intBounds.first), new SgValueExp(intBounds.second), NULL));
}
static inline pair<string, SgStatement*> genTemplateDelc(DIST::Array *templ, const string &name, SgFile *file, SgStatement *module = NULL, bool isMain = false)
{
string templDecl = (module == NULL) ? "!DVM$ TEMPLATE, COMMON :: " : "!DVM$ TEMPLATE ";
SgStatement* templDeclSt = NULL;
if (module == NULL)
templDeclSt = new SgStatement(DVM_VAR_DECL);
else
templDeclSt = new SgStatement(HPF_TEMPLATE_STAT);
if (module && templ->IsTemplate() && !templ->IsLoopArray())
templ->ChangeLocation(DIST::l_MODULE, module->symbol()->identifier());
const vector<pair<int, int>> &sizes = templ->GetSizes();
const auto &sizesExpr = templ->GetSizesExpr();
for (auto &size : sizes)
{
if (templ->IsLoopArray())
{
// TODO: move gen sizes to TEMPLATE CREATE directive immediately before parallel loop
bool ok = true;
for (auto &elem : sizesExpr)
if (elem.first.first == NULL || elem.second.first == NULL)
ok = false;
if (size.first > size.second && module == NULL && !ok)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
else
{
if (size.first > size.second)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
SgExprListExp *listDim = new SgExprListExp();
templDecl += name + "(";
for (int z = 0; z < sizes.size(); ++z)
{
auto bounds = genBoundsOfDim(sizes[z], make_pair(sizesExpr[z].first.first, sizesExpr[z].second.first));
templDecl += bounds.first;
if (z == 0)
listDim->setLhs(bounds.second);
else
listDim->append(*bounds.second);
if (z != sizes.size() - 1)
templDecl += ",";
}
templDecl += ")\n";
if (module != NULL)
templDeclSt->setExpression(0, new SgArrayRefExp(*findSymbolOrCreate(file, name, new SgArrayType(*SgTypeInt())), *listDim));
else
templDeclSt->setExpression(0, new SgExpression(EXPR_LIST, new SgArrayRefExp(*findSymbolOrCreate(file, name, new SgArrayType(*SgTypeInt())), *listDim), NULL, NULL));
if (module == NULL)
templDeclSt->setExpression(2, new SgExpression(EXPR_LIST, new SgExpression(TEMPLATE_OP), new SgExpression(EXPR_LIST, new SgExpression(COMMON_OP), NULL, NULL), NULL));
return make_pair(templDecl, templDeclSt);
}
static inline pair<string, SgStatement*>
genTemplateDistr(DIST::Array *array, const string &name, const vector<string> &distrRules, const vector<vector<dist>> &distrRulesSt,
const uint64_t regionId, const int templIdx, bool isMain, SgFile *file)
{
auto newOrder = array->GetNewTemplateDimsOrder();
//TODO:!!!
//"!DVM$ DISTRIBUTE :: " + templ->GetShortName() + "\n";
SgExpression *ex1 = new SgVarRefExp(*findSymbolOrCreate(file, name));
SgExprListExp *ex2 = new SgExprListExp();
for (int z = 0; z < distrRulesSt[templIdx].size(); ++z)
{
string val = "";
if (newOrder.size() == 0)
{
if (distrRulesSt[templIdx][z] == dist::BLOCK)
val = "BLOCK";
else
val = "*";
}
else
{
if (distrRulesSt[templIdx][newOrder[z]] == dist::BLOCK)
val = "BLOCK";
else
val = "*";
}
if (z == 0)
ex2->setLhs(new SgKeywordValExp(val.c_str()));
else
ex2->append(*new SgKeywordValExp(val.c_str()));
}
SgStatement *distrSt = new SgStatement(DVM_DISTRIBUTE_DIR, NULL, NULL, ex1, ex2, NULL);
return make_pair("!DVM$ DISTRIBUTE " + distrRules[templIdx] + "\n", distrSt);
}
static pair<string, SgStatement*> genDynamicDecl(DIST::Array *templ, SgFile *file)
{
auto allClones = templ->GetAllClones();
string templDyn = "!DVM$ DYNAMIC " + templ->GetShortName();
for (auto &elem : allClones)
templDyn += ", " + elem.second;
templDyn += "\n";
SgStatement* templDynSt = NULL;
if (allClones.size() == 0)
templDynSt = new SgStatement(DVM_DYNAMIC_DIR, NULL, NULL, new SgVarRefExp(*findSymbolOrCreate(file, templ->GetShortName())), NULL, NULL);
else
{
vector<SgExpression*> list;
list.push_back(new SgVarRefExp(*findSymbolOrCreate(file, templ->GetShortName())));
for (auto& elem : allClones)
list.push_back(new SgVarRefExp(*findSymbolOrCreate(file, elem.second)));
templDynSt = new SgStatement(DVM_DYNAMIC_DIR, NULL, NULL, makeExprList(list), NULL, NULL);
}
return make_pair(templDyn, templDynSt);
}
static inline int findTeplatePosition(const DIST::Array *templ, const DataDirective &dataDir)
{
int templIdx = -1;
const string templName = templ->GetShortName();
for (int z = 0; z < dataDir.distrRules.size(); ++z)
{
if (dataDir.distrRules[z].first->GetShortName() == templName)
{
templIdx = z;
break;
}
}
if (templIdx == -1)
{
__spf_print(1, "can not find template position ['%s']\n", templName.c_str());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
return templIdx;
}
static inline DIST::Array* findLinkWithTemplate(DIST::Array *alignArray, const DIST::Arrays<int> &allArrays,
DIST::GraphCSR<int, double, attrType> &reducedG, const uint64_t regionId)
{
DIST::Array *templ = NULL;
vector<tuple<DIST::Array*, int, pair<int, int>>> links;
reducedG.GetAlignRuleWithTemplate(alignArray, allArrays, links, regionId);
for (int i = 0; i < links.size(); ++i)
{
templ = std::get<0>(links[i]);
if (templ)
break;
}
return templ;
}
static string createFullTemplateDir(const tuple<string, string, string> &templDir)
{
string fullDir = "";
if (!out_free_form)
{
fullDir += splitDirectiveFull(std::get<0>(templDir));
fullDir += splitDirectiveFull(std::get<1>(templDir));
fullDir += splitDirectiveFull(std::get<2>(templDir));
}
else
fullDir += std::get<0>(templDir) + std::get<1>(templDir) + std::get<2>(templDir);
return fullDir;
}
struct templateDir
{
templateDir() { isTemplateInModule = false; }
pair<string, vector<SgStatement*>> templDecl;
pair<string, vector<SgStatement*>> templDist;
pair<string, SgStatement*> templDyn;
bool isTemplateInModule;
};
static pair<templateDir, string>
getNewTemplateDirective(DIST::Array *alignArray, const DIST::Arrays<int> &allArrays,
DIST::GraphCSR<int, double, attrType> &reducedG,
const DataDirective &dataDir, const vector<string> &distrRules,
const vector<vector<dist>> &distrRulesSt,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls,
const uint64_t regionId, SgStatement *module, bool isMain, SgFile *file,
vector<Messages>& messagesForFile)
{
DIST::Array *templ = findLinkWithTemplate(alignArray, allArrays, reducedG, regionId);
bool templDynSt = false;
string lastReturn = "";
//checkNull(templ, convertFileName(__FILE__).c_str(), __LINE__);
if (templ == NULL)
{
set<DIST::Array*> realArrayRefs;
getRealArrayRefs(alignArray, alignArray, realArrayRefs, arrayLinksByFuncCalls);
vector<DIST::Array*> templates;
for (auto &array : realArrayRefs)
templates.push_back(findLinkWithTemplate(array, allArrays, reducedG, regionId));
if (templates.size() == 0)
{
__spf_print(1, "can not find templates\n");
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
else if (templates.size() == 1)
templ = templates[0];
else
{
templ = templates[0];
bool isErr = false;
for (auto& t : templates)
{
if (t != templ)
{
isErr = true;
__spf_print(1, "find more then one template: %s and %s, align array is %s\n", t->GetShortName().c_str(), templ->GetShortName().c_str(), alignArray->GetShortName().c_str());
}
}
if (isErr)
{
auto allDecl = alignArray->GetDeclInfo();
for (auto& decl : allDecl)
{
std::wstring bufE, bufR;
__spf_printToLongBuf(bufE, L"Can not find align rules for array '%s'", to_wstring(alignArray->GetShortName()).c_str());
__spf_printToLongBuf(bufR, R171, to_wstring(alignArray->GetShortName()).c_str());
messagesForFile.push_back(Messages(ERROR, decl.second, bufR, bufE, 3020));
}
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
lastReturn = "!DVM$ INHERIT\n";
}
else
lastReturn = templ->GetShortName();
auto allClones = templ->GetAllClones();
templateDir retDir;
int templIdx = findTeplatePosition(templ, dataDir);
auto templDecl = genTemplateDelc(templ, templ->GetShortName(), file, module, isMain);
retDir.templDecl.first = templDecl.first;
retDir.templDecl.second.push_back(templDecl.second);
for (auto &elem : allClones)
{
auto templDecl = genTemplateDelc(templ, elem.second, file, module, isMain);
retDir.templDecl.first += templDecl.first;
retDir.templDecl.second.push_back(templDecl.second);
}
auto templDist = genTemplateDistr(templ, templ->GetShortName(), distrRules, distrRulesSt, regionId, templIdx, isMain || module != NULL, file);
retDir.templDist.first = templDist.first;
retDir.templDist.second.push_back(templDist.second);
if (templ->GetLocation().first == DIST::l_MODULE)
retDir.isTemplateInModule = true;
for (auto &elem : allClones)
{
vector<vector<dist>> tmpRuleSt = { elem.first };
string strRule = elem.second + "(";
for (int z = 0; z < elem.first.size(); ++z)
{
if (z != 0)
strRule += ",";
if (elem.first[z] == BLOCK)
strRule += "BLOCK";
else if (elem.first[z] == NONE)
strRule += "*";
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
strRule += ")";
vector<string> tmpStrRule = { strRule };
auto templDist = genTemplateDistr(templ, elem.second, tmpStrRule, tmpRuleSt, regionId, 0, isMain || module != NULL, file);
retDir.templDist.first += templDist.first;
retDir.templDist.second.push_back(templDist.second);
}
retDir.templDyn = genDynamicDecl(templ, file);
return make_pair(retDir, lastReturn);
}
2025-02-10 17:16:15 +03:00
static pair<string, string> getModuleRename(const set<SgStatement*>& allocatableStmts, const DIST::Array* array)
2023-09-14 19:43:13 +03:00
{
2025-02-10 17:16:15 +03:00
if (array->GetLocation().first == DIST::l_MODULE)
{
set<string> arrayNames;
for (auto& alloc : allocatableStmts)
if (alloc->variant() == ALLOCATE_STMT)
2025-02-18 13:45:20 +03:00
arrayNames.insert(array->GetNameInLocation(alloc));
2025-02-10 17:16:15 +03:00
if (arrayNames.size() > 1 || arrayNames.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return make_pair(array->GetShortName(), *arrayNames.begin());
}
else
return make_pair("", "");
2023-09-14 19:43:13 +03:00
}
static pair<DIST::Array*, string>
getNewDirective(const string &fullArrayName,
const vector<string> &distrRules,
const vector<string> &alignRules,
const DataDirective &dataDir,
2025-02-10 17:16:15 +03:00
const set<SgStatement*>& allocatableStmts)
2023-09-14 19:43:13 +03:00
{
string out = "";
DIST::Array* outA = NULL;
for (int i = 0; i < dataDir.distrRules.size(); ++i)
{
if (dataDir.distrRules[i].first->GetName() == fullArrayName)
{
out += "!DVM$ DISTRIBUTE " + distrRules[i] + "\n";
if (!out_free_form)
out = splitDirective(out);
return make_pair(dataDir.distrRules[i].first, out);
}
}
for (int i = 0; i < dataDir.alignRules.size(); ++i)
{
if (dataDir.alignRules[i].alignArray->GetName() == fullArrayName)
{
string rule = alignRules[i];
2025-02-10 17:16:15 +03:00
if (allocatableStmts.size())
2023-09-14 19:43:13 +03:00
{
auto it = rule.find("ALIGN");
while (it != string::npos)
{
rule = rule.replace(it, 5, "REALIGN");
it = rule.find("ALIGN", it + 7);
}
2025-02-10 17:16:15 +03:00
auto renamePair = getModuleRename(allocatableStmts, dataDir.alignRules[i].alignArray);
2023-09-14 19:43:13 +03:00
if (renamePair.first != "")
{
it = rule.find(renamePair.first);
if (it != string::npos)
if (rule[it + renamePair.first.size()] == '(' && rule[it - 1] == ' ')
rule = rule.replace(it, renamePair.first.size(), renamePair.second);
}
}
out += "!DVM$ " + rule + "\n";
if (!out_free_form)
out = splitDirective(out);
return make_pair(dataDir.alignRules[i].alignArray, out);
}
}
return make_pair(outA, out);
}
static SgStatement* firstExec(SgStatement *in, const string &currF)
{
while (in)
{
if (isSgExecutableStatement(in) && !isSPF_stat(in) && in->fileName() == currF)
return in;
in = in->lexNext();
}
return in;
}
void insertLoopTempalteDeclaration(SgFile* file, const DataDirective& dataDir,
const vector<string>& distrRules, const vector<vector<dist>>& distrRulesSt,
const DIST::Arrays<int>& allArrays,
const bool extractDir, const uint64_t regionId)
{
vector<SgStatement*> modulesAndFuncs;
getModulesAndFunctions(file, modulesAndFuncs);
const set<DIST::Array*>& arrays = allArrays.GetArrays();
set<DIST::Array*> loopArrays;
for (auto& array : arrays)
if (array->IsTemplate() && array->IsLoopArray())
loopArrays.insert(array);
if (loopArrays.size())
{
for (int i = 0; i < modulesAndFuncs.size(); ++i)
{
SgStatement* st = modulesAndFuncs[i];
string name = "";
if (st->variant() == PROG_HEDR || (st->variant() == FUNC_HEDR))
name = ((SgFuncHedrStmt*)st)->name().identifier();
else if (st->variant() == PROC_HEDR)
name = ((SgProcHedrStmt*)st)->name().identifier();
if (name == "")
continue;
for (auto& arrayPair : sortArraysByName(loopArrays))
{
DIST::Array* array = arrayPair.second;
const auto& location = array->GetLocation();
if (location.second == name)
{
int templIdx = findTeplatePosition(array, dataDir);
string tmp = distrRules[templIdx];
convertToLower(tmp);
if (tmp.find("block") == string::npos)
continue;
auto templDecl = genTemplateDelc(array, array->GetShortName(), file, (SgStatement*)-1, true);
auto templDist = genTemplateDistr(array, array->GetShortName(), distrRules, distrRulesSt, regionId, templIdx, true, file);
SgStatement* nextSt = firstExec(st->lexNext(), st->fileName());
if (!extractDir)
{
auto cp = nextSt->controlParent();
nextSt->insertStmtBefore(*templDist.second, *cp);
nextSt->insertStmtBefore(*templDecl.second, *cp);
}
}
}
}
}
}
void insertTempalteDeclarationToMainFile(SgFile *file, const DataDirective &dataDir,
const map<string, string> &templateDeclInIncludes,
const vector<string> &distrRules, const vector<vector<dist>> &distrRulesSt,
const DIST::Arrays<int> &allArrays,
const bool extractDir, const uint64_t regionId,
const set<string> &includedToThisFile)
{
vector<SgStatement*> modulesAndFuncs;
getModulesAndFunctions(file, modulesAndFuncs);
map<string, SgStatement*> modules;
for (int i = 0; i < modulesAndFuncs.size(); ++i)
{
if (modulesAndFuncs[i]->variant() == MODULE_STMT)
modules[modulesAndFuncs[i]->symbol()->identifier()] = modulesAndFuncs[i];
}
for (int i = 0; i < modulesAndFuncs.size(); ++i)
{
SgStatement *st = modulesAndFuncs[i];
if (st->variant() == PROG_HEDR)
{
SgStatement *last = st->lastNodeOfStmt();
set<string> includes;
for (SgStatement *stLoc = modulesAndFuncs[i]; stLoc != last; stLoc = stLoc->lexNext())
{
if (stLoc->variant() == CONTAINS_STMT)
break;
if (stLoc->fileName() != string(file->filename()))
includes.insert(stLoc->fileName());
}
vector<SgStatement*> useStmt;
for (SgStatement *stLoc = modulesAndFuncs[i]; stLoc != last; stLoc = stLoc->lexNext())
{
if (stLoc->variant() == USE_STMT)
useStmt.push_back(stLoc);
}
for (auto &arrayPair : sortArraysByName(allArrays.GetArrays()))
{
DIST::Array* array = arrayPair.second;
if (array->IsTemplate() && !array->IsLoopArray() && array->GetLocation().first != DIST::l_MODULE)
{
int templIdx = findTeplatePosition(array, dataDir);
auto allClones = array->GetAllClones();
vector<SgStatement*> insertList1, insertList2;
auto templDeclP = genTemplateDelc(array, array->GetShortName(), file, NULL, true);
string templDecl = templDeclP.first;
insertList1.push_back(templDeclP.second);
for (auto& elem : allClones)
{
auto tmp = genTemplateDelc(array, elem.second, file, NULL, true);
templDecl += tmp.first;
insertList1.push_back(tmp.second);
}
auto tmp = genTemplateDistr(array, array->GetShortName(), distrRules, distrRulesSt, regionId, templIdx, true, file);
string templDist = tmp.first;
insertList2.push_back(tmp.second);
for (auto &elem : allClones)
{
vector<vector<dist>> tmpRuleSt = { elem.first };
string strRule = elem.second + "(";
for (int z = 0; z < elem.first.size(); ++z)
{
if (z != 0)
strRule += ",";
if (elem.first[z] == BLOCK)
strRule += "BLOCK";
else if (elem.first[z] == NONE)
strRule += "*";
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
strRule += ")";
vector<string> tmpStrRule = { strRule };
tmp = genTemplateDistr(array, elem.second, tmpStrRule, tmpRuleSt, regionId, 0, true, file);
templDist += tmp.first;
insertList2.push_back(tmp.second);
}
auto tmpDyn = genDynamicDecl(array, file);
const string templDyn = tmpDyn.first;
const string fullDecl = createFullTemplateDir(make_tuple(templDecl, templDist, templDyn));
bool needToInsert = true;
auto inIncl = templateDeclInIncludes.find(fullDecl);
if (inIncl != templateDeclInIncludes.end())
{
auto hasInThisFunc = includes.find(inIncl->second);
if (hasInThisFunc != includes.end())
needToInsert = false;
}
//check modules
if (needToInsert)
{
for (auto &use : useStmt)
{
string name = use->symbol()->identifier();
auto it = modules.find(name);
if (it == modules.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
else
{
auto last = it->second->lastNodeOfStmt();
for (SgStatement *stLoc = it->second; stLoc != last; stLoc = stLoc->lexNext())
{
const string &templName = array->GetShortName();
if (stLoc->variant() == CONTAINS_STMT)
break;
const char *comment = stLoc->comments();
if (comment)
{
if (string(comment).find(templName) != string::npos)
{
needToInsert = false;
break;
}
}
}
if (needToInsert)
break;
}
}
}
if (needToInsert)
{
SgStatement *nextSt = firstExec(st->lexNext(), st->fileName());
if (!extractDir)
{
auto cp = nextSt->controlParent();
for (int z = 0; z < insertList1.size(); ++z)
{
nextSt->insertStmtBefore(*insertList1[z], *cp);
nextSt->insertStmtBefore(*insertList2[z], *cp);
}
nextSt->insertStmtBefore(*tmpDyn.second, *cp);
}
}
}
}
}
}
}
static SgStatement* insertDvmhModule(SgStatement *firstSt, const vector<SgStatement*> &modulesAndFuncs)
{
for (auto& st : modulesAndFuncs)
{
if (st->variant() == MODULE_STMT)
{
if (st->symbol()->identifier() == dvmhModuleName)
return st;
}
}
SgFuncHedrStmt *moduleN = new SgFuncHedrStmt((char*)dvmhModuleName.c_str());
moduleN->setVariant(MODULE_STMT);
moduleN->setlineNumber(getNextNegativeLineNumber());
moduleN->setFileId(current_file_id);
firstSt->insertStmtAfter(*moduleN, *firstSt);
return moduleN;
}
extern "C" int out_free_form;
void correctTemplateModuleDeclaration(const string& folderName)
{
int ifInOneFile = 0;
map<SgFile*, vector<SgStatement*>> modsAndFuncs;
for (int z = 0; z < CurrentProject->numberOfFiles(); ++z)
{
SgFile* file = &CurrentProject->file(z);
getModulesAndFunctions(file, modsAndFuncs[file]);
for (auto& elem : modsAndFuncs[file])
if (elem->variant() == MODULE_STMT && elem->symbol()->identifier() == dvmhModuleName)
if (elem->lexNext()->variant() != CONTROL_END)
ifInOneFile++;
}
set<string> unitedModuleDecl;
set<string> fileNames;
for (int z = 0; z < CurrentProject->numberOfFiles(); ++z)
{
SgFile* file = &CurrentProject->file(z);
fileNames.insert(file->filename());
for (auto& elem : modsAndFuncs[file])
{
if (elem->variant() == MODULE_STMT && elem->symbol()->identifier() == dvmhModuleName)
{
if (elem->lexNext()->variant() != CONTROL_END)
{
for (auto st = elem->lexNext(); st != elem->lastNodeOfStmt(); st = st->lexNext())
unitedModuleDecl.insert(st->unparse());
if (ifInOneFile > 1)
elem->deleteStmt();
}
else
elem->deleteStmt();
break;
}
}
}
int t = 0;
if (ifInOneFile > 1)
{
const string base = "spfTemplateModuleDecl";
string fName = (out_free_form == 0) ? (base + ".f") : (base + ".f90");
while (fileNames.find(fName) != fileNames.end())
{
const string tmpB = base + std::to_string(t++);
fName = (out_free_form == 0) ? (tmpB + ".f") : (tmpB + ".f90");
}
const string fullPath = (folderName == "") ? fName : (folderName + "/" + fName);
FILE* fout = fopen(fullPath.c_str(), "w");
if (fout == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
else
__spf_print(1, " created new file for template module decl -> %s\n", fullPath.c_str());
const string shift = (out_free_form == 0) ? " " : "";
const string first = shift + "module " + dvmhModuleName + "\n";
const string last = shift + "end module" + "\n";
string out = first;
for (auto& elem : unitedModuleDecl)
out += elem;
out += last;
fwrite(out.c_str(), sizeof(char), out.size(), fout);
fclose(fout);
}
}
static void findAllArrayRefs(SgExpression *ex, set<SgSymbol*> &refs)
{
if (ex)
{
if (isArrayRef(ex))
{
SgSymbol* symb = ex->symbol();
if (symb->type())
{
if (symb->type()->variant() == T_ARRAY)
refs.insert(ex->symbol());
}
}
findAllArrayRefs(ex->lhs(), refs);
findAllArrayRefs(ex->rhs(), refs);
}
}
static bool hasPrivateAllInModule(SgStatement *mod)
{
bool ret = false;
if (mod && mod->variant() == MODULE_STMT)
{
for (SgStatement* st = mod->lexNext(); st != mod->lastNodeOfStmt(); st = st->lexNext())
{
if (isSgExecutableStatement(st))
break;
if (st->variant() == PRIVATE_STMT)
{
SgVarListDeclStmt* listPrivates = isSgVarListDeclStmt(st);
checkNull(listPrivates, convertFileName(__FILE__).c_str(), __LINE__);
if (listPrivates->numberOfVars() == 0)
{
ret = true;
break;
}
}
}
}
return ret;
}
void insertTemplateModuleUse(SgFile *file, const set<uint64_t> &regNums, const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
int funcNum = file->numberOfFunctions();
map<string, set<string>> moduleUseMap = createMapOfModuleUses(file);
vector<SgStatement*> modules;
findModulesInFile(file, modules);
for (int i = 0; i < funcNum; ++i)
{
SgStatement *st = file->functions(i);
auto cp = st->controlParent();
if (cp->variant() != GLOBAL &&
cp->variant() != PROG_HEDR &&
cp->variant() != PROC_HEDR &&
cp->variant() != FUNC_HEDR)
continue;
else
{
//check for module
if (cp->variant() == PROC_HEDR || cp->variant() == FUNC_HEDR)
{
if (cp->controlParent()->variant() == MODULE_STMT)
continue;
}
}
set<SgSymbol*> refs;
set<string> modUse;
for (st = st->lexNext(); st; st = st->lexNext())
{
if (isSgExecutableStatement(st))
break;
if (st->variant() == VAR_DECL || st->variant() == VAR_DECL_90)
{
for (int z = 0; z < 3; ++z)
findAllArrayRefs(st->expr(z), refs);
}
else if (st->variant() == USE_STMT)
modUse.insert(st->symbol()->identifier());
}
set<DIST::Array*> templates;
for (auto &arrayR : refs)
{
SgStatement *decl = declaratedInStmt(arrayR);
DIST::Array *currArray = getArrayFromDeclarated(decl, arrayR->identifier());
checkNull(currArray, convertFileName(__FILE__).c_str(), __LINE__);
if (!currArray->IsNotDistribute())
{
set<DIST::Array*> realRefs;
getRealArrayRefs(currArray, currArray, realRefs, arrayLinksByFuncCalls);
if (!(realRefs.size() == 1 && realRefs.find(currArray) != realRefs.end()))
continue;
for (auto& num : regNums)
{
auto templ = currArray->GetTemplateArray(num);
if (templ)
{
if (templ->GetLocation().first == DIST::l_MODULE)
{
bool needToAdd = true;
if (modUse.find(dvmhModuleName) == modUse.end())
{
for (auto& elem : modUse)
{
auto it = moduleUseMap.find(elem);
if (it != moduleUseMap.end())
{
SgStatement* currMod = NULL;
for (auto& modV : modules)
if (modV->symbol()->identifier() == elem)
currMod = modV;
if (it->second.find(dvmhModuleName) != it->second.end() && !hasPrivateAllInModule(currMod))
{
needToAdd = false;
break;
}
}
}
}
if (needToAdd)
templates.insert(templ);
}
}
}
}
}
if (templates.size())
{
st = file->functions(i);
SgStatement* useSt = new SgStatement(USE_STMT);
useSt->setSymbol(*findSymbolOrCreate(file, dvmhModuleName));
useSt->setlineNumber(getNextNegativeLineNumber());
st->insertStmtAfter(*useSt, *st);
}
}
}
static set<SgStatement*> filterAllocateStats(SgFile* file, const vector<SgStatement*> &currentAlloc, const string &array)
{
set<SgStatement*> filtered;
const string fileName = file->filename();
for (auto &stat : currentAlloc)
{
set<string> arraySyns;
arraySyns.insert(array);
if (stat->fileName() != fileName)
if (!stat->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
2025-02-18 13:45:20 +03:00
SgExpression* list = stat->expr(0);
bool find = false;
while (list)
{
if (list->lhs() && list->lhs()->symbol())
{
if (OriginalSymbol(list->lhs()->symbol())->identifier() == array)
{
find = true;
break;
}
}
list = list->rhs();
}
2023-09-14 19:43:13 +03:00
2025-02-18 13:45:20 +03:00
if (find)
filtered.insert(stat);
2023-09-14 19:43:13 +03:00
SgFile::switchToFile(fileName);
}
//TODO: removed this checking 17.04.2020
/*if (filtered.size() != 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);*/
return filtered;
}
// by file and function
static map<string, map<string, set<string>>> dynamicDirsByFile;
static map<string, map<string, set<string>>> dynamicArraysByFile;
static map<string, map<string, set<string>>> alignArraysByFile;
static map<string, map<string, map<string, pair<SgExpression*, SgExpression*>>>> insertedShadowByFile;
static inline void addStringToComments(const vector<string> &toInsert, map<string, map<int, set<string>>> &commentsToInclude,
const string& fileName, const int line)
{
//check for file in project
int totalFiles = CurrentProject->numberOfFiles();
string wasFile = current_file->filename();
bool exist = false;
for (int z = 0; z < totalFiles && !exist; ++z)
if (CurrentProject->file(z).filename() == fileName)
exist = true;
SgFile::switchToFile(wasFile);
if (exist)
return;
auto currF = commentsToInclude.find(fileName);
if (currF == commentsToInclude.end())
currF = commentsToInclude.insert(currF, make_pair(fileName, map<int, set<string>>()));
auto place = currF->second.find(line);
if (place == currF->second.end())
place = currF->second.insert(place, make_pair(line, set<string>()));
for (auto &str : toInsert)
{
if (str == "")
continue;
bool needToInsert = true;
for (auto &elem : currF->second)
{
for (auto addedStr : elem.second)
{
if (addedStr == str)
{
needToInsert = false;
break;
}
}
if (needToInsert == false)
break;
}
if (needToInsert)
place->second.insert(str);
}
}
static void addComment(SgStatement* st, const string& toAdd, bool needUniq = false)
{
if (needUniq)
{
char* comm = st->comments();
if (comm == NULL)
st->addComment(toAdd.c_str());
else if (string(comm).find(toAdd) == string::npos)
st->addComment(toAdd.c_str());
}
else
st->addComment(toAdd.c_str());
}
static string getFullArrayName(SgSymbol *symb)
{
string fullArrayName = "";
if (symb->type()->variant() == T_ARRAY)
{
auto uniqKey = getFromUniqTable(symb);
fullArrayName = getShortName(uniqKey);
}
return fullArrayName;
}
static vector<SgExpression*> createVarListFromDecl(const int currV, SgStatement *st)
{
vector<SgExpression*> varList;
if (currV == COMM_STAT)
{
map<string, vector<SgExpression*>> commonBlocks;
getCommonBlocksRef(commonBlocks, st, st->lexNext());
for (auto &elem : commonBlocks)
{
for (auto &commList : elem.second)
{
SgExpression *list = commList->lhs();
while (list)
{
varList.push_back(list->lhs());
list = list->rhs();
}
}
}
}
else
{
SgVarDeclStmt *varDecl = (SgVarDeclStmt*)st;
SgExpression *varL = varDecl->varList();
while (varL)
{
varList.push_back(varL->lhs());
varL = varL->rhs();
}
}
return varList;
}
static string getFullArrayNameOfParameter(SgStatement* fPointer, const int numOfParams, const int currPar)
{
string oldFile = current_file->filename(); //save file
if (!fPointer->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto hedrOfIface = (SgProgHedrStmt*)fPointer;
if (hedrOfIface->numberOfParameters() != numOfParams)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto sInIface = hedrOfIface->parameter(currPar);
const string fullArrayName = getFullArrayName(sInIface);
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return fullArrayName;
}
static void createInherit(pair<SgStatement*, SgStatement*>& inheritDir, SgStatement* insertBefore, SgExpression* ref)
{
if (inheritDir.first == NULL)
{
inheritDir.first = new SgStatement(DVM_INHERIT_DIR);
SgExpression* list = new SgExpression(EXPR_LIST);
list->setLhs(ref);
inheritDir.first->setExpression(0, *list);
inheritDir.second = insertBefore;
}
else
{
SgExpression* list = new SgExpression(EXPR_LIST);
list->setLhs(ref);
list->setRhs(inheritDir.first->expr(0));
inheritDir.first->setExpression(0, *list);
}
}
void insertDistributionToFile(SgFile *file, const char *fin_name, const DataDirective &dataDir,
const set<string> &distrArrays, const vector<string> &distrRules,
const vector<vector<dist>> &distrRulesSt,
const vector<string> &alignRules, const map<string, vector<LoopGraph*>> &loopGraph,
const DIST::Arrays<int> &allArrays,
DIST::GraphCSR<int, double, attrType> &reducedG,
map<string, map<int, set<string>>> &commentsToInclude,
map<string, string> &templateDeclInIncludes,
const bool extractDir, vector<Messages> &messagesForFile,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls,
const map<string, FuncInfo*>& funcsInFile,
const uint64_t regionId, const set<string>& allFileNames)
{
const string currFilename = file->filename();
vector<SgStatement*> modulesAndFuncs;
getModulesAndFunctions(file, modulesAndFuncs);
SgStatement *dvmhModule = NULL;
for (int i = 0; i < modulesAndFuncs.size(); ++i)
{
SgStatement *isModule = (modulesAndFuncs[i]->variant() == MODULE_STMT) ? modulesAndFuncs[i] : NULL;
if (isModule)
{
dvmhModule = insertDvmhModule(file->firstStatement(), modulesAndFuncs);
break;
}
}
map<SgStatement*, set<string>> dvmhModuleSt;
if (dvmhModule)
dvmhModuleSt[dvmhModule] = set<string>();
for (int i = 0; i < modulesAndFuncs.size(); ++i)
{
SgStatement *st = modulesAndFuncs[i];
FuncInfo* currFI = NULL;
if (st->variant() != MODULE_STMT)
{
for (auto& funcs : funcsInFile)
if (funcs.second->funcPointer->GetOriginal() == st)
currFI = funcs.second;
if (currFI == NULL)
{
__spf_print(1, "function '%s' not found in map of functons\n", st->symbol()->identifier());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
SgStatement *lastNode = st->lastNodeOfStmt();
const auto lineRange = make_pair(st->lineNumber(), lastNode->lineNumber());
const string filename = st->fileName();
set<string> templateDelc;
SgStatement *isModule = (st->variant() == MODULE_STMT) ? st : NULL;
bool isMain = (st->variant() == PROG_HEDR);
const string modName = st->symbol()->identifier();
map<string, pair<SgExpression*, SgExpression*>> &insertedShadow = insertedShadowByFile[fin_name][modName];
set<string> &dynamicDirs = dynamicDirsByFile[fin_name][modName];
set<string> &dynamicArraysAdded = dynamicArraysByFile[fin_name][modName];
set<string> &alignArrays = alignArraysByFile[fin_name][modName];
// PAIR<dir, insertBefore>
pair<SgStatement*, SgStatement*> inheritDir = make_pair((SgStatement*)NULL, (SgStatement*)NULL);
map<SgStatement*, pair<SgStatement*, SgStatement*>> inheritDirIface;
while (st != lastNode)
{
if (st == NULL)
{
messagesForFile.push_back(Messages(ERROR, 1, R128, L"internal error in analysis, parallel directives will not be generated for this file!", 3008));
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
break;
}
if (st->variant() == CONTAINS_STMT)
break;
const int currV = st->variant();
if (currV == VAR_DECL || currV == VAR_DECL_90 || currV == DIM_STAT || currV == COMM_STAT)
{
auto varList = createVarListFromDecl(currV, st);
set<DIST::Array*> dynamicArrays;
set<DIST::Array*> dynamicArraysLocal;
for (auto &varExp : varList)
{
if (isArrayRef(varExp))
{
SgSymbol *currSymb = OriginalSymbol(varExp->symbol());
const string fullArrayName = getFullArrayName(currSymb);
const string arrayName = string(currSymb->identifier());
if (isModule == NULL && extractDir == false)
{
SgStatement* st_cp = st->controlParent();
if (st_cp->variant() == PROC_HEDR || st_cp->variant() == FUNC_HEDR)
{
if (st_cp->controlParent()->variant() == INTERFACE_STMT) // interface in procedure, check distribution state
{
auto hedr = ((SgProgHedrStmt*)st_cp);
int numOfParams = hedr->numberOfParameters();
int z = 0;
for (; z < numOfParams; ++z)
{
auto t = hedr->parameter(z);
if (t->identifier() == arrayName)
break;
}
if (numOfParams)
{
if (z == numOfParams)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const string fName = hedr->name().identifier();
auto itIface = currFI->interfaceBlocks.find(fName);
if (itIface == currFI->interfaceBlocks.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (itIface->second == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
set<string> fullArrayNames;
if (itIface->second->fullCopiesOfThisFunction.size() == 0)
if (itIface->second->funcPointer->variant() > 0)
fullArrayNames.insert(getFullArrayNameOfParameter(itIface->second->funcPointer->GetOriginal(), numOfParams, z));
for (auto& fullCopies : itIface->second->fullCopiesOfThisFunction)
if (fullCopies->funcPointer->variant() > 0)
fullArrayNames.insert(getFullArrayNameOfParameter(fullCopies->funcPointer->GetOriginal(), numOfParams, z));
bool needToInherit = false;
for (auto& fullArrayName : fullArrayNames)
if (distrArrays.find(fullArrayName) != distrArrays.end())
needToInherit = true;
if (needToInherit)
{
auto it = inheritDirIface.find(st_cp);
if (it == inheritDirIface.end())
it = inheritDirIface.insert(it, make_pair(st_cp, make_pair((SgStatement*)NULL, (SgStatement*)NULL)));
createInherit(it->second, st_cp, new SgVarRefExp(currSymb));
}
}
}
}
}
if (distrArrays.find(fullArrayName) != distrArrays.end())
{
const vector<SgStatement*> &allocatableStmtsCopy = getAttributes<SgStatement*, SgStatement*>(st, set<int>{ ALLOCATE_STMT });
set<SgStatement*> allocatableStmts;
if (allocatableStmtsCopy.size())
allocatableStmts = filterAllocateStats(file, allocatableStmtsCopy, currSymb->identifier());
2025-02-10 17:16:15 +03:00
pair<DIST::Array*, string> dirWithArray = getNewDirective(fullArrayName, distrRules, alignRules, dataDir, allocatableStmts);
2023-09-14 19:43:13 +03:00
string toInsert = dirWithArray.second;
if (toInsert != "")
{
auto alignIt = alignArrays.find(fullArrayName);
if (alignIt == alignArrays.end() && !extractDir)
alignArrays.insert(alignIt, fullArrayName);
else if (alignIt != alignArrays.end() && extractDir)
alignArrays.erase(alignIt);
else
toInsert = "";
const pair<templateDir, string> &templDir =
getNewTemplateDirective(dirWithArray.first, allArrays, reducedG, dataDir, distrRules, distrRulesSt, arrayLinksByFuncCalls, regionId, isModule, isMain, file, messagesForFile);
string templDecl = templDir.first.templDecl.first; //std::get<0>(templDir.first);
//if array is inherit array
if (templDir.second == "!DVM$ INHERIT\n")
{
toInsert = "";
if (extractDir == false)
createInherit(inheritDir, st, new SgVarRefExp(findSymbolOrCreate(file, dirWithArray.first->GetShortName())));
}
else
dynamicArraysLocal.insert(dirWithArray.first);
dynamicArrays.insert(dirWithArray.first);
if (templDir.second == "!DVM$ INHERIT\n" && templDir.first.isTemplateInModule)
templDecl = "";
else
{
if (templateDelc.find(templDecl) == templateDelc.end())
templateDelc.insert(templDecl);
else
templDecl = "";
if (templDecl != "")
templDecl = createFullTemplateDir(make_tuple(templDir.first.templDecl.first, templDir.first.templDist.first, templDir.first.templDyn.first));
}
const bool isFromInclude = allFileNames.find(st->fileName()) == allFileNames.end();
if (isMain)
templDecl = "";
else
{
set<DIST::Array*> realRefs;
getRealArrayRefs(dirWithArray.first, dirWithArray.first, realRefs, arrayLinksByFuncCalls);
for (auto &elem : realRefs)
{
if (elem->GetTemplateArray(regionId)->GetLocation().first == DIST::l_MODULE)
{
templDecl = "";
break;
}
}
}
vector<string> toAdd;
if (isModule && dvmhModule)
toAdd = { toInsert, "" };
else
toAdd = { templDecl, toInsert };
if (extractDir)
{
if (allocatableStmts.size())
{
if (isModule && dvmhModule)
{
for (auto& elem : allocatableStmts)
{
if (elem->fileName() != currFilename)
continue;
extractComments(elem->lexNext(), toAdd[0] + toAdd[1]);
}
extractComments(st, ("!DVM$ ALIGN :: " + dirWithArray.first->GetShortName() + "\n").c_str());
}
else
{
for (auto& elem : allocatableStmts)
{
if (elem->fileName() != currFilename)
continue;
extractComments(elem->lexNext(), toInsert);
}
extractComments(st, (templDecl + "!DVM$ ALIGN :: " + dirWithArray.first->GetShortName() + "\n").c_str());
}
}
else
extractComments(st, toAdd[0] + toAdd[1]);
}
else
{
if (allocatableStmts.size())
{
if (isModule && dvmhModule)
{
for (auto& elem : allocatableStmts)
{
if (elem->fileName() != currFilename)
continue;
if (elem->lexNext()->variant() != CONT_STAT)
elem->insertStmtAfter(*new SgContinueStmt(), *elem->controlParent());
addComment(elem->lexNext(), (toAdd[0] + toAdd[1]).c_str(), true);
}
const string newDecl = "!DVM$ ALIGN :: " + dirWithArray.first->GetShortName() + "\n";
if (isFromInclude)
addStringToComments({ newDecl }, commentsToInclude, st->fileName(), st->lineNumber());
else
st->addComment(newDecl.c_str());
}
else
{
for (auto& elem : allocatableStmts)
{
if (elem->fileName() != currFilename)
continue;
if (elem->lexNext()->variant() != CONT_STAT)
elem->insertStmtAfter(*new SgContinueStmt(), *elem->controlParent());
addComment(elem->lexNext(), toInsert.c_str(), true);
}
const string newDecl = templDecl + "!DVM$ ALIGN :: " + dirWithArray.first->GetShortName() + "\n";
if (isFromInclude)
addStringToComments({ newDecl }, commentsToInclude, st->fileName(), st->lineNumber());
else
st->addComment(newDecl.c_str());
}
}
else
{
if (isFromInclude)
addStringToComments({ toAdd }, commentsToInclude, st->fileName(), st->lineNumber());
else
st->addComment((toAdd[0] + toAdd[1]).c_str());
}
if (isFromInclude)
if (templDecl != "")
templateDeclInIncludes[templDecl] = st->fileName();
if (isModule && dvmhModule)
{
if (dvmhModuleSt[dvmhModule].find(templDir.first.templDyn.first) == dvmhModuleSt[dvmhModule].end())
{
dvmhModule->insertStmtAfter(*templDir.first.templDyn.second, *dvmhModule);
dvmhModuleSt[dvmhModule].insert(templDir.first.templDyn.first);
}
if (dvmhModuleSt[dvmhModule].find(templDir.first.templDecl.first) == dvmhModuleSt[dvmhModule].end())
{
for (int z = 0; z < templDir.first.templDecl.second.size(); ++z)
dvmhModule->insertStmtAfter(*templDir.first.templDecl.second[z], *dvmhModule);
dvmhModuleSt[dvmhModule].insert(templDir.first.templDecl.first);
}
if (dvmhModuleSt[dvmhModule].find(templDir.first.templDist.first) == dvmhModuleSt[dvmhModule].end())
{
for (int z = 0; z < templDir.first.templDist.second.size(); ++z)
dvmhModule->insertStmtAfter(*templDir.first.templDist.second[z], *dvmhModule);
dvmhModuleSt[dvmhModule].insert(templDir.first.templDist.first);
}
const string useS = dvmhModule->symbol()->identifier();
string str = string("use ") + useS;
if (dvmhModuleSt[isModule].find(str) == dvmhModuleSt[isModule].end())
{
dvmhModuleSt[isModule].insert(str);
SgStatement *useSt = new SgStatement(USE_STMT);
useSt->setSymbol(*findSymbolOrCreate(file, useS));
useSt->setlineNumber(getNextNegativeLineNumber());
isModule->insertStmtAfter(*useSt, *isModule);
}
}
}
}
else // may be INHERIT array?
{
SgStatement* st_cp = st->controlParent();
if (!extractDir && (st_cp->variant() == PROC_HEDR || st_cp->variant() == FUNC_HEDR))
{
SgProgHedrStmt* hedr = (SgProgHedrStmt*)st_cp;
for (int z = 0; z < hedr->numberOfParameters(); ++z)
{
if (hedr->parameter(z)->identifier() == string(currSymb->identifier()))
{
auto array = getArrayFromDeclarated(declaratedInStmt(currSymb), currSymb->identifier());
checkNull(array, convertFileName(__FILE__).c_str(), __LINE__);
set<DIST::Array*> realRefs;
getRealArrayRefs(array, array, realRefs, arrayLinksByFuncCalls);
bool distributed = false;
int rank = -1;
bool diffRank = false;
for (auto& elem : realRefs)
{
if (elem->IsNotDistribute() == false)
{
distributed = true;
int oldRank = rank;
rank = elem->GetDimSize();
if (oldRank != -1 && oldRank != elem->GetDimSize())
diffRank = true;
}
}
if (distributed && !diffRank && rank == array->GetDimSize())
createInherit(inheritDir, st, new SgVarRefExp(currSymb));
break;
}
}
}
}
}
}
}
string toInsert = "!DVM$ DYNAMIC ";
set<string> toInsertArrays;
for (auto &array : dynamicArraysLocal)
{
if (extractDir)
{
if (dynamicArraysAdded.find(array->GetShortName()) != dynamicArraysAdded.end())
{
dynamicArraysAdded.erase(array->GetShortName());
toInsertArrays.insert(array->GetShortName());
}
}
else
{
if (dynamicArraysAdded.find(array->GetShortName()) == dynamicArraysAdded.end())
{
dynamicArraysAdded.insert(array->GetShortName());
toInsertArrays.insert(array->GetShortName());
}
}
}
int z = 0;
for (auto &array : toInsertArrays)
{
if (z != 0)
toInsert += ",";
toInsert += array;
++z;
}
if (z != 0)
{
toInsert += "\n";
auto dynIt = dynamicDirs.find(toInsert);
if (dynIt == dynamicDirs.end() && !extractDir)
dynamicDirs.insert(dynIt, toInsert);
else if (extractDir && dynIt != dynamicDirs.end())
dynamicDirs.erase(dynIt);
else
toInsert = "";
}
else
toInsert = "";
if (dynamicArrays.size() > 0)
createShadowSpec(loopGraph, arrayLinksByFuncCalls, dynamicArrays);
if (toInsert != "")
{
if (!strcmp(st->fileName(), fin_name))
{
if (extractDir)
extractComments(st, toInsert);
else
st->addComment(toInsert.c_str());
}
else
{
if (!extractDir)
addStringToComments({ toInsert }, commentsToInclude, st->fileName(), st->lineNumber());
}
}
}
st = st->lexNext();
}
if (extractDir == false)
{
if (inheritDir.second)
{
inheritDir.second->insertStmtBefore(*inheritDir.first, *inheritDir.second->controlParent());
SgStatement* dynamicDir = new SgStatement(DVM_DYNAMIC_DIR);
dynamicDir->setExpression(0, inheritDir.first->expr(0)->copy());
inheritDir.second->insertStmtBefore(*dynamicDir, *inheritDir.second->controlParent());
}
for (auto& inherit : inheritDirIface)
{
SgStatement* dynamicDir = new SgStatement(DVM_DYNAMIC_DIR);
dynamicDir->setExpression(0, inherit.second.first->expr(0)->copy());
inherit.first->insertStmtAfter(*dynamicDir, *inherit.first);
inherit.first->insertStmtAfter(*inherit.second.first, *inherit.first);
}
}
}
if (extractDir)
{
if (dvmhModule)
dvmhModule->deleteStmt();
}
else
{
//TODO: do it better!!
if (dvmhModule)
{
if (dvmhModule->lexNext()->variant() == CONTROL_END)
dvmhModule->deleteStmt();
}
}
}
void insertShadowSpecToFile(SgFile *file, const char *fin_name, const set<string> &distrArrays,
DIST::GraphCSR<int, double, attrType> &reducedG,
map<string, map<int, set<string>>> &commentsToInclude,
const bool extractDir, vector<Messages> &messagesForFile,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays)
{
vector<SgStatement*> modulesAndFuncs;
getModulesAndFunctions(file, modulesAndFuncs);
for (int i = 0; i < modulesAndFuncs.size(); ++i)
{
SgStatement *st = modulesAndFuncs[i];
SgStatement *lastNode = st->lastNodeOfStmt();
const string modName = st->symbol()->identifier();
map<string, pair<SgExpression*, SgExpression*>> &insertedShadow = insertedShadowByFile[fin_name][modName];
while (st != lastNode)
{
if (st == NULL)
{
messagesForFile.push_back(Messages(ERROR, 1, R128, L"internal error in analysis, parallel directives will not be generated for this file!", 3008));
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
break;
}
if (st->variant() == CONTAINS_STMT)
break;
const int currV = st->variant();
if (currV == VAR_DECL || currV == VAR_DECL_90 || currV == DIM_STAT || currV == COMM_STAT)
{
auto varList = createVarListFromDecl(currV, st);
set<DIST::Array*> declaratedDistrArrays;
for (auto &varExpr : varList)
{
if (isArrayRef(varExpr))
{
SgSymbol *currSymb = OriginalSymbol(varExpr->symbol());
const string fullArrayName = getFullArrayName(currSymb);
if (distrArrays.find(fullArrayName) != distrArrays.end())
{
auto uniqKey = getFromUniqTable(currSymb);
auto itArr = declaredArrays.find(uniqKey);
if (itArr != declaredArrays.end())
declaratedDistrArrays.insert(itArr->second.first);
}
}
}
vector<pair<SgExpression*, SgExpression*>> shadowsSpecs;
vector<string> shadowsSpecsString;
for (auto &arrayPair : sortArraysByName(declaratedDistrArrays))
{
DIST::Array* array = arrayPair.second;
const vector<pair<int, int>> currSpec = array->GetShadowSpec();
bool needToGen = false;
for (auto &elem : currSpec)
if (elem.first != 0 || elem.second != 0)
needToGen = true;
if (needToGen)
{
string shadowSpecInsert = "!DVM$ SHADOW " + array->GetShortName() + "(";
for (int k = 0; k < currSpec.size(); ++k)
{
char buf[256];
sprintf(buf, "%d:%d", currSpec[k].first, currSpec[k].second);
shadowSpecInsert += buf;
if (k != currSpec.size() - 1)
shadowSpecInsert += ",";
}
shadowSpecInsert += ")\n";
shadowsSpecsString.push_back(shadowSpecInsert);
pair<SgExpression*, SgExpression*> newSpec = genShadowSpec(file, make_pair(array->GetShortName(), currSpec));
if (newSpec.first == NULL || newSpec.second == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
shadowsSpecs.push_back(newSpec);
}
}
if (shadowsSpecsString.size() > 0)
{
if (!strcmp(st->fileName(), fin_name))
{
if (!extractDir)
{
for (int i = 0; i < shadowsSpecs.size(); ++i)
{
SgStatement *tmp = new SgStatement(DVM_SHADOW_DIR, NULL, NULL, shadowsSpecs[i].first, shadowsSpecs[i].second, NULL);
st->insertStmtAfter(*tmp, *st->controlParent());
insertedShadow.insert(make_pair(shadowsSpecs[i].first->unparse(), shadowsSpecs[i]));
}
}
else
{
for (int i = 0; i < shadowsSpecs.size(); ++i)
{
auto it = insertedShadow.find(shadowsSpecs[i].first->unparse());
if (it != insertedShadow.end())
insertedShadow.erase(it);
}
}
}
else
{
if (!extractDir)
addStringToComments(shadowsSpecsString, commentsToInclude, st->fileName(), st->lineNumber());
}
}
}
st = st->lexNext();
}
}
}
void insertDistributionToFile(const char *origFile, const char *outFile, const map<int, set<string>> &commentsToInclude)
{
FILE *F = fopen(origFile, "r");
vector<string> lines;
set<string> uniqLines;
while (!feof(F))
{
char buf[8192];
char *res = fgets(buf, 8192, F);
if (res)
{
string bufStr(buf);
convertToLower(bufStr);
bool iSPF = isSPF_comment(bufStr);
bool iDVM = isDVM_comment(bufStr);
if ((iSPF && (keepSpfDirs == 0)) || iDVM)
{
lines.push_back(" ");
uniqLines.insert(" ");
}
else
{
lines.push_back(buf);
uniqLines.insert(buf);
}
}
}
fclose(F);
F = fopen(outFile, "w");
//save order
int idx = 0;
for (auto k = commentsToInclude.begin(); k != commentsToInclude.end(); ++k)
{
int currLine = k->first - 1;
if (currLine > idx)
{
if (idx < lines.size())
{
for ( ; idx < currLine; ++idx)
if (lines[idx] != " " && lines[idx] != "\n")
fprintf(F, "%s", lines[idx].c_str());
}
for (auto it = k->second.begin(); it != k->second.end(); ++it)
fprintf(F, "%s", (*it).c_str());
}
else
for (auto it = k->second.begin(); it != k->second.end(); ++it)
fprintf(F, "%s", (*it).c_str());
}
for ( ; idx < lines.size(); ++idx)
if (lines[idx] != " " && lines[idx] != "\n")
fprintf(F, "%s", lines[idx].c_str());
fclose(F);
}
void insertDistributeDirsToParallelRegions(const vector<ParallelRegionLines> *currLines,
const vector<Statement*> &reDistrRulesBefore,
const vector<Statement*> &reDistrRulesAfter,
const vector<Statement*> &reAlignRules)
{
if (currLines)
{
for (int i = 0; i < currLines->size(); ++i)
{
SgStatement *insertBefore = (*currLines)[i].stats.first;
SgStatement *insertAfter = (*currLines)[i].stats.second;
if (insertBefore == NULL || insertAfter == NULL)
continue;
SgStatement *controlParentAfter = insertAfter->controlParent();
if (insertAfter->variant() == CONTROL_END)
controlParentAfter = controlParentAfter->controlParent();
while (insertBefore->lexPrev()->variant() == DVM_PARALLEL_ON_DIR || insertBefore->lexPrev()->variant() == DVM_REDISTRIBUTE_DIR)
insertBefore = insertBefore->lexPrev();
while (insertAfter->lexPrev()->variant() == DVM_PARALLEL_ON_DIR)
insertAfter = insertAfter->lexPrev();
while (insertAfter->lexNext()->variant() == DVM_REDISTRIBUTE_DIR)
insertAfter = insertAfter->lexNext();
while (insertBefore && isSgExecutableStatement(insertBefore) == NULL)
insertBefore = insertBefore->lexNext();
for (int k = 0; k < reDistrRulesBefore.size(); ++k)
insertBefore->insertStmtBefore(reDistrRulesBefore[k]->copy(), *insertBefore->controlParent());
for (int k = 0; k < reDistrRulesAfter.size(); ++k)
insertAfter->insertStmtAfter(reDistrRulesAfter[k]->copy(), *controlParentAfter);
for (int k = 0; k < reAlignRules.size(); ++k)
insertBefore->insertStmtBefore(reAlignRules[k]->copy(), *insertBefore->controlParent());
// insert redistribute before all return stats
for (SgStatement *st = (*currLines)[i].stats.first; st->variant() != SPF_END_PARALLEL_REG_DIR; st = st->lexNext())
{
if (st->variant() == RETURN_STAT)
{
SgStatement *cp = st->controlParent();
if (cp->variant() == LOGIF_NODE)
cp = ((SgLogIfStmt*)cp)->convertLogicIf();
for (int k = 0; k < reDistrRulesBefore.size(); ++k)
st->insertStmtBefore(reDistrRulesAfter[k]->copy(), *cp);
}
}
SgStatement *module = (*currLines)[i].stats.first;
int modVar = module->variant();
while (modVar != MODULE_STMT && modVar != FUNC_HEDR && modVar != PROC_HEDR && modVar != PROG_HEDR)
{
module = module->controlParent();
modVar = module->variant();
}
map<int, vector<int>> allLabRefs;
findAllRefsToLables(module, allLabRefs);
int labNum = 1;
// insert redistribute after all entry points
for (SgStatement *st = (*currLines)[i].stats.first->lexNext(); st->variant() != SPF_END_PARALLEL_REG_DIR; st = st->lexNext())
{
if (st->variant() == ENTRY_STAT)
{
SgStatement *cp = st->controlParent();
SgStatement *afterEntry = st->lexNext();
int goToLab = -1;
SgLabel *goToLabp = NULL;
if (afterEntry->label())
{
goToLabp = afterEntry->label();
goToLab = goToLabp->getLabNumber();
}
else
{
while (allLabRefs.find(labNum) != allLabRefs.end())
++labNum;
goToLab = labNum;
allLabRefs.insert(make_pair(labNum, vector<int>()));
++labNum;
goToLabp = new SgLabel(goToLab);
afterEntry->setLabel(*goToLabp);
BIF_LABEL_USE(afterEntry->thebif) = goToLabp->thelabel;
}
SgGotoStmt *gotoStat = new SgGotoStmt(*goToLabp);
st->insertStmtBefore(*gotoStat, *cp);
for (int k = 0; k < reAlignRules.size(); ++k)
st->insertStmtAfter(reAlignRules[k]->copy(), *cp);
for (int k = 0; k < reDistrRulesBefore.size(); ++k)
st->insertStmtAfter(reDistrRulesBefore[k]->copy(), *cp);
}
}
}
}
2024-03-24 21:24:32 +03:00
}
void insertParallelDirs(SgFile *file, bool extract,
vector<Directive*>& createdDirectives,
vector<Messages>& messages,
map<string, string>& templateDeclInIncludes,
map<string, map<int, set<string>>>& commentsToInclude,
const vector<FuncInfo*>& callGraph,
const vector<ParallelRegion*>& parallelRegions,
const map<string, vector<LoopGraph*>>& loopGraph,
const set<string>& allFileNames,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<DIST::Array*, tuple<int, string, string>>& tableOfUniqNamesByArray)
{
const char* file_name = file->filename();
insertDirectiveToFile(file, file_name, createdDirectives, extract, messages);
if (sharedMemoryParallelization == 0)
2024-03-24 21:24:32 +03:00
{
map<string, FuncInfo*> mapFuncInfo;
createMapOfFunc(callGraph, mapFuncInfo);
for (int z = 0; z < parallelRegions.size(); ++z)
{
ParallelRegion* currReg = parallelRegions[z];
const DataDirective& dataDirectives = currReg->GetDataDir();
const vector<int>& currentVariant = currReg->GetCurrentVariant();
const DIST::Arrays<int>& allArrays = currReg->GetAllArrays();
DIST::GraphCSR<int, double, attrType>& reducedG = currReg->GetReducedGraphToModify();
const set<string> distrArrays = fillDistributedArrays(dataDirectives, tableOfUniqNamesByArray, arrayLinksByFuncCalls);
const vector<string> distrRules = dataDirectives.GenRule(currentVariant);
const vector<vector<dist>> distrRulesSt = dataDirectives.GenRule(currentVariant, 0);
const vector<string> alignRules = dataDirectives.GenAlignsRules();
insertDistributionToFile(file, file_name, dataDirectives, distrArrays, distrRules, distrRulesSt, alignRules, loopGraph,
allArrays, reducedG, commentsToInclude, templateDeclInIncludes, extract, messages,
arrayLinksByFuncCalls, mapFuncInfo, currReg->GetId(), allFileNames);
insertLoopTempalteDeclaration(file, dataDirectives, distrRules, distrRulesSt, allArrays, extract, currReg->GetId());
}
}
if (extract)
{
createdDirectives.clear();
//clear shadow specs
for (auto& array : declaredArrays)
array.second.first->ClearShadowSpecs();
}
else if (sharedMemoryParallelization == 0)
2024-03-24 21:24:32 +03:00
{
set<uint64_t> regNum;
for (int z = 0; z < parallelRegions.size(); ++z)
regNum.insert(parallelRegions[z]->GetId());
insertTemplateModuleUse(file, regNum, arrayLinksByFuncCalls);
}
2023-09-14 19:43:13 +03:00
}