772 lines
34 KiB
C++
772 lines
34 KiB
C++
#include "leak_detector.h"
|
|
|
|
#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 "../Distribution/Arrays.h"
|
|
#include "graph_calls.h"
|
|
#include "../GraphLoop/graph_loops.h"
|
|
#include "../ParallelizationRegions/ParRegions.h"
|
|
#include "remote_access.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;
|
|
|
|
#define DEB 0
|
|
|
|
static set<string> fillRemotesInParallel(const ParallelDirective* dvm_dir)
|
|
{
|
|
set<string> remotesInParallel;
|
|
for (auto& elem : dvm_dir->remoteAccess)
|
|
remotesInParallel.insert(elem.first.first.first + "(" + elem.first.second + ")");
|
|
return remotesInParallel;
|
|
}
|
|
|
|
static void createRemoteInParallel(const pair<LoopGraph*, const ParallelDirective*>& under_dvm_dir,
|
|
const set<DIST::Array*>& doneInLoops,
|
|
const map<string, FuncInfo*>& funcMap,
|
|
map<string, ArrayRefExp*>& uniqRemotes, vector<Messages>& messages,
|
|
const DataDirective& data, const vector<int>& currVar, const uint64_t regionId,
|
|
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
|
|
{
|
|
const set<DIST::Array*> usedArrays = under_dvm_dir.first->usedArrays;
|
|
const set<DIST::Array*> usedArraysWrite = under_dvm_dir.first->usedArraysWrite;
|
|
const set<string> remotesInParallel = fillRemotesInParallel(under_dvm_dir.second);
|
|
set<ArrayRefExp*> addedRemotes;
|
|
|
|
for (auto& usedArr : usedArrays)
|
|
{
|
|
if (doneInLoops.find(usedArr) == doneInLoops.end() && usedArraysWrite.find(usedArr) == usedArraysWrite.end())
|
|
{
|
|
set<DIST::Array*> realRefs;
|
|
getRealArrayRefs(usedArr, usedArr, realRefs, arrayLinksByFuncCalls);
|
|
|
|
bool isDistr = false;
|
|
|
|
for (auto& realRef : realRefs)
|
|
{
|
|
auto templ = realRef->GetTemplateArray(regionId);
|
|
for (int z = 0; z < data.distrRules.size(); ++z)
|
|
{
|
|
if (templ == data.distrRules[z].first)
|
|
{
|
|
for (auto& elem : data.distrRules[z].second[currVar[z]].distRule)
|
|
if (elem == BLOCK)
|
|
isDistr = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isDistr)
|
|
{
|
|
vector<string> mapToLoop;
|
|
for (int z = 0; z < usedArr->GetDimSize(); ++z)
|
|
mapToLoop.push_back("");
|
|
|
|
//TODO: find all array refs
|
|
addRemoteLink(under_dvm_dir.first, funcMap, createRemoteLink(under_dvm_dir.first, usedArr), uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, -1, false);
|
|
__spf_print(DEB, "CRIP: %d, AFTER MAIN CHECK for arrray '%s'\n", __LINE__, usedArr->GetShortName().c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void createRemoteInParallel(const map<DIST::Array*, vector<ArrayOp>> remoteRegularReadsOfTopLoop,
|
|
const pair<LoopGraph*, const ParallelDirective*> under_dvm_dir,
|
|
const DIST::Arrays<int>& allArrays,
|
|
const map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>& loopInfo,
|
|
DIST::GraphCSR<int, double, attrType>& reducedG,
|
|
const DataDirective& data,
|
|
const vector<int>& currVar,
|
|
map<string, ArrayRefExp*>& uniqRemotes,
|
|
vector<Messages>& messages,
|
|
const uint64_t regionId,
|
|
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
|
|
set<DIST::Array*>& doneInLoops,
|
|
const map<string, FuncInfo*>& funcMap)
|
|
{
|
|
if (!under_dvm_dir.first || !under_dvm_dir.second)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
__spf_print(DEB, "createRemoteInParallel %d, for loop %d\n", __LINE__, under_dvm_dir.first->lineNum);
|
|
set<ArrayRefExp*> addedRemotes;
|
|
|
|
auto it = loopInfo.find(under_dvm_dir.first);
|
|
if (it == loopInfo.end())
|
|
{
|
|
if (under_dvm_dir.first->perfectLoop > 1)
|
|
{
|
|
pair<LoopGraph*, const ParallelDirective*> nextDir = under_dvm_dir;
|
|
nextDir.first = under_dvm_dir.first->children[0];
|
|
|
|
createRemoteInParallel(remoteRegularReadsOfTopLoop, nextDir, allArrays, loopInfo, reducedG, data, currVar, uniqRemotes, messages, regionId, arrayLinksByFuncCalls, doneInLoops, funcMap);
|
|
}
|
|
return;
|
|
}
|
|
|
|
const map<DIST::Array*, ArrayInfo*>& currInfo = it->second;
|
|
const ParallelDirective* parDir = under_dvm_dir.second;
|
|
|
|
DIST::Array* arrayRefOnDir = parDir->arrayRef;
|
|
set<DIST::Array*> realRefArrayOnDir;
|
|
const set<string> remotesInParallel = fillRemotesInParallel(parDir);
|
|
const LoopGraph* currLoop = under_dvm_dir.first;
|
|
|
|
|
|
if (!arrayRefOnDir->IsTemplate())
|
|
{
|
|
getRealArrayRefs(arrayRefOnDir, arrayRefOnDir, realRefArrayOnDir, arrayLinksByFuncCalls);
|
|
if (realRefArrayOnDir.size() != 1)
|
|
{
|
|
vector<vector<tuple<DIST::Array*, int, pair<int, int>>>> allRules(realRefArrayOnDir.size());
|
|
int tmpIdx = 0;
|
|
for (auto& array : realRefArrayOnDir)
|
|
reducedG.GetAlignRuleWithTemplate(array, allArrays, allRules[tmpIdx++], regionId);
|
|
|
|
if (!isAllRulesEqual(allRules))
|
|
{
|
|
__spf_print(1, "not supported yet\n");
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
}
|
|
else
|
|
arrayRefOnDir = *(realRefArrayOnDir.begin());
|
|
}
|
|
else
|
|
arrayRefOnDir = *(realRefArrayOnDir.begin());
|
|
}
|
|
|
|
// for all array accesses in loop
|
|
for (auto& array : currInfo)
|
|
{
|
|
DIST::Array* arrayRef = array.first;
|
|
if (!arrayRef)
|
|
continue;
|
|
doneInLoops.insert(arrayRef);
|
|
|
|
const ArrayInfo* currArrayInfo = array.second;
|
|
|
|
set<DIST::Array*> realArrayRef;
|
|
getRealArrayRefs(arrayRef, arrayRef, realArrayRef, arrayLinksByFuncCalls);
|
|
|
|
for (auto& elem : realArrayRef)
|
|
{
|
|
arrayRef = elem;
|
|
|
|
// fill links between current array and array in parallel dir
|
|
vector<int> links;
|
|
if (arrayRef != arrayRefOnDir)
|
|
links = findLinksBetweenArrays(arrayRef, arrayRefOnDir, regionId);
|
|
else
|
|
{
|
|
links.resize(arrayRef->GetDimSize());
|
|
for (int k = 0; k < arrayRef->GetDimSize(); ++k)
|
|
links[k] = k;
|
|
}
|
|
|
|
//fill info links with template
|
|
auto linksWithTempl = arrayRef->GetLinksWithTemplate(regionId);
|
|
auto alignRuleWithTempl = arrayRef->GetAlignRulesWithTemplate(regionId);
|
|
|
|
const DIST::Array* templArray = arrayRef->GetTemplateArray(regionId);
|
|
if (!templArray)
|
|
continue; // may be error?
|
|
|
|
DIST::Array* templRefOnDir = arrayRefOnDir;
|
|
if (!templRefOnDir->IsTemplate())
|
|
templRefOnDir = templRefOnDir->GetTemplateArray(regionId);
|
|
|
|
if (templArray != templRefOnDir) // different templates
|
|
{
|
|
doneInLoops.erase(array.first);
|
|
continue;
|
|
}
|
|
|
|
|
|
// fill distribute data variant
|
|
const DistrVariant* distrVar = NULL;
|
|
for (int k = 0; k < data.distrRules.size(); ++k)
|
|
{
|
|
if (data.distrRules[k].first == templArray)
|
|
{
|
|
distrVar = &data.distrRules[k].second[currVar[k]];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!distrVar)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
// set new redistribute rule, if exist
|
|
const DistrVariant* newDistVar = currLoop->getRedistributeRule(templArray);
|
|
if (newDistVar)
|
|
distrVar = newDistVar;
|
|
|
|
set<string> parallelVars;
|
|
parallelVars.insert(parDir->parallel.begin(), parDir->parallel.end());
|
|
|
|
vector<string> mapToLoop;
|
|
for (int i = 0; i < links.size(); ++i)
|
|
{
|
|
if (links[i] != -1 && linksWithTempl[i] != -1)
|
|
{
|
|
bool isCorrect = false;
|
|
const bool isInParallel = parallelVars.find(parDir->on[links[i]].first) != parallelVars.end();
|
|
if (distrVar->distRule[linksWithTempl[i]] == BLOCK)
|
|
{
|
|
if (parDir->on[links[i]].first != "*" && isInParallel)
|
|
isCorrect = true;
|
|
else
|
|
isCorrect = false;
|
|
}
|
|
if (isCorrect)
|
|
mapToLoop.push_back(parDir->on[links[i]].first);
|
|
else
|
|
mapToLoop.push_back("");
|
|
}
|
|
else
|
|
mapToLoop.push_back("");
|
|
}
|
|
|
|
// main check
|
|
for (int i = 0; i < links.size(); ++i)
|
|
{
|
|
bool needToCheck = false;
|
|
if (links[i] != -1 && linksWithTempl[i] != -1)
|
|
{
|
|
const bool isInParallel = parallelVars.find(parDir->on[links[i]].first) != parallelVars.end();
|
|
if (distrVar->distRule[linksWithTempl[i]] == BLOCK)
|
|
{
|
|
if (parDir->on[links[i]].first != "*" && !isInParallel)
|
|
needToCheck = false;
|
|
else
|
|
needToCheck = true;
|
|
}
|
|
}
|
|
else if (linksWithTempl[i] != -1)
|
|
{
|
|
// if distributed and used in loop with out link with array on dir
|
|
if (distrVar->distRule[linksWithTempl[i]] == BLOCK)
|
|
{
|
|
// check all unrecognized refs
|
|
for (auto& unrec : currArrayInfo->arrayAccessUnrec)
|
|
{
|
|
if (addedRemotes.find(unrec.first) != addedRemotes.end())
|
|
continue;
|
|
else if (unrec.second.second[i] == REMOTE_TRUE)
|
|
{
|
|
addRemoteLink(currLoop, funcMap, unrec.first, uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, unrec.second.first);
|
|
__spf_print(DEB, "CRIP: %d, REMOTE_TRUE\n", __LINE__);
|
|
}
|
|
}
|
|
|
|
// check all regular refs
|
|
for (auto& reg : currArrayInfo->arrayAccess)
|
|
{
|
|
if (addedRemotes.find(reg.first) != addedRemotes.end())
|
|
continue;
|
|
|
|
if (arrayRef == arrayRefOnDir)
|
|
continue;
|
|
|
|
addRemoteLink(currLoop, funcMap, reg.first, uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, reg.second.first);
|
|
__spf_print(DEB, "CRIP: %d, IRREG_REFS\n", __LINE__);
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// check if current dimention is distributed
|
|
if (needToCheck)
|
|
{
|
|
// check unregular acceses
|
|
for (auto& unrec : currArrayInfo->arrayAccessUnrec)
|
|
{
|
|
if (addedRemotes.find(unrec.first) != addedRemotes.end())
|
|
continue;
|
|
|
|
if (unrec.second.second[i] == REMOTE_TRUE)
|
|
{
|
|
addRemoteLink(currLoop, funcMap, unrec.first, uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, unrec.second.first);
|
|
__spf_print(DEB, "CRIP: %d, IRREG_REFS && REMOTE_TRUE\n", __LINE__);
|
|
}
|
|
}
|
|
|
|
// and check regular acceses
|
|
for (auto& regAccess : currArrayInfo->arrayAccess)
|
|
{
|
|
if (addedRemotes.find(regAccess.first) != addedRemotes.end())
|
|
continue;
|
|
|
|
if (arrayRef == arrayRefOnDir)
|
|
continue;
|
|
|
|
//if has reads in more than one dim and it dims are dirstributed
|
|
int countOfDimAcc = 0;
|
|
for (int z = 0; z < linksWithTempl.size(); ++z)
|
|
{
|
|
bool distributed = false;
|
|
if (linksWithTempl[z] != -1)
|
|
distributed = (distrVar->distRule[linksWithTempl[z]] == BLOCK);
|
|
|
|
countOfDimAcc += ((regAccess.second.second[z].coefficients.size() != 0) && distributed) ? 1 : 0;
|
|
}
|
|
|
|
if (countOfDimAcc > 1 ||
|
|
countOfDimAcc == 1 && parDir->on[links[i]].first == "*")
|
|
{
|
|
addRemoteLink(currLoop, funcMap, regAccess.first, uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, regAccess.second.first);
|
|
__spf_print(DEB, "CRIP: %d ---\n", __LINE__);
|
|
continue;
|
|
}
|
|
|
|
//if has distributed dim but loop maped to *
|
|
if (parDir->on[links[i]].first == "*")
|
|
{
|
|
if (linksWithTempl[i] != -1)
|
|
if (distrVar->distRule[linksWithTempl[i]] == BLOCK)
|
|
{
|
|
addRemoteLink(currLoop, funcMap, regAccess.first, uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, regAccess.second.first);
|
|
__spf_print(DEB, "CRIP: %d, NOT MAPPED\n", __LINE__);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//if this array has no map rules to current array and this dim is distributed
|
|
if (currLoop->directiveForLoop)
|
|
{
|
|
if (currLoop->directiveForLoop->on[links[i]].first != "*")
|
|
{
|
|
if (regAccess.second.second[i].coefficients.size() == 0)
|
|
{
|
|
addRemoteLink(currLoop, funcMap, regAccess.first, uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, regAccess.second.first);
|
|
__spf_print(DEB, "CRIP: %d, ----\n", __LINE__);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// check with loop alignment
|
|
auto itRegRemote = remoteRegularReadsOfTopLoop.find(array.first);
|
|
if (itRegRemote != remoteRegularReadsOfTopLoop.end())
|
|
{
|
|
bool wasAdd = false;
|
|
for (auto& reads : regAccess.second.second[i].coefficients)
|
|
{
|
|
const pair<int, int>& currReadAcc = reads.first;
|
|
for (auto& ref : itRegRemote->second[i].coefficients)
|
|
{
|
|
if (ref.first == currReadAcc)
|
|
{
|
|
addRemoteLink(currLoop, funcMap, regAccess.first, uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, regAccess.second.first);
|
|
__spf_print(DEB, "CRIP: %d, MISS\n", __LINE__);
|
|
wasAdd = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (wasAdd)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} // main check
|
|
}
|
|
}
|
|
|
|
if (currLoop->perfectLoop > 1)
|
|
{
|
|
pair<LoopGraph*, const ParallelDirective*> nextDir = under_dvm_dir;
|
|
nextDir.first = currLoop->children[0];
|
|
|
|
createRemoteInParallel(remoteRegularReadsOfTopLoop, nextDir, allArrays, loopInfo, reducedG, data, currVar, uniqRemotes, messages, regionId, arrayLinksByFuncCalls, doneInLoops, funcMap);
|
|
}
|
|
}
|
|
|
|
map<string, ArrayRefExp*>
|
|
createRemoteInParallel(const pair<LoopGraph*, const ParallelDirective*> under_dvm_dir,
|
|
const DIST::Arrays<int>& allArrays,
|
|
const map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>& loopInfo,
|
|
DIST::GraphCSR<int, double, attrType>& reducedG,
|
|
const DataDirective& data,
|
|
const vector<int>& currVar,
|
|
vector<Messages>& messages,
|
|
const uint64_t regionId,
|
|
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
|
|
const map<string, FuncInfo*>& funcMap)
|
|
{
|
|
map<string, ArrayRefExp*> uniqRemotes;
|
|
set<DIST::Array*> doneInLoops;
|
|
|
|
createRemoteInParallel(under_dvm_dir.first->remoteRegularReads, under_dvm_dir, allArrays, loopInfo, reducedG, data, currVar, uniqRemotes, messages, regionId, arrayLinksByFuncCalls, doneInLoops, funcMap);
|
|
createRemoteInParallel(under_dvm_dir, doneInLoops, funcMap, uniqRemotes, messages, data, currVar, regionId, arrayLinksByFuncCalls);
|
|
|
|
return uniqRemotes;
|
|
}
|
|
|
|
static void addInfoToMap(map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>& loopInfo, LoopGraph* position, DIST::Array* array,
|
|
ArrayRefExp* arrayRef, const int dimNum, const REMOTE_TYPE& value, const int currLine,
|
|
const int maxDimSize, vector<RemoteRequest>& requests)
|
|
{
|
|
requests.push_back(RemoteRequest(position, dimNum, value, currLine, maxDimSize));
|
|
|
|
auto it = loopInfo.find(position);
|
|
if (loopInfo.end() == it)
|
|
it = loopInfo.insert(it, make_pair(position, map<DIST::Array*, ArrayInfo*>()));
|
|
|
|
auto it1 = it->second.find(array);
|
|
if (it1 == it->second.end())
|
|
it1 = it->second.insert(it1, make_pair(array, new ArrayInfo()));
|
|
|
|
auto it2 = it1->second->arrayAccessUnrec.find(arrayRef);
|
|
if (it2 == it1->second->arrayAccessUnrec.end())
|
|
{
|
|
it2 = it1->second->arrayAccessUnrec.insert(it2, make_pair(arrayRef, make_pair(currLine, vector<REMOTE_TYPE>())));
|
|
|
|
it2->second.second.resize(maxDimSize);
|
|
std::fill(it2->second.second.begin(), it2->second.second.end(), REMOTE_NONE);
|
|
}
|
|
|
|
if (dimNum == -1)
|
|
{
|
|
for (int z = 0; z < it2->second.second.size(); ++z)
|
|
it2->second.second[z] |= value;
|
|
}
|
|
else
|
|
it2->second.second[dimNum] |= value;
|
|
|
|
if (value == REMOTE_TRUE)
|
|
__spf_print(DEB, "RemoteAccess[%d]: true for dim %d and array %s, loop line %d\n", __LINE__, dimNum, array->GetShortName().c_str(), position->lineNum);
|
|
}
|
|
|
|
static pair<DIST::Array*, const DistrVariant*>
|
|
getDistrVariant(const vector<pair<DIST::Array*, vector<DistrVariant>>>& distrRules,
|
|
DIST::Array* forTempl, const vector<int>& currentVariant)
|
|
{
|
|
pair<DIST::Array*, const DistrVariant*> currentVar;
|
|
for (int z1 = 0; z1 < currentVariant.size(); ++z1)
|
|
{
|
|
if (distrRules[z1].first == forTempl)
|
|
{
|
|
currentVar = make_pair(distrRules[z1].first, &distrRules[z1].second[currentVariant[z1]]);
|
|
break;
|
|
}
|
|
}
|
|
if (!currentVar.first)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
return currentVar;
|
|
}
|
|
|
|
// call this function for each array reference under loop(s)
|
|
vector<RemoteRequest>
|
|
checkArrayRefInLoopForRemoteStatus(bool ifUnknownArrayAssignFound,
|
|
int sumMatched, // sum of matched dimensions of 'arrayRef' to each 'parentLoops'
|
|
int numOfSubs, // number of subscriptions of 'arrayRef'
|
|
int maxMatched, // maximum numbe of matched dimensions of 'arrayRef' to each 'parentLoops'
|
|
int currLine, // current line in source code of 'arrayRef'
|
|
DIST::Array* currArray, // DIST::Array of 'arrayRef'
|
|
vector<int>& wasFoundForLoop, // size == 'parentLoops'.size(), init value -> 0, each position is sum of match dims count of 'arrayRef'
|
|
ArrayRefExp* arrayRef, // current expression of array ref under all 'parentLoops',
|
|
map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>& loopInfo,
|
|
const vector<int>& matchedToDim, // size == 'parentLoops'.size(), init value -> -1, each position is dimension of match 'arrayRef' for 'parentLoop'
|
|
const map<int, LoopGraph*>& sortedLoopGraph,
|
|
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
|
|
const ParallelRegion* region,
|
|
const vector<LoopGraph*>& parentLoops) // all loops which are associated with 'arrayRef'
|
|
{
|
|
vector<RemoteRequest> requests;
|
|
if (sumMatched != parentLoops.size() && sumMatched == numOfSubs)
|
|
{
|
|
set<DIST::Array*> realArrayRefs;
|
|
getRealArrayRefs(currArray, currArray, realArrayRefs, arrayLinksByFuncCalls);
|
|
|
|
bool ok = true;
|
|
DIST::Array* templ = NULL;
|
|
vector<int> alignCoefs;
|
|
for (auto& real : realArrayRefs)
|
|
{
|
|
DIST::Array* curr = real->GetTemplateArray(region->GetId(), false);
|
|
alignCoefs = real->GetLinksWithTemplate(region->GetId());
|
|
|
|
if (templ == NULL)
|
|
templ = curr;
|
|
else if (templ != curr)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
}
|
|
|
|
string debOutStr = "";
|
|
char buf[256];
|
|
sprintf(buf, "RemoteAccess[%d]: check aligns for '%s'\n", __LINE__, currArray->GetShortName().c_str());
|
|
debOutStr += buf;
|
|
|
|
for (int z = 0; z < wasFoundForLoop.size(); ++z)
|
|
{
|
|
sprintf(buf, "RemoteAccess[%d]: check aligns %d == %d\n", __LINE__, z, wasFoundForLoop[z]);
|
|
debOutStr += buf;
|
|
}
|
|
|
|
for (int z = 0; z < matchedToDim.size(); ++z)
|
|
{
|
|
sprintf(buf, "RemoteAccess[%d]: matchedToDim[%d] = %d\n", __LINE__, z, matchedToDim[z]);
|
|
debOutStr += buf;
|
|
}
|
|
|
|
for (int l = 0; l < alignCoefs.size(); ++l)
|
|
{
|
|
sprintf(buf, "RemoteAccess[%d]: alignCoefs[%d] = %d\n", __LINE__, l, alignCoefs[l]);
|
|
debOutStr += buf;
|
|
}
|
|
|
|
//check array's alignment
|
|
for (int z = 0; z < wasFoundForLoop.size() && ok; ++z)
|
|
{
|
|
auto it = sortedLoopGraph.find(parentLoops[z]->lineNum);
|
|
if (it == sortedLoopGraph.end())
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
if (!templ)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
const DataDirective& dataDirectives = region->GetDataDir();
|
|
const vector<int>& currentVariant = region->GetCurrentVariant();
|
|
|
|
pair<DIST::Array*, const DistrVariant*> currentVar = getDistrVariant(dataDirectives.distrRules, templ, currentVariant);
|
|
|
|
LoopGraph* loop = it->second;
|
|
if (!loop->directiveForLoop)
|
|
{
|
|
if (wasFoundForLoop[z])
|
|
{
|
|
if (matchedToDim[z] != -1 && alignCoefs[matchedToDim[z]] != -1 &&
|
|
currentVar.second->distRule[alignCoefs[matchedToDim[z]]] == distType::BLOCK)
|
|
{
|
|
ok = false;
|
|
if (!ok)
|
|
{
|
|
__spf_print(DEB, "%s\n", debOutStr.c_str());
|
|
__spf_print(DEB, "RemoteAccess[%d]: call addInfoMaps from aligns miss\n", __LINE__);
|
|
__spf_print(DEB, "RemoteAccess[%d]: z = %d\n", __LINE__, z);
|
|
addInfoToMap(loopInfo, parentLoops[z], currArray, arrayRef, matchedToDim[z], REMOTE_TRUE, currLine, numOfSubs, requests);
|
|
}
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
//apply redistribute
|
|
if (loop->getRedistributeRule(currentVar.first) != NULL)
|
|
currentVar.second = loop->getRedistributeRule(currentVar.first);
|
|
|
|
DIST::Array* loopT = loop->directiveForLoop->arrayRef;
|
|
sprintf(buf, "RemoteAccess[%d]: z = %d, array '%s'\n", __LINE__, z, loopT->GetShortName().c_str());
|
|
debOutStr += buf;
|
|
|
|
int dimToMap = -1;
|
|
for (int z1 = 0; z1 < loopT->GetDimSize(); ++z1)
|
|
if (loop->directiveForLoop->on[z1].first != "*")
|
|
dimToMap = z1;
|
|
|
|
sprintf(buf, "RemoteAccess[%d]: z = %d, dimToMap = %d\n", __LINE__, z, dimToMap);
|
|
debOutStr += buf;
|
|
if (dimToMap != -1)
|
|
{
|
|
if (loopT != templ && !loopT->IsTemplate())
|
|
{
|
|
sprintf(buf, "RemoteAccess[%d]: z = %d, false check !=\n", __LINE__, z);
|
|
debOutStr += buf;
|
|
|
|
DIST::Array* loopTempl = loopT->GetTemplateArray(region->GetId(), false);
|
|
vector<int> loopAlignCoefs = loopT->GetLinksWithTemplate(region->GetId());
|
|
|
|
if (loopTempl == NULL)
|
|
{
|
|
set<DIST::Array*> tmpSet;
|
|
getRealArrayRefs(loopT, loopT, tmpSet, arrayLinksByFuncCalls);
|
|
|
|
set<DIST::Array*> templates;
|
|
for (auto& elem : tmpSet)
|
|
{
|
|
loopTempl = elem->GetTemplateArray(region->GetId(), false);
|
|
loopAlignCoefs = elem->GetLinksWithTemplate(region->GetId());
|
|
templates.insert(loopTempl);
|
|
}
|
|
|
|
if (templates.size() != 1)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
}
|
|
|
|
if (loopTempl)
|
|
{
|
|
sprintf(buf, "RemoteAccess[%d]: z = %d, array '%s'\n", __LINE__, z, loopTempl->GetShortName().c_str());
|
|
debOutStr += buf;
|
|
}
|
|
|
|
if (templ != loopTempl)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
if (loopAlignCoefs.size() == 0)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
if (loopAlignCoefs.size() <= dimToMap)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
if (loopAlignCoefs[dimToMap] == -1)
|
|
{
|
|
//TODO: need more tests for this case: prev bug => bugreport_1676461809
|
|
/*if (loop->hasParalleDirectiveBefore())
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
else*/
|
|
continue;
|
|
}
|
|
else
|
|
dimToMap = loopAlignCoefs[dimToMap];
|
|
}
|
|
else if (loopT != templ && loopT->IsTemplate())
|
|
{
|
|
bool isDistr = false;
|
|
for (auto& elem : currentVar.second->distRule)
|
|
if (elem == BLOCK)
|
|
isDistr = true;
|
|
|
|
if (isDistr)
|
|
{
|
|
ok = false;
|
|
__spf_print(DEB, "%s\n", debOutStr.c_str());
|
|
__spf_print(DEB, "RemoteAccess[%d]: call addInfoMaps from template miss\n", __LINE__);
|
|
__spf_print(DEB, "RemoteAccess[%d]: z = %d\n", __LINE__, z);
|
|
addInfoToMap(loopInfo, parentLoops[z], currArray, arrayRef, matchedToDim[z], REMOTE_TRUE, currLine, numOfSubs, requests);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
sprintf(buf, "RemoteAccess[%d]: ** z = %d, dimToMap = %d\n", __LINE__, z, dimToMap);
|
|
debOutStr += buf;
|
|
|
|
for (int z = 0; z < currentVar.second->distRule.size(); ++z)
|
|
{
|
|
sprintf(buf, "RemoteAccess[%d]: distRule[%d] = %d\n", __LINE__, z, currentVar.second->distRule[z]);
|
|
debOutStr += buf;
|
|
}
|
|
|
|
if (wasFoundForLoop[z])
|
|
{
|
|
if (matchedToDim[z] != -1 && currentVar.second->distRule[alignCoefs[matchedToDim[z]]] == distType::BLOCK)
|
|
{
|
|
bool found = false;
|
|
|
|
for (int l = 0; l < alignCoefs.size(); ++l)
|
|
{
|
|
if (alignCoefs[l] == dimToMap)
|
|
found = true;
|
|
}
|
|
ok = found;
|
|
|
|
if (!ok)
|
|
{
|
|
__spf_print(DEB, "%s\n", debOutStr.c_str());
|
|
__spf_print(DEB, "RemoteAccess[%d]: call addInfoMaps from aligns miss\n", __LINE__);
|
|
__spf_print(DEB, "RemoteAccess[%d]: z = %d\n", __LINE__, z);
|
|
__spf_print(DEB, "RemoteAccess[%d]: dimToMap = %d\n", __LINE__, dimToMap);
|
|
addInfoToMap(loopInfo, parentLoops[z], currArray, arrayRef, matchedToDim[z], REMOTE_TRUE, currLine, numOfSubs, requests);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bool distrAny = false;
|
|
bool distrAll = true;
|
|
int dDim = -1;
|
|
|
|
for (int idx = 0; idx < alignCoefs.size(); ++idx)
|
|
{
|
|
if (currentVar.second->distRule[idx] == distType::BLOCK)
|
|
{
|
|
dDim = idx;
|
|
distrAny = true;
|
|
}
|
|
else
|
|
distrAll = false;
|
|
}
|
|
|
|
|
|
if (matchedToDim[z] == -1 && distrAny && !distrAll)
|
|
{
|
|
ok = false;
|
|
if (!ok)
|
|
{
|
|
__spf_print(DEB, "%s\n", debOutStr.c_str());
|
|
__spf_print(DEB, "RemoteAccess[%d]: call addInfoMaps from aligns miss\n", __LINE__);
|
|
__spf_print(DEB, "RemoteAccess[%d]: z = %d\n", __LINE__, z);
|
|
__spf_print(DEB, "RemoteAccess[%d]: dimToMap = %d\n", __LINE__, dimToMap);
|
|
addInfoToMap(loopInfo, parentLoops[z], currArray, arrayRef, dDim, REMOTE_TRUE, currLine, numOfSubs, requests);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ok && currArray->GetDimSize() > 1)
|
|
for (int z = 0; z < wasFoundForLoop.size(); ++z)
|
|
wasFoundForLoop[z] = 1;
|
|
}
|
|
|
|
if (ifUnknownArrayAssignFound)
|
|
{
|
|
if (sumMatched != numOfSubs ||
|
|
maxMatched != 1 ||
|
|
(sumMatched != parentLoops.size() && sumMatched != numOfSubs))
|
|
{
|
|
int local = 0;
|
|
bool hasLimits = false;
|
|
for (int i = 0; i < wasFoundForLoop.size(); ++i)
|
|
{
|
|
if (wasFoundForLoop[i] == 1)
|
|
{
|
|
auto itLoop = sortedLoopGraph.find(parentLoops[i]->lineNum);
|
|
if (itLoop == sortedLoopGraph.end())
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
if (itLoop->second->hasLimitsToParallel())
|
|
hasLimits = true;
|
|
}
|
|
}
|
|
for (int i = 0; i < wasFoundForLoop.size(); ++i)
|
|
{
|
|
if (wasFoundForLoop[i] != 1)
|
|
{
|
|
for (int k = 0; k < numOfSubs; ++k)
|
|
{
|
|
if (hasLimits)
|
|
{
|
|
__spf_print(DEB, "RemoteAccess[%d]: call addInfoMaps from hasLimits\n", __LINE__);
|
|
addInfoToMap(loopInfo, parentLoops[i], currArray, arrayRef, k, REMOTE_TRUE, currLine, numOfSubs, requests);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return requests;
|
|
} |