Refactor shared memory parallelization #49

Merged
Alexander_KS merged 10 commits from refactor_shared_memory_parallelization into master 2024-07-18 06:50:40 +00:00
13 changed files with 108 additions and 1605 deletions
Showing only changes of commit 3cb6f6dd5c - Show all commits

View File

@@ -240,8 +240,6 @@ set(DIRA _src/DirectiveProcessing/directive_analyzer.cpp
_src/DirectiveProcessing/directive_creator.cpp
_src/DirectiveProcessing/directive_creator_base.cpp
_src/DirectiveProcessing/directive_creator.h
_src/DirectiveProcessing/directive_creator_base_nodist.cpp
_src/DirectiveProcessing/directive_creator_nodist.h
_src/DirectiveProcessing/directive_parser.cpp
_src/DirectiveProcessing/directive_parser.h
_src/DirectiveProcessing/directive_omp_parser.cpp
@@ -266,11 +264,8 @@ set(DISTR _src/Distribution/Array.cpp
_src/Distribution/Distribution.h
_src/Distribution/DvmhDirective.cpp
_src/Distribution/DvmhDirective.h
_src/Distribution/DvmhDirective_nodist.cpp
_src/Distribution/DvmhDirective_internal.h
_src/Distribution/DvmhDirective_func.h
_src/Distribution/DvmhDirectiveBase.cpp
_src/Distribution/DvmhDirectiveBase_nodist.cpp
_src/Distribution/DvmhDirectiveBase.h
_src/Distribution/GraphCSR.cpp
_src/Distribution/GraphCSR.h)
@@ -319,9 +314,6 @@ set(INLINER _src/Inliner/inliner.cpp
set(LOOP_ANALYZER _src/LoopAnalyzer/allocations_prepoc.cpp
_src/LoopAnalyzer/dep_analyzer.cpp
_src/LoopAnalyzer/loop_analyzer.cpp
_src/LoopAnalyzer/loop_analyzer_nodist.cpp
_src/LoopAnalyzer/loop_analyzer_nodist.h
_src/LoopAnalyzer/loop_analyzer_internal.h
_src/LoopAnalyzer/loop_analyzer.h)
set(RENAME_SYMBOLS _src/RenameSymbols/rename_symbols.cpp

View File

@@ -1,166 +0,0 @@
#include "../Utils/leak_detector.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <vector>
#include <map>
#include <set>
#include "../ParallelizationRegions/ParRegions.h"
#include "../Distribution/Arrays.h"
#include "../Transformations/loop_transform.h"
#include "../Utils/errors.h"
#include "directive_parser.h"
#include "directive_creator.h"
#include "directive_creator_nodist.h"
#define PRINT_PROF_INFO 1
#define PRINT_DIR_RESULT 0
using std::vector;
using std::pair;
using std::tuple;
using std::map;
using std::set;
using std::make_pair;
using std::make_tuple;
using std::get;
using std::string;
using std::wstring;
void createParallelDirectivesNoDist(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*>> &loopInfos,
const vector<ParallelRegion*>& regions,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls,
vector<Messages> &messages)
{
for (auto &loopInfo : loopInfos)
{
LoopGraph* currLoop = loopInfo.first;
ParallelRegion *currReg = getRegionByLine(regions, currLoop->fileName.c_str(), currLoop->lineNum);
if (currReg == NULL || currLoop->userDvmDirective != NULL)
{
__spf_print(PRINT_PROF_INFO, "Skip loop on file %s and line %d\n", currLoop->fileName.c_str(), currLoop->lineNum);
continue;
}
const int itersCount = currLoop->calculatedCountOfIters;
uint64_t regId = (uint64_t)currLoop;
const DIST::Arrays<int> &allArrays = currReg->GetAllArrays();
vector<pair<pair<string, string>, vector<pair<int, int>>>> acrossInfo;
fillAcrossInfoFromDirectives(currLoop, acrossInfo);
bool hasConflict = false;
// uniqKey -> pair<position of access, pair<acces>> ///write acceses ///
map<DIST::Array*, pair<int, pair<int, int>>, DIST::ArrayComparator> arrayWriteAcc;
set<DIST::Array*> acrossOutArrays;
__spf_print(PRINT_DIR_RESULT, " Loop on line %d:\n", currLoop->lineNum);
const map<DIST::Array*, ArrayInfo*> &currAccesses = loopInfo.second;
// find conflict and fill arrayWriteAcc
hasConflict = checkForConflict(currAccesses, currLoop, arrayWriteAcc, acrossInfo, acrossOutArrays);
if (hasConflict)
__spf_print(PRINT_DIR_RESULT, " has conflict\n");
else
{
if (!currLoop->hasLimitsToParallel() &&
(currLoop->lineNum > 0 || (currLoop->lineNum < 0 && currLoop->altLineNum > 0)))
{
ParallelDirective* parDir = new ParallelDirective();
#if __SPF
parDir->langType = LANG_F;
#else
parDir->langType = LANG_C;
#endif
parDir->line = currLoop->lineNum;
parDir->col = 0;
parDir->file = currLoop->fileName;
fillInfoFromDirectives(currLoop, parDir);
parDir->parallel.push_back(currLoop->loopSymbol);
currLoop->directive = parDir;
currLoop->acrossOutAttribute.insert(acrossOutArrays.begin(), acrossOutArrays.end());
addShadowFromAnalysis(parDir, currAccesses);
currLoop->directiveForLoop = new ParallelDirective(*currLoop->directive);
__spf_print(PRINT_DIR_RESULT, " directive created\n");
}
}
}
}
void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currParReg,
DIST::Arrays<int>& allArrays,
const vector<LoopGraph*>& loopGraph,
const map<int, LoopGraph*>& mapLoopsInFile,
const map<string, FuncInfo*>& mapFuncInfo,
vector<Directive*>& toInsert,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<LoopGraph*, void*>& depInfoForLoopGraph,
vector<Messages>& messages)
{
for (int i = 0; i < loopGraph.size(); ++i)
{
LoopGraph* loop = loopGraph[i];
const bool hasDirective = loop->directive;
const bool noLimits = loop->hasLimitsToParallel() == false;
const bool isMyRegion = loop->region == currParReg;
const bool noUserDir = loop->userDvmDirective == NULL;
if (hasDirective && noLimits && isMyRegion && noUserDir)
{
if (loop->perfectLoop >= 1)
{
ParallelDirective* parDirective = loop->directive;
parDirective->cloneOfTemplate = "";
//try to unite loops
if (createNestedLoops(loop, depInfoForLoopGraph, mapFuncInfo, messages))
parDirective = loop->recalculateParallelDirective();
// rewrite bool topCheck = isOnlyTopPerfect(loop, distribution);
Directive* dirImpl = parDirective->genDirectiveNoDist(file, loop, allArrays, arrayLinksByFuncCalls);
#if __SPF
//move label before loop
if(loop->lineNum > 0)
moveLabelBefore(loop->loop);
// check correctness
if (loop->lineNum < 0)
{
if (loop->altLineNum == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* local = NULL;
local = SgStatement::getStatementByFileAndLine(loop->loop->fileName(), loop->lineNum);
if (local == NULL)
local = SgStatement::getStatementByFileAndLine(loop->loop->fileName(), loop->altLineNum);
checkNull(local, convertFileName(__FILE__).c_str(), __LINE__);
}
#endif
toInsert.push_back(dirImpl);
}
}
else //TODO: add checker for indexing in this loop
{
if (loopGraph[i]->children.size() != 0)
selectParallelDirectiveForVariantNoDist(file, currParReg, allArrays, loopGraph[i]->children, mapLoopsInFile, mapFuncInfo,
toInsert, arrayLinksByFuncCalls,depInfoForLoopGraph, messages);
}
}
}
#undef PRINT_PROF_INFO
#undef PRINT_DIR_RESULT

View File

@@ -1,26 +0,0 @@
#pragma once
#include <vector>
#include <map>
#include <set>
#include <string>
#include "../Distribution/Distribution.h"
#include "../Utils/errors.h"
#include "../GraphLoop/graph_loops.h"
#include "../Utils/types.h"
void createParallelDirectivesNoDist(const std::map<LoopGraph*, std::map<DIST::Array*, ArrayInfo*>>& loopInfos,
const std::vector<ParallelRegion*>& regions,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
std::vector<Messages>& messages);
void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currParReg,
DIST::Arrays<int>& allArrays,
const std::vector<LoopGraph*>& loopGraph,
const std::map<int, LoopGraph*>& mapLoopsInFile,
const std::map<std::string, FuncInfo*>& mapFuncInfo,
std::vector<Directive*>& toInsert,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
const std::map<LoopGraph*, void*>& depInfoForLoopGraph,
std::vector<Messages>& messages);

View File

@@ -9,7 +9,6 @@
#include "../Utils/types.h"
#include "DvmhDirective.h"
#include "DvmhDirective_internal.h"
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "../Sapfor.h"
@@ -75,7 +74,7 @@ static bool findArrayRefAndCheck(SgExpression *ex, const DIST::Array* currArray,
return res;
}
bool needCorner(const DIST::Array* currArray, const vector<map<pair<int, int>, int>> &shiftsByAccess, Statement *loop)
static bool needCorner(const DIST::Array* currArray, const vector<map<pair<int, int>, int>> &shiftsByAccess, Statement *loop)
{
bool need = false;
@@ -93,7 +92,6 @@ bool needCorner(const DIST::Array* currArray, const vector<map<pair<int, int>, i
return need;
}
vector<SgExpression*> genSubscripts(const vector<pair<int, int>> &shadowRenew, const vector<pair<int, int>> &shadowRenewShifts)
{
vector<SgExpression*> subs;
@@ -174,7 +172,7 @@ static SgExpression* genSgExpr(SgFile *file, const string &letter, const pair<in
return retVal;
}
std::multimap<string, Symbol*> setToMapWithSortByStr(const set<Symbol*> &setIn)
static std::multimap<string, Symbol*> setToMapWithSortByStr(const set<Symbol*> &setIn)
{
std::multimap<string, Symbol*> retMap;
for (auto& elem : setIn)
@@ -207,7 +205,7 @@ static set<string> fillUsedSymbols(SgStatement *loop)
return usedS;
}
SgStatement* getRealStat(const char *file, const int line, const int altLine)
static SgStatement* getRealStat(const char *file, const int line, const int altLine)
{
SgStatement* local = SgStatement::getStatementByFileAndLine(file, line);
if (local == NULL)
@@ -216,7 +214,7 @@ SgStatement* getRealStat(const char *file, const int line, const int altLine)
return local;
}
string correctSymbolModuleName(const string& origFull)
static string correctSymbolModuleName(const string& origFull)
{
auto it = origFull.find("::");
if (it == string::npos)
@@ -225,7 +223,7 @@ string correctSymbolModuleName(const string& origFull)
return origFull.substr(it + 2);
}
SgStatement* getModuleScope(const string& origFull, vector<SgStatement*>& moduleList, SgStatement *local)
static SgStatement* getModuleScope(const string& origFull, vector<SgStatement*>& moduleList, SgStatement *local)
{
auto it = origFull.find("::");
if (it == string::npos)
@@ -249,7 +247,9 @@ static vector<SgExpression*>
{
vector<SgExpression*> tieList;
vector<pair<DIST::Array*, DIST::Array*>> realRefsUsed;
for (auto& elem : currLoop->usedArrays)
const auto& usedArrays = sharedMemoryParallelization ? currLoop->usedArraysAll : currLoop->usedArrays;
for (auto& elem : usedArrays)
{
if (onlyFor.size())
if (onlyFor.find(elem) == onlyFor.end())
@@ -392,7 +392,7 @@ static vector<SgExpression*>
}
//TODO: need to improve
set<SgSymbol*> fillPrivateOnlyFromSpfParameter(SgStatement* loop, const int altLine)
static set<SgSymbol*> fillPrivateOnlyFromSpfParameter(SgStatement* loop, const int altLine)
{
set<SgSymbol*> used;
set<SgSymbol*> usedInSpfPar;
@@ -412,7 +412,7 @@ set<SgSymbol*> fillPrivateOnlyFromSpfParameter(SgStatement* loop, const int altL
return usedInSpfPar;
}
set<SgSymbol*> changeLoopOrder(const vector<string>& parallel, const vector<string>& newParallel, vector<LoopGraph*>& loops)
static set<SgSymbol*> changeLoopOrder(const vector<string>& parallel, const vector<string>& newParallel, vector<LoopGraph*>& loops)
{
set<SgSymbol*> additionalPrivates;
if (parallel == newParallel)
@@ -479,7 +479,7 @@ set<SgSymbol*> changeLoopOrder(const vector<string>& parallel, const vector<stri
return additionalPrivates;
}
vector<int> sortShadow(const vector<pair<pair<string, string>, vector<pair<int, int>>>>& toSort)
static vector<int> sortShadow(const vector<pair<pair<string, string>, vector<pair<int, int>>>>& toSort)
{
map<string, int> order;
for (int z = 0; z < toSort.size(); ++z)
@@ -687,9 +687,7 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
p->setLhs(makeExprList(list));
}
if (sharedMemoryParallelization || across.size() != 0)
{
if (!arrayRef2->IsLoopArray())
if (sharedMemoryParallelization || (across.size() != 0 && !arrayRef2->IsLoopArray()))
{
vector<LoopGraph*> loopsTie;
for (int i = 0; i < (int)parallel.size(); ++i)
@@ -734,7 +732,6 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
directive += ")";
}
}
}
set<DIST::Array*> arraysInAcross;
if (across.size() != 0)

View File

@@ -143,10 +143,6 @@ public:
const uint64_t regionId,
const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls);
Directive*
genDirectiveNoDist(File* file, LoopGraph* currLoop, DIST::Arrays<int>& allArrays,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
friend ParallelDirective* operator+(const ParallelDirective &first, const ParallelDirective &second);
~ParallelDirective()

View File

@@ -1,96 +0,0 @@
#include "../Utils/leak_detector.h"
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <algorithm>
#include "DvmhDirective.h"
#include "../Distribution/Array.h"
#include "../Distribution/Arrays.h"
#include "../Distribution/GraphCSR.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../GraphCall/graph_calls_func.h"
using std::vector;
using std::string;
using std::pair;
using std::set;
using std::map;
static inline string calculateShiftsNoDist(
DIST::Array* arrayRef, DIST::Array* calcForArray,
pair<pair<string, string>, vector<pair<int, int>>>& coeffs,
vector<pair<int, int>>& shifts,
vector<map<pair<int, int>, int>>& shiftsByAccess,
const map<DIST::Array*, pair<vector<ArrayOp>, vector<bool>>>& readOps,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
string out = "";
// check for distributed and not mapped dims -> zero them out ('coeffs.second')
set<DIST::Array*> refs;
getRealArrayRefs(calcForArray, calcForArray, refs, arrayLinksByFuncCalls);
const pair<vector<ArrayOp>, vector<bool>>* currReadOp = NULL;
auto readIt = readOps.find(calcForArray);
if (readIt != readOps.end())
currReadOp = &(readIt->second);
const int len = (int)coeffs.second.size();
bool allZero = true;
for (int k = 0; k < len; ++k)
{
shiftsByAccess.push_back(map<pair<int, int>, int>());
if (k != 0)
out += ",";
char buf[256];
// calculate correct shifts from readOp info
if (currReadOp)
{
// no unrecognized read operations
if (currReadOp->second[k] == false)
{
for (auto& coefs : currReadOp->first[k].coefficients)
{
auto currAccess = coefs.first;
const int currShift = coefs.first.second;
auto itFound = shiftsByAccess[k].find(currAccess);
if (itFound == shiftsByAccess[k].end())
itFound = shiftsByAccess[k].insert(itFound, make_pair(currAccess, currShift));
}
}
}
sprintf(buf, "%d:%d", coeffs.second[k].first, coeffs.second[k].second);
shifts[k] = {0, 0};
if (coeffs.second[k].first != 0 || coeffs.second[k].second != 0)
allZero = false;
out += buf;
}
if (allZero)
return "";
else
return out;
}
string ParallelDirective::genBoundsNoDist(pair<pair<string, string>, vector<pair<int, int>>>& shadowOp,
vector<pair<int, int>>& shadowOpShift,
DIST::Array* currArray,
const map<DIST::Array*, pair<vector<ArrayOp>, vector<bool>>>& readOps,
set<DIST::Array*>& arraysInAcross,
vector<map<pair<int, int>, int>>& shiftsByAccess,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls) const
{
arraysInAcross.insert(currArray);
return calculateShiftsNoDist(arrayRef, currArray, shadowOp, shadowOpShift, shiftsByAccess, readOps, arrayLinksByFuncCalls);
}

View File

@@ -1,17 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include <set>
#include <map>
std::vector<int> sortShadow(const std::vector<std::pair<std::pair<std::string, std::string>, std::vector<std::pair<int, int>>>>& toSort);
std::set<SgSymbol*> changeLoopOrder(const std::vector<std::string>& parallel, const std::vector<std::string>& newParallel, std::vector<LoopGraph*>& loops);
std::set<SgSymbol*> fillPrivateOnlyFromSpfParameter(SgStatement* loop, const int altLine);
SgStatement* getModuleScope(const std::string& origFull, std::vector<SgStatement*>& moduleList, SgStatement* local);
std::string correctSymbolModuleName(const std::string& origFull);
SgStatement* getRealStat(const char* file, const int line, const int altLine);
std::multimap<std::string, Symbol*> setToMapWithSortByStr(const std::set<Symbol*>& setIn);
bool needCorner(const DIST::Array* currArray, const std::vector<std::map<std::pair<int, int>, int>>& shiftsByAccess, Statement* loop);

View File

@@ -1,477 +0,0 @@
#include "../Utils/leak_detector.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <vector>
#include <string>
#include <algorithm>
#include "../Utils/types.h"
#include "DvmhDirective.h"
#include "DvmhDirective_func.h"
#include "DvmhDirective_internal.h"
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "../Sapfor.h"
#include "../GraphCall/graph_calls_func.h"
#include "dvm.h"
using std::vector;
using std::tuple;
using std::get;
using std::string;
using std::pair;
using std::set;
using std::map;
using std::make_pair;
static vector<SgExpression*>
compliteTieListNoDist(const LoopGraph* currLoop,
const set<string>& privates,
const vector<LoopGraph*>& loops,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<string, set<SgSymbol*>>& byUseInFunc,
File* file, const pair<int, int>& lineRange)
{
vector<SgExpression*> tieList;
if (currLoop->usedArraysAll.size() == 0)
return tieList;
SgVarRefExp* zeroS = new SgVarRefExp(findSymbolOrCreate(file, "*"));
for (auto& elem : currLoop->usedArraysAll)
{
if (privates.find(elem->GetShortName()) != privates.end())
continue;
auto type = elem->GetDeclSymbol(currLoop->fileName, lineRange, getAllFilesInProject())->GetOriginal()->type();
SgSymbol* arrayS = getFromModule(byUseInFunc, findSymbolOrCreate(file, elem->GetShortName(), type));
SgArrayRefExp* array = new SgArrayRefExp(*arrayS);
bool needToAdd = false;
vector<SgExpression*> subs;
for (int k = 0; k < elem->GetDimSize(); ++k)
subs.push_back(&zeroS->copy());
for (int z = 0; z < loops.size(); ++z)
{
currLoop = loops[z];
for (const auto& source : { currLoop->readOpsForLoop, currLoop->writeOpsForLoop }) {
auto array_it = source.find(elem);
if (array_it != source.end()) {
bool dim_found = false;
for (int i = 0; i < array_it->second.size(); i++) {
if (array_it->second[i].coefficients.size() != 0)
{
needToAdd = true;
dim_found = true;
subs[i] = new SgVarRefExp(findSymbolOrCreate(file, currLoop->loopSymbol));
break;
}
}
if (dim_found)
break;
}
}
}
if (needToAdd)
{
for (int k = 0; k < subs.size(); ++k)
array->addSubscript(*subs[k]);
tieList.push_back(array);
}
}
return tieList;
}
Directive*
ParallelDirective::genDirectiveNoDist(File* file, LoopGraph* currLoop, DIST::Arrays<int>& allArrays,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
const set<DIST::Array*>& acrossOutAttribute = currLoop->acrossOutAttribute;
const map<DIST::Array*, pair<vector<ArrayOp>, vector<bool>>>& readOps = currLoop->readOps;
map< DIST::Array*, vector<ArrayOp>>& remoteReads = currLoop->remoteRegularReads;
Statement* loop = currLoop->loop;
string directive = "";
vector<Expression*> dirStatement = { NULL, NULL, NULL };
SgForStmt* loopG = (SgForStmt*)loop->GetOriginal();
vector<SgStatement*> moduleList;
findModulesInFile(file, moduleList);
SgStatement* realStat = getRealStat(file->filename(), currLoop->lineNum, currLoop->altLineNum);
SgStatement* parentFunc = getFuncStat(realStat);
const map<string, set<SgSymbol*>> byUseInFunc = moduleRefsByUseInFunction(realStat);
const int nested = countPerfectLoopNest(loopG);
const pair<int, int> lineRange = make_pair(parentFunc->lineNumber(), parentFunc->lastNodeOfStmt()->lineNumber());
const string& filename = currLoop->fileName;
vector<SgSymbol*> loopSymbs;
vector<LoopGraph*> loops;
LoopGraph* pLoop = currLoop;
const set<string> allFiles = getAllFilesInProject();
map<string, DIST::Array*> arrayByName;
for (DIST::Array* arr : currLoop->getAllArraysInLoop())
arrayByName[arr->GetName()] = arr;
for (int z = 0; z < nested; ++z)
{
loopSymbs.push_back(loopG->symbol());
auto next = loopG->lexNext();
auto attrSpfPar = getAttributes<SgStatement*, SgStatement*>(next, set<int>{ SPF_PARAMETER_OP });
while (attrSpfPar.size() != 0 && next)
{
next = next->lexNext();
attrSpfPar = getAttributes<SgStatement*, SgStatement*>(next, set<int>{ SPF_PARAMETER_OP });
}
if (next->variant() != FOR_NODE && z + 1 < nested)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
loopG = (SgForStmt*)next;
loops.push_back(pLoop);
if (pLoop->children.size())
pLoop = pLoop->children[0];
}
SgExpression* expr = new SgExpression(EXPR_LIST);
SgExpression* p = expr;
directive += "!DVM$ PARALLEL(";
//filter parallel
vector<string> filteredParalel;
for (int i = 0; i < (int)parallel.size(); ++i)
if (parallel[i] != "*")
filteredParalel.push_back(parallel[i]);
set<SgSymbol*> privatesAfterSwap = changeLoopOrder(parallel, filteredParalel, loops);
for (int i = 0; i < (int)filteredParalel.size(); ++i)
{
if (filteredParalel[i] == "*")
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (i == 0)
directive += filteredParalel[i];
else
directive += "," + filteredParalel[i];
SgVarRefExp* tmp = NULL;
tmp = new SgVarRefExp(findSymbolOrCreate(file, filteredParalel[i]));
p->setLhs(tmp);
if (i != (int)filteredParalel.size() - 1)
p = createAndSetNext(RIGHT, EXPR_LIST, p);
else
p->setRhs(NULL);
}
dirStatement[2] = new Expression(expr);
directive += ")";
SgArrayRefExp* arrayExpr = NULL;
string arrayExprS = "";
expr = new SgExpression(EXPR_LIST);
p = expr;
dirStatement[1] = NULL;
set<string> uniqNamesOfPrivates;
for (auto& elem : privates)
uniqNamesOfPrivates.insert(elem->identifier());
auto unitedPrivates = privates;
for (auto& elem : privatesAfterSwap)
{
if (uniqNamesOfPrivates.find(elem->identifier()) == uniqNamesOfPrivates.end())
{
unitedPrivates.insert(new Symbol(elem));
uniqNamesOfPrivates.insert(elem->identifier());
}
}
if (unitedPrivates.size() != 0)
{
p = createAndSetNext(LEFT, ACC_PRIVATE_OP, p);
directive += ", PRIVATE(";
int k = 0;
vector<SgExpression*> list;
auto spfParVars = fillPrivateOnlyFromSpfParameter(loop, currLoop->lineNum < 0 ? currLoop->altLineNum : 0);
for (auto& privVar : setToMapWithSortByStr(unitedPrivates))
{
bool isSfpPriv = false;
for (auto& elem : spfParVars)
if (OriginalSymbol(elem)->identifier() == string(OriginalSymbol(privVar.second)->identifier()))
isSfpPriv = true;
if (isSfpPriv)
continue;
directive += (k != 0) ? "," + privVar.first : privVar.first;
list.push_back(new SgVarRefExp(getFromModule(byUseInFunc, privVar.second)));
++k;
}
directive += ")";
dirStatement[1] = new Expression(expr);
p->setLhs(makeExprList(list));
}
vector<LoopGraph*> loopsTie;
for (int i = 0; i < (int)parallel.size(); ++i)
if (parallel[i] != "*")
loopsTie.push_back(loops[i]);
vector<SgExpression*> tieList;
tieList = compliteTieListNoDist(currLoop, uniqNamesOfPrivates, loopsTie, arrayLinksByFuncCalls, byUseInFunc, file, lineRange);
if (tieList.size())
{
if (dirStatement[1] != NULL)
{
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
p = expr;
}
p = createAndSetNext(LEFT, ACC_TIE_OP, p);
p->setLhs(makeExprList(tieList));
directive += ", TIE(";
int k = 0;
for (auto& tieL : tieList)
{
if (k != 0)
directive += ",";
directive += tieL->unparse();
++k;
}
directive += ")";
}
set<DIST::Array*> arraysInAcross;
if (across.size() != 0)
{
if (acrossShifts.size() == 0)
{
acrossShifts.resize(across.size());
for (int i = 0; i < across.size(); ++i)
acrossShifts[i].resize(across[i].second.size());
}
//TODO: add "OUT" key for string representation
string acrossAdd = ", ACROSS(";
int inserted = 0;
SgExpression* acr_out = new SgExpression(EXPR_LIST);
SgExpression* p_out = acr_out;
SgExpression* acr_in = new SgExpression(EXPR_LIST);
SgExpression* p_in = acr_in;
SgExpression* acr_op = NULL;
int inCount = 0;
int outCount = 0;
vector<int> ordered = sortShadow(across);
for (int k = 0; k < (int)across.size(); ++k)
{
const int i1 = ordered[k];
vector<map<pair<int, int>, int>> shiftsByAccess;
auto currArray_it = arrayByName.find(across[i1].first.second);
if (currArray_it == arrayByName.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
DIST::Array* currArray = currArray_it->second;
bool isOut = acrossOutAttribute.find(currArray) != acrossOutAttribute.end();
string bounds = genBoundsNoDist(across[i1], acrossShifts[i1], currArray, readOps, arraysInAcross, shiftsByAccess, arrayLinksByFuncCalls);
if (bounds != "")
{
if (inserted != 0)
{
acrossAdd += ",";
if (isOut)
{
if (outCount > 0)
p_out = createAndSetNext(RIGHT, EXPR_LIST, p_out);
outCount++;
p = p_out;
}
else
{
if (inCount > 0)
p_in = createAndSetNext(RIGHT, EXPR_LIST, p_in);
inCount++;
p = p_in;
}
}
else if (inserted == 0)
{
if (dirStatement[1] != NULL)
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
acr_op = createAndSetNext(LEFT, ACROSS_OP, expr);
if (isOut)
{
outCount++;
p = p_out;
}
else
{
inCount++;
p = p_in;
}
}
acrossAdd += across[i1].first.first + "(" + bounds + ")";
SgArrayRefExp* newArrayRef = new SgArrayRefExp(*getFromModule(byUseInFunc, currArray->GetDeclSymbol(filename, lineRange, allFiles)->GetOriginal()));
newArrayRef->addAttribute(ARRAY_REF, currArray, sizeof(DIST::Array));
for (auto& elem : genSubscripts(across[i1].second, acrossShifts[i1]))
newArrayRef->addSubscript(*elem);
p->setLhs(newArrayRef);
inserted++;
}
}
acrossAdd += ")";
if (inserted > 0)
{
directive += acrossAdd;
if (dirStatement[1] == NULL)
dirStatement[1] = new Expression(expr);
if (acrossOutAttribute.size() > 0)
{
SgExpression* tmp = new SgExpression(DDOT, new SgKeywordValExp("OUT"), acr_out, NULL);
acr_op->setLhs(*tmp);
if (inCount != 0)
acr_op->setRhs(acr_in);
}
else
acr_op->setLhs(acr_in);
}
}
if (reduction.size() != 0)
{
if (dirStatement[1] != NULL)
{
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
p = expr;
}
p = createAndSetNext(LEFT, REDUCTION_OP, p);
p = createAndSetNext(LEFT, EXPR_LIST, p);
directive += ", REDUCTION(";
int k = 0;
for (auto it = reduction.begin(); it != reduction.end(); ++it)
{
const string& nameGroup = it->first;
for (auto& list : it->second)
{
if (k != 0)
{
directive += ",";
p = createAndSetNext(RIGHT, EXPR_LIST, p);
}
SgSymbol* base = findSymbolOrCreate(file, correctSymbolModuleName(list), NULL, getModuleScope(list, moduleList, parentFunc));
SgSymbol* redS = getFromModule(byUseInFunc, base, list.find("::") != string::npos);
directive += nameGroup + "(" + redS->identifier() + ")";
SgVarRefExp* tmp2 = new SgVarRefExp(redS);
SgFunctionCallExp* tmp1 = new SgFunctionCallExp(*findSymbolOrCreate(file, nameGroup), *tmp2);
p->setLhs(tmp1);
++k;
}
}
if (reductionLoc.size() != 0)
directive += ", ";
else
{
directive += ")";
if (dirStatement[1] == NULL)
dirStatement[1] = new Expression(expr);
}
}
if (reductionLoc.size() != 0)
{
if (dirStatement[1] != NULL && reduction.size() == 0)
{
expr = createAndSetNext(RIGHT, EXPR_LIST, expr);
p = expr;
}
if (reduction.size() == 0)
{
p = createAndSetNext(LEFT, REDUCTION_OP, p);
p = createAndSetNext(LEFT, EXPR_LIST, p);
directive += ", REDUCTION(";
}
else
p = createAndSetNext(RIGHT, EXPR_LIST, p);
int k = 0;
for (auto it = reductionLoc.begin(); it != reductionLoc.end(); ++it)
{
const string& nameGroup = it->first;
for (auto& list : it->second)
{
if (k != 0)
{
directive += ",";
p = createAndSetNext(RIGHT, EXPR_LIST, p);
}
SgSymbol* base1 = findSymbolOrCreate(file, correctSymbolModuleName(get<0>(list)), NULL, getModuleScope(get<0>(list), moduleList, parentFunc));
SgSymbol* base2 = findSymbolOrCreate(file, correctSymbolModuleName(get<1>(list)), NULL, getModuleScope(get<1>(list), moduleList, parentFunc));
SgSymbol* redS1 = getFromModule(byUseInFunc, base1, get<0>(list).find("::") != string::npos);
SgSymbol* redS2 = getFromModule(byUseInFunc, base2, get<1>(list).find("::") != string::npos);
directive += nameGroup + "(" + redS1->identifier() + ", " + redS2->identifier() + ", " + std::to_string(get<2>(list)) + ")";
SgFunctionCallExp* tmp1 = new SgFunctionCallExp(*findSymbolOrCreate(file, nameGroup));
tmp1->addArg(*new SgVarRefExp(redS1));
tmp1->addArg(*new SgVarRefExp(redS2));
tmp1->addArg(*new SgValueExp(get<2>(list)));
p->setLhs(tmp1);
++k;
}
}
directive += ")";
if (dirStatement[1] == NULL)
dirStatement[1] = new Expression(expr);
}
directive += "\n";
auto dir = new CreatedDirective(directive, dirStatement);
dir->line = currLoop->lineNum;
return dir;
}

View File

@@ -14,10 +14,57 @@
#include <utility>
#include <assert.h>
#include "loop_analyzer_internal.h"
#include "loop_analyzer.h"
#include <tuple>
#include <stack>
#include "../Utils/leak_detector.h"
#if _WIN32 && NDEBUG && __BOOST
#include <boost/thread.hpp>
#endif
extern int passDone;
#include "../Distribution/Distribution.h"
#include "../Distribution/GraphCSR.h"
#include "../Distribution/Arrays.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "../Utils/errors.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DirectiveProcessing/directive_creator.h"
#include "../Utils/SgUtils.h"
#include "../Utils/AstWrapper.h"
#include "../GraphCall/graph_calls_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../SageAnalysisTool/depInterfaceExt.h"
#include "../VisualizerCalls/get_information.h"
#include "../VisualizerCalls/SendMessage.h"
#include "../Transformations/enddo_loop_converter.h"
#include "../DirectiveProcessing/remote_access.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
#define PRINT_ARRAY_ARCS 0
#define PRINT_LOOP_STRUCT 0
#define PRINT_PROF_INFO 0
#define DEB 0
extern REGIME currRegime;
extern std::vector<Messages>* currMessages;
extern int sharedMemoryParallelization;
extern int ignoreIO;
extern int parallizeFreeLoops;
using std::vector;
using std::pair;
using std::tuple;
@@ -126,7 +173,9 @@ static void addInfoToMap(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, S
__spf_print(DEB, "RemoteAccess[%d]: true for dim %d and array %s, loop line %d\n", __LINE__, dimNum, symb->identifier(), position->lineNumber());
}
void addInfoToVectors(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, SgForStmt *position, SgSymbol *symb,
enum { READ_OP, WRITE_OP, UNREC_OP };
static void addInfoToVectors(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, SgForStmt *position, SgSymbol *symb,
const int dimNum, const pair<int, int> newCoef, int type, const int maxDimSize, const double currentW)
{
auto itLoop = loopInfo.find(position);
@@ -159,7 +208,7 @@ void addInfoToVectors(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, SgFo
}
vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, SgExpression *subscr,
static vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, SgExpression *subscr,
SgArrayRefExp *arrayRefIn, const int side, const int dimNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo,
const int currLine, const int numOfSubscriptions, const double currentW)
@@ -1464,7 +1513,7 @@ inline static void fillPrivatesFromDecl(SgExpression *ex, set<SgSymbol*> &delcsS
fillPrivatesFromDecl(ex->lhs(), delcsSymbViewed, delcsStatViewed, declaredArrays, declaratedArraysSt, privatesVars);
}
void changeLoopWeight(double &currentWeight, const map<int, LoopGraph*> &sortedLoopGraph, const int line, bool increase)
static void changeLoopWeight(double &currentWeight, const map<int, LoopGraph*> &sortedLoopGraph, const int line, bool increase = true)
{
auto loopIt = sortedLoopGraph.find(line);
if (loopIt == sortedLoopGraph.end())
@@ -1476,7 +1525,7 @@ void changeLoopWeight(double &currentWeight, const map<int, LoopGraph*> &sortedL
currentWeight /= loopIt->second->countOfIters;
}
bool hasNonPureFunctions(SgExpression *ex, LoopGraph *loopRef, vector<Messages> &messagesForFile, const int line, const map<string, FuncInfo*> &funcByName)
static bool hasNonPureFunctions(SgExpression *ex, LoopGraph *loopRef, vector<Messages> &messagesForFile, const int line, const map<string, FuncInfo*> &funcByName)
{
bool retVal = false;
@@ -1521,7 +1570,7 @@ void fillFromModule(SgSymbol* s, const map<string, set<string>>& privatesByModul
}
}
SgStatement* takeOutConditions(stack<SgExpression*>& conditions, stack<SgStatement*>& ifBlocks, SgStatement* st)
static SgStatement* takeOutConditions(stack<SgExpression*>& conditions, stack<SgStatement*>& ifBlocks, SgStatement* st)
{
auto res = createIfConditions(conditions, ifBlocks, st);
@@ -2165,7 +2214,10 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
addToDistributionGraph(convertedLoopInfo, arrayLinksByFuncCalls);
for (auto &toDel : tmpLoops)
{
convertedLoopInfo.erase(toDel);
delete toDel;
}
tmpToConvert.clear();
if (!skipDeps)

View File

@@ -1,70 +0,0 @@
#pragma once
#include "loop_analyzer.h"
#include <string>
#include <vector>
#include <map>
#include <set>
#include <tuple>
#include <stack>
#include "../Utils/leak_detector.h"
#if _WIN32 && NDEBUG && __BOOST
#include <boost/thread.hpp>
#endif
extern int passDone;
#include "../Distribution/Distribution.h"
#include "../Distribution/GraphCSR.h"
#include "../Distribution/Arrays.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "../Utils/errors.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DirectiveProcessing/directive_creator.h"
#include "../Utils/SgUtils.h"
#include "../Utils/AstWrapper.h"
#include "../GraphCall/graph_calls_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../SageAnalysisTool/depInterfaceExt.h"
#include "../VisualizerCalls/get_information.h"
#include "../VisualizerCalls/SendMessage.h"
#include "../Transformations/enddo_loop_converter.h"
#include "../DirectiveProcessing/remote_access.h"
#define PRINT_ARRAY_ARCS 0
#define PRINT_LOOP_STRUCT 0
#define PRINT_PROF_INFO 0
#define DEB 0
extern REGIME currRegime;
extern std::vector<Messages>* currMessages;
extern int sharedMemoryParallelization;
extern int ignoreIO;
extern int parallizeFreeLoops;
void changeLoopWeight(double& currentWeight, const std::map<int, LoopGraph*>& sortedLoopGraph, const int line, bool increase = true);
SgStatement* takeOutConditions(std::stack<SgExpression*>& conditions, std::stack<SgStatement*>& ifBlocks, SgStatement* st);
enum { READ_OP, WRITE_OP, UNREC_OP };
void addInfoToVectors(std::map<SgForStmt*, std::map<SgSymbol*, ArrayInfo>>& loopInfo, SgForStmt* position, SgSymbol* symb,
const int dimNum, const std::pair<int, int> newCoef, int type, const int maxDimSize, const double currentW);
std::vector<int> matchSubscriptToLoopSymbols(const std::vector<SgForStmt*>& parentLoops, SgExpression* subscr,
SgArrayRefExp* arrayRefIn, const int side, const int dimNum,
std::map<SgForStmt*, std::map<SgSymbol*, ArrayInfo>>& loopInfo,
const int currLine, const int numOfSubscriptions, const double currentW);
bool hasNonPureFunctions(SgExpression* ex, LoopGraph* loopRef, std::vector<Messages>& messagesForFile, const int line, const std::map<std::string, FuncInfo*>& funcByName);

View File

@@ -1,667 +0,0 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <utility>
#include <assert.h>
#include "../DirectiveProcessing/directive_creator_nodist.h"
#include "loop_analyzer_internal.h"
#include "loop_analyzer_nodist.h"
using std::vector;
using std::pair;
using std::tuple;
using std::map;
using std::set;
using std::make_pair;
using std::make_tuple;
using std::get;
using std::string;
using std::wstring;
using std::stack;
extern void createMapLoopGraph(map<int, LoopGraph*>& sortedLoopGraph, const vector<LoopGraph*>* loopGraph);
extern map<DIST::Array*, std::tuple<int, string, string>> tableOfUniqNamesByArray;
static void convertOneLoopNoDist(LoopGraph* currLoop, map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>& outInfo,
const map<SgSymbol*, ArrayInfo>& toConvert,
const map<string, vector<SgExpression*>>& commonBlocks,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
map<tuple<int, string, string>, DIST::Array*>& createdArrays,
bool freeArrays = false)
{
map<DIST::Array*, ArrayInfo*> toAdd;
for (auto& conv : toConvert)
{
SgSymbol* currentArray = OriginalSymbol(conv.first);
ArrayInfo* currentInfo = (ArrayInfo*)(&conv.second);
DIST::Array* arrayToAdd;
SgStatement* decl = declaratedInStmt(currentArray);
const char* symbIdent = currentArray->identifier();
const tuple<int, string, string> uniqKey = getUniqName(commonBlocks, decl, currentArray);
auto itFound = createdArrays.find(uniqKey);
if (itFound == createdArrays.end())
{
auto itArray = declaredArrays.find(uniqKey);
if (itArray == declaredArrays.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
arrayToAdd = itArray->second.first;
itFound = createdArrays.insert(itFound, make_pair(uniqKey, arrayToAdd));
}
else
arrayToAdd = itFound->second;
set<DIST::Array*> links;
getRealArrayRefs(arrayToAdd, arrayToAdd, links, arrayLinksByFuncCalls);
int countOflinks = 0;
for (auto& linkedArray : links)
{
if (arrayToAdd == linkedArray)
continue;
++countOflinks;
auto key = tableOfUniqNamesByArray[linkedArray];
auto value = declaredArrays.find(key)->second;
if (value.second == 0 && createdArrays.find(key) == createdArrays.end())
createdArrays.insert(make_pair(key, linkedArray));
}
if (freeArrays)
if (countOflinks == 0)
continue;
toAdd[arrayToAdd] = currentInfo;
for (int z = 0; z < currentInfo->getDimSize(); ++z)
{
if (currentInfo->readOps[z].coefficients.size() || currentInfo->writeOps[z].coefficients.size())
{
arrayToAdd->SetMappedDim(z);
for (auto& realRef : links)
realRef->SetMappedDim(z);
}
}
}
outInfo[currLoop] = toAdd;
}
static map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>
convertLoopInfoNoDist(const map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
const map<int, LoopGraph*>& sortedLoopGraph,
const map<string, vector<SgExpression*>>& commonBlocks,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
map<tuple<int, string, string>, DIST::Array*>& createdArrays)
{
map<LoopGraph*, map<DIST::Array*, ArrayInfo*>> outInfo;
for (auto it = loopInfo.begin(); it != loopInfo.end(); ++it)
{
auto itGraph = sortedLoopGraph.find(it->first->lineNumber());
if (itGraph == sortedLoopGraph.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
convertOneLoopNoDist(itGraph->second, outInfo, it->second, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
}
return outInfo;
}
static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops, vector<set<string>>& privatesVarsForLoop,
SgExpression *currExp, const int side,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, const int currLine,
map<int, LoopGraph*> &sortedLoopGraph, const ParallelRegion *reg, const double currentW,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls)
{
SgArrayRefExp *arrayRef = (SgArrayRefExp*)currExp;
int numOfSubs = arrayRef->numberOfSubscripts();
currExp = currExp->lhs();
vector<int> wasFoundForLoop(parentLoops.size());
vector<int> matched(numOfSubs);
vector<int> matchedToDim(parentLoops.size());
std::fill(wasFoundForLoop.begin(), wasFoundForLoop.end(), 0);
std::fill(matched.begin(), matched.end(), -1);
std::fill(matchedToDim.begin(), matchedToDim.end(), -1);
int maxMatched = 0;
int sumMatched = 0;
for (int i = 0; i < numOfSubs; ++i)
{
vector<int> matchToLoops = matchSubscriptToLoopSymbols(parentLoops, currExp->lhs(), arrayRef, side, i, loopInfo, currLine, numOfSubs, currentW);
for (int k = 0; k < matchToLoops.size(); ++k)
{
wasFoundForLoop[matchToLoops[k]]++;
matchedToDim[matchToLoops[k]] = i;
}
matched[i] = matchToLoops.size();
sumMatched += matchToLoops.size();
maxMatched = std::max(maxMatched, (int)matchToLoops.size());
currExp = currExp->rhs();
}
//full array is used, add unknown operations to all loops
if (numOfSubs == 0)
{
SgSymbol *currOrigArrayS = OriginalSymbol(arrayRef->symbol());
auto arrType = isSgArrayType(currOrigArrayS->type());
if (arrType != NULL)
{
for (int d = 0; d < arrType->dimension(); ++d)
for (int i = 0; i < parentLoops.size(); ++i)
addInfoToVectors(loopInfo, parentLoops[i], currOrigArrayS, d, make_pair(0, 0), UNREC_OP, arrType->dimension(), currentW);
}
}
bool ifUnknownArrayAssignFound = false;
vector<int> canNotMapToLoop;
for (int i = 0; i < wasFoundForLoop.size(); ++i)
{
if (wasFoundForLoop[i] != 1 &&
privatesVarsForLoop[i].find(string(arrayRef->symbol()->identifier())) == privatesVarsForLoop[i].end())
{
auto itLoop = sortedLoopGraph.find(parentLoops[i]->lineNumber());
if (itLoop == sortedLoopGraph.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
ifUnknownArrayAssignFound = true;
if (side == LEFT)
itLoop->second->hasUnknownArrayAssigns = true;
itLoop->second->hasUnknownDistributedMap = true;
canNotMapToLoop.push_back(parentLoops[i]->lineNumber());
}
}
if (side == LEFT)
{
if (ifUnknownArrayAssignFound)
{
const string arrayRefS = arrayRef->unparse();
for (auto &line : canNotMapToLoop)
{
__spf_print(1, "WARN: can not map write to array '%s' to loop on line %d\n", arrayRefS.c_str(), line);
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"can not map write to array '%s' to this loop", to_wstring(arrayRefS).c_str());
__spf_printToLongBuf(messageR, R59, to_wstring(arrayRefS).c_str());
if (line > 0)
currMessages->push_back(Messages(WARR, line, messageR, messageE, 1025));
}
}
}
return wasFoundForLoop;
}
static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp,
const vector<SgForStmt*>& parentLoops, const int side, const int lineNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
vector<set<string>>& privatesVarsForLoop,
map<int, LoopGraph*>& sortedLoopGraph, map<string, pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays,
set<string>& mappedDistrbutedArrays,
const ParallelRegion* reg, const double currentW, const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
const char* printSide = NULL;
if (PRINT_ARRAY_ARCS)
printBlanks(2, (int)parentLoops.size());
if (side == LEFT)
printSide = "W_OP";
else
printSide = "R_OP";
__spf_print(PRINT_ARRAY_ARCS, "%s to array <%s> on line %d: ", printSide, OriginalSymbol(currExp->symbol())->identifier(), lineNum);
bool wasMapped = false;
vector<int> matched = matchArrayToLoopSymbols(parentLoops, privatesVarsForLoop, currExp, side, loopInfo, lineNum, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls);
for (int z = 0; z < matched.size(); ++z)
wasMapped |= (matched[z] != 0);
if (parentLoops.size() == 0)
{
SgSymbol* symb = currExp->symbol();
if (symb->type()->variant() == T_ARRAY)
notMappedDistributedArrays[symb->identifier()] = make_pair(symb, currentSt);
}
else
{
if (wasMapped)
mappedDistrbutedArrays.insert(currExp->symbol()->identifier());
else
{
SgSymbol* symb = currExp->symbol();
if (symb->type()->variant() == T_ARRAY)
notMappedDistributedArrays[symb->identifier()] = make_pair(symb, currentSt);
}
}
__spf_print(PRINT_ARRAY_ARCS, "\n");
}
static void findArrayRef(const vector<SgForStmt*>& parentLoops, SgExpression* currExp, const int lineNum, const int side,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
vector<set<string>>& privatesVarsForLoop, map<int, LoopGraph*>& sortedLoopGraph,
map<string, pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays,
set<string>& mappedDistrbutedArrays, SgStatement* currentSt, const ParallelRegion* reg, const double currentW,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
int nextSide = side;
if (isArrayRef(currExp))
{
mapArrayRef(currentSt, currExp, parentLoops, side, lineNum, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, reg, currentW, arrayLinksByFuncCalls);
nextSide = (side == LEFT) ? RIGHT : side;
}
bool needToContinue = true;
if (currExp->variant() == FUNC_CALL)
{
SgFunctionCallExp* funcExp = (SgFunctionCallExp*)currExp;
auto currFunc = isUserFunctionInProject(funcExp->funName()->identifier());
if (currFunc)
{
for (int z = 0; z < funcExp->numberOfArgs(); ++z)
{
if ((currFunc->funcParams.inout_types[z] & OUT_BIT) != 0)
nextSide = LEFT;
else
nextSide = RIGHT;
findArrayRef(parentLoops, funcExp->arg(z), lineNum, nextSide, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, currentSt, reg, currentW, arrayLinksByFuncCalls);
}
needToContinue = false;
}
}
if (needToContinue)
{
if (currExp->lhs())
findArrayRef(parentLoops, currExp->lhs(), lineNum, nextSide, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, currentSt, reg, currentW, arrayLinksByFuncCalls);
if (currExp->rhs())
findArrayRef(parentLoops, currExp->rhs(), lineNum, nextSide, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, currentSt, reg, currentW, arrayLinksByFuncCalls);
}
}
void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tuple<int, string, string>, DIST::Array*>& createdArrays,
vector<Messages>& messagesForFile, const map<string, vector<FuncInfo*>>& AllfuncInfo,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<SgStatement*, set<tuple<int, string, string>>>& declaratedArraysSt,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<SgStatement*, vector<DefUseList>>& defUseByPlace,
vector<LoopGraph*>* loopGraph)
{
currMessages = &messagesForFile;
currRegime = DATA_DISTR; //?
map<string, vector<SgExpression*>> commonBlocks;
map<int, LoopGraph*> sortedLoopGraph;
map<int, pair<SgForStmt*, pair<set<string>, set<string>>>> allLoops;
createMapLoopGraph(sortedLoopGraph, loopGraph);
int funcNum = file->numberOfFunctions();
__spf_print(PRINT_PROF_INFO, "functions num in file = %d\n", funcNum);
vector<SgStatement*> modules;
findModulesInFile(file, modules);
map<string, SgStatement*> modulesByName;
for (int i = 0; i < modules.size(); ++i)
modulesByName[modules[i]->symbol()->identifier()] = modules[i];
map<string, FuncInfo*> funcByName;
createMapOfFunc(AllfuncInfo, funcByName);
const vector<FuncInfo*>& funcInfo = AllfuncInfo.find(file->filename())->second;
for (int i = 0; i < funcNum; ++i)
{
createNeededException();
string fName = file->functions(i)->symbol()->identifier();
#if _WIN32
if (file->functions(i)->variant() != MODULE_STMT)
sendMessage_2lvl(wstring(L"обработка функции '") + wstring(fName.begin(), fName.end()) + L"'");
else
sendMessage_2lvl(wstring(L"обработка модуля '") + wstring(fName.begin(), fName.end()) + L"'");
#else
if (file->functions(i)->variant() != MODULE_STMT)
sendMessage_2lvl(wstring(L"processing function '") + wstring(fName.begin(), fName.end()) + L"'");
else
sendMessage_2lvl(wstring(L"processing module '") + wstring(fName.begin(), fName.end()) + L"'");
#endif
set<SgSymbol*> delcsSymbViewed;
set<SgStatement*> delcsStatViewed;
if (funcInfo[i]->doNotAnalyze)
continue;
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> loopInfo;
set<int> loopWithOutArrays;
SgStatement* st = file->functions(i);
string funcName = "";
if (st->variant() == PROG_HEDR)
{
SgProgHedrStmt* progH = (SgProgHedrStmt*)st;
__spf_print(PRINT_PROF_INFO, "*** Program <%s> started at line %d / %s\n", progH->symbol()->identifier(), st->lineNumber(), st->fileName());
funcName = progH->symbol()->identifier();
}
else if (st->variant() == PROC_HEDR)
{
SgProcHedrStmt* procH = (SgProcHedrStmt*)st;
__spf_print(PRINT_PROF_INFO, "*** Function <%s> started at line %d / %s\n", procH->symbol()->identifier(), st->lineNumber(), st->fileName());
funcName = procH->symbol()->identifier();
}
else if (st->variant() == FUNC_HEDR)
{
SgFuncHedrStmt* funcH = (SgFuncHedrStmt*)st;
__spf_print(PRINT_PROF_INFO, "*** Function <%s> started at line %d / %s\n", funcH->symbol()->identifier(), st->lineNumber(), st->fileName());
funcName = funcH->symbol()->identifier();
}
vector<LoopGraph*> loopsForFunction;
for (auto& loop : *loopGraph)
{
auto fStat = getFuncStat(loop->loop->GetOriginal());
if (fStat->symbol()->identifier() == funcName)
loopsForFunction.push_back(loop);
}
commonBlocks.clear();
getCommonBlocksRef(commonBlocks, st, st->lastNodeOfStmt());
__spf_print(PRINT_PROF_INFO, " number of common blocks %d\n", (int)commonBlocks.size());
SgStatement* lastNode = st->lastNodeOfStmt();
vector<SgForStmt*> parentLoops;
vector<set<string>> privatesVarsForLoop;
//For remote access
pair<SgForStmt*, LoopGraph*>* under_dvm_dir = NULL;
map<string, pair<SgSymbol*, SgStatement*>> notMappedDistributedArrays;
set<string> mappedDistrbutedArrays;
double currentWeight = 1.0;
while (st != lastNode)
{
createNeededException();
if (st == NULL)
{
currMessages->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;
if (!__gcov_doesThisLineExecuted(st->fileName(), st->lineNumber()))
{
st = st->lexNext();
continue;
}
const int currentLine = st->lineNumber() < -1 ? st->localLineNumber() : st->lineNumber();
ParallelRegion* currReg = getRegionByLine(regions, st->fileName(), currentLine);
if (currReg == NULL)
{
st = st->lexNext();
continue;
}
if (isSgExecutableStatement(st) == NULL)
delcsStatViewed.insert(st);
//printf("new st with var = %d, on line %d\n", st->variant(), st->lineNumber());
const int currV = st->variant();
if (currV == FOR_NODE)
{
//tryToFindPrivateInAttributes(st, privatesVars);
set<string> toAdd;
tryToFindPrivateInAttributes(st, toAdd);
if (PRINT_LOOP_STRUCT)
printBlanks(2, (int)parentLoops.size());
__spf_print(PRINT_LOOP_STRUCT, "FOR NODE on line %d\n", st->lineNumber());
parentLoops.push_back((SgForStmt*)st);
changeLoopWeight(currentWeight, sortedLoopGraph, st->lineNumber());
privatesVarsForLoop.push_back(toAdd);
}
else if (currV == CONTROL_END)
{
SgStatement* contrlParent = st->controlParent();
if (contrlParent)
{
if (contrlParent->variant() == FOR_NODE)
{
changeLoopWeight(currentWeight, sortedLoopGraph, contrlParent->lineNumber(), false);
if (loopInfo.find((SgForStmt*)contrlParent) == loopInfo.end() && !sortedLoopGraph[contrlParent->lineNumber()]->hasUnknownDistributedMap)
loopWithOutArrays.insert(contrlParent->lineNumber());
set<string> unitedPrivates;
for (int p = 0; p < parentLoops.size(); ++p)
for (auto& privVar : privatesVarsForLoop[p])
unitedPrivates.insert(privVar);
set<string> setDiff;
allLoops[contrlParent->lineNumber()] = make_pair((SgForStmt*)contrlParent, make_pair(unitedPrivates, setDiff));
parentLoops.pop_back();
privatesVarsForLoop.pop_back();
}
}
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
else if (currV == ASSIGN_STAT)
{
if (st->expr(0))
findArrayRef(parentLoops, st->expr(0), st->lineNumber(), LEFT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
if (st->expr(1))
findArrayRef(parentLoops, st->expr(1), st->lineNumber(), RIGHT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
else if (currV == IF_NODE || currV == ELSEIF_NODE || currV == LOGIF_NODE || currV == SWITCH_NODE)
{
SgStatement* before = NULL;
if (st->expr(0))
{
findArrayRef(parentLoops, st->expr(0), st->lineNumber(), RIGHT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
}
else if (currV == PROC_STAT)
{
auto func = isUserFunctionInProject(st->symbol()->identifier());
if (func != NULL)
{
SgExpression* parList = st->expr(0);
set<DIST::Array*> toRedistr;
if (parList)
{
SgExprListExp* list = isSgExprListExp(parList);
for (int z = 0; z < list->length(); ++z)
{
SgExpression* par = list->elem(z);
if ((func->funcParams.inout_types[z] & OUT_BIT) != 0)
findArrayRef(parentLoops, par, st->lineNumber(), LEFT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
else
findArrayRef(parentLoops, par, st->lineNumber(), RIGHT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
}
}
}
else if (currV == USE_STMT)
{
if (st->lineNumber() > 0)
{
auto itF = modulesByName.find(st->symbol()->identifier());
if (itF == modulesByName.end())
{
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"Module with name '%s' must be placed in current file", to_wstring(st->symbol()->identifier()).c_str());
__spf_printToLongBuf(messageR, R62, to_wstring(st->symbol()->identifier()).c_str());
currMessages->push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1028));
__spf_print(1, "Module at line %d with name '%s' must be placed in current file\n", st->lineNumber(), st->symbol()->identifier());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
}
else
{
if (isDVM_stat(st) == false && isSgExecutableStatement(st))
{
int const var = st->variant();
int side = (var == READ_STAT || var == WRITE_STAT || var == PRINT_STAT) ? LEFT : RIGHT;
for (int z = 0; z < 3; ++z)
if (st->expr(z))
findArrayRef(parentLoops, st->expr(z), st->lineNumber(), side, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
}
st = st->lexNext();
}
auto convertedLoopInfo = convertLoopInfoNoDist(loopInfo, sortedLoopGraph, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
processLoopInformationForFunction(convertedLoopInfo);
//find dependencies for loops in function
initAnnotationsSysExt(0);
set<SgStatement*> funcWasInit;
map<SgExpression*, string> collection;
int idx = 0;
for (auto& loop : convertedLoopInfo)
{
++idx;
createNeededException();
string fName = file->functions(i)->symbol()->identifier();
#ifdef _WIN32
sendMessage_2lvl(wstring(L"обработка цикла ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
#else
sendMessage_2lvl(wstring(L"processing loop ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
#endif
tryToFindDependencies(loop.first, allLoops, funcWasInit, file, regions, currMessages, collection, funcByName, defUseByPlace);
}
for (auto& loopLine : loopWithOutArrays)
{
if (loopLine > 0)
{
tryToFindDependencies(sortedLoopGraph[loopLine], allLoops, funcWasInit, file, regions, currMessages, collection, funcByName, defUseByPlace);
sortedLoopGraph[loopLine]->withoutDistributedArrays = true;
//TODO: enable linear writes to non distr arrays for CONSISTENT
bool hasWritesToArray = false;
//TODO: add IPA for non pure
bool hasNonPureProcedures = false;
auto loopRef = sortedLoopGraph[loopLine];
SgStatement* loopSt = loopRef->loop;
for (SgStatement* start = loopSt->lexNext(); start != loopSt->lastNodeOfStmt(); start = start->lexNext())
{
if (start->variant() == PROC_STAT && isIntrinsicFunctionName(start->symbol()->identifier()) == 0)
{
checkNull(isSgCallStmt(start), convertFileName(__FILE__).c_str(), __LINE__);
auto itF = funcByName.find(isSgCallStmt(start)->name()->identifier());
bool isPure = false;
if (itF != funcByName.end())
isPure = itF->second->isPure;
if (!isPure)
{
hasNonPureProcedures = true;
loopRef->hasNonPureProcedures = true;
messagesForFile.push_back(Messages(WARR, start->lineNumber(), R80, L"Only pure procedures were supported", 1044));
}
}
for (int z = 1; z < 3; ++z)
if (hasNonPureFunctions(start->expr(z), loopRef, messagesForFile, start->lineNumber(), funcByName))
hasNonPureProcedures = true;
}
if (hasWritesToArray || hasNonPureProcedures)
loopRef->withoutDistributedArrays = false;
}
}
sendMessage_2lvl(L"");
createParallelDirectivesNoDist(convertedLoopInfo, regions, arrayLinksByFuncCalls, messagesForFile);
for (auto& loopLine : loopWithOutArrays)
{
auto loopRef = sortedLoopGraph[loopLine];
if (loopRef->withoutDistributedArrays && loopRef->region && !loopRef->hasLimitsToParallel() && loopRef->lineNum > 0)
{
int nesting = 0;
LoopGraph* it = loopRef;
for (int z = 0; z < loopRef->perfectLoop; ++z, it->children.size() ? it = it->children[0] : it)
if (it->withoutDistributedArrays && it->region && !it->hasLimitsToParallel() && it->lineNum > 0)
++nesting;
map<LoopGraph*, map<DIST::Array*, ArrayInfo*>> convertedLoopInfo;
it = loopRef;
for (int z = 0; z < nesting; ++z, it->children.size() ? it = it->children[0] : it)
convertedLoopInfo.insert(make_pair(it, map<DIST::Array*, ArrayInfo*>()));
createParallelDirectivesNoDist(convertedLoopInfo, regions, map<DIST::Array*, set<DIST::Array*>>(), messagesForFile);
}
}
__spf_print(PRINT_PROF_INFO, "Function ended\n");
}
}

View File

@@ -1,13 +0,0 @@
#include<map>
#include<string>
#include<set>
#include<vector>
#include<tuple>
void loopAnalyzerNoDist(SgFile* file, std::vector<ParallelRegion*>& regions, std::map<std::tuple<int, std::string, std::string>, DIST::Array*>& createdArrays,
std::vector<Messages>& messagesForFile, const std::map<std::string, std::vector<FuncInfo*>>& AllfuncInfo,
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const std::map<SgStatement*, std::set<std::tuple<int, std::string, std::string>>>& declaratedArraysSt,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
const std::map<SgStatement*, std::vector<DefUseList>>& defUseByPlace,
std::vector<LoopGraph*>* loopGraph);

View File

@@ -38,7 +38,6 @@
#include "ProjectManipulation/ConvertFiles.h"
#include "LoopAnalyzer/loop_analyzer.h"
#include "LoopAnalyzer/loop_analyzer_nodist.h"
#include "GraphCall/graph_calls_func.h"
#include "GraphCall/select_array_conf.h"
@@ -48,7 +47,6 @@
#include "DirectiveProcessing/directive_analyzer.h"
#include "DirectiveProcessing/directive_creator.h"
#include "DirectiveProcessing/directive_creator_nodist.h"
#include "DirectiveProcessing/insert_directive.h"
#include "DirectiveProcessing/directive_omp_parser.h"
#include "VerificationCode/verifications.h"