From 8e4a4c78adec203e54eec8c2d48c97fde3f325f9 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Sat, 11 Jan 2025 09:32:17 +0300 Subject: [PATCH] improved ROUTINE insertion --- .../trunk/Sage/lib/include/unparseDVM.def | 2 +- dvm/tools/pppa/trunk/src/dvmh_stat.h | 6 + .../_src/DvmhRegions/DvmhRegionInserter.cpp | 233 ++++++++++++++++-- .../_src/DvmhRegions/DvmhRegionInserter.h | 11 +- .../experts/Sapfor_2017/_src/Utils/version.h | 2 +- 5 files changed, 222 insertions(+), 32 deletions(-) diff --git a/dvm/fdvm/trunk/Sage/lib/include/unparseDVM.def b/dvm/fdvm/trunk/Sage/lib/include/unparseDVM.def index 3e5ca45..a460aec 100644 --- a/dvm/fdvm/trunk/Sage/lib/include/unparseDVM.def +++ b/dvm/fdvm/trunk/Sage/lib/include/unparseDVM.def @@ -270,7 +270,7 @@ DEFNODECODE(ACC_CHECKSECTION_DIR, "%CMNT!DVM$%PUTTABCOMTHOSTSECTION%NL", 's',0,BIFNODE) DEFNODECODE(ACC_END_CHECKSECTION_DIR,"%CMNT!DVM$%PUTTABCOMTEND HOSTSECTION%NL", '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) DEFNODECODE(ACC_DECLARE_DIR, "%CMNT!DVM$%PUTTABCOMTDECLARE %LL1%NL", 's',1,BIFNODE) diff --git a/dvm/tools/pppa/trunk/src/dvmh_stat.h b/dvm/tools/pppa/trunk/src/dvmh_stat.h index 77fc50a..60cbce4 100644 --- a/dvm/tools/pppa/trunk/src/dvmh_stat.h +++ b/dvm/tools/pppa/trunk/src/dvmh_stat.h @@ -50,6 +50,9 @@ typedef enum { DVMH_STAT_METRIC_CPY_HTOD, DVMH_STAT_METRIC_CPY_DTOD, /* 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_HTOD, DVMH_STAT_METRIC_CPY_SHADOW_DTOD, @@ -86,6 +89,9 @@ static const char *dvmhStatMetricsTitles[DVMH_STAT_METRIC_FORCE_INT] = { "Copy GPU to CPU", "Copy CPU 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 CPU to GPU", "[Shadow] Copy GPU to GPU", diff --git a/sapfor/experts/Sapfor_2017/_src/DvmhRegions/DvmhRegionInserter.cpp b/sapfor/experts/Sapfor_2017/_src/DvmhRegions/DvmhRegionInserter.cpp index 71921f4..ea21174 100644 --- a/sapfor/experts/Sapfor_2017/_src/DvmhRegions/DvmhRegionInserter.cpp +++ b/sapfor/experts/Sapfor_2017/_src/DvmhRegions/DvmhRegionInserter.cpp @@ -104,7 +104,7 @@ void DvmhRegionInserter::parFuncsInNode(LoopGraph *loop, bool isParallel) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); } else - parallel_functions.insert(it->second); + parallel_functions[it->second].insert(loop); } } else @@ -133,23 +133,36 @@ void DvmhRegionInserter::updateParallelFunctions(const map newList; + map> newList; for (auto& funcPair : allFunctions) { FuncInfo* func = funcPair.second; for (auto& callsTo : func->callsTo) { - if (parallel_functions.find(callsTo) != parallel_functions.end() && - parallel_functions.find(func) == parallel_functions.end()) + auto itF = parallel_functions.find(func); + + set added; + if (itF != parallel_functions.end()) + added = itF->second; + + auto itTo = parallel_functions.find(callsTo); + if (itTo != parallel_functions.end()) { - newList.insert(func); - changes_done = true; + for (auto& loop : itTo->second) + { + if (added.find(loop) == added.end()) + { + changes_done = true; + newList[func].insert(loop); + } + } } } } 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__); } -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 getParallelLoops(const std::set& loops) +{ + set 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 getPrivateArrays(const set& parLoops, + const map>& arrayLinksByFuncCalls) +{ + set 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 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& inLoops, + const map>& arrayLinksByFuncCalls, + SgExpression* addedPrivList) +{ + if (!funcInfo) + return NULL; + + map 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 inParLoops = getParallelLoops(inLoops); + set 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 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 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& inLoops, + const map>& arrayLinksByFuncCalls) { string oldFile = current_file->filename(); if (!func->switchToFile()) @@ -1048,26 +1210,34 @@ static void insertRoutine(SgStatement* func) SgStatement* st = func->lexNext(); SgStatement* last = func->lastNodeOfStmt(); - bool has = false; + + SgStatement* routine = NULL; while (st != last) { if (st->variant() == ACC_ROUTINE_DIR) { - has = true; + routine = st; break; } st = st->lexNext(); } - - if (has == false) + + if (!routine) { 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) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } 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); } -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) { 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); if (it == callTo->interfaceBlocks.end()) { @@ -1124,7 +1302,7 @@ void DvmhRegionInserter::createInterfaceBlockForParallelFunctions() st->symbol()->identifier() == parF->funcName) { iface = st; - insertRoutine(iface); + insertRoutine(iface, parF, inLoops, arrayLinksByFuncCalls); break; } } @@ -1362,15 +1540,16 @@ void insertDvmhRegions(SgProject& project, int files, const vector= 0; --i, ++k) { 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 - 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) diff --git a/sapfor/experts/Sapfor_2017/_src/DvmhRegions/DvmhRegionInserter.h b/sapfor/experts/Sapfor_2017/_src/DvmhRegions/DvmhRegionInserter.h index ecf8391..2e48afb 100644 --- a/sapfor/experts/Sapfor_2017/_src/DvmhRegions/DvmhRegionInserter.h +++ b/sapfor/experts/Sapfor_2017/_src/DvmhRegions/DvmhRegionInserter.h @@ -30,7 +30,7 @@ class DvmhRegionInserter bool isMpiProgram; ReadWriteAnalyzer& rw_analyzer; - std::set parallel_functions; + std::map> parallel_functions; std::set writesToArraysInParallelLoops; std::set usedArraysInParallelLoops; const std::map>& arrayLinksByFuncCalls; @@ -76,7 +76,7 @@ public: void insertActualDirectives(const std::vector* regs); void updateParallelFunctions(const std::map>& loopGraphs); - void createInterfaceBlockForParallelFunctions(); + void createInterfaceBlockForParallelFunctions(bool onlyRoutine = true); void removePrivatesFromParallelLoops(); void addPrivatesToParallelLoops(); void addUsedArrays(std::set& arrays); @@ -95,7 +95,12 @@ public: usedArraysInParallelLoops = newSet; } - const std::set& getParallelFunctions() const { return parallel_functions; } + const std::set getParallelFunctions() const { + std::set retVal; + for (auto& elem : parallel_functions) + retVal.insert(elem.first); + return retVal; + } static void createInterfaceBlockForOutCall(FuncInfo* func, FuncInfo* callFrom); static void createInterfaceBlockForOutCalls(FuncInfo* func); diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/version.h b/sapfor/experts/Sapfor_2017/_src/Utils/version.h index 2584b43..bcf1ed3 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/version.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2375" +#define VERSION_SPF "2379"