From 7daf1b40381822c5fe1db31a06f70cdecdcb8100 Mon Sep 17 00:00:00 2001 From: Mikhail Kocharmin Date: Thu, 20 Jun 2024 13:00:01 +0300 Subject: [PATCH] loop analyzer refactor for shared memory parallelization --- .../directive_creator_base.cpp | 383 +++++++++--------- .../_src/LoopAnalyzer/loop_analyzer.cpp | 267 ++++++------ .../_src/LoopAnalyzer/loop_analyzer.h | 2 +- sapfor/experts/Sapfor_2017/_src/Sapfor.cpp | 4 +- 4 files changed, 324 insertions(+), 332 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_creator_base.cpp b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_creator_base.cpp index 8730a95..d1ee848 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_creator_base.cpp +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_creator_base.cpp @@ -91,26 +91,17 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai } currentLoop->directive = directive; - for (auto& read : currentLoop->readOpsArray) + if(!sharedMemoryParallelization) { - const string shortName = read->GetName(); - const string orignName = read->GetShortName(); - pair key = make_pair(orignName, shortName); - bool found = false; - for (int i = 0; i < directive->shadowRenew.size(); ++i) + for (auto& read : currentLoop->readOpsArray) { - if (directive->shadowRenew[i].first == key) + const string shortName = read->GetName(); + const string orignName = read->GetShortName(); + pair key = make_pair(orignName, shortName); + bool found = false; + for (int i = 0; i < directive->shadowRenew.size(); ++i) { - found = true; - break; - } - } - - if (found == false) - { - for (int i = 0; i < directive->across.size(); ++i) - { - if (directive->across[i].first == key) + if (directive->shadowRenew[i].first == key) { found = true; break; @@ -119,11 +110,23 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai if (found == false) { - directive->shadowRenew.push_back(make_pair(key, vector>())); + for (int i = 0; i < directive->across.size(); ++i) + { + if (directive->across[i].first == key) + { + found = true; + break; + } + } - const DIST::Array *arrayRef = read; - for (int i = 0; i < arrayRef->GetDimSize(); ++i) - directive->shadowRenew.back().second.push_back(make_pair(0, 0)); + if (found == false) + { + directive->shadowRenew.push_back(make_pair(key, vector>())); + + 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 uniqNamesWithAcross; - fillArraysWithAcrossStatus(currLoop, uniqNamesWithAcross); - - if (arrayWriteAcc.size() == 1) + if(!sharedMemoryParallelization) { - mainArray.arrayRef = arrayWriteAcc.begin()->first; - mainArray.dimentionPos = arrayWriteAcc.begin()->second.first; - mainArray.mainAccess = arrayWriteAcc.begin()->second.second; + set uniqNamesWithAcross; + fillArraysWithAcrossStatus(currLoop, uniqNamesWithAcross); - if (uniqNamesWithAcross.size()) - mainArray.underAcross = true; - } - else if (arrayWriteAcc.size() > 1) - { - if (uniqNamesWithAcross.size()) - mainArray.underAcross = true; - - int posDim = -1; - int minDim = 999999; - int k = 0; - - vector>>> accesses; - map>> sameDims; - for (auto i = arrayWriteAcc.begin(); i != arrayWriteAcc.end(); ++i, ++k) + if (arrayWriteAcc.size() == 1) { - const auto array = i->first; - const string &uniqName = array->GetName(); + mainArray.arrayRef = arrayWriteAcc.begin()->first; + mainArray.dimentionPos = arrayWriteAcc.begin()->second.first; + mainArray.mainAccess = arrayWriteAcc.begin()->second.second; - //ACROSS arrays have priority state for all nested loops! - if (uniqNamesWithAcross.size() > 0) - if (uniqNamesWithAcross.find(uniqName) == uniqNamesWithAcross.end()) - continue; + if (uniqNamesWithAcross.size()) + mainArray.underAcross = true; + } + else if (arrayWriteAcc.size() > 1) + { + if (uniqNamesWithAcross.size()) + mainArray.underAcross = true; - 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)); + int posDim = -1; + int minDim = 999999; + int k = 0; - if (currDim < minDim) + vector>>> accesses; + map>> 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; - 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> 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 &realArrayRefs1 = realArrayRefs[i]; - const set &realArrayRefs2 = realArrayRefs[k]; - - for (auto &refs1 : realArrayRefs1) - { - for (auto &refs2 : realArrayRefs2) + if (itersCount == 0 || (itersCount != 0) && currSize >= itersCount) { - 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; - const int dimTo = accesses[k].second.first; + if (posDim != -1) + { + 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> 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 &realArrayRefs1 = realArrayRefs[i]; + const set &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", - 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 links = findLinksBetweenArrays(refs1, refs2, regId); - auto templRule1 = refs1->GetAlignRulesWithTemplate(regId); - auto templRule2 = refs2->GetAlignRulesWithTemplate(regId); + const int dimFrom = accesses[i].second.first; + 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 -->"; - 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(), + __spf_print(1, "arrays '%s' and '%s' have different align dimensions for loop on line %d\n --> %d vs %d(%d) \n", 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); + 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); + 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) - { - 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) break; @@ -704,43 +712,43 @@ void createParallelDirectives(const mapfirst; - mainArray.dimentionPos = array->second.first; - mainArray.mainAccess = array->second.second; - break; + if (k == posDim) + { + mainArray.arrayRef = array->first; + mainArray.dimentionPos = array->second.first; + mainArray.mainAccess = array->second.second; + break; + } } } + else + { + __spf_print(PRINT_DIR_RESULT, " has conflict writes\n"); + hasConflict = true; + } } else { - __spf_print(PRINT_DIR_RESULT, " has conflict writes\n"); - hasConflict = true; + mainArray.hasWrite = false; + __spf_print(PRINT_DIR_RESULT, " no regular writes on loop\n"); } - } - else - { - mainArray.hasWrite = false; - __spf_print(PRINT_DIR_RESULT, " no regular writes on loop\n"); + + // fill mainArray if no regular writes found + // now OmegaTest is used for searching dependencies + if (!mainArray.hasWrite) + findMainArrayFromRead(currAccesses, mainArray, itersCount, arrayLinksByFuncCalls); } - // fill mainArray if no regular writes found - // now OmegaTest is used for searching dependencies - if (!mainArray.hasWrite) - findMainArrayFromRead(currAccesses, mainArray, itersCount, arrayLinksByFuncCalls); + bool dimPosFound = sharedMemoryParallelization || + (mainArray.arrayRef != NULL && mainArray.dimentionPos != -1); - if (!hasConflict && - mainArray.arrayRef != NULL && mainArray.dimentionPos != -1 && + if (dimPosFound && !currLoop->hasLimitsToParallel() && (currLoop->lineNum > 0 || (currLoop->lineNum < 0 && currLoop->altLineNum > 0))) { @@ -749,7 +757,7 @@ void createParallelDirectives(const mapIsLoopArray())) + if (!sharedMemoryParallelization && mainArray.underAcross == false && !mainArray.arrayRef->IsLoopArray()) { set realArrayRef; getRealArrayRefs(mainArray.arrayRef, mainArray.arrayRef, realArrayRef, arrayLinksByFuncCalls); @@ -788,25 +796,30 @@ void createParallelDirectives(const mapdirective; if (parDir != NULL) { - parDir->arrayRef2 = mainArrayOfLoop; - if (mainArray.underAcross == false) + if(!sharedMemoryParallelization) { - for (int i = 0; i < mainArrayOfLoop->GetDimSize(); ++i) - { - if (i == dimPos) - parDir->on2.push_back(make_pair(currLoop->loopSymbol, mainAccess)); - else - parDir->on2.push_back(make_pair("*", make_pair(0, 0))); - } + parDir->arrayRef2 = mainArrayOfLoop; - 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; + if (mainArray.underAcross == false) + { + for (int i = 0; i < mainArrayOfLoop->GetDimSize(); ++i) + { + if (i == dimPos) + 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; + + addShadowFromAnalysis(parDir, currAccesses); } - else - parDir->on2 = parDir->on; - addShadowFromAnalysis(parDir, currAccesses); loop->directiveForLoop = new ParallelDirective(*loop->directive); } __spf_print(PRINT_DIR_RESULT, " directive created\n"); diff --git a/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp b/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp index caadd09..3c91121 100644 --- a/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp +++ b/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp @@ -204,7 +204,7 @@ vector matchSubscriptToLoopSymbols(const vector &parentLoops, S if (countOfSymbols > 1) { __spf_print(PRINT_ARRAY_ARCS, " <%d|%d> ", 0, 0); - if (currRegime == DATA_DISTR) + if (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR) { const pair &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); @@ -238,7 +238,7 @@ vector matchSubscriptToLoopSymbols(const vector &parentLoops, S for (int i = 0; i < (int)parentLoops.size(); ++i) 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 &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr); @@ -294,7 +294,7 @@ vector matchSubscriptToLoopSymbols(const vector &parentLoops, S if (side == RIGHT) 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 &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); @@ -387,7 +387,8 @@ vector matchSubscriptToLoopSymbols(const vector &parentLoops, S return allPositions; } -static vector matchArrayToLoopSymbols(const vector &parentLoops, SgExpression *currExp, const int side, +static vector matchArrayToLoopSymbols(const vector &parentLoops, vector>& privatesVarsForLoop, + SgExpression *currExp, const int side, map> &loopInfo, const int currLine, map &sortedLoopGraph, const ParallelRegion *reg, const double currentW, const map> &arrayLinksByFuncCalls) @@ -440,7 +441,9 @@ static vector matchArrayToLoopSymbols(const vector &parentLoops vector canNotMapToLoop; 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()); if (itLoop == sortedLoopGraph.end()) @@ -456,7 +459,7 @@ static vector matchArrayToLoopSymbols(const vector &parentLoops if (side == LEFT) { - if (ifUnknownArrayAssignFound && (currRegime == DATA_DISTR)) + if (ifUnknownArrayAssignFound && (currRegime == DATA_DISTR || currRegime == SHARED_MEMORY_PAR)) { const string arrayRefS = arrayRef->unparse(); for (auto &line : canNotMapToLoop) @@ -517,7 +520,8 @@ static vector matchArrayToLoopSymbols(const vector &parentLoops } static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp, - const vector& parentLoops, const int side, const int lineNum, + const vector& parentLoops, vector>& privatesVarsForLoop, + const int side, const int lineNum, map>& loopInfo, map &sortedLoopGraph, map>& notMappedDistributedArrays, set& 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); bool wasMapped = false; - vector matched = matchArrayToLoopSymbols(parentLoops, currExp, side, loopInfo, lineNum, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls); + vector matched = matchArrayToLoopSymbols(parentLoops, privatesVarsForLoop, currExp, side, loopInfo, lineNum, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls); for (int z = 0; z < matched.size(); ++z) wasMapped |= (matched[z] != 0); @@ -570,7 +574,8 @@ static void findArrayRef(const vector &parentLoops, SgExpression *cu if (isArrayRef(currExp)) { //... 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) { @@ -582,147 +587,104 @@ static void findArrayRef(const vector &parentLoops, SgExpression *cu printInternalError(convertFileName(__FILE__).c_str(), __LINE__); if (itLoop->second->perfectLoop != depth) break; - itLoop->second->hasIndirectAccess = true; - if (sharedMemoryParallelization && side == RIGHT) - itLoop->second->hasIndirectAccess = false; + + if (!(sharedMemoryParallelization && side == RIGHT)) + 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); } else { wasDistributedArrayRef = true; - mapArrayRef(currentSt, currExp, parentLoops, side, lineNum, loopInfo, sortedLoopGraph, + mapArrayRef(currentSt, currExp, parentLoops, privatesVarsForLoop, side, lineNum, loopInfo, sortedLoopGraph, 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()); - SgStatement *decl = declaratedInStmt(symb); - auto uniqKey = getUniqName(commonBlocks, decl, symb); + set loopsPrivates; + set loopsPrivatesS; + set loopsRedUnited; + map> loopsReductions; + map>> 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 - if (itFound->second.first->GetDistributeFlagVal() != DIST::DISTR) + + for (int z = 0; z < parentLoops.size(); ++z) { - set loopsPrivates; - set loopsPrivatesS; - set loopsRedUnited; - map> loopsReductions; - map>> loopsReductionsLoc; - - - for (int z = 0; z < parentLoops.size(); ++z) + auto& loop = parentLoops[z]; + for (auto &data : getAttributes(loop, set{ SPF_ANALYSIS_DIR })) { - auto& loop = parentLoops[z]; - for (auto &data : getAttributes(loop, set{ SPF_ANALYSIS_DIR })) - { - fillPrivatesFromComment(new Statement(data), loopsPrivatesS); - for (auto& elem : loopsPrivatesS) - loopsPrivates.insert(elem->GetOriginal()->identifier()); - fillReductionsFromComment(new Statement(data), loopsReductions); - fillReductionsFromComment(new Statement(data), loopsReductionsLoc); - } + fillPrivatesFromComment(new Statement(data), loopsPrivatesS); + for (auto& elem : loopsPrivatesS) + 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()); - loopsRedUnited.insert(get<0>(setElem)->GetOriginal()->identifier()); - loopsRedUnited.insert(get<1>(setElem)->GetOriginal()->identifier()); - } + loopsPrivates.insert(get<0>(setElem)->GetOriginal()->identifier()); + loopsPrivates.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()); - if (loopsPrivates.find(key) == loopsPrivates.end()) + const string key = string(OriginalSymbol(currExp->symbol())->identifier()); + if (loopsPrivates.find(key) == loopsPrivates.end()) + { + for (auto& loop : parentLoops) { - if (sharedMemoryParallelization == 0) - { - for (auto& loop : parentLoops) - { - __spf_print(1, "WARN: write to non distributed array '%s' in loop on line %d\n", symb->identifier(), loop->lineNumber()); + __spf_print(1, "WARN: write to non distributed array '%s' in loop on line %d\n", symb->identifier(), loop->lineNumber()); - wstring messageE, messageR; - __spf_printToLongBuf(messageE, L"write to non distributed array '%s' in this loop", to_wstring(symb->identifier()).c_str()); + 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, R61, to_wstring(symb->identifier()).c_str()); + __spf_printToLongBuf(messageR, R61, to_wstring(symb->identifier()).c_str()); - if (loop->lineNumber() > 0) - currMessages->push_back(Messages(WARR, loop->lineNumber(), messageR, messageE, 1026)); - sortedLoopGraph[loop->lineNumber()]->hasWritesToNonDistribute = true; - } - } + if (loop->lineNumber() > 0) + currMessages->push_back(Messages(WARR, loop->lineNumber(), messageR, messageE, 1026)); + 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; - currRegime = ARRAY_ACC_CORNER; - bool wasMapped = false; - map> tmpLoopInfo = loopInfo; - - vector 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) + DIST::Array* currArray = getArrayFromDeclarated(declaratedInStmt(currOrigArrayS), currOrigArrayS->identifier()); + checkNull(currArray, convertFileName(__FILE__).c_str(), __LINE__); { - if (sharedMemoryParallelization == 0) - { - 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()); + set realArrayRefs; + getRealArrayRefs(currArray, currArray, realArrayRefs, arrayLinksByFuncCalls); - __spf_printToLongBuf(messageR, R60, to_wstring(symb->identifier()).c_str()); - - 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 realArrayRefs; - getRealArrayRefs(currArray, currArray, realArrayRefs, arrayLinksByFuncCalls); - - for (auto& array : realArrayRefs) - array->SetPrivateInLoopStatus(true); - } + for (auto& array : realArrayRefs) + array->SetPrivateInLoopStatus(true); } } } @@ -1384,7 +1346,7 @@ static void convertOneLoop(LoopGraph *currLoop, mapidentifier(); - if (privateArrays.find(symbIdent) == privateArrays.end()) + if (privateArrays.find(symbIdent) == privateArrays.end() || sharedMemoryParallelization) { const tuple uniqKey = getUniqName(commonBlocks, decl, currentArray); @@ -1401,7 +1363,7 @@ static void convertOneLoop(LoopGraph *currLoop, mapsecond; - if (arrayToAdd->IsNotDistribute() == true) + if (!sharedMemoryParallelization && arrayToAdd->IsNotDistribute() == true) continue; set links; @@ -1609,8 +1571,9 @@ void loopAnalyzer(SgFile *file, vector ®ions, mapsymbol()->identifier()] = modules[i]; map> privatesByModule; - for (int i = 0; i < modules.size(); ++i) - privatesByModule[modules[i]->symbol()->identifier()] = getPrivatesFromModule(modules[i], declaredArrays, declaratedArraysSt, modulesByName); + if(!sharedMemoryParallelization) + for (int i = 0; i < modules.size(); ++i) + privatesByModule[modules[i]->symbol()->identifier()] = getPrivatesFromModule(modules[i], declaredArrays, declaratedArraysSt, modulesByName); map funcByName; createMapOfFunc(AllfuncInfo, funcByName); @@ -1674,13 +1637,17 @@ void loopAnalyzer(SgFile *file, vector ®ions, mapvariant() != GLOBAL) + if(!sharedMemoryParallelization) { - tmpModFind = tmpModFind->controlParent(); - if (tmpModFind->variant() == MODULE_STMT) - fillFromModule(tmpModFind->symbol(), privatesByModule, privatesVars); + SgStatement* tmpModFind = st; + while (tmpModFind->variant() != GLOBAL) + { + tmpModFind = tmpModFind->controlParent(); + if (tmpModFind->variant() == MODULE_STMT) + fillFromModule(tmpModFind->symbol(), privatesByModule, privatesVars); + } } + commonBlocks.clear(); getCommonBlocksRef(commonBlocks, st, st->lastNodeOfStmt()); __spf_print(PRINT_PROF_INFO, " number of common blocks %d\n", (int)commonBlocks.size()); @@ -1727,7 +1694,8 @@ void loopAnalyzer(SgFile *file, vector ®ions, mapexpr(i), delcsSymbViewed, delcsStatViewed, declaredArrays, declaratedArraysSt, privatesVars); @@ -1735,9 +1703,12 @@ void loopAnalyzer(SgFile *file, vector ®ions, mapvariant(); if (currV == FOR_NODE) { - tryToFindPrivateInAttributes(st, privatesVars); - fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars); - + if(!sharedMemoryParallelization) + { + tryToFindPrivateInAttributes(st, privatesVars); + fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars); + } + set toAdd; tryToFindPrivateInAttributes(st, toAdd); @@ -1783,9 +1754,10 @@ void loopAnalyzer(SgFile *file, vector ®ions, map setDiff; - for (auto &privVars : privatesVars) - if (unitedPrivates.find(privVars) == unitedPrivates.end()) - setDiff.insert(privVars); + if(!sharedMemoryParallelization) + for (auto &privVars : privatesVars) + if (unitedPrivates.find(privVars) == unitedPrivates.end()) + setDiff.insert(privVars); allLoops[contrlParent->lineNumber()] = make_pair((SgForStmt*)contrlParent, make_pair(unitedPrivates, setDiff)); parentLoops.pop_back(); @@ -2084,14 +2056,18 @@ void loopAnalyzer(SgFile *file, vector ®ions, mapsecond.begin(); it != itF->second.end(); ++it) - privatesVars.insert(*it); + if(!sharedMemoryParallelization) + for (auto it = itF->second.begin(); it != itF->second.end(); ++it) + privatesVars.insert(*it); } } else { - tryToFindPrivateInAttributes(st, privatesVars); - fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars); + if(!sharedMemoryParallelization) + { + tryToFindPrivateInAttributes(st, privatesVars); + fillNonDistrArraysAsPrivate(st, declaredArrays, declaratedArraysSt, privatesVars); + } if (isDVM_stat(st) == false && isSgExecutableStatement(st)) { @@ -2125,7 +2101,7 @@ void loopAnalyzer(SgFile *file, vector ®ions, map ®ions, map ®ions, map 0) @@ -2300,6 +2276,9 @@ void loopAnalyzer(SgFile *file, vector ®ions, map, std::pair> attrType; 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 bool checkExistence(SgExpression *exp, const std::string& doName); diff --git a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp index ae13641..5bf8626 100644 --- a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp @@ -562,9 +562,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne else if (curr_regime == LOOP_ANALYZER_NODIST) { 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(), - &(loopsInFile)); + false, &(loopsInFile)); UniteNestedDirectives(loopsInFile); }