diff --git a/src/Predictor/PredictSchemeWithLibrary.cpp b/src/Predictor/PredictSchemeWithLibrary.cpp index cc9929b..ff39245 100644 --- a/src/Predictor/PredictSchemeWithLibrary.cpp +++ b/src/Predictor/PredictSchemeWithLibrary.cpp @@ -17,16 +17,16 @@ #include "../Utils/utils.h" using std::map; -using std::string; -using std::vector; using std::pair; +using std::string; using std::tuple; +using std::vector; -map createTemplateIdMapping(const vector ¶llelRegions) +map createTemplateIdMapping(const vector& parallelRegions) { size_t maxArrayId = 0; for (int z = 0; z < parallelRegions.size(); ++z) { - const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); + const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); for (const auto& distrRule : dataDirectives.distrRules) { if (distrRule.first && !distrRule.first->IsTemplate()) { @@ -44,7 +44,7 @@ map createTemplateIdMapping(const vector ¶l map templateIdMapping; size_t nextTemplateId = maxArrayId + 1; for (int z = 0; z < parallelRegions.size(); ++z) { - const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); + const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); for (const auto& distrRule : dataDirectives.distrRules) { if (distrRule.first && distrRule.first->IsTemplate()) { @@ -64,43 +64,29 @@ map createTemplateIdMapping(const vector ¶l } } } - + return templateIdMapping; } -// TODO: вычислять директивы разово заранее -double runLibpredictCalc(SgProject &project, - const vector& topology, - const string& clusterConfStr, - const vector ¶llelRegions, - map>& loopGraph, - map> &SPF_messages, - const map &templateIdMapping) +PrecomputedLibpredictParams precomputeLibpredictParams( + SgProject& project, + const vector& parallelRegions, + const map>& loopGraph, + const map& templateIdMapping) { - libpredict::RetInitGrid retInitGrid = libpredict::InitGrid(topology[0], topology[1], topology[2], topology[3]); - - if (retInitGrid != libpredict::INIT_GRID_SUCCESS) { - __spf_print(1, "ERROR: Failed to initialize libpredict grid with topology: %zu %zu %zu %zu, return code: %d\n", - topology[0], topology[1], topology[2], topology[3], (int)retInitGrid); - - std::wstring messageR, messageE; - __spf_printToLongBuf(messageE, L"Failed to initialize libpredict grid with topology: %zu %zu %zu %zu, return code: %d", - topology[0], topology[1], topology[2], topology[3], (int)retInitGrid); - __spf_printToLongBuf(messageR, R207); - getObjectForFileFromMap(clusterConfStr.c_str(), SPF_messages).push_back(Messages(ERROR, 1, messageR, messageE, 1064)); - return -1; - } + PrecomputedLibpredictParams result; // distribute and align from parallelRegions for (int z = 0; z < parallelRegions.size(); ++z) { - const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); - const vector ¤tVariant = parallelRegions[z]->GetCurrentVariant(); - const DIST::Arrays &allArrays = parallelRegions[z]->GetAllArrays(); + const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); + const vector& currentVariant = parallelRegions[z]->GetCurrentVariant(); + const DIST::Arrays& allArrays = parallelRegions[z]->GetAllArrays(); - auto &tmp = dataDirectives.distrRules; + auto& tmp = dataDirectives.distrRules; vector> currentVar; - for (int z1 = 0; z1 < currentVariant.size(); ++z1) + for (int z1 = 0; z1 < currentVariant.size(); ++z1) { currentVar.push_back(std::make_pair(tmp[z1].first, &tmp[z1].second[currentVariant[z1]])); + } // distribute for (const auto& distrRule : currentVar) { @@ -108,51 +94,40 @@ double runLibpredictCalc(SgProject &project, const DistrVariant* variant = distrRule.second; if (array && variant && !array->IsNotDistribute()) { + PrecomputedDistributeParams params; + size_t originalId = array->GetId(); - size_t arrayId = originalId; + params.arrayId = originalId; if (array->IsTemplate()) { auto it = templateIdMapping.find(originalId); if (it != templateIdMapping.end()) { - arrayId = it->second; + params.arrayId = it->second; } } - size_t elemSize = array->GetTypeSize(); + params.elemSize = array->GetTypeSize(); + params.array = array; - vector axisDistributions; const auto& arraySizes = array->GetSizes(); for (int dim = 0; dim < array->GetDimSize(); ++dim) { size_t dimSize = arraySizes[dim].second - arraySizes[dim].first + 1; if (dim < variant->distRule.size() && variant->distRule[dim] == dist::BLOCK) { - axisDistributions.emplace_back(dimSize, libpredict::TypeDistribute::BLOCK); + params.axisDistributions.emplace_back(dimSize, libpredict::TypeDistribute::BLOCK); } else { - axisDistributions.emplace_back(dimSize, libpredict::TypeDistribute::NONE); + params.axisDistributions.emplace_back(dimSize, libpredict::TypeDistribute::NONE); } } - vector> shadowEdges; const auto& shadowSpec = array->GetShadowSpec(); for (int dim = 0; dim < shadowSpec.size() && dim < array->GetDimSize(); ++dim) { if (dim < variant->distRule.size() && variant->distRule[dim] == dist::BLOCK) { - shadowEdges.emplace_back(shadowSpec[dim].first, shadowSpec[dim].second); + params.shadowEdges.emplace_back(shadowSpec[dim].first, shadowSpec[dim].second); } } - libpredict::RetDistribute retDistribute = libpredict::Distribute(arrayId, elemSize, axisDistributions, shadowEdges); - - if (retDistribute != libpredict::DISTRIBUTE_SUCCESS) { - __spf_print(1, "ERROR: Failed to distribute array '%s' (id=%zu) with libpredict, return code: %d\n", - array->GetShortName().c_str(), arrayId, (int)retDistribute); - - std::wstring messageR, messageE; - __spf_printToLongBuf(messageE, L"Failed to distribute array '%s' with libpredict, return code: %d", - to_wstring(array->GetShortName()).c_str(), (int)retDistribute); - __spf_printToLongBuf(messageR, R208); - getObjectForFileFromMap(array->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back( - Messages(ERROR, array->GetDeclInfo().begin()->second, messageR, messageE, 1065)); - } + result.distributeParams.push_back(params); } } @@ -162,27 +137,29 @@ double runLibpredictCalc(SgProject &project, DIST::Array* alignWithArray = alignRule.alignWith; if (alignArray && alignWithArray && !alignArray->IsNotDistribute()) { - size_t arrayId = alignArray->GetId(); + PrecomputedAlignParams params; + + params.arrayId = alignArray->GetId(); size_t originalDistributedArrayId = alignWithArray->GetId(); - size_t distributedArrayId = originalDistributedArrayId; + params.distributedArrayId = originalDistributedArrayId; if (alignWithArray->IsTemplate()) { auto it = templateIdMapping.find(originalDistributedArrayId); if (it != templateIdMapping.end()) { - distributedArrayId = it->second; + params.distributedArrayId = it->second; } } - size_t elemSize = alignArray->GetTypeSize(); + params.elemSize = alignArray->GetTypeSize(); + params.alignArray = alignArray; + params.alignWithArray = alignWithArray; const auto& arraySizes = alignArray->GetSizes(); - vector dimensions; for (int dim = 0; dim < alignArray->GetDimSize(); ++dim) { size_t dimSize = arraySizes[dim].second - arraySizes[dim].first + 1; - dimensions.push_back(dimSize); + params.dimensions.push_back(dimSize); } - vector distributionExpressions; for (int dim = 0; dim < alignWithArray->GetDimSize(); ++dim) { bool found = false; for (int i = 0; i < alignRule.alignRuleWith.size(); ++i) { @@ -190,51 +167,39 @@ double runLibpredictCalc(SgProject &project, if (ruleWith.first == dim) { const auto& rule = ruleWith.second; if (rule.first == 0) { - // Константа - distributionExpressions.emplace_back(rule.second); + // constant + params.distributionExpressions.emplace_back(rule.second); } else { - // Линейное выражение a * I + b - distributionExpressions.emplace_back(i, rule.first, rule.second); + // linear expression a * I + b + params.distributionExpressions.emplace_back(i, rule.first, rule.second); } found = true; break; } } if (!found) { - // Нет правила для этого измерения - distributionExpressions.emplace_back(); + // There is no rule for this measurement + params.distributionExpressions.emplace_back(); } } - vector> shadowEdges; const auto& shadowSpec = alignArray->GetShadowSpec(); for (int dim = 0; dim < shadowSpec.size() && dim < alignArray->GetDimSize(); ++dim) { - shadowEdges.emplace_back(shadowSpec[dim].first, shadowSpec[dim].second); + params.shadowEdges.emplace_back(shadowSpec[dim].first, shadowSpec[dim].second); } - libpredict::RetAlign retAlign = libpredict::Align(arrayId, distributedArrayId, elemSize, dimensions, distributionExpressions, shadowEdges); - - if (retAlign != libpredict::ALIGN_SUCCESS) { - __spf_print(1, "ERROR: Failed to align array '%s' (id=%zu) with array '%s' (id=%zu), return code: %d\n", - alignArray->GetShortName().c_str(), arrayId, - alignWithArray->GetShortName().c_str(), distributedArrayId, (int)retAlign); - - std::wstring messageR, messageE; - __spf_printToLongBuf(messageE, L"Failed to align array '%s' with array '%s' using libpredict, return code: %d", - to_wstring(alignArray->GetShortName()).c_str(), - to_wstring(alignWithArray->GetShortName()).c_str(), (int)retAlign); - __spf_printToLongBuf(messageR, R209); - getObjectForFileFromMap(alignArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back( - Messages(ERROR, alignArray->GetDeclInfo().begin()->second, messageR, messageE, 1066)); - } + result.alignParams.push_back(params); } } // shadow_renew map parallelDirs; for (int i = project.numberOfFiles() - 1; i >= 0; --i) { - SgFile *file = &(project.file(i)); - auto fountInfo = findAllDirectives(file, getObjectForFileFromMap(file->filename(), loopGraph), parallelRegions[z]->GetId()); + SgFile* file = &(project.file(i)); + auto fountInfo = findAllDirectives( + file, + getObjectForFileFromMap(file->filename(), const_cast>&>(loopGraph)), + parallelRegions[z]->GetId()); parallelDirs.insert(fountInfo.begin(), fountInfo.end()); } @@ -249,65 +214,135 @@ double runLibpredictCalc(SgProject &project, const vector>& bounds = shadowRenewItem.second; DIST::Array* shadowArray = allArrays.GetArrayByName(arrayName); - if (shadowArray == NULL) + if (shadowArray == NULL) { continue; + } if (shadowArray && !shadowArray->IsNotDistribute()) { - size_t arrayId = shadowArray->GetId(); + PrecomputedShadowRenewParams params; + + params.arrayId = shadowArray->GetId(); + params.shadowArray = shadowArray; - vector> shadow_renew; for (const auto& bound : bounds) { - shadow_renew.emplace_back(static_cast(bound.first), - static_cast(bound.second)); + params.shadow_renew.emplace_back(static_cast(bound.first), + static_cast(bound.second)); } - bool corner = directive->shadowRenewCorner[shadowIdx]; - size_t number_loop_iterations = loopPtr ? static_cast(loopPtr->countOfIters) : 1; + params.corner = directive->shadowRenewCorner[shadowIdx]; + params.number_loop_iterations = loopPtr ? static_cast(loopPtr->countOfIters) : 1; - libpredict::RetShadowRenew retShadowRenew = libpredict::ShadowRenew(arrayId, shadow_renew, corner, number_loop_iterations); - - if (retShadowRenew != libpredict::SHADOW_RENEW_SUCCESS) { - __spf_print(1, "ERROR: Failed to process shadow_renew for array '%s' (id=%zu), return code: %d\n", - shadowArray->GetShortName().c_str(), arrayId, (int)retShadowRenew); - - std::wstring messageR, messageE; - __spf_printToLongBuf(messageE, L"Failed to process shadow_renew for array '%s' with libpredict, return code: %d", - to_wstring(shadowArray->GetShortName()).c_str(), (int)retShadowRenew); - __spf_printToLongBuf(messageR, R210); - getObjectForFileFromMap(shadowArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back( - Messages(ERROR, shadowArray->GetDeclInfo().begin()->second, messageR, messageE, 1067)); - } + result.shadowRenewParams.push_back(params); } } } } } + return result; +} + +double runLibpredictCalc(const vector& topology, + const string& clusterConfStr, + const PrecomputedLibpredictParams& precomputedParams, + map>& SPF_messages) +{ + libpredict::RetInitGrid retInitGrid = libpredict::InitGrid(topology[0], topology[1], topology[2], topology[3]); + + if (retInitGrid != libpredict::INIT_GRID_SUCCESS) { + __spf_print(1, "ERROR: Failed to initialize libpredict grid with topology: %zu %zu %zu %zu, return code: %d\n", + topology[0], topology[1], topology[2], topology[3], (int)retInitGrid); + + std::wstring messageR, messageE; + __spf_printToLongBuf(messageE, L"Failed to initialize libpredict grid with topology: %zu %zu %zu %zu, return code: %d", + topology[0], topology[1], topology[2], topology[3], (int)retInitGrid); + __spf_printToLongBuf(messageR, R207); + getObjectForFileFromMap(clusterConfStr.c_str(), SPF_messages).push_back(Messages(ERROR, 1, messageR, messageE, 1064)); + return -1; + } + + // distribute + for (const auto& params : precomputedParams.distributeParams) { + libpredict::RetDistribute retDistribute = libpredict::Distribute( + params.arrayId, params.elemSize, params.axisDistributions, params.shadowEdges); + + if (retDistribute != libpredict::DISTRIBUTE_SUCCESS) { + __spf_print(1, "ERROR: Failed to distribute array '%s' (id=%zu) with libpredict, return code: %d\n", + params.array->GetShortName().c_str(), params.arrayId, (int)retDistribute); + + std::wstring messageR, messageE; + __spf_printToLongBuf(messageE, L"Failed to distribute array '%s' with libpredict, return code: %d", + to_wstring(params.array->GetShortName()).c_str(), (int)retDistribute); + __spf_printToLongBuf(messageR, R208); + getObjectForFileFromMap(params.array->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back(Messages(ERROR, params.array->GetDeclInfo().begin()->second, messageR, messageE, 1065)); + } + } + + // align + for (const auto& params : precomputedParams.alignParams) { + libpredict::RetAlign retAlign = libpredict::Align( + params.arrayId, params.distributedArrayId, params.elemSize, + params.dimensions, params.distributionExpressions, params.shadowEdges); + + if (retAlign != libpredict::ALIGN_SUCCESS) { + __spf_print(1, "ERROR: Failed to align array '%s' (id=%zu) with array '%s' (id=%zu), return code: %d\n", + params.alignArray->GetShortName().c_str(), params.arrayId, + params.alignWithArray->GetShortName().c_str(), params.distributedArrayId, (int)retAlign); + + std::wstring messageR, messageE; + __spf_printToLongBuf(messageE, L"Failed to align array '%s' with array '%s' using libpredict, return code: %d", + to_wstring(params.alignArray->GetShortName()).c_str(), + to_wstring(params.alignWithArray->GetShortName()).c_str(), (int)retAlign); + __spf_printToLongBuf(messageR, R209); + getObjectForFileFromMap(params.alignArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back(Messages(ERROR, params.alignArray->GetDeclInfo().begin()->second, messageR, messageE, 1066)); + } + } + + // shadow_renew + for (const auto& params : precomputedParams.shadowRenewParams) { + libpredict::RetShadowRenew retShadowRenew = libpredict::ShadowRenew( + params.arrayId, params.shadow_renew, params.corner, params.number_loop_iterations); + + if (retShadowRenew != libpredict::SHADOW_RENEW_SUCCESS) { + __spf_print(1, "ERROR: Failed to process shadow_renew for array '%s' (id=%zu), return code: %d\n", + params.shadowArray->GetShortName().c_str(), params.arrayId, (int)retShadowRenew); + + std::wstring messageR, messageE; + __spf_printToLongBuf(messageE, L"Failed to process shadow_renew for array '%s' with libpredict, return code: %d", + to_wstring(params.shadowArray->GetShortName()).c_str(), (int)retShadowRenew); + __spf_printToLongBuf(messageR, R210); + getObjectForFileFromMap(params.shadowArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back(Messages(ERROR, params.shadowArray->GetDeclInfo().begin()->second, messageR, messageE, 1067)); + } + } + return libpredict::GetTime(); } -void runPredictScheme(SgProject &project, - vector> &topologies, - const vector ¶llelRegions, +void runPredictScheme(SgProject& project, + vector>& topologies, + const vector& parallelRegions, map>& loopGraph, - map> &SPF_messages) + map>& SPF_messages) { // calculating maximum dimension of distribution int maxSizeDist = 0; for (int z = 0; z < parallelRegions.size(); ++z) { - const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); - const vector ¤tVariant = parallelRegions[z]->GetCurrentVariant(); + const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); + const vector& currentVariant = parallelRegions[z]->GetCurrentVariant(); - auto &tmp = dataDirectives.distrRules; + auto& tmp = dataDirectives.distrRules; vector currentVar; - for (int z1 = 0; z1 < currentVariant.size(); ++z1) + for (int z1 = 0; z1 < currentVariant.size(); ++z1) { currentVar.push_back(&tmp[z1].second[currentVariant[z1]]); + } for (auto var : currentVar) { int countBlock = 0; - for (int z = 0; z < var->distRule.size(); ++z) - if (var->distRule[z] == dist::BLOCK) + for (int z = 0; z < var->distRule.size(); ++z) { + if (var->distRule[z] == dist::BLOCK) { ++countBlock; + } + } maxSizeDist = std::max(maxSizeDist, countBlock); } } @@ -324,11 +359,16 @@ void runPredictScheme(SgProject &project, // creating template ID display to avoid conflicts map templateIdMapping = createTemplateIdMapping(parallelRegions); + // Precomputing parameters of directive functions from libpredict + PrecomputedLibpredictParams precomputedParams = precomputeLibpredictParams( + project, parallelRegions, loopGraph, templateIdMapping); + // iterating through topologies to find most optimal one topologies = vector>(); if (maxSizeDist) { - - if (maxSizeDist > 4) maxSizeDist = 4; + if (maxSizeDist > 4) { + maxSizeDist = 4; + } // Initialize cluster int procCount = 0; @@ -336,7 +376,7 @@ void runPredictScheme(SgProject &project, if (retInitCluster != libpredict::INIT_CLUSTER_SUCCESS) { __spf_print(1, "ERROR: Failed to initialize libpredict cluster with config: %s, return code: %d\n", clusterConfStr.c_str(), (int)retInitCluster); - + std::wstring messageR, messageE; __spf_printToLongBuf(messageE, L"Failed to initialize libpredict cluster with config: %s, return code: %d", to_wstring(clusterConfStr).c_str(), (int)retInitCluster); @@ -347,13 +387,19 @@ void runPredictScheme(SgProject &project, for (size_t n1 = 2; n1 <= procCount; ++n1) { for (size_t n2 = 1; n2 <= n1 && n1 * n2 <= procCount; ++n2) { - if (n2 != 1 && maxSizeDist < 2 || n2 == 1 && maxSizeDist == 2) continue; - + if (n2 != 1 && maxSizeDist < 2 || n2 == 1 && maxSizeDist == 2) { + continue; + } + for (size_t n3 = 1; n3 <= n2 && n1 * n2 * n3 <= procCount; ++n3) { - if (n3 != 1 && maxSizeDist < 3 || n3 == 1 && maxSizeDist == 3) continue; + if (n3 != 1 && maxSizeDist < 3 || n3 == 1 && maxSizeDist == 3) { + continue; + } for (size_t n4 = 1; n4 <= n3 && n1 * n2 * n3 * n4 <= procCount; ++n4) { - if (n4 != 1 && maxSizeDist < 4 || n4 == 1 && maxSizeDist == 4) continue; + if (n4 != 1 && maxSizeDist < 4 || n4 == 1 && maxSizeDist == 4) { + continue; + } topologies.push_back(vector{n1, n2, n3, n4}); } @@ -363,25 +409,28 @@ void runPredictScheme(SgProject &project, vector best; double bestTime = std::numeric_limits::max(); - for (auto &topology : topologies) { - double currTime = runLibpredictCalc(project, topology, clusterConfStr, parallelRegions, loopGraph, SPF_messages, templateIdMapping); + for (auto& topology : topologies) { + double currTime = runLibpredictCalc(topology, clusterConfStr, precomputedParams, SPF_messages); string outStr = ""; - for (const auto &elem : topology) + for (const auto& elem : topology) { outStr += std::to_string(elem) + " "; + } __spf_print(1, "topology %s has time %f\n", outStr.c_str(), currTime); - if (currTime == -1) + if (currTime == -1) { return; - + } + if (currTime < bestTime) { bestTime = currTime; best = topology; } } string outStr; - for (const auto &elem : best) + for (const auto& elem : best) { outStr += std::to_string(elem) + " "; + } __spf_print(1, "best topology %s with time %f\n", outStr.c_str(), bestTime); } else { diff --git a/src/Predictor/PredictSchemeWithLibrary.h b/src/Predictor/PredictSchemeWithLibrary.h index 4e8e84b..8d6ed87 100644 --- a/src/Predictor/PredictSchemeWithLibrary.h +++ b/src/Predictor/PredictSchemeWithLibrary.h @@ -4,17 +4,54 @@ #include #include "dvm.h" #include "graph_calls.h" +#include "../../projects/libpredictor/include/libpredict/predictor.h" -void runPredictScheme(SgProject &project, - std::vector> &topologies, - const std::vector ¶llelRegions, - std::map>& loopGraph, - std::map> &SPF_messages); +struct PrecomputedDistributeParams { + size_t arrayId; + size_t elemSize; + std::vector axisDistributions; + std::vector> shadowEdges; + DIST::Array* array; +}; -double runLibpredictCalc(SgProject &project, - const std::vector& topology, - const std::string& clusterConfStr, - const std::vector ¶llelRegions, - std::map>& loopGraph, - std::map> &SPF_messages, - const std::map &templateIdMapping); +struct PrecomputedAlignParams { + size_t arrayId; + size_t distributedArrayId; + size_t elemSize; + std::vector dimensions; + std::vector distributionExpressions; + std::vector> shadowEdges; + DIST::Array* alignArray; + DIST::Array* alignWithArray; +}; + +struct PrecomputedShadowRenewParams { + size_t arrayId; + std::vector> shadow_renew; + bool corner; + size_t number_loop_iterations; + DIST::Array* shadowArray; +}; + +struct PrecomputedLibpredictParams { + std::vector distributeParams; + std::vector alignParams; + std::vector shadowRenewParams; +}; + +PrecomputedLibpredictParams precomputeLibpredictParams( + SgProject& project, + const std::vector& parallelRegions, + const std::map>& loopGraph, + const std::map& templateIdMapping); + +void runPredictScheme(SgProject& project, + std::vector>& topologies, + const std::vector& parallelRegions, + std::map>& loopGraph, + std::map>& SPF_messages); + +double runLibpredictCalc(const std::vector& topology, + const std::string& clusterConfStr, + const PrecomputedLibpredictParams& precomputedParams, + std::map>& SPF_messages);