Refactor shared memory parallelization #49
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 ¤tWeight, const map<int, LoopGraph*> &sortedLoopGraph, const int line, bool increase)
|
||||
static void changeLoopWeight(double ¤tWeight, 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 ¤tWeight, 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*> ®ions, map<tuple<int,
|
||||
addToDistributionGraph(convertedLoopInfo, arrayLinksByFuncCalls);
|
||||
|
||||
for (auto &toDel : tmpLoops)
|
||||
{
|
||||
convertedLoopInfo.erase(toDel);
|
||||
delete toDel;
|
||||
}
|
||||
tmpToConvert.clear();
|
||||
|
||||
if (!skipDeps)
|
||||
|
||||
@@ -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);
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user