diff --git a/projects/dvm b/projects/dvm index a711f8e..6a86c96 160000 --- a/projects/dvm +++ b/projects/dvm @@ -1 +1 @@ -Subproject commit a711f8ebfd023ca90a6d9c9bdf5a4726cd276d51 +Subproject commit 6a86c96abec37282bc2aaa8f11b047d1d3f0b84e diff --git a/projects/libpredictor b/projects/libpredictor index d0772cd..840f9d9 160000 --- a/projects/libpredictor +++ b/projects/libpredictor @@ -1 +1 @@ -Subproject commit d0772cdb57432b8c96ce634687641b1c8c76d21c +Subproject commit 840f9d9c1ad579825d81c46cdf70877c497fecca diff --git a/src/DirectiveProcessing/directive_creator_base.cpp b/src/DirectiveProcessing/directive_creator_base.cpp index 3747126..6a7f183 100644 --- a/src/DirectiveProcessing/directive_creator_base.cpp +++ b/src/DirectiveProcessing/directive_creator_base.cpp @@ -1601,7 +1601,7 @@ static bool matchParallelAndDist(const pair& parallelOn = NULL; for (auto& refOn : realRefs) { - linkWithTempl = parallelOn->GetLinksWithTemplate(regionId); + linkWithTempl = refOn->GetLinksWithTemplate(regionId); int z = 0; for (int k = 0; k < linkWithTempl.size(); ++k) if (linkWithTempl[k] != -1) diff --git a/src/Distribution/Array.h b/src/Distribution/Array.h index dd9f615..652200f 100644 --- a/src/Distribution/Array.h +++ b/src/Distribution/Array.h @@ -1,872 +1,830 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "DvmhDirectiveBase.h" -#include "../Utils/utils.h" -#include "../Utils/errors.h" -#include "../Utils/json.hpp" - -class Symbol; -class Expression; -struct FuncInfo; - -#define STRING std::string -#define VECTOR std::vector -#define PAIR std::pair -#define MAP std::map -#define SET std::set -#define TO_STR std::to_string -#define JSON nlohmann::json - -#if __SPF -extern int sharedMemoryParallelization; -#endif - -namespace Distribution -{ - typedef enum distFlag : int { DISTR = 0, NO_DISTR, SPF_PRIV, IO_PRIV } distFlagType; - typedef enum arrayLocation : int { l_LOCAL = 0, l_COMMON, l_MODULE, l_PARAMETER, l_STRUCT, l_LOCAL_SAVE } arrayLocType; - - class Array; - - class TemplateLink - { - private: - VECTOR linkWithTemplate; - VECTOR> alignRuleWithTemplate; - Array *templateArray; - - public: - TemplateLink(const int dimSize) - { - linkWithTemplate.resize(dimSize); - alignRuleWithTemplate.resize(dimSize); - for (int i = 0; i < dimSize; ++i) - linkWithTemplate[i] = -1; - templateArray = NULL; - } - - TemplateLink(const TemplateLink ©) - { - linkWithTemplate = copy.linkWithTemplate; - alignRuleWithTemplate = copy.alignRuleWithTemplate; - templateArray = copy.templateArray; - } - - Array* GetTemplateArray() const { return templateArray; } - VECTOR> GetAlignRules() const; - VECTOR GetLinks() const; - void AddRule(const int dimNum, int value, const PAIR &rule, Array *templateArray_); - STRING toString() const; - }; - - class Array - { - private: - unsigned id; - STRING name; - STRING shortName; - int dimSize; - int typeSize; // size of one element of array - // calculated sizes - VECTOR> sizes; - // original sizes + shifts - VECTOR>, PAIR>>> sizesExpr; - - VECTOR> orderedSizes; - VECTOR>, PAIR>>> orderedSizesExpr; - - // template info by region - MAP templateInfo; - bool isTemplFlag; - bool isLoopArrayFlag; - distFlag isNonDistribute; - Symbol *declSymbol; - STRING uniqKey; - - // PAIR - SET> declPlaces; - MAP, Symbol*> declPlacesSymbol; - //file-> map[incFile, line] -> symbol - MAP, Symbol*>> declPlacesSymbolByFile; - - //TYPE: 0 - local, 1 - common, 2 - module, 3 - function parameter - // PAIR - PAIR locationPos; - VECTOR>> allShadowSpecs; - - SET containsInRegions; - - // file -> lines - MAP> usagePlaces; - - VECTOR mappedDims; - VECTOR depracateToDistribute; - - bool ompThreadPrivate; - bool privateInLoop; - bool inEquivalence; - private: - TemplateLink* getTemlateInfo(const uint64_t regionId, bool withCheck = false) - { - auto it = templateInfo.find(regionId); - TemplateLink *currLink = NULL; - if (it == templateInfo.end()) - { -#if __SPF - if (withCheck && sharedMemoryParallelization != 0) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); -#endif - currLink = new TemplateLink(dimSize); - templateInfo[regionId] = currLink; - } - else - currLink = it->second; - return currLink; - } - - void GenUniqKey() - { - uniqKey = shortName + locationPos.second + TO_STR(dimSize); - for (auto &place : declPlaces) - uniqKey += place.first + TO_STR(place.second); - } - - //clones of template for realignes - MAP, STRING> templateClones; - VECTOR templateDimsOrder; - - public: - Array() - { - isTemplFlag = false; - isLoopArrayFlag = false; - isNonDistribute = NO_DISTR; - typeSize = 0; - uniqKey = ""; - dimSize = 0; - id = -1; - declSymbol = NULL; - ompThreadPrivate = false; - privateInLoop = false; - inEquivalence = false; - } - - Array(const STRING &name, const STRING &shortName, const int dimSize, const unsigned id, - const STRING &declFile, const int declLine, const PAIR &locationPos, - Symbol *declSymbol, bool inOmpThreadPriv, bool privateInLoop, bool inEquivalence, - const VECTOR ®ions, const int typeSize, const distFlag flag = DISTR) : - - name(name), dimSize(dimSize), id(id), shortName(shortName), - isTemplFlag(false), isNonDistribute(flag), isLoopArrayFlag(false), - locationPos(locationPos), declSymbol(declSymbol), typeSize(typeSize), - ompThreadPrivate(inOmpThreadPriv), privateInLoop(privateInLoop), inEquivalence(inEquivalence) - { - declPlaces.insert(std::make_pair(declFile, declLine)); - sizes.resize(dimSize); - sizesExpr.resize(dimSize); - mappedDims.resize(dimSize); - depracateToDistribute.resize(dimSize); - - for (int z = 0; z < dimSize; ++z) - { - sizes[z] = std::make_pair((int)INT_MAX, (int)INT_MIN); - PAIR initVal = std::make_pair(0, 0); - sizesExpr[z] = std::make_pair(std::make_pair((Expression*)NULL, initVal), std::make_pair((Expression*)NULL, initVal)); - mappedDims[z] = false; - depracateToDistribute[z] = false; - } - - GenUniqKey(); - for (auto ® : regions) - containsInRegions.insert(reg); - } - - Array(const Array ©) - { - id = copy.id; - name = copy.name; - shortName = copy.shortName; - dimSize = copy.dimSize; - typeSize = copy.typeSize; - - sizes = copy.sizes; - sizesExpr = copy.sizesExpr; - - isTemplFlag = copy.isTemplFlag; - isNonDistribute = copy.isNonDistribute; - isLoopArrayFlag = copy.isLoopArrayFlag; - - declPlaces = copy.declPlaces; - locationPos = copy.locationPos; - - allShadowSpecs = copy.allShadowSpecs; - - for (auto &elem : copy.templateInfo) - templateInfo[elem.first] = new TemplateLink(*elem.second); - - declSymbol = copy.declSymbol; - uniqKey = copy.uniqKey; - containsInRegions = copy.containsInRegions; - mappedDims = copy.mappedDims; - depracateToDistribute = copy.depracateToDistribute; - ompThreadPrivate = copy.ompThreadPrivate; - privateInLoop = copy.privateInLoop; - inEquivalence = copy.inEquivalence; - } - - bool RemoveUnpammedDims() - { - bool needToRemove = false; - int countToRem = 0; - for (int z = 0; z < dimSize; ++z) - { - if (!mappedDims[z] || depracateToDistribute[z]) - { - needToRemove = true; - countToRem++; - //break; - } - } - - if (needToRemove == false) - return false; - if (countToRem == dimSize) - return true; - - VECTOR> newSizes; - VECTOR>, PAIR>>> newSizesExpr; - VECTOR newMappedDims; - VECTOR newDepr; - - for (int z = 0; z < dimSize; ++z) - { - if (mappedDims[z] && !depracateToDistribute[z]) - { - newSizes.push_back(sizes[z]); - newSizesExpr.push_back(sizesExpr[z]); - newMappedDims.push_back(mappedDims[z]); - newDepr.push_back(depracateToDistribute[z]); - } - } - - sizes = newSizes; - sizesExpr = newSizesExpr; - mappedDims = newMappedDims; - depracateToDistribute = newDepr; - dimSize = (int)sizes.size(); - - return false; - } - - int GetDimSize() const { return dimSize; } - const STRING GetName() const { return name; } - const STRING GetShortName() const { return shortName; } - const STRING GetNameInLocation(void* location) const; - void* GetNameInLocationS(void* location) const; - - unsigned GetId() const { return id; } - void SetSizes(VECTOR> &_sizes, bool notCopyToExpr = false) - { - sizes = _sizes; - if (!notCopyToExpr) - { - for (int i = 0; i < sizesExpr.size(); ++i) - { - sizesExpr[i].first.second.first = sizes[i].first; - sizesExpr[i].second.second.first = sizes[i].second; - } - } - } - const VECTOR>& GetSizes(); - const VECTOR>, PAIR>>>& GetSizesExpr(); - void SetTemplateFlag(const bool templFlag) { isTemplFlag = templFlag; } - bool IsTemplate() const { return isTemplFlag; } - bool IsLoopArray() const { return isLoopArrayFlag; } - bool IsArray() const { return !isTemplFlag && !isLoopArrayFlag; } - void SetLoopArray(const bool flag) { isLoopArrayFlag = flag; } - void SetSizesExpr(const VECTOR> &_sizesExpr) - { - for (int i = 0; i < _sizesExpr.size(); ++i) - { - sizesExpr[i].first.first = _sizesExpr[i].first; - sizesExpr[i].second.first = _sizesExpr[i].second; - } - } - - int AddLinkWithTemplate(const int dimNum, const int dimTempl, Array *templateArray_, const PAIR &rule, const uint64_t regionId) - { - int err = 0; - if (dimNum >= dimSize) - err = -1; - else - { - TemplateLink *currLink = getTemlateInfo(regionId, templateArray_ == NULL); - currLink->AddRule(dimNum, dimTempl, rule, templateArray_); - } - return err; - } - - VECTOR GetLinksWithTemplate(const uint64_t regionId) - { - TemplateLink *currLink = getTemlateInfo(regionId, true); - return currLink->GetLinks(); - } - - VECTOR> GetAlignRulesWithTemplate(const uint64_t regionId) - { - TemplateLink *currLink = getTemlateInfo(regionId, true); - return currLink->GetAlignRules(); - } - - bool HasTemplateInfo(const uint64_t regionId) const - { - auto it = templateInfo.find(regionId); - return (it != templateInfo.end()); - } - - void ChangeName(const STRING &newName) - { - auto pos = name.find(shortName); - if (pos != STRING::npos) - { - name.erase(pos, shortName.size()); - shortName = newName; - name += newName; - } - GenUniqKey(); - } - - void ExtendDimSize(const int dim, const PAIR &size) - { - /*if (size.first == size.second) - return;*/ - - sizes[dim].first = std::min(sizes[dim].first, size.first); - sizes[dim].second = std::max(sizes[dim].second, size.second); - - PAIR &left = sizesExpr[dim].first.second; - PAIR &right = sizesExpr[dim].second.second; - - left.second = std::min(left.second, sizes[dim].first - left.first); - right.second = std::max(right.second, sizes[dim].second - right.first); - } - void SetId(const unsigned newId) { id = newId; } - - const SET>& GetDeclInfo() const { return declPlaces; } - const MAP, Symbol*>& GetDeclInfoWithSymb() const { return declPlacesSymbol; } - void AddDeclInfo(const PAIR &declInfo, const SET& allFilesInProj, - const STRING& currFile, Symbol* symb = NULL) - { - declPlaces.insert(declInfo); - if (symb) - { - declPlacesSymbol[declInfo] = symb; - if (allFilesInProj.find(declInfo.first) == allFilesInProj.end()) // from include - declPlacesSymbolByFile[currFile][declInfo] = symb; - } - GenUniqKey(); - } - - //save request of shadow spec - void ExtendShadowSpec(const VECTOR> &newSpec) - { - if (allShadowSpecs.size() == 0) - allShadowSpecs.resize(dimSize); - - const PAIR zeroPair(0, 0); - for (int i = 0; i < newSpec.size(); ++i) - if (newSpec[i] != zeroPair) - allShadowSpecs[i].push_back(newSpec[i]); - } - - //remove last requst of shadow spec - void RemoveShadowSpec(const VECTOR> &delSpec) - { - int dimN = 0; - for (auto &group : allShadowSpecs) - { - for (int i = 0; i < group.size(); ++i) - { - if (group[i] == delSpec[dimN]) - { - group.erase(group.begin() + i); - break; - } - } - ++dimN; - } - } - - //construct shadow spec from all requests - const VECTOR> GetShadowSpec() const - { - VECTOR> shadowSpec; - shadowSpec.resize(dimSize); - for (int i = 0; i < dimSize; ++i) - shadowSpec[i] = std::make_pair(0, 0); - - int dimN = 0; - for (auto &group : allShadowSpecs) - { - for (auto &elem : group) - { - shadowSpec[dimN].first = std::max(shadowSpec[dimN].first, elem.first); - shadowSpec[dimN].second = std::max(shadowSpec[dimN].second, elem.second); - } - ++dimN; - } - return shadowSpec; - } - - void ClearShadowSpecs() { allShadowSpecs.clear(); } - - //TODO: to remove - STRING toString() - { - STRING retVal = ""; - retVal += TO_STR(id); - retVal += "#" + name; - retVal += "#" + shortName; - retVal += "#" + TO_STR(dimSize); - retVal += "#" + TO_STR(typeSize); - retVal += "#" + TO_STR(isNonDistribute); - - retVal += "#" + TO_STR(locationPos.first); - retVal += "#" + locationPos.second; - - retVal += "#" + TO_STR(sizes.size()); - for (int i = 0; i < sizes.size(); ++i) - retVal += "#" + TO_STR(sizes[i].first) + "#" + TO_STR(sizes[i].second); - - retVal += "#" + TO_STR(depracateToDistribute.size()); - for (int i = 0; i < depracateToDistribute.size(); ++i) - retVal += "#" + TO_STR((int)depracateToDistribute[i]); - - retVal += "#" + TO_STR(mappedDims.size()); - for (int i = 0; i < mappedDims.size(); ++i) - retVal += "#" + TO_STR((int)mappedDims[i]); - - retVal += "#" + TO_STR(templateInfo.size()); - for (auto it = templateInfo.begin(); it != templateInfo.end(); ++it) - retVal += "#" + TO_STR(it->first) + it->second->toString(); - - retVal += "#" + TO_STR((int)isTemplFlag); - retVal += "|" + TO_STR((int)isLoopArrayFlag); - retVal += "|" + TO_STR(declPlaces.size()); - - for (auto &place : declPlaces) - retVal += "|" + place.first + "|" + TO_STR(place.second); - - retVal += "|" + TO_STR(containsInRegions.size()); - for (auto ® : containsInRegions) - retVal += "|" + reg; - return retVal; - } - - JSON toJson() - { - JSON retVal; - - retVal["id"] = (int64_t)id; - retVal["name"] = name; - retVal["shortName"] = shortName; - - retVal["dimSize"] = dimSize; - retVal["typeSize"] = typeSize; - retVal["state"] = (int)isNonDistribute; - retVal["location"] = (int)locationPos.first; - retVal["locName"] = locationPos.second; - - retVal["isTemplFlag"] = (int)isTemplFlag; - retVal["isLoopArrayFlag"] = (int)isLoopArrayFlag; - - JSON deprToDist = nlohmann::json::array(); - for (int i = 0; i < depracateToDistribute.size(); ++i) - deprToDist.push_back((int)depracateToDistribute[i]); - retVal["depracateToDist"] = deprToDist; - - JSON mappedDimsJ = nlohmann::json::array(); - for (int i = 0; i < mappedDims.size(); ++i) - mappedDimsJ.push_back((int)mappedDims[i]); - retVal["mappedDims"] = mappedDimsJ; - - JSON sizesJ = nlohmann::json::array(); - for (int i = 0; i < sizes.size(); ++i) - { - JSON pair; - pair["key"] = sizes[i].first; - pair["value"] = sizes[i].second; - sizesJ.push_back(pair); - } - retVal["sizes"] = sizesJ; - - JSON regions = nlohmann::json::array(); - for (auto& reg : containsInRegions) - regions.push_back(reg); - retVal["regions"] = regions; - - - JSON declPlacesJ = nlohmann::json::array(); - for (auto& place : declPlaces) - { - JSON elem; - elem["file"] = place.first; - elem["line"] = place.second; - - declPlacesJ.push_back(elem); - } - retVal["declPlaces"] = declPlacesJ; - - return retVal; - } - - Array* GetTemplateArray(const uint64_t regionId, bool withCheck = true) - { - TemplateLink *currLink = getTemlateInfo(regionId, withCheck); - return currLink->GetTemplateArray(); - } - - void SetDistributeFlag(const distFlag isNonDistribute_) { isNonDistribute = isNonDistribute_; } - bool IsNotDistribute() const { return (isNonDistribute == DISTR) ? false : true; } - distFlag GetDistributeFlagVal() const { return isNonDistribute; } - - void ChangeLocation(arrayLocation loc, const STRING &name) - { - locationPos = std::make_pair(loc, name); - } - - void SetLocation(arrayLocation loc, const STRING &name) - { - ChangeLocation(loc, name); - GenUniqKey(); - } - PAIR GetLocation() const { return locationPos; } - - Symbol* GetDeclSymbol(const STRING& file, const PAIR& range, const SET& allFilesInProj) const - { - if (!IsArray() || locationPos.first != l_COMMON) - return declSymbol; - - for (auto& pos : declPlacesSymbol) - { - if (pos.first.first == file) - { - const int line = pos.first.second; - if (range.first <= line && line <= range.second) - return pos.second; - } // may be in include? - else if (allFilesInProj.find(pos.first.first) == allFilesInProj.end() && allFilesInProj.size()) - { - auto it = declPlacesSymbolByFile.find(file); - if (it != declPlacesSymbolByFile.end() && it->second.find(pos.first) != it->second.end()) - { - auto s = it->second.find(pos.first); - return s->second; - } - else -#if __SPF - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); -#else - return NULL; -#endif - return NULL; - } - } -#if __SPF - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); -#endif - return NULL; - } - - Symbol* GetDeclSymbol() const { return declSymbol; } - void SetDeclSymbol(Symbol *s) { declSymbol = s; } - - const STRING& GetArrayUniqKey() const { return uniqKey; } - - STRING GetIndepUniqName() const { return shortName + locationPos.second + TO_STR(dimSize); } - - const SET& GetRegionsName() const { return containsInRegions; } - void SetRegionPlace(const STRING ®Name) { if (regName != "") containsInRegions.insert(regName); } - - const MAP>& GetUsagePlaces() const { return usagePlaces; } - const SET GetUsagePlaces(const STRING& fileName, const PAIR* filter = NULL) const - { - auto it = usagePlaces.find(fileName); - if (it == usagePlaces.end()) - return SET(); - if (!filter) - return it->second; - else - { - SET ret; - int first = filter->first; - int last = filter->second; - for (auto& elem : it->second) - if (first <= elem && elem <= last) - ret.insert(elem); - - return ret; - } - } - - void AddUsagePlace(const STRING &fileName, int lineNumber) - { - auto it = usagePlaces.find(fileName); - if (it == usagePlaces.end()) - it = usagePlaces.insert(it, make_pair(fileName, SET())); - it->second.insert(lineNumber); - } - - void SetMappedDim(const int dim) - { - if (dim >= dimSize) - return; - mappedDims[dim] = true; - } - - bool IsDimMapped(const int dim) const - { - if (dim >= dimSize) - return false; - else - { - if (templateDimsOrder.size() == 0) - return mappedDims[dim]; - else - return mappedDims[templateDimsOrder[dim]]; - } - } - - void DeprecateDimension(const int dim, bool value = true) - { - if (dim >= dimSize) - return; - depracateToDistribute[dim] = value; - } - - void DeprecateAllDims() - { - for (int dim = 0; dim < dimSize; ++dim) - depracateToDistribute[dim] = true; - } - - bool IsDimDepracated(const int dim) const - { - if (dim >= dimSize) - return false; - else - { - if (templateDimsOrder.size() == 0) - return depracateToDistribute[dim]; - else - return depracateToDistribute[templateDimsOrder[dim]]; - } - } - - bool IsAllDeprecated() const - { - bool ret = true; - for (int z = 0; z < dimSize; ++z) - ret = ret && depracateToDistribute[z]; - return ret; - } - - const VECTOR& GetDeprecetedDims() const { return depracateToDistribute; } - - int GetTypeSize() const { return typeSize; } - - STRING AddTemplateClone(const VECTOR &newDist) - { - auto it = templateClones.find(newDist); - if (it == templateClones.end()) - it = templateClones.insert(it, std::make_pair(newDist, shortName + STRING("_r") + TO_STR(templateClones.size()))); - return it->second; - } - - void ClearTemplateClones() - { - templateClones.clear(); - templateDimsOrder.clear(); - orderedSizes.clear(); - orderedSizesExpr.clear(); - } - - const MAP, STRING>& GetAllClones() const { return templateClones; } - - void AddNewTemplateDimsOrder(const VECTOR &newOrder) { templateDimsOrder = newOrder; } - - VECTOR GetNewTemplateDimsOrder() const { return templateDimsOrder; } - - void SetDimSizesToMaxMin(bool notCopyToExpr = false) - { - for (int i = 0; i < dimSize; ++i) - sizes[i] = std::make_pair((int)INT_MAX, (int)INT_MIN); - - if (!notCopyToExpr) - { - for (int i = 0; i < sizesExpr.size(); ++i) - { - sizesExpr[i].first.second.first = sizes[i].first; - sizesExpr[i].second.second.first = sizes[i].second; - } - } - } - - bool IsOmpThreadPrivate() const { return ompThreadPrivate; } - bool IsSpfPrivate() const { return ((isNonDistribute == SPF_PRIV) || (isNonDistribute == IO_PRIV)); } - - bool IsInEquvalence() const { return inEquivalence; } - void SetEquvalence(bool value) { inEquivalence = value; } - - bool IsPrivateInLoop() const { return privateInLoop; } - void SetPrivateInLoopStatus(bool value) { privateInLoop = value; } - - bool IsModuleSymbol() const { return locationPos.first == l_MODULE; } - - ~Array() - { - for (auto &templ : templateInfo) - delete templ.second; - } - }; - - struct ArrayComparator - { - bool operator()(const Array* left, const Array* right) const - { - return (left->GetArrayUniqKey() > right->GetArrayUniqKey()); - } - }; - - struct UnaryAccess - { - UnaryAccess() - { - line = -1; - type = -1; - underFunctionPar = -1; - fName = ""; - count = 0; - } - - UnaryAccess(const PAIR& info) - { - line = info.first; - type = info.second; - underFunctionPar = -1; - fName = ""; - count = 1; - } - - UnaryAccess(const PAIR& info, const STRING &f, const int parN) - { - line = info.first; - type = info.second; - underFunctionPar = parN; - fName = f; - count = 1; - } - - STRING PrintInfo() const - { - STRING out = "#" + std::to_string(count) + " of "; - if (type == 0) - out += "READ "; - else if(type == 1) - out += "WRITE "; - else - out += "UNKN "; - out += "on line " + std::to_string(line); - if (underFunctionPar != -1) - out += " in '#" + std::to_string(underFunctionPar + 1) + "' par of function call '" + fName + "'"; - return out; - } - - bool operator==(const UnaryAccess &left) const - { - return (line == left.line && type == left.type && - underFunctionPar == left.underFunctionPar && fName == left.fName); - } - - bool operator!=(const UnaryAccess& left) const - { - return !(*this == left); - } - - int line; - int type; // R/W -> 0, 1 - int underFunctionPar; - STRING fName; - int count; - }; - - class ArrayAccessInfo - { - private: - MAP>> accessPatterns; // file -> MAP - public: - void AddAccessInfo(const STRING& file, const PAIR &info, const STRING fName = "", int underParN = -1) - { - auto it = accessPatterns.find(file); - if (it == accessPatterns.end()) - it = accessPatterns.insert(it, std::make_pair(file, MAP>())); - - bool found = false; - UnaryAccess toAdd; - if (underParN == -1) - toAdd = UnaryAccess(info); - else - toAdd = UnaryAccess(info, fName, underParN); - - auto itMap = it->second.find(info.first); - if (itMap == it->second.end()) - it->second[info.first].push_back(toAdd); - else - { - for (int z = 0; z < itMap->second.size(); ++z) - { - if (itMap->second[z] == toAdd) - { - found = true; - itMap->second[z].count++; - break; - } - } - - if (found == false) - { - if (underParN == -1) - itMap->second.push_back(toAdd); - else - itMap->second.push_back(toAdd); - } - } - } - - void checkAndUpdate(const MAP& allFuncs); - const MAP>>& GetAllAccessInfo() const { return accessPatterns; } - const MAP>* GetAccessInfoByFile(const STRING &file) const - { - auto it = accessPatterns.find(file); - if (it == accessPatterns.end()) - return NULL; - else - return &(it->second); - } - }; - - void printArrayInfo(const STRING &file, const MAP, PAIR> &declaredArrays); - void fixTypeOfArrayInfoWithCallGraph(MAP, PAIR>& declaredArrays, const MAP& allFuncs); -} -#undef VECTOR -#undef STRING -#undef PAIR -#undef MAP -#undef SET +#pragma once + +#include +#include +#include +#include +#include +#include +#include "DvmhDirectiveBase.h" +#include "../Utils/utils.h" +#include "../Utils/errors.h" +#include "../Utils/json.hpp" + +class Symbol; +class Expression; +struct FuncInfo; + +#define STRING std::string +#define VECTOR std::vector +#define PAIR std::pair +#define MAP std::map +#define SET std::set +#define TO_STR std::to_string +#define JSON nlohmann::json + +#if __SPF +extern int sharedMemoryParallelization; +#endif + +namespace Distribution +{ + typedef enum distFlag : int { DISTR = 0, NO_DISTR, SPF_PRIV, IO_PRIV } distFlagType; + typedef enum arrayLocation : int { l_LOCAL = 0, l_COMMON, l_MODULE, l_PARAMETER, l_STRUCT, l_LOCAL_SAVE } arrayLocType; + + class Array; + + class TemplateLink + { + private: + VECTOR linkWithTemplate; + VECTOR> alignRuleWithTemplate; + Array *templateArray; + + public: + TemplateLink(const int dimSize) + { + linkWithTemplate.resize(dimSize); + alignRuleWithTemplate.resize(dimSize); + for (int i = 0; i < dimSize; ++i) + linkWithTemplate[i] = -1; + templateArray = NULL; + } + + TemplateLink(const TemplateLink ©) + { + linkWithTemplate = copy.linkWithTemplate; + alignRuleWithTemplate = copy.alignRuleWithTemplate; + templateArray = copy.templateArray; + } + + Array* GetTemplateArray() const { return templateArray; } + VECTOR> GetAlignRules() const; + VECTOR GetLinks() const; + void AddRule(const int dimNum, int value, const PAIR &rule, Array *templateArray_); + STRING toString() const; + }; + + class Array + { + private: + unsigned id; + STRING name; + STRING shortName; + int dimSize; + int typeSize; // size of one element of array + // calculated sizes + VECTOR> sizes; + // original sizes + shifts + VECTOR>, PAIR>>> sizesExpr; + + VECTOR> orderedSizes; + VECTOR>, PAIR>>> orderedSizesExpr; + + // template info by region + MAP templateInfo; + bool isTemplFlag; + bool isLoopArrayFlag; + distFlag isNonDistribute; + Symbol *declSymbol; + STRING uniqKey; + + // PAIR + SET> declPlaces; + MAP, Symbol*> declPlacesSymbol; + //file-> map[incFile, line] -> symbol + MAP, Symbol*>> declPlacesSymbolByFile; + + //TYPE: 0 - local, 1 - common, 2 - module, 3 - function parameter + // PAIR + PAIR locationPos; + VECTOR>> allShadowSpecs; + + SET containsInRegions; + + // file -> lines + MAP> usagePlaces; + + VECTOR mappedDims; + VECTOR deprecateToDistribute; + + bool ompThreadPrivate; + bool privateInLoop; + bool inEquivalence; + private: + TemplateLink* getTemlateInfo(const uint64_t regionId, bool withCheck = false) + { + auto it = templateInfo.find(regionId); + TemplateLink *currLink = NULL; + if (it == templateInfo.end()) + { +#if __SPF + if (withCheck && sharedMemoryParallelization != 0) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); +#endif + currLink = new TemplateLink(dimSize); + templateInfo[regionId] = currLink; + } + else + currLink = it->second; + return currLink; + } + + void GenUniqKey() + { + uniqKey = shortName + locationPos.second + TO_STR(dimSize); + for (auto &place : declPlaces) + uniqKey += place.first + TO_STR(place.second); + } + + //clones of template for realignes + MAP, STRING> templateClones; + VECTOR templateDimsOrder; + + public: + Array() + { + isTemplFlag = false; + isLoopArrayFlag = false; + isNonDistribute = NO_DISTR; + typeSize = 0; + uniqKey = ""; + dimSize = 0; + id = -1; + declSymbol = NULL; + ompThreadPrivate = false; + privateInLoop = false; + inEquivalence = false; + } + + Array(const STRING &name, const STRING &shortName, const int dimSize, const unsigned id, + const STRING &declFile, const int declLine, const PAIR &locationPos, + Symbol *declSymbol, bool inOmpThreadPriv, bool privateInLoop, bool inEquivalence, + const VECTOR ®ions, const int typeSize, const distFlag flag = DISTR) : + + name(name), dimSize(dimSize), id(id), shortName(shortName), + isTemplFlag(false), isNonDistribute(flag), isLoopArrayFlag(false), + locationPos(locationPos), declSymbol(declSymbol), typeSize(typeSize), + ompThreadPrivate(inOmpThreadPriv), privateInLoop(privateInLoop), inEquivalence(inEquivalence) + { + declPlaces.insert(std::make_pair(declFile, declLine)); + sizes.resize(dimSize); + sizesExpr.resize(dimSize); + mappedDims.resize(dimSize); + deprecateToDistribute.resize(dimSize); + + for (int z = 0; z < dimSize; ++z) + { + sizes[z] = std::make_pair((int)INT_MAX, (int)INT_MIN); + PAIR initVal = std::make_pair(0, 0); + sizesExpr[z] = std::make_pair(std::make_pair((Expression*)NULL, initVal), std::make_pair((Expression*)NULL, initVal)); + mappedDims[z] = false; + deprecateToDistribute[z] = false; + } + + GenUniqKey(); + for (auto ® : regions) + containsInRegions.insert(reg); + } + + Array(const Array ©) + { + id = copy.id; + name = copy.name; + shortName = copy.shortName; + dimSize = copy.dimSize; + typeSize = copy.typeSize; + + sizes = copy.sizes; + sizesExpr = copy.sizesExpr; + + isTemplFlag = copy.isTemplFlag; + isNonDistribute = copy.isNonDistribute; + isLoopArrayFlag = copy.isLoopArrayFlag; + + declPlaces = copy.declPlaces; + locationPos = copy.locationPos; + + allShadowSpecs = copy.allShadowSpecs; + + for (auto &elem : copy.templateInfo) + templateInfo[elem.first] = new TemplateLink(*elem.second); + + declSymbol = copy.declSymbol; + uniqKey = copy.uniqKey; + containsInRegions = copy.containsInRegions; + mappedDims = copy.mappedDims; + deprecateToDistribute = copy.deprecateToDistribute; + ompThreadPrivate = copy.ompThreadPrivate; + privateInLoop = copy.privateInLoop; + inEquivalence = copy.inEquivalence; + } + + bool RemoveUnpammedDims() + { + bool needToRemove = false; + int countToRem = 0; + for (int z = 0; z < dimSize; ++z) + { + if (!mappedDims[z] || deprecateToDistribute[z]) + { + needToRemove = true; + countToRem++; + //break; + } + } + + if (needToRemove == false) + return false; + if (countToRem == dimSize) + return true; + + VECTOR> newSizes; + VECTOR>, PAIR>>> newSizesExpr; + VECTOR newMappedDims; + VECTOR newDepr; + + for (int z = 0; z < dimSize; ++z) + { + if (mappedDims[z] && !deprecateToDistribute[z]) + { + newSizes.push_back(sizes[z]); + newSizesExpr.push_back(sizesExpr[z]); + newMappedDims.push_back(mappedDims[z]); + newDepr.push_back(deprecateToDistribute[z]); + } + } + + sizes = newSizes; + sizesExpr = newSizesExpr; + mappedDims = newMappedDims; + deprecateToDistribute = newDepr; + dimSize = (int)sizes.size(); + + return false; + } + + int GetDimSize() const { return dimSize; } + const STRING GetName() const { return name; } + const STRING GetShortName() const { return shortName; } + const STRING GetNameInLocation(void* location) const; + void* GetNameInLocationS(void* location) const; + + unsigned GetId() const { return id; } + void SetSizes(VECTOR> &_sizes, bool notCopyToExpr = false) + { + sizes = _sizes; + if (!notCopyToExpr) + { + for (int i = 0; i < sizesExpr.size(); ++i) + { + sizesExpr[i].first.second.first = sizes[i].first; + sizesExpr[i].second.second.first = sizes[i].second; + } + } + } + const VECTOR>& GetSizes(); + const VECTOR>, PAIR>>>& GetSizesExpr(); + void SetTemplateFlag(const bool templFlag) { isTemplFlag = templFlag; } + bool IsTemplate() const { return isTemplFlag; } + bool IsLoopArray() const { return isLoopArrayFlag; } + bool IsArray() const { return !isTemplFlag && !isLoopArrayFlag; } + void SetLoopArray(const bool flag) { isLoopArrayFlag = flag; } + void SetSizesExpr(const VECTOR> &_sizesExpr) + { + for (int i = 0; i < _sizesExpr.size(); ++i) + { + sizesExpr[i].first.first = _sizesExpr[i].first; + sizesExpr[i].second.first = _sizesExpr[i].second; + } + } + + int AddLinkWithTemplate(const int dimNum, const int dimTempl, Array *templateArray_, const PAIR &rule, const uint64_t regionId) + { + int err = 0; + if (dimNum >= dimSize) + err = -1; + else + { + TemplateLink *currLink = getTemlateInfo(regionId, templateArray_ == NULL); + currLink->AddRule(dimNum, dimTempl, rule, templateArray_); + } + return err; + } + + VECTOR GetLinksWithTemplate(const uint64_t regionId) + { + TemplateLink *currLink = getTemlateInfo(regionId, true); + return currLink->GetLinks(); + } + + VECTOR> GetAlignRulesWithTemplate(const uint64_t regionId) + { + TemplateLink *currLink = getTemlateInfo(regionId, true); + return currLink->GetAlignRules(); + } + + bool HasTemplateInfo(const uint64_t regionId) const + { + auto it = templateInfo.find(regionId); + return (it != templateInfo.end()); + } + + void ChangeName(const STRING &newName) + { + auto pos = name.find(shortName); + if (pos != STRING::npos) + { + name.erase(pos, shortName.size()); + shortName = newName; + name += newName; + } + GenUniqKey(); + } + + void ExtendDimSize(const int dim, const PAIR &size) + { + /*if (size.first == size.second) + return;*/ + + sizes[dim].first = std::min(sizes[dim].first, size.first); + sizes[dim].second = std::max(sizes[dim].second, size.second); + + PAIR &left = sizesExpr[dim].first.second; + PAIR &right = sizesExpr[dim].second.second; + + left.second = std::min(left.second, sizes[dim].first - left.first); + right.second = std::max(right.second, sizes[dim].second - right.first); + } + void SetId(const unsigned newId) { id = newId; } + + const SET>& GetDeclInfo() const { return declPlaces; } + const MAP, Symbol*>& GetDeclInfoWithSymb() const { return declPlacesSymbol; } + void AddDeclInfo(const PAIR &declInfo, const SET& allFilesInProj, + const STRING& currFile, Symbol* symb = NULL) + { + declPlaces.insert(declInfo); + if (symb) + { + declPlacesSymbol[declInfo] = symb; + if (allFilesInProj.find(declInfo.first) == allFilesInProj.end()) // from include + declPlacesSymbolByFile[currFile][declInfo] = symb; + } + GenUniqKey(); + } + + //save request of shadow spec + void ExtendShadowSpec(const VECTOR> &newSpec) + { + if (allShadowSpecs.size() == 0) + allShadowSpecs.resize(dimSize); + + const PAIR zeroPair(0, 0); + for (int i = 0; i < newSpec.size(); ++i) + if (newSpec[i] != zeroPair) + allShadowSpecs[i].push_back(newSpec[i]); + } + + //remove last requst of shadow spec + void RemoveShadowSpec(const VECTOR> &delSpec) + { + int dimN = 0; + for (auto &group : allShadowSpecs) + { + for (int i = 0; i < group.size(); ++i) + { + if (group[i] == delSpec[dimN]) + { + group.erase(group.begin() + i); + break; + } + } + ++dimN; + } + } + + //construct shadow spec from all requests + const VECTOR> GetShadowSpec() const + { + VECTOR> shadowSpec; + shadowSpec.resize(dimSize); + for (int i = 0; i < dimSize; ++i) + shadowSpec[i] = std::make_pair(0, 0); + + int dimN = 0; + for (auto &group : allShadowSpecs) + { + for (auto &elem : group) + { + shadowSpec[dimN].first = std::max(shadowSpec[dimN].first, elem.first); + shadowSpec[dimN].second = std::max(shadowSpec[dimN].second, elem.second); + } + ++dimN; + } + return shadowSpec; + } + + void ClearShadowSpecs() { allShadowSpecs.clear(); } + + JSON toJson() + { + JSON retVal; + + retVal["id"] = (int64_t)id; + retVal["name"] = name; + retVal["shortName"] = shortName; + retVal["packedAddress"] = std::to_string((long long)this); + + retVal["dimSize"] = dimSize; + retVal["typeSize"] = typeSize; + retVal["state"] = (int)isNonDistribute; + retVal["location"] = (int)locationPos.first; + retVal["locName"] = locationPos.second; + + retVal["isTemplFlag"] = (int)isTemplFlag; + retVal["isLoopArrayFlag"] = (int)isLoopArrayFlag; + + JSON deprToDist = nlohmann::json::array(); + for (int i = 0; i < deprecateToDistribute.size(); ++i) + deprToDist.push_back((int)deprecateToDistribute[i]); + retVal["deprecateToDist"] = deprToDist; + + JSON mappedDimsJ = nlohmann::json::array(); + for (int i = 0; i < mappedDims.size(); ++i) + mappedDimsJ.push_back((int)mappedDims[i]); + retVal["mappedDims"] = mappedDimsJ; + + JSON sizesJ = nlohmann::json::array(); + for (int i = 0; i < sizes.size(); ++i) + { + JSON pair; + pair["key"] = sizes[i].first; + pair["value"] = sizes[i].second; + sizesJ.push_back(pair); + } + retVal["sizes"] = sizesJ; + + JSON regions = nlohmann::json::array(); + for (auto& reg : containsInRegions) + regions.push_back(reg); + retVal["regions"] = regions; + + + JSON declPlacesJ = nlohmann::json::array(); + for (auto& place : declPlaces) + { + JSON elem; + elem["file"] = place.first; + elem["line"] = place.second; + + declPlacesJ.push_back(elem); + } + retVal["declPlaces"] = declPlacesJ; + + return retVal; + } + + Array* GetTemplateArray(const uint64_t regionId, bool withCheck = true) + { + TemplateLink *currLink = getTemlateInfo(regionId, withCheck); + return currLink->GetTemplateArray(); + } + + void SetDistributeFlag(const distFlag isNonDistribute_) { isNonDistribute = isNonDistribute_; } + bool IsNotDistribute() const { return (isNonDistribute == DISTR) ? false : true; } + distFlag GetDistributeFlagVal() const { return isNonDistribute; } + + void ChangeLocation(arrayLocation loc, const STRING &name) + { + locationPos = std::make_pair(loc, name); + } + + void SetLocation(arrayLocation loc, const STRING &name) + { + ChangeLocation(loc, name); + GenUniqKey(); + } + PAIR GetLocation() const { return locationPos; } + + Symbol* GetDeclSymbol(const STRING& file, const PAIR& range, const SET& allFilesInProj) const + { + if (!IsArray() || locationPos.first != l_COMMON) + return declSymbol; + + for (auto& pos : declPlacesSymbol) + { + if (pos.first.first == file) + { + const int line = pos.first.second; + if (range.first <= line && line <= range.second) + return pos.second; + } // may be in include? + else if (allFilesInProj.find(pos.first.first) == allFilesInProj.end() && allFilesInProj.size()) + { + auto it = declPlacesSymbolByFile.find(file); + if (it != declPlacesSymbolByFile.end() && it->second.find(pos.first) != it->second.end()) + { + auto s = it->second.find(pos.first); + return s->second; + } + else +#if __SPF + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); +#else + return NULL; +#endif + return NULL; + } + } +#if __SPF + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); +#endif + return NULL; + } + + Symbol* GetDeclSymbol() const { return declSymbol; } + void SetDeclSymbol(Symbol *s) { declSymbol = s; } + + const STRING& GetArrayUniqKey() const { return uniqKey; } + + STRING GetIndepUniqName() const { return shortName + locationPos.second + TO_STR(dimSize); } + + const SET& GetRegionsName() const { return containsInRegions; } + void SetRegionPlace(const STRING ®Name) { if (regName != "") containsInRegions.insert(regName); } + + const MAP>& GetUsagePlaces() const { return usagePlaces; } + const SET GetUsagePlaces(const STRING& fileName, const PAIR* filter = NULL) const + { + auto it = usagePlaces.find(fileName); + if (it == usagePlaces.end()) + return SET(); + if (!filter) + return it->second; + else + { + SET ret; + int first = filter->first; + int last = filter->second; + for (auto& elem : it->second) + if (first <= elem && elem <= last) + ret.insert(elem); + + return ret; + } + } + + void AddUsagePlace(const STRING &fileName, int lineNumber) + { + auto it = usagePlaces.find(fileName); + if (it == usagePlaces.end()) + it = usagePlaces.insert(it, make_pair(fileName, SET())); + it->second.insert(lineNumber); + } + + void SetMappedDim(const int dim) + { + if (dim >= dimSize) + return; + mappedDims[dim] = true; + } + + bool IsDimMapped(const int dim) const + { + if (dim >= dimSize) + return false; + else + { + if (templateDimsOrder.size() == 0) + return mappedDims[dim]; + else + return mappedDims[templateDimsOrder[dim]]; + } + } + + void DeprecateDimension(const int dim, bool value = true) + { + if (dim >= dimSize) + return; + deprecateToDistribute[dim] = value; + } + + void DeprecateAllDims() + { + for (int dim = 0; dim < dimSize; ++dim) + deprecateToDistribute[dim] = true; + } + + bool IsDimDepracated(const int dim) const + { + if (dim >= dimSize) + return false; + else + { + if (templateDimsOrder.size() == 0) + return deprecateToDistribute[dim]; + else + return deprecateToDistribute[templateDimsOrder[dim]]; + } + } + + bool IsAllDeprecated() const + { + bool ret = true; + for (int z = 0; z < dimSize; ++z) + ret = ret && deprecateToDistribute[z]; + return ret; + } + + const VECTOR& GetDeprecetedDims() const { return deprecateToDistribute; } + + int GetTypeSize() const { return typeSize; } + + STRING AddTemplateClone(const VECTOR &newDist) + { + auto it = templateClones.find(newDist); + if (it == templateClones.end()) + it = templateClones.insert(it, std::make_pair(newDist, shortName + STRING("_r") + TO_STR(templateClones.size()))); + return it->second; + } + + void ClearTemplateClones() + { + templateClones.clear(); + templateDimsOrder.clear(); + orderedSizes.clear(); + orderedSizesExpr.clear(); + } + + const MAP, STRING>& GetAllClones() const { return templateClones; } + + void AddNewTemplateDimsOrder(const VECTOR &newOrder) { templateDimsOrder = newOrder; } + + VECTOR GetNewTemplateDimsOrder() const { return templateDimsOrder; } + + void SetDimSizesToMaxMin(bool notCopyToExpr = false) + { + for (int i = 0; i < dimSize; ++i) + sizes[i] = std::make_pair((int)INT_MAX, (int)INT_MIN); + + if (!notCopyToExpr) + { + for (int i = 0; i < sizesExpr.size(); ++i) + { + sizesExpr[i].first.second.first = sizes[i].first; + sizesExpr[i].second.second.first = sizes[i].second; + } + } + } + + bool IsOmpThreadPrivate() const { return ompThreadPrivate; } + bool IsSpfPrivate() const { return ((isNonDistribute == SPF_PRIV) || (isNonDistribute == IO_PRIV)); } + + bool IsInEquvalence() const { return inEquivalence; } + void SetEquvalence(bool value) { inEquivalence = value; } + + bool IsPrivateInLoop() const { return privateInLoop; } + void SetPrivateInLoopStatus(bool value) { privateInLoop = value; } + + bool IsModuleSymbol() const { return locationPos.first == l_MODULE; } + + ~Array() + { + for (auto &templ : templateInfo) + delete templ.second; + } + }; + + struct ArrayComparator + { + bool operator()(const Array* left, const Array* right) const + { + return (left->GetArrayUniqKey() > right->GetArrayUniqKey()); + } + }; + + struct UnaryAccess + { + UnaryAccess() + { + line = -1; + type = -1; + underFunctionPar = -1; + fName = ""; + count = 0; + } + + UnaryAccess(const PAIR& info) + { + line = info.first; + type = info.second; + underFunctionPar = -1; + fName = ""; + count = 1; + } + + UnaryAccess(const PAIR& info, const STRING &f, const int parN) + { + line = info.first; + type = info.second; + underFunctionPar = parN; + fName = f; + count = 1; + } + + STRING PrintInfo() const + { + STRING out = "#" + std::to_string(count) + " of "; + if (type == 0) + out += "READ "; + else if(type == 1) + out += "WRITE "; + else + out += "UNKN "; + out += "on line " + std::to_string(line); + if (underFunctionPar != -1) + out += " in '#" + std::to_string(underFunctionPar + 1) + "' par of function call '" + fName + "'"; + return out; + } + + bool operator==(const UnaryAccess &left) const + { + return (line == left.line && type == left.type && + underFunctionPar == left.underFunctionPar && fName == left.fName); + } + + bool operator!=(const UnaryAccess& left) const + { + return !(*this == left); + } + + int line; + int type; // R/W -> 0, 1 + int underFunctionPar; + STRING fName; + int count; + }; + + class ArrayAccessInfo + { + private: + MAP>> accessPatterns; // file -> MAP + public: + void AddAccessInfo(const STRING& file, const PAIR &info, const STRING fName = "", int underParN = -1) + { + auto it = accessPatterns.find(file); + if (it == accessPatterns.end()) + it = accessPatterns.insert(it, std::make_pair(file, MAP>())); + + bool found = false; + UnaryAccess toAdd; + if (underParN == -1) + toAdd = UnaryAccess(info); + else + toAdd = UnaryAccess(info, fName, underParN); + + auto itMap = it->second.find(info.first); + if (itMap == it->second.end()) + it->second[info.first].push_back(toAdd); + else + { + for (int z = 0; z < itMap->second.size(); ++z) + { + if (itMap->second[z] == toAdd) + { + found = true; + itMap->second[z].count++; + break; + } + } + + if (found == false) + { + if (underParN == -1) + itMap->second.push_back(toAdd); + else + itMap->second.push_back(toAdd); + } + } + } + + void checkAndUpdate(const MAP& allFuncs); + const MAP>>& GetAllAccessInfo() const { return accessPatterns; } + const MAP>* GetAccessInfoByFile(const STRING &file) const + { + auto it = accessPatterns.find(file); + if (it == accessPatterns.end()) + return NULL; + else + return &(it->second); + } + }; + + void printArrayInfo(const STRING &file, const MAP, PAIR> &declaredArrays); + void fixTypeOfArrayInfoWithCallGraph(MAP, PAIR>& declaredArrays, const MAP& allFuncs); +} +#undef VECTOR +#undef STRING +#undef PAIR +#undef MAP +#undef SET #undef TO_STR \ No newline at end of file diff --git a/src/Distribution/DvmhDirective.cpp b/src/Distribution/DvmhDirective.cpp index 798eef2..1f8f0d2 100644 --- a/src/Distribution/DvmhDirective.cpp +++ b/src/Distribution/DvmhDirective.cpp @@ -199,15 +199,6 @@ static set fillUsedSymbols(SgStatement *loop) return usedS; } -static string correctSymbolModuleName(const string& origFull) -{ - auto it = origFull.find("::"); - if (it == string::npos) - return origFull; - else - return origFull.substr(it + 2); -} - static SgStatement* getModuleScope(const string& origFull, vector& moduleList, SgStatement *local) { auto it = origFull.find("::"); @@ -959,7 +950,7 @@ ParallelDirective::genDirective(File* file, const vectorsymbol()->identifier()); + redS = getNameInLocation(parentFunc, red, getModuleScope(red, moduleList, parentFunc)->symbol()->identifier()); else redS = findSymbolOrCreate(file, clearName, NULL, parentFunc); @@ -1017,12 +1008,12 @@ ParallelDirective::genDirective(File* file, const vector(list)); if (clearName1 != get<0>(list)) - redS1 = getNameInLocation(parentFunc, clearName1, getModuleScope(get<0>(list), moduleList, parentFunc)->symbol()->identifier()); + redS1 = getNameInLocation(parentFunc, get<0>(list), getModuleScope(get<0>(list), moduleList, parentFunc)->symbol()->identifier()); else redS1 = findSymbolOrCreate(file, clearName1, NULL, parentFunc); if (clearName2 != get<1>(list)) - redS2 = getNameInLocation(parentFunc, clearName2, getModuleScope(get<1>(list), moduleList, parentFunc)->symbol()->identifier()); + redS2 = getNameInLocation(parentFunc, get<1>(list), getModuleScope(get<1>(list), moduleList, parentFunc)->symbol()->identifier()); else redS2 = findSymbolOrCreate(file, clearName2, NULL, parentFunc); diff --git a/src/Distribution/DvmhDirectiveBase.cpp b/src/Distribution/DvmhDirectiveBase.cpp index 55b6586..28576a8 100644 --- a/src/Distribution/DvmhDirectiveBase.cpp +++ b/src/Distribution/DvmhDirectiveBase.cpp @@ -12,6 +12,8 @@ #include "../Distribution/GraphCSR.h" #include "../Utils/errors.h" #include "../Utils/utils.h" +#include "../Utils/json.hpp" + #include "../GraphCall/graph_calls_func.h" using std::vector; @@ -27,6 +29,8 @@ using std::make_pair; using std::min; using std::max; +using nlohmann::json; + template static void uniteSets(const set &first, const set &second, set &result) { @@ -732,30 +736,34 @@ string AlignRuleBase::GenRuleBase() const return retVal; } -string AlignRuleBase::toString() +json AlignRuleBase::toJson() { - string retVal = ""; + json retVal; - if (alignArray) - retVal += "#" + std::to_string((long long)alignArray); - else - retVal += "#-1"; + retVal["packedAlignArrayAddress"] = alignArray ? std::to_string((long long)alignArray) : std::to_string((long long)-1); + retVal["packedAlignWithAddress"] = alignWith ? std::to_string((long long)alignWith) : std::to_string((long long)-1); - if (alignWith) - retVal += "#" + std::to_string((long long)alignWith); - else - retVal += "#-1"; + json alignRules = json::array(); + for (auto& rule : alignRule) + { + json pair; + pair["key"] = rule.first; + pair["value"] = rule.second; + alignRules.push_back(pair); + } + retVal["alignRule"] = alignRules; - retVal += "#" + std::to_string(alignRule.size()); - for (int i = 0; i < alignRule.size(); ++i) - retVal += "#" + std::to_string(alignRule[i].first) + "#" + std::to_string(alignRule[i].second); - - retVal += "#" + std::to_string(alignRuleWith.size()); - for (int i = 0; i < alignRuleWith.size(); ++i) - retVal += "#" + std::to_string(alignRuleWith[i].first) - + "#" + std::to_string(alignRuleWith[i].second.first) - + "#" + std::to_string(alignRuleWith[i].second.second); + json alignRuleWithJ = json::array(); + for (auto& [dimNum, AB] : alignRuleWith) + { + json tuple; + tuple["dimNum"] = dimNum; + tuple["a"] = AB.first; + tuple["b"] = AB.second; + alignRuleWithJ.push_back(tuple); + } + retVal["alignRuleWith"] = alignRuleWithJ; return retVal; } diff --git a/src/Distribution/DvmhDirectiveBase.h b/src/Distribution/DvmhDirectiveBase.h index 5d0ac07..d3c98a7 100644 --- a/src/Distribution/DvmhDirectiveBase.h +++ b/src/Distribution/DvmhDirectiveBase.h @@ -3,6 +3,8 @@ #include #include +#include "../Utils/json.hpp" + typedef enum lang : int { LANG_C, LANG_F } language; typedef enum dist : int { BLOCK, NONE } distType; typedef std::pair, std::pair> attrType; @@ -48,7 +50,7 @@ public: public: std::string GenRuleBase() const; - std::string toString(); + nlohmann::json toJson(); public: DIST::Array *alignArray; diff --git a/src/ParallelizationRegions/ParRegions.h b/src/ParallelizationRegions/ParRegions.h index 30087b0..d613d31 100644 --- a/src/ParallelizationRegions/ParRegions.h +++ b/src/ParallelizationRegions/ParRegions.h @@ -11,6 +11,8 @@ #include "../Distribution/Distribution.h" #include "../Utils/AstWrapper.h" +#include "../Utils/json.hpp" + #if __SPF #include "../Utils/SgUtils.h" #endif @@ -253,35 +255,42 @@ public: return retVal; } - std::string toString() + nlohmann::json toJson() { - std::string retVal = ""; + nlohmann::json retVal; - retVal += "#" + std::to_string(regionId); - retVal += "#" + originalName; - retVal += "#" + std::to_string(lines.size()); + retVal["packedRegionId"] = std::to_string(regionId); + retVal["originalName"] = originalName; - for (auto it = lines.begin(); it != lines.end(); ++it) + nlohmann::json arrays = nlohmann::json::array(); + for (auto& array : allArrays.GetArrays()) + arrays.push_back(array->toJson()); + retVal["packedArrays"] = arrays; + + nlohmann::json linesInfo = nlohmann::json::array(); + for (auto& [file, linesByFile] : lines) { - retVal += "|" + it->first + "|"; - retVal += std::to_string(it->second.size()); - for (int i = 0; i < it->second.size(); ++i) - retVal += "#" + std::to_string(it->second[i].lines.first) + "#" + std::to_string(it->second[i].lines.second); + nlohmann::json linesRegs; + nlohmann::json lines = nlohmann::json::array(); + + for (auto& elem : linesByFile) + { + JSON pair; + pair["key"] = elem.lines.first; + pair["value"] = elem.lines.second; + lines.push_back(pair); + } + linesRegs["file"] = file; + linesRegs["lines"] = lines; + + linesInfo.push_back(linesRegs); } + retVal["regionsLines"] = linesInfo; - const std::set &arrays = allArrays.GetArrays(); - retVal += "#" + std::to_string(arrays.size()); - - //create map - for (auto it = arrays.begin(); it != arrays.end(); ++it) - { - retVal += "#" + std::to_string((long long)(*it)); - retVal += "#" + (*it)->toString(); - } - - retVal += "#" + std::to_string(dataDirectives.alignRules.size()); - for (int i = 0; i < dataDirectives.alignRules.size(); ++i) - retVal += dataDirectives.alignRules[i].toString(); + nlohmann::json alignRules = nlohmann::json::array(); + for (auto& rule : dataDirectives.alignRules) + alignRules.push_back(rule.toJson()); + retVal["alignRules"] = alignRules; return retVal; } diff --git a/src/Predictor/PredictScheme.h b/src/Predictor/PredictScheme.h index b444aa1..35ccf9e 100644 --- a/src/Predictor/PredictScheme.h +++ b/src/Predictor/PredictScheme.h @@ -2,6 +2,7 @@ #include #include "dvm.h" #include "../GraphCall/graph_calls.h" +#include "../Utils/json.hpp" class ParallelStats { @@ -11,10 +12,10 @@ public: RemoteCount = ShadowCount = ReductionCount = AcrossCount = 0; } - int RemoteCount; - int ShadowCount; - int ReductionCount; - int AcrossCount; + int RemoteCount = 0; + int ShadowCount = 0; + int ReductionCount = 0; + int AcrossCount = 0; }; class PredictorStats @@ -27,28 +28,32 @@ public: } ParallelStats ParallelStat; - int ParallelCount; - int RemoteCount; - int RedistributeCount; - int IntervalCount; - int TotalScoreComm; - int TotalScorePar; - int TotalScoreDist; + int ParallelCount = 0; + int RemoteCount = 0; + int RedistributeCount = 0; + int IntervalCount = 0; + int TotalScoreComm = 0; + int TotalScorePar = 0; + int TotalScoreDist = 0; - std::string to_string() + nlohmann::json toJson() { - std::string res = ""; - res += std::to_string(ParallelCount) + "|"; - res += std::to_string(RemoteCount) + "|"; - res += std::to_string(RedistributeCount) + "|"; - res += std::to_string(IntervalCount) + "|"; + nlohmann::json stat; - res += std::to_string(ParallelStat.RemoteCount) + "|"; - res += std::to_string(ParallelStat.ShadowCount) + "|"; - res += std::to_string(ParallelStat.ReductionCount) + "|"; - res += std::to_string(ParallelStat.AcrossCount); + stat["ParallelCount"] = ParallelCount; + stat["RemoteCount"] = RemoteCount; + stat["RedistributeCount"] = RedistributeCount; + stat["IntervalCount"] = IntervalCount; - return res; + stat["PS_RemoteCount"] = ParallelStat.RemoteCount; + stat["PS_ShadowCount"] = ParallelStat.ShadowCount; + stat["PS_ReductionCount"] = ParallelStat.ReductionCount; + stat["PS_AcrossCount"] = ParallelStat.AcrossCount; + + //TODO: need to improve + // (summed.TotalScoreComm != 0 ? 1.0 / summed.TotalScoreComm : 0.0) + (double)summed.TotalScorePar * 1000 + (countOfDist == 0 ? -5000 : countOfDist); + stat["TotalScore"] = -1 * (ParallelStat.RemoteCount + ParallelStat.ShadowCount + ParallelStat.ReductionCount + ParallelStat.AcrossCount); + return stat; } }; diff --git a/src/ProjectManipulation/ParseFiles.cpp b/src/ProjectManipulation/ParseFiles.cpp index cfb469e..d474b85 100644 --- a/src/ProjectManipulation/ParseFiles.cpp +++ b/src/ProjectManipulation/ParseFiles.cpp @@ -387,7 +387,50 @@ static string shiftLines(const string &in, const map &m return newStr; } -static int dumpErrors(const vector& listOfProject, const vector& errors) +static void addMessage(const string& in, const map& mapOfFiles, + const FileInfo* currF, map>& messages, typeMessage type) +{ + int byNum = 0; + + auto it = in.find("on line "); + if (it != string::npos) + it += strlen("on line "); + + int line = 0; + sscanf(in.c_str() + it, "%d", &line); + + auto it1 = in.find("of", it + 1); + if (it1 == string::npos) + return; + it1 += 3; + + string fileN = in.substr(it1, in.find(':', it1) - it1); + auto itF = mapOfFiles.find(fileN); + if (itF != mapOfFiles.end() && itF->second != currF) + { + byNum = itF->second->includesAdded; + if (byNum != 0) + { + if (line - byNum <= 0) + { + //return in; + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + else + line -= byNum; + } + } + + const string newStr = in.substr(0, it) + std::to_string(line) + in.substr(in.find(' ', it + 1)); + + wstring messageE, messageR; + __spf_printToLongBuf(messageE, L"%s", to_wstring(newStr).c_str()); + __spf_printToLongBuf(messageR, L"%s", to_wstring(newStr).c_str()); + + messages[fileN].push_back(Messages(type, line, messageR, messageE, 6000)); +} + +static int dumpErrors(const vector& listOfProject, const vector& errors, map>& messages) { int errorsCount = 0; map mapOfFiles; @@ -420,9 +463,13 @@ static int dumpErrors(const vector& listOfProject, const vector& errors, vector& listOfProject, v return rethrow; } -int parseFiles(const char* proj, vector& filesCompilationOrder, int parseForInlining) +int parseFiles(const char* proj, vector& filesCompilationOrder, int parseForInlining, map>& messages) { FILE* list = fopen(proj, "r"); if (!list) @@ -723,7 +770,7 @@ int parseFiles(const char* proj, vector& filesCompilationOrder, int pars vector errors; int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, parseForInlining); - int errCount = dumpErrors(listOfProject, errors); + int errCount = dumpErrors(listOfProject, errors, messages); if (rethrow != 0) throw rethrow; @@ -732,6 +779,8 @@ int parseFiles(const char* proj, vector& filesCompilationOrder, int pars void parseFiles(int argc, char** argv) { + map> messages; + bool isInline = false; auto result = splitCommandLineForParse(argv, argc, isInline); if (result.second.size() == 0) diff --git a/src/ProjectManipulation/ParseFiles.h b/src/ProjectManipulation/ParseFiles.h index c9f908b..05fb68a 100644 --- a/src/ProjectManipulation/ParseFiles.h +++ b/src/ProjectManipulation/ParseFiles.h @@ -3,5 +3,5 @@ #include #include -int parseFiles(const char* proj, std::vector& filesCompilationOrder, int parseForInlining); +int parseFiles(const char* proj, std::vector& filesCompilationOrder, int parseForInlining, std::map>& messages); void parseFiles(int argc, char** argv); diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index b7e80b8..5f5f93d 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -64,6 +64,7 @@ #include "DvmhRegions/LoopChecker.h" #include "DvmhRegions/ReadWriteAnalyzer.h" #include "Utils/utils.h" +#include "Utils/json.hpp" #include "Distribution/Array.h" #include "VisualizerCalls/get_information.h" @@ -107,6 +108,7 @@ using namespace std; using std::chrono::high_resolution_clock; using std::chrono::duration_cast; using std::chrono::milliseconds; +using json = nlohmann::json; int PASSES_DONE[EMPTY_PASS]; bool PASSES_DONE_INIT = false; @@ -331,9 +333,10 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile, moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, false, true); auto itI = filesToInclude.find(file_name); - for (auto& [_, incl] : itI->second) - if (allIncludeFiles.find(incl) != allIncludeFiles.end()) - allIncludeFiles.erase(incl); + for (auto& [_, incls] : itI->second) + for (auto& incl : incls) + if (allIncludeFiles.find(incl) != allIncludeFiles.end()) + allIncludeFiles.erase(incl); } else { @@ -827,7 +830,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne { auto fileIt = includeDependencies.find(file_name); if (fileIt == includeDependencies.end()) - fileIt = includeDependencies.insert(fileIt, make_pair(file_name, vector>())); + fileIt = includeDependencies.insert(fileIt, make_pair(file_name, map>())); set modFiles; for (auto& elem : moduleDecls) @@ -844,7 +847,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne { if (lastFromFile == NULL) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - fileIt->second.push_back(make_pair(lastFromFile->lineNumber(), st->fileName())); + fileIt->second[lastFromFile->lineNumber()].insert(st->fileName()); } else lastFromFile = st; @@ -1603,12 +1606,15 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne set includedToThisFile; if (itDep != includeDependencies.end()) { - for (auto& [_, incl] : itDep->second) + for (auto& [_, incls] : itDep->second) { - auto comm = commentsToInclude.find(incl); - if (comm != commentsToInclude.end()) - for (auto &allComm : comm->second) - includedToThisFile.insert(allComm.second.begin(), allComm.second.end()); + for (auto& incl : incls) + { + auto comm = commentsToInclude.find(incl); + if (comm != commentsToInclude.end()) + for (auto& allComm : comm->second) + includedToThisFile.insert(allComm.second.begin(), allComm.second.end()); + } } } @@ -2042,7 +2048,7 @@ static void findFunctionsToInclude(bool needToAddErrors) SPF_messages[byFile.first].push_back(message); else { - if (message.type != ERROR) + if (message.getType() != ERROR) SPF_messages[byFile.first].push_back(message); else lastErrors[byFile.first].push_back(message); @@ -2217,8 +2223,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam runPass(GROUP_ACTUAL_AND_REMOTE, proj_name, folderName); runAnalysis(*project, CALCULATE_STATS_SCHEME, false); - for (auto& elem : allPredictorStats) - __spf_print(1, " stat for file %s: %s\n", elem.first.c_str(), elem.second.to_string().c_str()); + //TODO: need to rewrite this to new algo /*if (!folderName && !consoleMode || predictOn) runAnalysis(*project, PREDICT_SCHEME, false); */ @@ -2386,7 +2391,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam break; case PARSE_FILES: { - int err = parseFiles(proj_name, filesCompilationOrder, parseForInlining); + int err = parseFiles(proj_name, filesCompilationOrder, parseForInlining, SPF_messages); if (err != 0) throw err; } @@ -2655,26 +2660,28 @@ int main(int argc, char **argv) { printStackTrace(); printf("exception occurred\n"); + + json byFileArray = json::array(); for (auto& byFile : SPF_messages) { + json inFile; + inFile["file"] = byFile.first; + + json messages = json::array(); for (auto& message : byFile.second) { - string toPrint = ""; - for (int z = 0; z < message.engMessage.size(); ++z) - toPrint += message.engMessage[z]; - string type; - if (message.type == WARR) - type = "WARR"; - else if (message.type == ERROR) - type = "ERROR"; - else if (message.type == NOTE) - type = "NOTE"; - else - type = "UNKN"; - - printf("%s - [#%d: %s: line %d]: %s\n", type.c_str(), message.group, byFile.first.c_str(), message.line, toPrint.c_str()); + message.print(byFile.first); + messages.push_back(message.toJson()); } + inFile["messages"] = messages; + byFileArray.push_back(inFile); } + json allMessages; + allMessages["allMessage"] = byFileArray; + + FILE* outF = fopen("dump_messages.json", "w"); + fprintf(outF, "%s", allMessages.dump().c_str()); + fclose(outF); } deleteAllAllocatedData(withDel); diff --git a/src/SapforData.h b/src/SapforData.h index 8a46da9..cfd4f42 100644 --- a/src/SapforData.h +++ b/src/SapforData.h @@ -85,7 +85,7 @@ std::map>> commentsToInclude; // //for INSERT_INCLUDES -std::map>> filesToInclude; // file -> includes [nearest line, include] +std::map>> filesToInclude; // file -> includes [nearest line, include] // //for PASSES DEPENDENSIES @@ -96,7 +96,7 @@ std::set passesIgnoreStateDone; //for files info std::map lineInfo; // file -> lines count std::map, std::set>> dirsInfo; // file -> dirs count -std::map>> includeDependencies; // file -> includes [nearest line, include] +std::map>> includeDependencies; // file -> includes [nearest line, include] std::vector filesCompilationOrder; // order of files for unite to one file std::map>> exctactedModuleStats; // file -> hided excluded modules // diff --git a/src/Utils/errors.h b/src/Utils/errors.h index 82e198b..274e779 100644 --- a/src/Utils/errors.h +++ b/src/Utils/errors.h @@ -1,5 +1,7 @@ #pragma once #include +#include "json.hpp" + #ifdef __SPF #include "dvm.h" #endif @@ -143,6 +145,9 @@ enum typeMessage { WARR, ERROR, NOTE }; // 06 "%s clause can be used only once." // 07 "Variable '%s' can't be used in FILES and EXCEPT clauses at the same time." +// 6000 PARSER GROUP +// + extern int langOfMessages; struct Messages { @@ -164,18 +169,41 @@ public: engMessage.erase(engMessage.begin() + engMessage.size() - 1); } - std::wstring toString() const + nlohmann::json toJson() const { - std::wstring retVal = L"|"; - retVal += std::to_wstring((int)type) + L" "; - retVal += std::to_wstring(line) + L" "; - retVal += std::to_wstring(group); - retVal += L"|" + value; - return retVal; + nlohmann::json resVal; + + resVal["line"] = line; + resVal["group"] = group; + resVal["value"] = std::string(value.begin(), value.end()); + resVal["type"] = (int)type; + return resVal; } - std::string getString() const { return std::string(engMessage.begin(), engMessage.end()); } -public: + typeMessage getType() const { return type; } + int getLine() const { return line; } + + void print(const std::string& file) const + { + std::string toPrint = ""; + for (int z = 0; z < engMessage.size(); ++z) + toPrint += engMessage[z]; + + std::string typeStr; + if (type == WARR) + typeStr = "WARR"; + else if (type == ERROR) + typeStr = "ERROR"; + else if (type == NOTE) + typeStr = "NOTE"; + else + typeStr = "UNKN"; + + printf("%s - [#%d: %s: line %d]: %s\n", typeStr.c_str(), group, file.c_str(), line, toPrint.c_str()); + } + + auto getUniqKey() const { return std::make_tuple(type, group, line, value); } +private: typeMessage type; int group; int line; diff --git a/src/Utils/module_utils.cpp b/src/Utils/module_utils.cpp index 055e658..9bc9e1a 100644 --- a/src/Utils/module_utils.cpp +++ b/src/Utils/module_utils.cpp @@ -343,9 +343,9 @@ const set& getModuleSymbols(SgStatement *func) return symbs; } -SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const string& locName) +static void findSymbol(SgStatement* func, const string& varName, const string& locName, + map& altNames) { - map altNames; for (const auto& s : getModuleSymbols(func)) { SgSymbol* orig = OriginalSymbol(s); @@ -353,11 +353,22 @@ SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const stri if (orig->identifier() == varName && orig->scope()->symbol()->identifier() == locName) altNames[s->identifier()] = s; } +} + +SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const string& locName) +{ + const string clearName = correctSymbolModuleName(varName); + + map altNames; + findSymbol(func, varName, locName, altNames); + + if (altNames.size() == 0 && clearName != varName) + findSymbol(func, clearName, locName, altNames); if (altNames.size() > 0) return altNames.begin()->second; else { - __spf_print(1, "%s %s %s\n", func->symbol()->identifier(), varName.c_str(), locName.c_str()); + __spf_print(1, "%s (%s %s) %s\n", func->symbol()->identifier(), clearName.c_str(), varName.c_str(), locName.c_str()); printInternalError(convertFileName(__FILE__).c_str(), __LINE__); } @@ -393,6 +404,15 @@ SgSymbol* getNameInLocation(SgSymbol* curr, SgStatement* location) return returnVal; } +string correctSymbolModuleName(const string& origFull) +{ + auto it = origFull.find("::"); + if (it == string::npos) + return origFull; + else + return origFull.substr(it + 2); +} + namespace Distribution { const string Array::GetNameInLocation(void* location_p) const diff --git a/src/Utils/module_utils.h b/src/Utils/module_utils.h index 8fd21da..e78b8e5 100644 --- a/src/Utils/module_utils.h +++ b/src/Utils/module_utils.h @@ -1,5 +1,6 @@ #pragma once +std::string correctSymbolModuleName(const std::string& origFull); const std::set& getModuleSymbols(SgStatement* func); void getModulesAndFunctions(SgFile* file, std::vector& modulesAndFunctions); void findModulesInFile(SgFile* file, std::vector& modules); diff --git a/src/Utils/utils.cpp b/src/Utils/utils.cpp index d301100..7d99610 100644 --- a/src/Utils/utils.cpp +++ b/src/Utils/utils.cpp @@ -30,6 +30,7 @@ #include "../Distribution/Arrays.h" #include "../DynamicAnalysis/gcov_info.h" #include "../ParallelizationRegions/ParRegions.h" +#include "json.hpp" #if __SPF #include "acc_analyzer.h" @@ -42,6 +43,7 @@ using std::set; using std::vector; using std::string; using std::wstring; +using json = nlohmann::json; #if __cplusplus >= 201703L #include @@ -427,7 +429,7 @@ static map> removeCopies(map> map, const Messages*> uniq; for (auto& message : byFile.second) { - auto key = make_tuple(message.type, message.group, message.line, message.value); + auto key = message.getUniqKey(); /*string tmp = ""; for (auto& s : message.toString()) tmp += (char)s; @@ -460,7 +462,7 @@ static void convertGlobalMessagesBuffer(short *&result, int *&resultSize) bool waschanged = false; for (auto &message : byFile.second) { - if (message.line > 0) + if (message.getLine() > 0) newVal.push_back(message); else waschanged = true; @@ -470,22 +472,30 @@ static void convertGlobalMessagesBuffer(short *&result, int *&resultSize) byFile.second = newVal; } - wstring val = L""; - val += std::to_wstring(copySPF_messages.size()); - for (auto it = copySPF_messages.begin(); it != copySPF_messages.end(); ++it) + json allMessages = json::array(); + for (auto& byFile : copySPF_messages) { - val += L"|" + to_wstring(it->first.c_str()) + L"|" + std::to_wstring(it->second.size()); - for (int k = 0; k < it->second.size(); ++k) - val += it->second[k].toString(); + json inFile; + inFile["file"] = byFile.first; + + json array = json::array(); + for (auto& message : byFile.second) + { + json msg = message.toJson(); + array.push_back(msg); + } + inFile["messages"] = array; + allMessages.push_back(inFile); } - const unsigned len = (unsigned)val.size(); - result = new short[len + 1]; - allocated.insert(result); + json all; + all["allMessages"] = allMessages; - result[len] = '\0'; - for (unsigned i = 0; i < len; ++i) - result[i] = val[i]; + const string str = all.dump(); + const unsigned len = (unsigned)str.size(); + + copyStringToShort(result, str); + allocated.insert(result); resultSize = new int[1]; resultSize[0] = (int)len; @@ -1717,4 +1727,16 @@ set fillDistributedArrays(const DataDirective& dataDirectives, for (auto& elem : ret) distrArrays.insert(shortName ? elem->GetShortName() : elem->GetName()); return distrArrays; +} + +void copyStringToShort(short*& result, const string& resVal, bool withEnd) +{ + result = new short[resVal.size() + 1]; + allocated.insert(result); + + for (int i = 0; i < resVal.size(); ++i) + result[i] = resVal[i]; + + if (withEnd) + result[resVal.size()] = (short)'\0'; } \ No newline at end of file diff --git a/src/Utils/utils.h b/src/Utils/utils.h index eb25db1..e96fd1b 100644 --- a/src/Utils/utils.h +++ b/src/Utils/utils.h @@ -96,3 +96,5 @@ std::vector splitAndArgvCreate(const std::string& options); std::set fillDistributedArraysD(const DataDirective& dataDirectives, const std::map>& tableOfUniqNamesByArray, const std::map>& arrayLinksByFuncCalls, bool onlyCommon = false); std::set fillDistributedArrays(const DataDirective& dataDirectives, const std::map>& tableOfUniqNamesByArray, const std::map>& arrayLinksByFuncCalls, bool onlyCommon = false, bool shortName = false); + +void copyStringToShort(short*& result, const std::string& resVal, bool withEnd = true); diff --git a/src/Utils/version.h b/src/Utils/version.h index ed408b9..43758a9 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2417" +#define VERSION_SPF "2422" diff --git a/src/VisualizerCalls/get_information.cpp b/src/VisualizerCalls/get_information.cpp index 058108f..8aa5102 100644 --- a/src/VisualizerCalls/get_information.cpp +++ b/src/VisualizerCalls/get_information.cpp @@ -218,18 +218,6 @@ static bool tryOpenProjectFile(const char *project) return ret; } -static void copyStringToShort(short *&result, const string &resVal, bool withEnd = true) -{ - result = new short[resVal.size() + 1]; - allocated.insert(result); - - for (int i = 0; i < resVal.size(); ++i) - result[i] = resVal[i]; - - if (withEnd) - result[resVal.size()] = (short)'\0'; -} - volatile int passDone = 0; static volatile int rethrow = 0; static void runPassesLoop(const vector &passesToRun, const char *prName, const char *folderNameChar) @@ -465,14 +453,15 @@ int SPF_ParseFilesWithOrder(void*& context, int winHandler, short* options, shor { runPassesForVisualizer(projName, { PARSE_FILES }); - string resVal = ""; - for (auto& elem : filesCompilationOrder) - { - if (resVal == "") - resVal += elem; - else - resVal += "|" + elem; - } + json filesArray = json::array(); + + for (auto& file : filesCompilationOrder) + filesArray.push_back(file); + + json filesOrder; + filesOrder["allFiles"] = filesArray; + + string resVal = filesOrder.dump(); copyStringToShort(result, resVal); retSize = 0; } @@ -766,15 +755,17 @@ int SPF_GetArrayDistribution(void*& context, int winHandler, short *options, sho else printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - string resVal = ""; - resVal += to_string(parallelRegions.size()); - for (int i = 0; i < parallelRegions.size(); ++i) - resVal += parallelRegions[i]->toString(); + json regions = json::array(); + for (auto& reg : parallelRegions) + { + json currReg = reg->toJson(); + regions.push_back(currReg); + } - //__spf_print(1, "==============\n"); - //__spf_print(1, "%s\n", resVal.c_str()); - //__spf_print(1, "==============\n"); + json allRegions; + allRegions["allRegions"] = regions; + string resVal = allRegions.dump(); copyStringToShort(result, resVal); retSize = (int)resVal.size() + 1; } @@ -1063,7 +1054,6 @@ int SPF_CreateParallelVariant(void*& context, int winHandler, short *options, sh printf("SAPFOR: set all info done\n"); runPassesForVisualizer(projName, { INSERT_PARALLEL_DIRS }, folderName); - string predictRes = ""; PredictorStats summed; for (auto &predFile : allPredictorStats) { @@ -1079,44 +1069,11 @@ int SPF_CreateParallelVariant(void*& context, int winHandler, short *options, sh summed.TotalScoreComm += predFile.second.TotalScoreComm; summed.TotalScoreDist += predFile.second.TotalScoreDist; summed.TotalScorePar += predFile.second.TotalScorePar; - } - predictRes += summed.to_string(); - //predictRes += "|" + to_string((summed.TotalScoreComm != 0 ? 1.0 / summed.TotalScoreComm : 0.0 )+ (double)summed.TotalScorePar * 1000 + (countOfDist == 0 ? -5000 : countOfDist)); - if (countOfDist == 0) - predictRes += "|x"; - else - predictRes += "|" + to_string(-1 * (summed.ParallelStat.AcrossCount + summed.ParallelStat.RemoteCount + summed.RedistributeCount + summed.RemoteCount)); - //predictRes += "|0"; - - //TODO: need to rewrite to new algo - /*if (folderName == NULL) - { - SpfInterval *mainIterval = getMainInterval(project, intervals); - const int idxBest = mainIterval->getBestTimeIdx(); - double speedUpBest = 1; - int procCount = 1; - string topo = ""; - if (idxBest != -1 && mainIterval->exec_time != 0) - { - speedUpBest = mainIterval->exec_time / mainIterval->predictedTimes[idxBest]; - topo += "["; - for (int z = 0; z < topologies[idxBest].size(); ++z) - { - topo += to_string(topologies[idxBest][z]); - procCount *= topologies[idxBest][z]; - if (z != topologies[idxBest].size() - 1) - topo += "x"; - } - topo += "]"; - } - char buf[256]; - sprintf(buf, "%.2f", speedUpBest / procCount * 100.0); - predictRes += "|" + string(buf) + topo; } - else - predictRes += "|0";*/ + string predictRes = summed.toJson().dump(); copyStringToShort(predictorStats, predictRes); + __spf_print(1, " statistic to send: %s\n", predictRes.c_str()); retSize = (int)predictRes.size(); } @@ -1156,8 +1113,6 @@ int SPF_GetArrayLinks(void*& context, int winHandler, short *options, short *pro { runPassesForVisualizer(projName, { CALL_GRAPH2 } ); - string resVal = ""; - map> linkedArrays; for (auto& inMap : arrayLinksByFuncCalls) { @@ -1171,17 +1126,24 @@ int SPF_GetArrayLinks(void*& context, int winHandler, short *options, short *pro linkedArrays[ref].insert(toAdd); } - + json allLinks = json::array(); for (auto& array : linkedArrays) { - resVal += to_string(array.first->GetId()) + "|" + to_string(array.second.size()) + "|"; + json currLink; + currLink["id"] = array.first->GetId(); + + json links = json::array(); for (auto& link : array.second) - resVal += to_string(link->GetId()) + "|"; + links.push_back(link->GetId()); + currLink["links"] = links; + + allLinks.push_back(currLink); } - if (resVal[resVal.size() - 1] == '|') - resVal.erase(resVal.size() - 1); + json links; + links["allLinks"] = allLinks; + string resVal = links.dump(); copyStringToShort(result, resVal); retSize = (int)resVal.size() + 1; } @@ -1308,7 +1270,7 @@ int SPF_GetIntrinsics(void*& context, short *&result) return (int)resVal.size() + 1; } -extern map>> includeDependencies; +extern map>> includeDependencies; int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, short *projName, short *&result, short*& output, int*& outputSize, short*& outputMessage, int*& outputMessageSize) { @@ -1328,12 +1290,15 @@ int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, s includes["file"] = deps.first; json array = json::array(); - for (const auto& [line, incl] : deps.second) + for (const auto& [line, incls] : deps.second) { - json elem; - elem["line"] = line; - elem["dependencyFileName"] = incl; - array.push_back(elem); + for (auto& incl : incls) + { + json elem; + elem["line"] = line; + elem["dependencyFileName"] = incl; + array.push_back(elem); + } } includes["includes"] = array; inc_array.push_back(includes); @@ -2192,7 +2157,7 @@ int SPF_InlineProcedures(void*& context, int winHandler, short* options, short* } -extern map>> filesToInclude; +extern map>> filesToInclude; int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *visFilesToInclude, short *&output, int *&outputSize, short *&outputMessage, int *&outputMessageSize) { @@ -2225,9 +2190,8 @@ int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short if (sscanf(splited[k].c_str(), "%d", &line) == -1) return -5; - auto pair = make_pair(line, splited[k + 1]); - filesToInclude[file].push_back(pair); - __spf_print(1, " include = [%d %s]\n", pair.first, pair.second.c_str()); + filesToInclude[file][line].insert(splited[k + 1]); + __spf_print(1, " include = [%d %s]\n", line, splited[k + 1].c_str()); } i += 2 * num; }