improved ROUTINE insertion

This commit is contained in:
ALEXks
2025-01-11 09:32:17 +03:00
committed by Dudarenko
parent b4038b532f
commit 8e4a4c78ad
5 changed files with 222 additions and 32 deletions

View File

@@ -270,7 +270,7 @@ DEFNODECODE(ACC_CHECKSECTION_DIR, "%CMNT!DVM$%PUTTABCOMTHOSTSECTION%NL",
's',0,BIFNODE) 's',0,BIFNODE)
DEFNODECODE(ACC_END_CHECKSECTION_DIR,"%CMNT!DVM$%PUTTABCOMTEND HOSTSECTION%NL", DEFNODECODE(ACC_END_CHECKSECTION_DIR,"%CMNT!DVM$%PUTTABCOMTEND HOSTSECTION%NL",
's',0,BIFNODE) 's',0,BIFNODE)
DEFNODECODE(ACC_ROUTINE_DIR, "%CMNT!DVM$%PUTTABCOMTROUTINE%IF(%LL1!=%NULL), %LL1%NL", DEFNODECODE(ACC_ROUTINE_DIR, "%CMNT!DVM$%PUTTABCOMTROUTINE%IF(%LL1!=%NULL), %LL1%ENDIF%NL",
's',1,BIFNODE) 's',1,BIFNODE)
DEFNODECODE(ACC_DECLARE_DIR, "%CMNT!DVM$%PUTTABCOMTDECLARE %LL1%NL", DEFNODECODE(ACC_DECLARE_DIR, "%CMNT!DVM$%PUTTABCOMTDECLARE %LL1%NL",
's',1,BIFNODE) 's',1,BIFNODE)

View File

@@ -50,6 +50,9 @@ typedef enum {
DVMH_STAT_METRIC_CPY_HTOD, DVMH_STAT_METRIC_CPY_HTOD,
DVMH_STAT_METRIC_CPY_DTOD, DVMH_STAT_METRIC_CPY_DTOD,
/* DVMH memcpy */ /* DVMH memcpy */
DVMH_STAT_METRIC_CPY_ACROSS_DTOH,
DVMH_STAT_METRIC_CPY_ACROSS_HTOD,
DVMH_STAT_METRIC_CPY_ACROSS_DTOD,
DVMH_STAT_METRIC_CPY_SHADOW_DTOH, DVMH_STAT_METRIC_CPY_SHADOW_DTOH,
DVMH_STAT_METRIC_CPY_SHADOW_HTOD, DVMH_STAT_METRIC_CPY_SHADOW_HTOD,
DVMH_STAT_METRIC_CPY_SHADOW_DTOD, DVMH_STAT_METRIC_CPY_SHADOW_DTOD,
@@ -86,6 +89,9 @@ static const char *dvmhStatMetricsTitles[DVMH_STAT_METRIC_FORCE_INT] = {
"Copy GPU to CPU", "Copy GPU to CPU",
"Copy CPU to GPU", "Copy CPU to GPU",
"Copy GPU to GPU", "Copy GPU to GPU",
"[Across] Copy GPU to CPU",
"[Across] Copy CPU to GPU",
"[Across] Copy GPU to GPU",
"[Shadow] Copy GPU to CPU", "[Shadow] Copy GPU to CPU",
"[Shadow] Copy CPU to GPU", "[Shadow] Copy CPU to GPU",
"[Shadow] Copy GPU to GPU", "[Shadow] Copy GPU to GPU",

View File

@@ -104,7 +104,7 @@ void DvmhRegionInserter::parFuncsInNode(LoopGraph *loop, bool isParallel)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
} }
else else
parallel_functions.insert(it->second); parallel_functions[it->second].insert(loop);
} }
} }
else else
@@ -133,23 +133,36 @@ void DvmhRegionInserter::updateParallelFunctions(const map<string, vector<LoopGr
while (changes_done) while (changes_done)
{ {
changes_done = false; changes_done = false;
set<FuncInfo*> newList; map<FuncInfo*, set<LoopGraph*>> newList;
for (auto& funcPair : allFunctions) for (auto& funcPair : allFunctions)
{ {
FuncInfo* func = funcPair.second; FuncInfo* func = funcPair.second;
for (auto& callsTo : func->callsTo) for (auto& callsTo : func->callsTo)
{ {
if (parallel_functions.find(callsTo) != parallel_functions.end() && auto itF = parallel_functions.find(func);
parallel_functions.find(func) == parallel_functions.end())
set<LoopGraph*> added;
if (itF != parallel_functions.end())
added = itF->second;
auto itTo = parallel_functions.find(callsTo);
if (itTo != parallel_functions.end())
{
for (auto& loop : itTo->second)
{
if (added.find(loop) == added.end())
{ {
newList.insert(func);
changes_done = true; changes_done = true;
newList[func].insert(loop);
}
}
} }
} }
} }
for (auto& newElem : newList) for (auto& newElem : newList)
parallel_functions.insert(newElem); for (auto& loop : newElem.second)
parallel_functions[newElem.first].insert(loop);
} }
} }
@@ -1040,7 +1053,156 @@ static void insertInterface(SgStatement* func, const string& iface, const string
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
} }
static void insertRoutine(SgStatement* func) static LoopGraph* getParallelLoop(LoopGraph* loop)
{
auto prev_st = loop->loop->lexPrev();
while (prev_st && isDVM_stat(prev_st))
{
if (prev_st->variant() == DVM_PARALLEL_ON_DIR)
return loop;
prev_st = prev_st->lexPrev();
loop = loop->parent;
}
return NULL;
}
static set<LoopGraph*> getParallelLoops(const std::set<LoopGraph*>& loops)
{
set<LoopGraph*> retVal;
for (auto& elem : loops)
{
string oldFile = current_file->filename();
if (!elem->loop->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto parLoop = getParallelLoop(elem);
checkNull(parLoop, convertFileName(__FILE__).c_str(), __LINE__);
retVal.insert(parLoop);
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
return retVal;
}
static set<DIST::Array*> getPrivateArrays(const set<LoopGraph*>& parLoops,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
set<DIST::Array*> retVal;
for (auto& loop : parLoops)
{
string oldFile = current_file->filename();
if (!loop->loop->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& priv : loop->directive->privates)
{
bool isArray = false;
if (isArrayType(priv->type()))
{
auto type = isSgArrayType(priv->type());
if (type && type->dimension())
isArray = true;
}
if (!isArray)
continue;
DIST::Array* arr = getArrayFromDeclarated(declaratedInStmt(priv), priv->identifier());
checkNull(arr, convertFileName(__FILE__).c_str(), __LINE__);
set<DIST::Array*> realArrayRefs;
getRealArrayRefs(arr, arr, realArrayRefs, arrayLinksByFuncCalls);
for (auto& elem : realArrayRefs)
retVal.insert(elem);
}
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
return retVal;
}
static SgExpression* getPrivateArraysInPar(const FuncInfo* funcInfo, const std::set<LoopGraph*>& inLoops,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
SgExpression* addedPrivList)
{
if (!funcInfo)
return NULL;
map<string, SgExpression*> addedPriv;
SgExpression* ex = addedPrivList;
while (ex)
{
if (ex->lhs() && ex->lhs()->variant() == ACC_PRIVATE_OP)
{
ex = ex->lhs()->lhs();
while (ex)
{
if (ex->lhs() && ex->lhs()->variant() == VAR_REF)
addedPriv[ex->lhs()->symbol()->identifier()] = ex->lhs();
ex = ex->rhs();
}
break;
}
ex = ex->rhs();
}
SgStatement* func = funcInfo->funcPointer->GetOriginal();
auto prog = isSgProgHedrStmt(func);
checkNull(prog, convertFileName(__FILE__).c_str(), __LINE__);
set<LoopGraph*> inParLoops = getParallelLoops(inLoops);
set<DIST::Array*> privArrays = getPrivateArrays(inLoops, arrayLinksByFuncCalls);
for (int z = 0; z < prog->numberOfParameters(); ++z)
{
SgSymbol* par = prog->parameter(z);
bool isArray = false;
if (isArrayType(par->type()))
{
auto type = isSgArrayType(par->type());
if (type && type->dimension())
isArray = true;
}
if (isArray && addedPriv.count(par->identifier()) == 0)
{
DIST::Array* arr = getArrayFromDeclarated(declaratedInStmt(par), par->identifier());
checkNull(arr, convertFileName(__FILE__).c_str(), __LINE__);
set<DIST::Array*> realArrayRefs;
getRealArrayRefs(arr, arr, realArrayRefs, arrayLinksByFuncCalls);
bool found = false;
for (auto& elem : realArrayRefs)
if (privArrays.find(elem) != privArrays.end())
found = true;
if (found)
addedPriv[par->identifier()] = new SgVarRefExp(par);
}
}
if (addedPriv.size())
{
vector<SgExpression*> list;
for (auto& elem : addedPriv)
list.push_back(elem.second);
return makeExprList(list, false);
}
else
return NULL;
}
static void insertRoutine(SgStatement* func, const FuncInfo* funcInfo, const std::set<LoopGraph*>& inLoops,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{ {
string oldFile = current_file->filename(); string oldFile = current_file->filename();
if (!func->switchToFile()) if (!func->switchToFile())
@@ -1048,26 +1210,34 @@ static void insertRoutine(SgStatement* func)
SgStatement* st = func->lexNext(); SgStatement* st = func->lexNext();
SgStatement* last = func->lastNodeOfStmt(); SgStatement* last = func->lastNodeOfStmt();
bool has = false;
SgStatement* routine = NULL;
while (st != last) while (st != last)
{ {
if (st->variant() == ACC_ROUTINE_DIR) if (st->variant() == ACC_ROUTINE_DIR)
{ {
has = true; routine = st;
break; break;
} }
st = st->lexNext(); st = st->lexNext();
} }
if (has == false) if (!routine)
{ {
st = func->lexNext(); st = func->lexNext();
st->insertStmtBefore(*new SgStatement(ACC_ROUTINE_DIR), *st->controlParent()); routine = new SgStatement(ACC_ROUTINE_DIR);
st->insertStmtBefore(*routine, *st->controlParent());
}
SgExpression* list = getPrivateArraysInPar(funcInfo, inLoops, arrayLinksByFuncCalls, routine->expr(0));
if (list)
{
list = new SgExpression(EXPR_LIST, new SgExpression(ACC_PRIVATE_OP, list));
routine->setExpression(0, list);
} }
if (SgFile::switchToFile(oldFile) == -1) if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
} }
static bool isPure(SgStatement* func) static bool isPure(SgStatement* func)
@@ -1089,15 +1259,23 @@ void DvmhRegionInserter::createInterfaceBlockForOutCall(FuncInfo* func, FuncInfo
insertInterface(func->funcPointer, getInterfaceBlock(callFrom->funcPointer->GetOriginal(), callFrom->funcParams), callFrom->funcName); insertInterface(func->funcPointer, getInterfaceBlock(callFrom->funcPointer->GetOriginal(), callFrom->funcParams), callFrom->funcName);
} }
void DvmhRegionInserter::createInterfaceBlockForParallelFunctions() void DvmhRegionInserter::createInterfaceBlockForParallelFunctions(bool onlyRoutine)
{ {
for (auto& parF : parallel_functions) for (auto& func_pair : parallel_functions)
{ {
const auto& parF = func_pair.first;
const auto& inLoops = func_pair.second;
for (auto& callTo : parF->callsTo) for (auto& callTo : parF->callsTo)
{ {
if (callTo->fileName != parF->fileName && isPure(parF->funcPointer->GetOriginal())) if (callTo->fileName != parF->fileName && isPure(parF->funcPointer->GetOriginal()))
{ {
insertRoutine(parF->funcPointer->GetOriginal()); if (onlyRoutine)
{
insertRoutine(parF->funcPointer->GetOriginal(), parF, inLoops, arrayLinksByFuncCalls);
continue;
}
auto it = callTo->interfaceBlocks.find(parF->funcName); auto it = callTo->interfaceBlocks.find(parF->funcName);
if (it == callTo->interfaceBlocks.end()) if (it == callTo->interfaceBlocks.end())
{ {
@@ -1124,7 +1302,7 @@ void DvmhRegionInserter::createInterfaceBlockForParallelFunctions()
st->symbol()->identifier() == parF->funcName) st->symbol()->identifier() == parF->funcName)
{ {
iface = st; iface = st;
insertRoutine(iface); insertRoutine(iface, parF, inLoops, arrayLinksByFuncCalls);
break; break;
} }
} }
@@ -1362,15 +1540,16 @@ void insertDvmhRegions(SgProject& project, int files, const vector<ParallelRegio
for (int i = files - 1, k = 0; i >= 0; --i, ++k) for (int i = files - 1, k = 0; i >= 0; --i, ++k)
{ {
SgFile* file = &(project.file(i)); SgFile* file = &(project.file(i));
DvmhRegionInserter* regionInserter = inserters[k];
for (auto& func : regionInserter->getParallelFunctions())
createInterfacesForOutCalls(func);
// create interface for 'parallel' functions and
// insert ROUTINE directive if needed // insert ROUTINE directive if needed
regionInserter->createInterfaceBlockForParallelFunctions(); inserters[k]->createInterfaceBlockForParallelFunctions();
}
for (int i = files - 1, k = 0; i >= 0; --i, ++k)
{
SgFile* file = &(project.file(i));
// create interface for 'parallel' functions
inserters[k]->createInterfaceBlockForParallelFunctions(false);
} }
for (auto& regionInserter : inserters) for (auto& regionInserter : inserters)

View File

@@ -30,7 +30,7 @@ class DvmhRegionInserter
bool isMpiProgram; bool isMpiProgram;
ReadWriteAnalyzer& rw_analyzer; ReadWriteAnalyzer& rw_analyzer;
std::set<FuncInfo*> parallel_functions; std::map<FuncInfo*, std::set<LoopGraph*>> parallel_functions;
std::set<DIST::Array*> writesToArraysInParallelLoops; std::set<DIST::Array*> writesToArraysInParallelLoops;
std::set<DIST::Array*> usedArraysInParallelLoops; std::set<DIST::Array*> usedArraysInParallelLoops;
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls; const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls;
@@ -76,7 +76,7 @@ public:
void insertActualDirectives(const std::vector<ParallelRegion*>* regs); void insertActualDirectives(const std::vector<ParallelRegion*>* regs);
void updateParallelFunctions(const std::map<std::string, std::vector<LoopGraph*>>& loopGraphs); void updateParallelFunctions(const std::map<std::string, std::vector<LoopGraph*>>& loopGraphs);
void createInterfaceBlockForParallelFunctions(); void createInterfaceBlockForParallelFunctions(bool onlyRoutine = true);
void removePrivatesFromParallelLoops(); void removePrivatesFromParallelLoops();
void addPrivatesToParallelLoops(); void addPrivatesToParallelLoops();
void addUsedArrays(std::set<DIST::Array*>& arrays); void addUsedArrays(std::set<DIST::Array*>& arrays);
@@ -95,7 +95,12 @@ public:
usedArraysInParallelLoops = newSet; usedArraysInParallelLoops = newSet;
} }
const std::set<FuncInfo*>& getParallelFunctions() const { return parallel_functions; } const std::set<FuncInfo*> getParallelFunctions() const {
std::set<FuncInfo*> retVal;
for (auto& elem : parallel_functions)
retVal.insert(elem.first);
return retVal;
}
static void createInterfaceBlockForOutCall(FuncInfo* func, FuncInfo* callFrom); static void createInterfaceBlockForOutCall(FuncInfo* func, FuncInfo* callFrom);
static void createInterfaceBlockForOutCalls(FuncInfo* func); static void createInterfaceBlockForOutCalls(FuncInfo* func);

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_SPF "2375" #define VERSION_SPF "2379"