loop analyzer refactor for shared memory parallelization

This commit is contained in:
2024-06-20 13:00:01 +03:00
parent 1be169e7ff
commit 7daf1b4038
4 changed files with 324 additions and 332 deletions

View File

@@ -91,26 +91,17 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai
} }
currentLoop->directive = directive; currentLoop->directive = directive;
for (auto& read : currentLoop->readOpsArray) if(!sharedMemoryParallelization)
{ {
const string shortName = read->GetName(); for (auto& read : currentLoop->readOpsArray)
const string orignName = read->GetShortName();
pair<string, string> key = make_pair(orignName, shortName);
bool found = false;
for (int i = 0; i < directive->shadowRenew.size(); ++i)
{ {
if (directive->shadowRenew[i].first == key) const string shortName = read->GetName();
const string orignName = read->GetShortName();
pair<string, string> key = make_pair(orignName, shortName);
bool found = false;
for (int i = 0; i < directive->shadowRenew.size(); ++i)
{ {
found = true; if (directive->shadowRenew[i].first == key)
break;
}
}
if (found == false)
{
for (int i = 0; i < directive->across.size(); ++i)
{
if (directive->across[i].first == key)
{ {
found = true; found = true;
break; break;
@@ -119,11 +110,23 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai
if (found == false) if (found == false)
{ {
directive->shadowRenew.push_back(make_pair(key, vector<pair<int, int>>())); for (int i = 0; i < directive->across.size(); ++i)
{
if (directive->across[i].first == key)
{
found = true;
break;
}
}
const DIST::Array *arrayRef = read; if (found == false)
for (int i = 0; i < arrayRef->GetDimSize(); ++i) {
directive->shadowRenew.back().second.push_back(make_pair(0, 0)); directive->shadowRenew.push_back(make_pair(key, vector<pair<int, int>>()));
const DIST::Array *arrayRef = read;
for (int i = 0; i < arrayRef->GetDimSize(); ++i)
directive->shadowRenew.back().second.push_back(make_pair(0, 0));
}
} }
} }
} }
@@ -553,150 +556,155 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
mainArray.hasWrite = true; mainArray.hasWrite = true;
mainArray.mainAccess; mainArray.mainAccess;
set<string> uniqNamesWithAcross; if(!sharedMemoryParallelization)
fillArraysWithAcrossStatus(currLoop, uniqNamesWithAcross);
if (arrayWriteAcc.size() == 1)
{ {
mainArray.arrayRef = arrayWriteAcc.begin()->first; set<string> uniqNamesWithAcross;
mainArray.dimentionPos = arrayWriteAcc.begin()->second.first; fillArraysWithAcrossStatus(currLoop, uniqNamesWithAcross);
mainArray.mainAccess = arrayWriteAcc.begin()->second.second;
if (uniqNamesWithAcross.size()) if (arrayWriteAcc.size() == 1)
mainArray.underAcross = true;
}
else if (arrayWriteAcc.size() > 1)
{
if (uniqNamesWithAcross.size())
mainArray.underAcross = true;
int posDim = -1;
int minDim = 999999;
int k = 0;
vector<pair<string, pair<int, pair<int, int>>>> accesses;
map<int, set<tuple<string, int, int>>> sameDims;
for (auto i = arrayWriteAcc.begin(); i != arrayWriteAcc.end(); ++i, ++k)
{ {
const auto array = i->first; mainArray.arrayRef = arrayWriteAcc.begin()->first;
const string &uniqName = array->GetName(); mainArray.dimentionPos = arrayWriteAcc.begin()->second.first;
mainArray.mainAccess = arrayWriteAcc.begin()->second.second;
//ACROSS arrays have priority state for all nested loops! if (uniqNamesWithAcross.size())
if (uniqNamesWithAcross.size() > 0) mainArray.underAcross = true;
if (uniqNamesWithAcross.find(uniqName) == uniqNamesWithAcross.end()) }
continue; else if (arrayWriteAcc.size() > 1)
{
if (uniqNamesWithAcross.size())
mainArray.underAcross = true;
const int currDim = array->GetDimSize(); int posDim = -1;
auto& sizes = array->GetSizes(); int minDim = 999999;
const int currSize = sizes[i->second.first].second - sizes[i->second.first].first + 1; int k = 0;
sameDims[currDim].insert(make_tuple(uniqName, k, currSize));
if (currDim < minDim) vector<pair<string, pair<int, pair<int, int>>>> accesses;
map<int, set<tuple<string, int, int>>> sameDims;
for (auto i = arrayWriteAcc.begin(); i != arrayWriteAcc.end(); ++i, ++k)
{ {
if (itersCount == 0 || (itersCount != 0) && currSize >= itersCount) const auto array = i->first;
const string &uniqName = array->GetName();
//ACROSS arrays have priority state for all nested loops!
if (uniqNamesWithAcross.size() > 0)
if (uniqNamesWithAcross.find(uniqName) == uniqNamesWithAcross.end())
continue;
const int currDim = array->GetDimSize();
auto& sizes = array->GetSizes();
const int currSize = sizes[i->second.first].second - sizes[i->second.first].first + 1;
sameDims[currDim].insert(make_tuple(uniqName, k, currSize));
if (currDim < minDim)
{ {
minDim = currDim; if (itersCount == 0 || (itersCount != 0) && currSize >= itersCount)
posDim = k;
}
}
__spf_print(PRINT_DIR_RESULT, " found writes for array %s -> [%d %d]\n", array->GetShortName().c_str(), i->second.second.first, i->second.second.second);
accesses.push_back(make_pair(array->GetName(), i->second));
}
if (posDim != -1)
{
auto itDim = sameDims.find(minDim);
if (itDim == sameDims.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
int maxArraySize = -1;
for (auto& elem : itDim->second)
{
if (get<2>(elem) > maxArraySize)
{
maxArraySize = get<2>(elem);
posDim = get<1>(elem);
}
}
}
else
{
mainArray.hasWrite = false;
__spf_print(PRINT_DIR_RESULT, " no appropriate regular writes on loop\n");
}
vector<set<DIST::Array*>> realArrayRefs(accesses.size());
for (int i = 0; i < (int)accesses.size(); ++i)
{
DIST::Array *array = allArrays.GetArrayByName(accesses[i].first);
getRealArrayRefs(array, array, realArrayRefs[i], arrayLinksByFuncCalls);
}
//check the same distribution
bool statusOk = true;
for (int i = 0; i < (int)accesses.size(); ++i)
{
for (int k = i + 1; k < (int)accesses.size(); ++k)
{
DIST::Array *array1 = allArrays.GetArrayByName(accesses[i].first);
DIST::Array *array2 = allArrays.GetArrayByName(accesses[k].first);
const set<DIST::Array*> &realArrayRefs1 = realArrayRefs[i];
const set<DIST::Array*> &realArrayRefs2 = realArrayRefs[k];
for (auto &refs1 : realArrayRefs1)
{
for (auto &refs2 : realArrayRefs2)
{ {
auto links = findLinksBetweenArrays(refs1, refs2, regId); minDim = currDim;
posDim = k;
}
}
__spf_print(PRINT_DIR_RESULT, " found writes for array %s -> [%d %d]\n", array->GetShortName().c_str(), i->second.second.first, i->second.second.second);
accesses.push_back(make_pair(array->GetName(), i->second));
}
const int dimFrom = accesses[i].second.first; if (posDim != -1)
const int dimTo = accesses[k].second.first; {
auto itDim = sameDims.find(minDim);
if (itDim == sameDims.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (dimTo != links[dimFrom]) int maxArraySize = -1;
for (auto& elem : itDim->second)
{
if (get<2>(elem) > maxArraySize)
{
maxArraySize = get<2>(elem);
posDim = get<1>(elem);
}
}
}
else
{
mainArray.hasWrite = false;
__spf_print(PRINT_DIR_RESULT, " no appropriate regular writes on loop\n");
}
vector<set<DIST::Array*>> realArrayRefs(accesses.size());
for (int i = 0; i < (int)accesses.size(); ++i)
{
DIST::Array *array = allArrays.GetArrayByName(accesses[i].first);
getRealArrayRefs(array, array, realArrayRefs[i], arrayLinksByFuncCalls);
}
//check the same distribution
bool statusOk = true;
for (int i = 0; i < (int)accesses.size(); ++i)
{
for (int k = i + 1; k < (int)accesses.size(); ++k)
{
DIST::Array *array1 = allArrays.GetArrayByName(accesses[i].first);
DIST::Array *array2 = allArrays.GetArrayByName(accesses[k].first);
const set<DIST::Array*> &realArrayRefs1 = realArrayRefs[i];
const set<DIST::Array*> &realArrayRefs2 = realArrayRefs[k];
for (auto &refs1 : realArrayRefs1)
{
for (auto &refs2 : realArrayRefs2)
{ {
__spf_print(1, "arrays '%s' and '%s' have different align dimensions for loop on line %d\n --> %d vs %d(%d) \n", auto links = findLinksBetweenArrays(refs1, refs2, regId);
array1->GetShortName().c_str(), array2->GetShortName().c_str(),
currLoop->lineNum, dimTo, links[dimFrom], dimFrom);
statusOk = false;
}
else
{
const auto accessFrom = accesses[i].second.second;
const auto accessTo = accesses[k].second.second;
auto templRule1 = refs1->GetAlignRulesWithTemplate(regId); const int dimFrom = accesses[i].second.first;
auto templRule2 = refs2->GetAlignRulesWithTemplate(regId); const int dimTo = accesses[k].second.first;
if (DIST::Fx(accessFrom, templRule1[dimFrom]) != DIST::Fx(accessTo, templRule2[dimTo])) if (dimTo != links[dimFrom])
{ {
string format = "arrays '%s' and '%s' have different align rules -- \n -->"; __spf_print(1, "arrays '%s' and '%s' have different align dimensions for loop on line %d\n --> %d vs %d(%d) \n",
format += "F1 = [%d.%d], x1 = [%d.%d], F2 = [%d.%d], x2 = [%d.%d] \n -->";
format += "F1(x1) = [%d.%d] != F2(x2) = [%d.%d]\n";
__spf_print(1, format.c_str(),
array1->GetShortName().c_str(), array2->GetShortName().c_str(), array1->GetShortName().c_str(), array2->GetShortName().c_str(),
templRule1[dimFrom].first, templRule1[dimFrom].second, accessFrom.first, accessFrom.second, currLoop->lineNum, dimTo, links[dimFrom], dimFrom);
templRule2[dimTo].first, templRule2[dimTo].second, accessTo.first, accessTo.second,
DIST::Fx(accessFrom, templRule1[dimFrom]).first, DIST::Fx(accessFrom, templRule1[dimFrom]).second,
DIST::Fx(accessTo, templRule2[dimTo]).first, DIST::Fx(accessTo, templRule2[dimTo]).second);
statusOk = false; statusOk = false;
} }
} else
{
const auto accessFrom = accesses[i].second.second;
const auto accessTo = accesses[k].second.second;
auto templRule1 = refs1->GetAlignRulesWithTemplate(regId);
auto templRule2 = refs2->GetAlignRulesWithTemplate(regId);
if (DIST::Fx(accessFrom, templRule1[dimFrom]) != DIST::Fx(accessTo, templRule2[dimTo]))
{
string format = "arrays '%s' and '%s' have different align rules -- \n -->";
format += "F1 = [%d.%d], x1 = [%d.%d], F2 = [%d.%d], x2 = [%d.%d] \n -->";
format += "F1(x1) = [%d.%d] != F2(x2) = [%d.%d]\n";
__spf_print(1, format.c_str(),
array1->GetShortName().c_str(), array2->GetShortName().c_str(),
templRule1[dimFrom].first, templRule1[dimFrom].second, accessFrom.first, accessFrom.second,
templRule2[dimTo].first, templRule2[dimTo].second, accessTo.first, accessTo.second,
DIST::Fx(accessFrom, templRule1[dimFrom]).first, DIST::Fx(accessFrom, templRule1[dimFrom]).second,
DIST::Fx(accessTo, templRule2[dimTo]).first, DIST::Fx(accessTo, templRule2[dimTo]).second);
statusOk = false;
}
}
if (!statusOk)
{
wstring bufE, bufR;
__spf_printToLongBuf(bufE, L"arrays '%s' and '%s' have different align rules in this loop according to their write accesses",
to_wstring(array1->GetShortName()).c_str(), to_wstring(array2->GetShortName()).c_str());
__spf_printToLongBuf(bufR, R132, to_wstring(array1->GetShortName()).c_str(), to_wstring(array2->GetShortName()).c_str());
messages.push_back(Messages(WARR, currLoop->lineNum, bufR, bufE, 3011));
currLoop->hasDifferentAlignRules = true;
break;
}
}
if (!statusOk) if (!statusOk)
{
wstring bufE, bufR;
__spf_printToLongBuf(bufE, L"arrays '%s' and '%s' have different align rules in this loop according to their write accesses",
to_wstring(array1->GetShortName()).c_str(), to_wstring(array2->GetShortName()).c_str());
__spf_printToLongBuf(bufR, R132, to_wstring(array1->GetShortName()).c_str(), to_wstring(array2->GetShortName()).c_str());
messages.push_back(Messages(WARR, currLoop->lineNum, bufR, bufE, 3011));
currLoop->hasDifferentAlignRules = true;
break; break;
}
} }
if (!statusOk) if (!statusOk)
break; break;
@@ -704,43 +712,43 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
if (!statusOk) if (!statusOk)
break; break;
} }
if (!statusOk)
break;
}
if (statusOk) if (statusOk)
{
k = 0;
for (auto array = arrayWriteAcc.begin(); array != arrayWriteAcc.end(); array++, ++k)
{ {
if (k == posDim) k = 0;
for (auto array = arrayWriteAcc.begin(); array != arrayWriteAcc.end(); array++, ++k)
{ {
mainArray.arrayRef = array->first; if (k == posDim)
mainArray.dimentionPos = array->second.first; {
mainArray.mainAccess = array->second.second; mainArray.arrayRef = array->first;
break; mainArray.dimentionPos = array->second.first;
mainArray.mainAccess = array->second.second;
break;
}
} }
} }
else
{
__spf_print(PRINT_DIR_RESULT, " has conflict writes\n");
hasConflict = true;
}
} }
else else
{ {
__spf_print(PRINT_DIR_RESULT, " has conflict writes\n"); mainArray.hasWrite = false;
hasConflict = true; __spf_print(PRINT_DIR_RESULT, " no regular writes on loop\n");
} }
}
else // fill mainArray if no regular writes found
{ // now OmegaTest is used for searching dependencies
mainArray.hasWrite = false; if (!mainArray.hasWrite)
__spf_print(PRINT_DIR_RESULT, " no regular writes on loop\n"); findMainArrayFromRead(currAccesses, mainArray, itersCount, arrayLinksByFuncCalls);
} }
// fill mainArray if no regular writes found bool dimPosFound = sharedMemoryParallelization ||
// now OmegaTest is used for searching dependencies (mainArray.arrayRef != NULL && mainArray.dimentionPos != -1);
if (!mainArray.hasWrite)
findMainArrayFromRead(currAccesses, mainArray, itersCount, arrayLinksByFuncCalls);
if (!hasConflict && if (dimPosFound &&
mainArray.arrayRef != NULL && mainArray.dimentionPos != -1 &&
!currLoop->hasLimitsToParallel() && !currLoop->hasLimitsToParallel() &&
(currLoop->lineNum > 0 || (currLoop->lineNum < 0 && currLoop->altLineNum > 0))) (currLoop->lineNum > 0 || (currLoop->lineNum < 0 && currLoop->altLineNum > 0)))
{ {
@@ -749,7 +757,7 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
const int dimPos = mainArray.dimentionPos; const int dimPos = mainArray.dimentionPos;
//change array to template if ACROSS was not found or not loop_array //change array to template if ACROSS was not found or not loop_array
if (mainArray.underAcross == false && !(sharedMemoryParallelization == 1 && mainArray.arrayRef->IsLoopArray())) if (!sharedMemoryParallelization && mainArray.underAcross == false && !mainArray.arrayRef->IsLoopArray())
{ {
set<DIST::Array*> realArrayRef; set<DIST::Array*> realArrayRef;
getRealArrayRefs(mainArray.arrayRef, mainArray.arrayRef, realArrayRef, arrayLinksByFuncCalls); getRealArrayRefs(mainArray.arrayRef, mainArray.arrayRef, realArrayRef, arrayLinksByFuncCalls);
@@ -788,25 +796,30 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
parDir = loop->directive; parDir = loop->directive;
if (parDir != NULL) if (parDir != NULL)
{ {
parDir->arrayRef2 = mainArrayOfLoop; if(!sharedMemoryParallelization)
if (mainArray.underAcross == false)
{ {
for (int i = 0; i < mainArrayOfLoop->GetDimSize(); ++i) parDir->arrayRef2 = mainArrayOfLoop;
if (mainArray.underAcross == false)
{ {
if (i == dimPos) for (int i = 0; i < mainArrayOfLoop->GetDimSize(); ++i)
parDir->on2.push_back(make_pair(currLoop->loopSymbol, mainAccess)); {
else if (i == dimPos)
parDir->on2.push_back(make_pair("*", make_pair(0, 0))); parDir->on2.push_back(make_pair(currLoop->loopSymbol, mainAccess));
else
parDir->on2.push_back(make_pair("*", make_pair(0, 0)));
}
for (int z = 0; z < parDir->on2.size(); ++z)
if (parDir->on2[z].first != "*" && parDir->on2[z].second == make_pair(0, 0))
parDir->on2[z].second = mainAccess;
} }
else
parDir->on2 = parDir->on;
for (int z = 0; z < parDir->on2.size(); ++z) addShadowFromAnalysis(parDir, currAccesses);
if (parDir->on2[z].first != "*" && parDir->on2[z].second == make_pair(0, 0))
parDir->on2[z].second = mainAccess;
} }
else
parDir->on2 = parDir->on;
addShadowFromAnalysis(parDir, currAccesses);
loop->directiveForLoop = new ParallelDirective(*loop->directive); loop->directiveForLoop = new ParallelDirective(*loop->directive);
} }
__spf_print(PRINT_DIR_RESULT, " directive created\n"); __spf_print(PRINT_DIR_RESULT, " directive created\n");

View File

@@ -204,7 +204,7 @@ vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, S
if (countOfSymbols > 1) if (countOfSymbols > 1)
{ {
__spf_print(PRINT_ARRAY_ARCS, " <%d|%d> ", 0, 0); __spf_print(PRINT_ARRAY_ARCS, " <%d|%d> ", 0, 0);
if (currRegime == DATA_DISTR) if (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR)
{ {
const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr); const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr);
__spf_print(1, "WARN: array ref '%s' at line %d has more than one loop's variables\n", arrayRefString.second.c_str(), currLine); __spf_print(1, "WARN: array ref '%s' at line %d has more than one loop's variables\n", arrayRefString.second.c_str(), currLine);
@@ -238,7 +238,7 @@ vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, S
for (int i = 0; i < (int)parentLoops.size(); ++i) for (int i = 0; i < (int)parentLoops.size(); ++i)
addInfoToMap(loopInfo, parentLoops[i], currOrigArrayS, arrayRef, dimNum, REMOTE_TRUE, currLine, numOfSubscriptions); addInfoToMap(loopInfo, parentLoops[i], currOrigArrayS, arrayRef, dimNum, REMOTE_TRUE, currLine, numOfSubscriptions);
} }
else if (currRegime == DATA_DISTR) else if (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR)
{ {
const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr); const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr);
@@ -294,7 +294,7 @@ vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, S
if (side == RIGHT) if (side == RIGHT)
addInfoToMap(loopInfo, parentLoops[position], currOrigArrayS, arrayRef, dimNum, REMOTE_TRUE, currLine, numOfSubscriptions); addInfoToMap(loopInfo, parentLoops[position], currOrigArrayS, arrayRef, dimNum, REMOTE_TRUE, currLine, numOfSubscriptions);
} }
else if (currRegime == DATA_DISTR) else if (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR)
{ {
const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr); const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr);
__spf_print(1, "WARN: can not calculate index expression for array ref '%s' at line %d\n", arrayRefString.second.c_str(), currLine); __spf_print(1, "WARN: can not calculate index expression for array ref '%s' at line %d\n", arrayRefString.second.c_str(), currLine);
@@ -387,7 +387,8 @@ vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, S
return allPositions; return allPositions;
} }
static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops, SgExpression *currExp, const int side, 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<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, const int currLine,
map<int, LoopGraph*> &sortedLoopGraph, const ParallelRegion *reg, const double currentW, map<int, LoopGraph*> &sortedLoopGraph, const ParallelRegion *reg, const double currentW,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls) const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls)
@@ -440,7 +441,9 @@ static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops
vector<int> canNotMapToLoop; vector<int> canNotMapToLoop;
for (int i = 0; i < wasFoundForLoop.size(); ++i) for (int i = 0; i < wasFoundForLoop.size(); ++i)
{ {
if (wasFoundForLoop[i] != 1) if (wasFoundForLoop[i] != 1 &&
// always true for distributed data case
privatesVarsForLoop[i].find(string(arrayRef->symbol()->identifier())) == privatesVarsForLoop[i].end())
{ {
auto itLoop = sortedLoopGraph.find(parentLoops[i]->lineNumber()); auto itLoop = sortedLoopGraph.find(parentLoops[i]->lineNumber());
if (itLoop == sortedLoopGraph.end()) if (itLoop == sortedLoopGraph.end())
@@ -456,7 +459,7 @@ static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops
if (side == LEFT) if (side == LEFT)
{ {
if (ifUnknownArrayAssignFound && (currRegime == DATA_DISTR)) if (ifUnknownArrayAssignFound && (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR))
{ {
const string arrayRefS = arrayRef->unparse(); const string arrayRefS = arrayRef->unparse();
for (auto &line : canNotMapToLoop) for (auto &line : canNotMapToLoop)
@@ -517,7 +520,8 @@ static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops
} }
static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp, static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp,
const vector<SgForStmt*>& parentLoops, const int side, const int lineNum, const vector<SgForStmt*>& parentLoops, vector<set<string>>& privatesVarsForLoop,
const int side, const int lineNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo, map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
map<int, LoopGraph*> &sortedLoopGraph, map<string, pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays, map<int, LoopGraph*> &sortedLoopGraph, map<string, pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays,
set<string>& mappedDistrbutedArrays, set<string>& mappedDistrbutedArrays,
@@ -533,7 +537,7 @@ static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp,
__spf_print(PRINT_ARRAY_ARCS, "%s to array <%s> on line %d: ", printSide, OriginalSymbol(currExp->symbol())->identifier(), lineNum); __spf_print(PRINT_ARRAY_ARCS, "%s to array <%s> on line %d: ", printSide, OriginalSymbol(currExp->symbol())->identifier(), lineNum);
bool wasMapped = false; bool wasMapped = false;
vector<int> matched = matchArrayToLoopSymbols(parentLoops, currExp, side, loopInfo, lineNum, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls); vector<int> matched = matchArrayToLoopSymbols(parentLoops, privatesVarsForLoop, currExp, side, loopInfo, lineNum, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls);
for (int z = 0; z < matched.size(); ++z) for (int z = 0; z < matched.size(); ++z)
wasMapped |= (matched[z] != 0); wasMapped |= (matched[z] != 0);
@@ -570,7 +574,8 @@ static void findArrayRef(const vector<SgForStmt*> &parentLoops, SgExpression *cu
if (isArrayRef(currExp)) if (isArrayRef(currExp))
{ {
//... and current array is not in private list //... and current array is not in private list
if (privatesVars.find(string(OriginalSymbol(currExp->symbol())->identifier())) == privatesVars.end()) if (sharedMemoryParallelization ||
privatesVars.find(string(OriginalSymbol(currExp->symbol())->identifier())) == privatesVars.end())
{ {
if (wasDistributedArrayRef) if (wasDistributedArrayRef)
{ {
@@ -582,147 +587,104 @@ static void findArrayRef(const vector<SgForStmt*> &parentLoops, SgExpression *cu
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (itLoop->second->perfectLoop != depth) if (itLoop->second->perfectLoop != depth)
break; break;
itLoop->second->hasIndirectAccess = true;
if (sharedMemoryParallelization && side == RIGHT) if (!(sharedMemoryParallelization && side == RIGHT))
itLoop->second->hasIndirectAccess = false; itLoop->second->hasIndirectAccess = true;
} }
mapArrayRef(currentSt, currExp, parentLoops, side, lineNum, loopInfo, sortedLoopGraph, mapArrayRef(currentSt, currExp, parentLoops, privatesVarsForLoop, side, lineNum, loopInfo, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, reg, currentW, arrayLinksByFuncCalls); notMappedDistributedArrays, mappedDistrbutedArrays, reg, currentW, arrayLinksByFuncCalls);
} }
else else
{ {
wasDistributedArrayRef = true; wasDistributedArrayRef = true;
mapArrayRef(currentSt, currExp, parentLoops, side, lineNum, loopInfo, sortedLoopGraph, mapArrayRef(currentSt, currExp, parentLoops, privatesVarsForLoop, side, lineNum, loopInfo, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, reg, currentW, arrayLinksByFuncCalls); notMappedDistributedArrays, mappedDistrbutedArrays, reg, currentW, arrayLinksByFuncCalls);
} }
} }
else else if (currRegime == DATA_DISTR && side == LEFT)
{ {
if (currRegime == DATA_DISTR && side == LEFT) auto symb = OriginalSymbol(currExp->symbol());
SgStatement *decl = declaratedInStmt(symb);
auto uniqKey = getUniqName(commonBlocks, decl, symb);
auto itFound = declaredArrays.find(uniqKey);
if (itFound == declaredArrays.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
//TODO: array access to non distributed arrays, add CONSISTENT
if (itFound->second.first->GetDistributeFlagVal() != DIST::DISTR)
{ {
auto symb = OriginalSymbol(currExp->symbol()); set<string> loopsPrivates;
SgStatement *decl = declaratedInStmt(symb); set<Symbol*> loopsPrivatesS;
auto uniqKey = getUniqName(commonBlocks, decl, symb); set<string> loopsRedUnited;
map<string, set<Symbol*>> loopsReductions;
map<string, set<tuple<Symbol*, Symbol*, int>>> loopsReductionsLoc;
auto itFound = declaredArrays.find(uniqKey);
if (itFound == declaredArrays.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
//TODO: array access to non distributed arrays, add CONSISTENT for (int z = 0; z < parentLoops.size(); ++z)
if (itFound->second.first->GetDistributeFlagVal() != DIST::DISTR)
{ {
set<string> loopsPrivates; auto& loop = parentLoops[z];
set<Symbol*> loopsPrivatesS; for (auto &data : getAttributes<SgStatement*, SgStatement*>(loop, set<int>{ SPF_ANALYSIS_DIR }))
set<string> loopsRedUnited;
map<string, set<Symbol*>> loopsReductions;
map<string, set<tuple<Symbol*, Symbol*, int>>> loopsReductionsLoc;
for (int z = 0; z < parentLoops.size(); ++z)
{ {
auto& loop = parentLoops[z]; fillPrivatesFromComment(new Statement(data), loopsPrivatesS);
for (auto &data : getAttributes<SgStatement*, SgStatement*>(loop, set<int>{ SPF_ANALYSIS_DIR })) for (auto& elem : loopsPrivatesS)
{ loopsPrivates.insert(elem->GetOriginal()->identifier());
fillPrivatesFromComment(new Statement(data), loopsPrivatesS); fillReductionsFromComment(new Statement(data), loopsReductions);
for (auto& elem : loopsPrivatesS) fillReductionsFromComment(new Statement(data), loopsReductionsLoc);
loopsPrivates.insert(elem->GetOriginal()->identifier());
fillReductionsFromComment(new Statement(data), loopsReductions);
fillReductionsFromComment(new Statement(data), loopsReductionsLoc);
}
} }
}
for (auto &elem : loopsReductions) for (auto &elem : loopsReductions)
{
for (auto &setElem : elem.second)
{ {
for (auto &setElem : elem.second) loopsPrivates.insert(setElem->GetOriginal()->identifier());
{ loopsRedUnited.insert(setElem->GetOriginal()->identifier());
loopsPrivates.insert(setElem->GetOriginal()->identifier());
loopsRedUnited.insert(setElem->GetOriginal()->identifier());
}
} }
}
for (auto &elem : loopsReductionsLoc) for (auto &elem : loopsReductionsLoc)
{
for (auto &setElem : elem.second)
{ {
for (auto &setElem : elem.second) loopsPrivates.insert(get<0>(setElem)->GetOriginal()->identifier());
{ loopsPrivates.insert(get<1>(setElem)->GetOriginal()->identifier());
loopsPrivates.insert(get<0>(setElem)->GetOriginal()->identifier()); loopsRedUnited.insert(get<0>(setElem)->GetOriginal()->identifier());
loopsPrivates.insert(get<1>(setElem)->GetOriginal()->identifier()); loopsRedUnited.insert(get<1>(setElem)->GetOriginal()->identifier());
loopsRedUnited.insert(get<0>(setElem)->GetOriginal()->identifier());
loopsRedUnited.insert(get<1>(setElem)->GetOriginal()->identifier());
}
} }
}
const string key = string(OriginalSymbol(currExp->symbol())->identifier()); const string key = string(OriginalSymbol(currExp->symbol())->identifier());
if (loopsPrivates.find(key) == loopsPrivates.end()) if (loopsPrivates.find(key) == loopsPrivates.end())
{
for (auto& loop : parentLoops)
{ {
if (sharedMemoryParallelization == 0) __spf_print(1, "WARN: write to non distributed array '%s' in loop on line %d\n", symb->identifier(), loop->lineNumber());
{
for (auto& loop : parentLoops)
{
__spf_print(1, "WARN: write to non distributed array '%s' in loop on line %d\n", symb->identifier(), loop->lineNumber());
wstring messageE, messageR; wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"write to non distributed array '%s' in this loop", to_wstring(symb->identifier()).c_str()); __spf_printToLongBuf(messageE, L"write to non distributed array '%s' in this loop", to_wstring(symb->identifier()).c_str());
__spf_printToLongBuf(messageR, R61, to_wstring(symb->identifier()).c_str()); __spf_printToLongBuf(messageR, R61, to_wstring(symb->identifier()).c_str());
if (loop->lineNumber() > 0) if (loop->lineNumber() > 0)
currMessages->push_back(Messages(WARR, loop->lineNumber(), messageR, messageE, 1026)); currMessages->push_back(Messages(WARR, loop->lineNumber(), messageR, messageE, 1026));
sortedLoopGraph[loop->lineNumber()]->hasWritesToNonDistribute = true; sortedLoopGraph[loop->lineNumber()]->hasWritesToNonDistribute = true;
}
}
} }
//TODO: this case looks strange }
/*else if (loopsRedUnited.find(key) == loopsRedUnited.end())
if (loopsPrivates.find(key) != loopsPrivates.end() || loopsRedUnited.find(key) != loopsRedUnited.end())
{
auto currOrigArrayS = OriginalSymbol(currExp->symbol());
if (currOrigArrayS->type()->variant() == T_ARRAY)
{ {
auto saveReg = currRegime; DIST::Array* currArray = getArrayFromDeclarated(declaratedInStmt(currOrigArrayS), currOrigArrayS->identifier());
currRegime = ARRAY_ACC_CORNER; checkNull(currArray, convertFileName(__FILE__).c_str(), __LINE__);
bool wasMapped = false;
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> tmpLoopInfo = loopInfo;
vector<int> matched = matchArrayToLoopSymbols(parentLoops, currExp, side, tmpLoopInfo, currLine, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls);
for (int z = 0; z < matched.size(); ++z)
wasMapped |= (matched[z] != 0);
currRegime = saveReg;
if (wasMapped)
{ {
if (sharedMemoryParallelization == 0) set<DIST::Array*> realArrayRefs;
{ getRealArrayRefs(currArray, currArray, realArrayRefs, arrayLinksByFuncCalls);
int z = 0;
for (auto& loop : parentLoops)
{
if (tmpLoopInfo.find(loop) != tmpLoopInfo.end() && matched[z])
{
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"write to non distributed array '%s' in this loop", to_wstring(symb->identifier()).c_str());
__spf_printToLongBuf(messageR, R60, to_wstring(symb->identifier()).c_str()); for (auto& array : realArrayRefs)
array->SetPrivateInLoopStatus(true);
if (loop->lineNumber() > 0)
currMessages->push_back(Messages(WARR, loop->lineNumber(), messageR, messageE, 1026));
sortedLoopGraph[loop->lineNumber()]->hasWritesToNonDistribute = true;
}
++z;
}
}
}
} */
if (loopsPrivates.find(key) != loopsPrivates.end() || loopsRedUnited.find(key) != loopsRedUnited.end())
{
auto currOrigArrayS = OriginalSymbol(currExp->symbol());
if (currOrigArrayS->type()->variant() == T_ARRAY)
{
DIST::Array* currArray = getArrayFromDeclarated(declaratedInStmt(currOrigArrayS), currOrigArrayS->identifier());
checkNull(currArray, convertFileName(__FILE__).c_str(), __LINE__);
{
set<DIST::Array*> realArrayRefs;
getRealArrayRefs(currArray, currArray, realArrayRefs, arrayLinksByFuncCalls);
for (auto& array : realArrayRefs)
array->SetPrivateInLoopStatus(true);
}
} }
} }
} }
@@ -1384,7 +1346,7 @@ static void convertOneLoop(LoopGraph *currLoop, map<LoopGraph*, map<DIST::Array*
SgStatement *decl = declaratedInStmt(currentArray); SgStatement *decl = declaratedInStmt(currentArray);
const char *symbIdent = currentArray->identifier(); const char *symbIdent = currentArray->identifier();
if (privateArrays.find(symbIdent) == privateArrays.end()) if (privateArrays.find(symbIdent) == privateArrays.end() || sharedMemoryParallelization)
{ {
const tuple<int, string, string> uniqKey = getUniqName(commonBlocks, decl, currentArray); const tuple<int, string, string> uniqKey = getUniqName(commonBlocks, decl, currentArray);
@@ -1401,7 +1363,7 @@ static void convertOneLoop(LoopGraph *currLoop, map<LoopGraph*, map<DIST::Array*
else else
arrayToAdd = itFound->second; arrayToAdd = itFound->second;
if (arrayToAdd->IsNotDistribute() == true) if (!sharedMemoryParallelization && arrayToAdd->IsNotDistribute() == true)
continue; continue;
set<DIST::Array*> links; set<DIST::Array*> links;
@@ -1609,8 +1571,9 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
modulesByName[modules[i]->symbol()->identifier()] = modules[i]; modulesByName[modules[i]->symbol()->identifier()] = modules[i];
map<string, set<string>> privatesByModule; map<string, set<string>> privatesByModule;
for (int i = 0; i < modules.size(); ++i) if(!sharedMemoryParallelization)
privatesByModule[modules[i]->symbol()->identifier()] = getPrivatesFromModule(modules[i], declaredArrays, declaratedArraysSt, modulesByName); for (int i = 0; i < modules.size(); ++i)
privatesByModule[modules[i]->symbol()->identifier()] = getPrivatesFromModule(modules[i], declaredArrays, declaratedArraysSt, modulesByName);
map<string, FuncInfo*> funcByName; map<string, FuncInfo*> funcByName;
createMapOfFunc(AllfuncInfo, funcByName); createMapOfFunc(AllfuncInfo, funcByName);
@@ -1674,13 +1637,17 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
loopsForFunction.push_back(loop); loopsForFunction.push_back(loop);
} }
SgStatement* tmpModFind = st; if(!sharedMemoryParallelization)
while (tmpModFind->variant() != GLOBAL)
{ {
tmpModFind = tmpModFind->controlParent(); SgStatement* tmpModFind = st;
if (tmpModFind->variant() == MODULE_STMT) while (tmpModFind->variant() != GLOBAL)
fillFromModule(tmpModFind->symbol(), privatesByModule, privatesVars); {
tmpModFind = tmpModFind->controlParent();
if (tmpModFind->variant() == MODULE_STMT)
fillFromModule(tmpModFind->symbol(), privatesByModule, privatesVars);
}
} }
commonBlocks.clear(); commonBlocks.clear();
getCommonBlocksRef(commonBlocks, st, st->lastNodeOfStmt()); getCommonBlocksRef(commonBlocks, st, st->lastNodeOfStmt());
__spf_print(PRINT_PROF_INFO, " number of common blocks %d\n", (int)commonBlocks.size()); __spf_print(PRINT_PROF_INFO, " number of common blocks %d\n", (int)commonBlocks.size());
@@ -1727,7 +1694,8 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
if (isSgExecutableStatement(st) == NULL) if (isSgExecutableStatement(st) == NULL)
delcsStatViewed.insert(st); delcsStatViewed.insert(st);
else if (!isDVM_stat(st) && !isSPF_stat(st)) else if (!sharedMemoryParallelization &&
!isDVM_stat(st) && !isSPF_stat(st))
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
fillPrivatesFromDecl(st->expr(i), delcsSymbViewed, delcsStatViewed, declaredArrays, declaratedArraysSt, privatesVars); fillPrivatesFromDecl(st->expr(i), delcsSymbViewed, delcsStatViewed, declaredArrays, declaratedArraysSt, privatesVars);
@@ -1735,8 +1703,11 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
const int currV = st->variant(); const int currV = st->variant();
if (currV == FOR_NODE) if (currV == FOR_NODE)
{ {
tryToFindPrivateInAttributes(st, privatesVars); if(!sharedMemoryParallelization)
fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars); {
tryToFindPrivateInAttributes(st, privatesVars);
fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars);
}
set<string> toAdd; set<string> toAdd;
tryToFindPrivateInAttributes(st, toAdd); tryToFindPrivateInAttributes(st, toAdd);
@@ -1783,9 +1754,10 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
unitedPrivates.insert(privVar); unitedPrivates.insert(privVar);
set<string> setDiff; set<string> setDiff;
for (auto &privVars : privatesVars) if(!sharedMemoryParallelization)
if (unitedPrivates.find(privVars) == unitedPrivates.end()) for (auto &privVars : privatesVars)
setDiff.insert(privVars); if (unitedPrivates.find(privVars) == unitedPrivates.end())
setDiff.insert(privVars);
allLoops[contrlParent->lineNumber()] = make_pair((SgForStmt*)contrlParent, make_pair(unitedPrivates, setDiff)); allLoops[contrlParent->lineNumber()] = make_pair((SgForStmt*)contrlParent, make_pair(unitedPrivates, setDiff));
parentLoops.pop_back(); parentLoops.pop_back();
@@ -2084,14 +2056,18 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
} }
for (auto it = itF->second.begin(); it != itF->second.end(); ++it) if(!sharedMemoryParallelization)
privatesVars.insert(*it); for (auto it = itF->second.begin(); it != itF->second.end(); ++it)
privatesVars.insert(*it);
} }
} }
else else
{ {
tryToFindPrivateInAttributes(st, privatesVars); if(!sharedMemoryParallelization)
fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars); {
tryToFindPrivateInAttributes(st, privatesVars);
fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars);
}
if (isDVM_stat(st) == false && isSgExecutableStatement(st)) if (isDVM_stat(st) == false && isSgExecutableStatement(st))
{ {
@@ -2125,7 +2101,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
} }
auto convertedLoopInfo = convertLoopInfo(loopInfo, sortedLoopGraph, privatesVars, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays); auto convertedLoopInfo = convertLoopInfo(loopInfo, sortedLoopGraph, privatesVars, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
if (regime == DATA_DISTR) if (regime == DATA_DISTR || regime == SHARED_MEMORY_PAR)
{ {
processLoopInformationForFunction(convertedLoopInfo); processLoopInformationForFunction(convertedLoopInfo);
@@ -2185,7 +2161,8 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
} }
} }
addToDistributionGraph(convertedLoopInfo, arrayLinksByFuncCalls); if(!sharedMemoryParallelization)
addToDistributionGraph(convertedLoopInfo, arrayLinksByFuncCalls);
for (auto &toDel : tmpLoops) for (auto &toDel : tmpLoops)
delete toDel; delete toDel;
@@ -2193,7 +2170,6 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
if (!skipDeps) if (!skipDeps)
{ {
for (auto &loopLine : loopWithOutArrays) for (auto &loopLine : loopWithOutArrays)
{ {
if (loopLine > 0) if (loopLine > 0)
@@ -2301,6 +2277,9 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
selectFreeLoopsForParallelization(loopsForFunction, funcName, (regime == DATA_DISTR), regions, messagesForFile); selectFreeLoopsForParallelization(loopsForFunction, funcName, (regime == DATA_DISTR), regions, messagesForFile);
} }
if(regime == SHARED_MEMORY_PAR)
createParallelDirectives(convertedLoopInfo, regions, arrayLinksByFuncCalls, messagesForFile);
__spf_print(PRINT_PROF_INFO, "Function ended\n"); __spf_print(PRINT_PROF_INFO, "Function ended\n");
} }
} }

View File

@@ -17,7 +17,7 @@
typedef std::pair<std::pair<int, int>, std::pair<int, int>> attrType; typedef std::pair<std::pair<int, int>, std::pair<int, int>> attrType;
namespace DIST = Distribution; namespace DIST = Distribution;
enum REGIME { DATA_DISTR, COMP_DISTR, REMOTE_ACC, ARRAY_ACC_CORNER, UNDEF }; enum REGIME { DATA_DISTR, COMP_DISTR, REMOTE_ACC, ARRAY_ACC_CORNER, SHARED_MEMORY_PAR, UNDEF };
// loop_analyzer.cpp // loop_analyzer.cpp
bool checkExistence(SgExpression *exp, const std::string& doName); bool checkExistence(SgExpression *exp, const std::string& doName);

View File

@@ -562,9 +562,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == LOOP_ANALYZER_NODIST) else if (curr_regime == LOOP_ANALYZER_NODIST)
{ {
auto& loopsInFile = getObjectForFileFromMap(file_name, loopGraph); auto& loopsInFile = getObjectForFileFromMap(file_name, loopGraph);
loopAnalyzerNoDist(file, parallelRegions, createdArrays, getObjectForFileFromMap(file_name, SPF_messages), loopAnalyzer(file, parallelRegions, createdArrays, getObjectForFileFromMap(file_name, SPF_messages), SHARED_MEMORY_PAR,
allFuncInfo, declaredArrays, declaratedArraysSt, arrayLinksByFuncCalls, createDefUseMapByPlace(), allFuncInfo, declaredArrays, declaratedArraysSt, arrayLinksByFuncCalls, createDefUseMapByPlace(),
&(loopsInFile)); false, &(loopsInFile));
UniteNestedDirectives(loopsInFile); UniteNestedDirectives(loopsInFile);
} }