Merge pull request 'remove select_dim_conf pass' (#50) from remove_select_dim_pass into master
This commit was merged in pull request #50.
This commit is contained in:
@@ -299,9 +299,7 @@ set(EXPR_TRANSFORM _src/ExpressionTransform/control_flow_graph_part.cpp
|
||||
set(GR_CALL _src/GraphCall/graph_calls.cpp
|
||||
_src/GraphCall/graph_calls.h
|
||||
_src/GraphCall/graph_calls_base.cpp
|
||||
_src/GraphCall/graph_calls_func.h
|
||||
_src/GraphCall/select_array_conf.cpp
|
||||
_src/GraphCall/select_array_conf.h)
|
||||
_src/GraphCall/graph_calls_func.h)
|
||||
|
||||
set(GR_LOOP _src/GraphLoop/graph_loops_base.cpp
|
||||
_src/GraphLoop/graph_loops.cpp
|
||||
|
||||
@@ -1,303 +0,0 @@
|
||||
#include "select_array_conf.h"
|
||||
#include "../Utils/utils.h"
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::set;
|
||||
using std::pair;
|
||||
using std::wstring;
|
||||
|
||||
using std::inserter;
|
||||
using std::copy;
|
||||
using std::to_string;
|
||||
|
||||
bool IsSetsIntersect(const set<DIST::Array*>& lhs, const set<DIST::Array*>& rhs)
|
||||
{
|
||||
if (lhs.empty() || rhs.empty())
|
||||
return false;
|
||||
|
||||
if (lhs.size() * 100 < rhs.size())
|
||||
{
|
||||
for (const auto& x : lhs)
|
||||
if (rhs.find(x) != rhs.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rhs.size() * 100 < lhs.size())
|
||||
{
|
||||
for (const auto& x : rhs)
|
||||
if (lhs.find(x) != lhs.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto l_it = lhs.begin(), l_end = lhs.end();
|
||||
auto r_it = rhs.begin(), r_end = rhs.end();
|
||||
|
||||
while (l_it != l_end && r_it != r_end)
|
||||
{
|
||||
if (*l_it < *r_it)
|
||||
{
|
||||
l_it = lhs.lower_bound(*r_it);
|
||||
continue;
|
||||
}
|
||||
if (*r_it < *l_it)
|
||||
{
|
||||
r_it = rhs.lower_bound(*l_it);
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void findUsedArraysInParallelLoops(LoopGraph* loop, set<DIST::Array*>& res)
|
||||
{
|
||||
if(loop->directive)
|
||||
copy(loop->usedArraysAll.begin(), loop->usedArraysAll.end(), inserter(res, res.end()));
|
||||
else
|
||||
for(LoopGraph* child : loop->children)
|
||||
findUsedArraysInParallelLoops(child, res);
|
||||
}
|
||||
|
||||
static void preventLoopsFromParallelizations(LoopGraph* loop, const set<DIST::Array*>& prevent,
|
||||
vector<Messages>& messagesForFile)
|
||||
{
|
||||
if (loop->directive)
|
||||
{
|
||||
if (IsSetsIntersect(prevent, loop->usedArraysAll))
|
||||
{
|
||||
// prevent this loop
|
||||
delete loop->directive;
|
||||
loop->directive = NULL;
|
||||
|
||||
vector<DIST::Array*> conflict_arrays; // = prevent \intersection loop->usedArraysAll
|
||||
|
||||
set_intersection(prevent.begin(), prevent.end(),
|
||||
loop->usedArraysAll.begin(), loop->usedArraysAll.end(),
|
||||
back_inserter(conflict_arrays));
|
||||
|
||||
for(auto& conflict_array : conflict_arrays)
|
||||
{
|
||||
// constructing string with array and it's sizes
|
||||
string array_bounds;
|
||||
const auto& array_sizes = conflict_array->GetSizes();
|
||||
for(int i = 0; i < array_sizes.size(); i++)
|
||||
{
|
||||
if(i != 0)
|
||||
array_bounds += ",";
|
||||
array_bounds += "*";
|
||||
}
|
||||
|
||||
string array_ref = conflict_array->GetShortName() + "(" + array_bounds + ")";
|
||||
|
||||
// add conflict message
|
||||
std::wstring bufE, bufR;
|
||||
__spf_printToLongBuf(bufE, L"Array reference '%s' has a different size from the original array", to_wstring(array_ref).c_str());
|
||||
__spf_printToLongBuf(bufR, R202, to_wstring(array_ref).c_str());
|
||||
|
||||
messagesForFile.push_back(Messages(WARR, loop->lineNum, bufR, bufE, 3023));
|
||||
loop->hasAccessToSubArray = true;
|
||||
}
|
||||
|
||||
if(!conflict_arrays.empty())
|
||||
messagesForFile.push_back(Messages(NOTE, loop->lineNum, R204, L"Array's memory intersections prevents this loop from parallelization", 3024));
|
||||
}
|
||||
}
|
||||
|
||||
for (LoopGraph* child : loop->children)
|
||||
preventLoopsFromParallelizations(child, prevent, messagesForFile);
|
||||
}
|
||||
|
||||
struct DimConf
|
||||
{
|
||||
vector<pair<int, int>> dims;
|
||||
|
||||
DimConf(DIST::Array* a) : dims(a->GetSizes()) { }
|
||||
|
||||
friend bool operator<(const DimConf& l, const DimConf& r) { return l.dims < r.dims; }
|
||||
};
|
||||
|
||||
static map<DimConf, map<FuncInfo*, set<DIST::Array*>>>::const_iterator
|
||||
pickBest(const map<DimConf, map<FuncInfo*, set<DIST::Array*>>>& arrs)
|
||||
{
|
||||
const int undefined = -1;
|
||||
int max_elems = undefined;
|
||||
auto best_it = arrs.begin();
|
||||
|
||||
for (auto it = arrs.begin(); it != arrs.end(); it++)
|
||||
{
|
||||
int elems = 1;
|
||||
for (const auto& p : it->first.dims)
|
||||
{
|
||||
if(p.first >= 0 && p.second >= p.first)
|
||||
{
|
||||
elems *= p.second - p.first;
|
||||
}
|
||||
else
|
||||
{
|
||||
elems = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (elems > max_elems)
|
||||
{
|
||||
max_elems = elems;
|
||||
best_it = it;
|
||||
}
|
||||
}
|
||||
|
||||
return best_it;
|
||||
}
|
||||
|
||||
void SelectArrayConfForParallelization(SgProject* proj, map<string, vector<FuncInfo*>>& funcByFile,
|
||||
const map<string, vector<LoopGraph*>>& loopGraph,
|
||||
map<string, vector<Messages>>& allMessages,
|
||||
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
|
||||
{
|
||||
map<string, FuncInfo*> funcByName;
|
||||
for (const auto& byFile : funcByFile)
|
||||
for(const auto& byFunc : byFile.second)
|
||||
funcByName[byFunc->funcName] = byFunc;
|
||||
|
||||
// array(real ref) dims func array in func
|
||||
map<DIST::Array*, map<DimConf, map<FuncInfo*, set<DIST::Array*>>>> usedArrays;
|
||||
|
||||
for (const auto& byFile : loopGraph)
|
||||
{
|
||||
SgFile::switchToFile(byFile.first);
|
||||
|
||||
auto& loops = byFile.second;
|
||||
|
||||
auto file_funcs_it = funcByFile.find(byFile.first);
|
||||
|
||||
if(file_funcs_it == funcByFile.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); // no such file in funcByFile
|
||||
|
||||
map<FuncInfo*, set<DIST::Array*>> usedInLoops;
|
||||
|
||||
for (const auto& loop : loops)
|
||||
{
|
||||
SgStatement* search_func = loop->loop->GetOriginal();
|
||||
|
||||
while (search_func && (!isSgProgHedrStmt(search_func)))
|
||||
search_func = search_func->controlParent();
|
||||
|
||||
if (!search_func)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //loop statement outside any function statement
|
||||
|
||||
bool loop_analyzed = false;
|
||||
for (const auto& byFunc : file_funcs_it->second)
|
||||
{
|
||||
if (byFunc->funcPointer->GetOriginal() == search_func)
|
||||
{
|
||||
if(!loop->usedArraysAll.empty())
|
||||
findUsedArraysInParallelLoops(loop, usedInLoops[byFunc]);
|
||||
|
||||
loop_analyzed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loop_analyzed)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //no func found for loop
|
||||
}
|
||||
|
||||
for (const auto& byFunc : usedInLoops)
|
||||
{
|
||||
for (DIST::Array* arr : byFunc.second)
|
||||
{
|
||||
set<DIST::Array*> realRefs;
|
||||
getRealArrayRefs(arr, arr, realRefs, arrayLinksByFuncCalls);
|
||||
|
||||
bool fullUnknownSizes = true;
|
||||
for (auto& dim : arr->GetSizes())
|
||||
{
|
||||
if (dim.first == dim.second && dim.first != -1)
|
||||
fullUnknownSizes = false;
|
||||
}
|
||||
|
||||
if (fullUnknownSizes && realRefs.find(arr) != realRefs.end())
|
||||
continue;
|
||||
|
||||
for(DIST::Array* ref : realRefs)
|
||||
usedArrays[ref][DimConf(arr)][byFunc.first].insert(arr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map<FuncInfo*, set<DIST::Array*>> preventFromParallelization;
|
||||
|
||||
for (const auto& byRealRef : usedArrays)
|
||||
{
|
||||
DIST::Array* realRef = byRealRef.first;
|
||||
auto& refferedDims = byRealRef.second;
|
||||
|
||||
// prevent from parallelization all configurations except best one
|
||||
|
||||
auto best_conf_it = pickBest(refferedDims);
|
||||
|
||||
for (auto by_worse_dim_conf_it = refferedDims.begin(); by_worse_dim_conf_it != refferedDims.end(); by_worse_dim_conf_it++)
|
||||
{
|
||||
if(by_worse_dim_conf_it != best_conf_it)
|
||||
{
|
||||
for (const auto& byFunc : by_worse_dim_conf_it->second)
|
||||
{
|
||||
FuncInfo* f = byFunc.first;
|
||||
auto& to_prevent = byFunc.second;
|
||||
|
||||
auto& destSet = preventFromParallelization[f];
|
||||
copy(to_prevent.begin(), to_prevent.end(), inserter(destSet, destSet.end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& byFile : loopGraph)
|
||||
{
|
||||
vector<Messages>& fileM = getObjectForFileFromMap(byFile.first.c_str(), allMessages);
|
||||
SgFile::switchToFile(byFile.first);
|
||||
|
||||
auto& loops = byFile.second;
|
||||
|
||||
auto file_funcs_it = funcByFile.find(byFile.first);
|
||||
|
||||
if (file_funcs_it == funcByFile.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); // no such file in funcByFile
|
||||
|
||||
map<FuncInfo*, set<DIST::Array*>> usedInLoops;
|
||||
|
||||
for (const auto& loop : loops)
|
||||
{
|
||||
SgStatement* search_func = loop->loop->GetOriginal();
|
||||
|
||||
while (search_func && (!isSgProgHedrStmt(search_func)))
|
||||
search_func = search_func->controlParent();
|
||||
|
||||
if (!search_func)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //loop statement outside any function statement
|
||||
|
||||
bool loop_analyzed = false;
|
||||
for (const auto& byFunc : file_funcs_it->second)
|
||||
{
|
||||
if (byFunc->funcPointer->GetOriginal() == search_func)
|
||||
{
|
||||
auto prevent_it = preventFromParallelization.find(byFunc);
|
||||
if (prevent_it != preventFromParallelization.end())
|
||||
preventLoopsFromParallelizations(loop, prevent_it->second, fileM);
|
||||
|
||||
loop_analyzed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loop_analyzed)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //no func found for loop
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include<map>
|
||||
#include<string>
|
||||
#include<vector>
|
||||
#include<set>
|
||||
|
||||
#include "../Distribution/Distribution.h"
|
||||
#include "../GraphLoop/graph_loops.h"
|
||||
#include "../ParallelizationRegions/ParRegions.h"
|
||||
|
||||
|
||||
void SelectArrayConfForParallelization(SgProject* proj, std::map<std::string, std::vector<FuncInfo*>>& funcByFile,
|
||||
const std::map<std::string, std::vector<LoopGraph*>>& loopGraph,
|
||||
std::map<std::string, std::vector<Messages>>& allMessages,
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
|
||||
@@ -911,14 +911,8 @@ extern int PASSES_DONE[EMPTY_PASS];
|
||||
static void printToBuffer(const LoopGraph *currLoop, const int childSize, char buf[512])
|
||||
{
|
||||
int loopState = 0; // 0 - unknown, 1 - good, 2 - bad
|
||||
if (PASSES_DONE[CREATE_TEMPLATE_LINKS])
|
||||
{
|
||||
if (currLoop->hasLimitsToParallel())
|
||||
loopState = 2;
|
||||
else
|
||||
loopState = 1;
|
||||
}
|
||||
else if (PASSES_DONE[SELECT_ARRAY_DIM_CONF])
|
||||
if (PASSES_DONE[CREATE_TEMPLATE_LINKS] ||
|
||||
PASSES_DONE[LOOP_ANALYZER_NODIST])
|
||||
{
|
||||
if (currLoop->hasLimitsToParallel())
|
||||
loopState = 2;
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "LoopAnalyzer/loop_analyzer.h"
|
||||
|
||||
#include "GraphCall/graph_calls_func.h"
|
||||
#include "GraphCall/select_array_conf.h"
|
||||
#include "GraphLoop/graph_loops_func.h"
|
||||
#include "DynamicAnalysis/gCov_parser_func.h"
|
||||
#include "DynamicAnalysis/createParallelRegions.h"
|
||||
@@ -1880,9 +1879,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
runPrivateVariableAnalysis(loopGraph, fullIR, commonBlocks, SPF_messages);
|
||||
else if (curr_regime == FIX_COMMON_BLOCKS)
|
||||
fixCommonBlocks(allFuncInfo, commonBlocks, &project);
|
||||
else if (curr_regime == SELECT_ARRAY_DIM_CONF) {
|
||||
;// SelectArrayConfForParallelization(&project, allFuncInfo, loopGraph, SPF_messages, arrayLinksByFuncCalls);
|
||||
}
|
||||
else if (curr_regime == GET_MIN_MAX_BLOCK_DIST)
|
||||
{
|
||||
__spf_print(1, "GET_MIN_MAX_BLOCK_DIST: %d %d\n", min_max_block.first, min_max_block.second);
|
||||
|
||||
@@ -67,7 +67,6 @@ enum passes {
|
||||
CHECK_ARGS_DECL,
|
||||
|
||||
FIND_FUNC_TO_INCLUDE,
|
||||
SELECT_ARRAY_DIM_CONF,
|
||||
ONLY_ARRAY_GRAPH,
|
||||
|
||||
PRIVATE_ANALYSIS_SPF,
|
||||
@@ -238,7 +237,6 @@ static void setPassValues()
|
||||
passNames[VERIFY_COMMON] = "VERIFY_COMMON";
|
||||
passNames[VERIFY_OPERATORS] = "VERIFY_OPERATORS";
|
||||
passNames[FIND_FUNC_TO_INCLUDE] = "FIND_FUNC_TO_INCLUDE";
|
||||
passNames[SELECT_ARRAY_DIM_CONF] = "SELECT_ARRAY_DIM_CONF";
|
||||
passNames[CREATE_DISTR_DIRS] = "CREATE_DISTR_DIRS";
|
||||
passNames[CREATE_PARALLEL_DIRS] = "CREATE_PARALLEL_DIRS";
|
||||
passNames[INSERT_PARALLEL_DIRS] = "INSERT_PARALLEL_DIRS";
|
||||
|
||||
@@ -233,7 +233,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
|
||||
|
||||
list({ GET_ALL_ARRAY_DECL, CALL_GRAPH2, CODE_CHECKER_PASSES, SUBST_EXPR_RD, ARRAY_ACCESS_ANALYSIS_FOR_CORNER }) <= list({ LOOP_ANALYZER_NODIST, LOOP_ANALYZER_DATA_DIST_S0, LOOP_ANALYZER_DATA_DIST_S1, ONLY_ARRAY_GRAPH });
|
||||
|
||||
list({ LOOP_ANALYZER_NODIST, REMOVE_OMP_DIRS }) <= Pass(SELECT_ARRAY_DIM_CONF) <= Pass(INSERT_PARALLEL_DIRS_NODIST);
|
||||
list({ LOOP_ANALYZER_NODIST, REMOVE_OMP_DIRS }) <= Pass(INSERT_PARALLEL_DIRS_NODIST);
|
||||
|
||||
Pass(CHECK_ARGS_DECL) <= Pass(CREATE_TEMPLATE_LINKS);
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_SPF "2351"
|
||||
#define VERSION_SPF "2352"
|
||||
|
||||
@@ -820,7 +820,7 @@ int SPF_GetArrayDistribution(void*& context, int winHandler, short *options, sho
|
||||
else if (regime == 1)
|
||||
{
|
||||
if (sharedMemoryParallelization)
|
||||
runPassesForVisualizer(projName, { SELECT_ARRAY_DIM_CONF });
|
||||
runPassesForVisualizer(projName, { LOOP_ANALYZER_NODIST });
|
||||
else
|
||||
runPassesForVisualizer(projName, { LOOP_ANALYZER_DATA_DIST_S1 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user