diff --git a/src/Predictor/PredictSchemeWithLibrary.cpp b/src/Predictor/PredictSchemeWithLibrary.cpp index b4a7f14..cc9929b 100644 --- a/src/Predictor/PredictSchemeWithLibrary.cpp +++ b/src/Predictor/PredictSchemeWithLibrary.cpp @@ -22,28 +22,76 @@ using std::vector; using std::pair; using std::tuple; -// МОЖЕТ КАК-ТО ВЫЧИСЛЯТЬ ДИРЕКТИВЫ, А ПОТОМ ДЕЛАТЬ ПРОГОНЫ? -double runLibpredictCalc(SgProject &project, - const vector &topology, - const string &clusterConfStr, - const vector ¶llelRegions, - map> &loopGraph, - map> &SPF_messages) +map createTemplateIdMapping(const vector ¶llelRegions) { - libpredict::RetInit retInit = libpredict::Init(clusterConfStr, topology[0], topology[1], topology[2], topology[3]); + size_t maxArrayId = 0; + for (int z = 0; z < parallelRegions.size(); ++z) { + const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); - if (retInit != libpredict::INIT_SUCCESS) { - __spf_print(1, "ERROR: Failed to initialize libpredict with cluster config: %s, return code: %d\n", clusterConfStr.c_str(), (int)retInit); + for (const auto& distrRule : dataDirectives.distrRules) { + if (distrRule.first && !distrRule.first->IsTemplate()) { + maxArrayId = std::max(maxArrayId, (size_t)distrRule.first->GetId()); + } + } + + for (const auto& alignRule : dataDirectives.alignRules) { + if (alignRule.alignArray && !alignRule.alignArray->IsTemplate()) { + maxArrayId = std::max(maxArrayId, (size_t)alignRule.alignArray->GetId()); + } + } + } + + map templateIdMapping; + size_t nextTemplateId = maxArrayId + 1; + for (int z = 0; z < parallelRegions.size(); ++z) { + const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); + + for (const auto& distrRule : dataDirectives.distrRules) { + if (distrRule.first && distrRule.first->IsTemplate()) { + size_t originalId = distrRule.first->GetId(); + if (templateIdMapping.find(originalId) == templateIdMapping.end()) { + templateIdMapping[originalId] = nextTemplateId++; + } + } + } + + for (const auto& alignRule : dataDirectives.alignRules) { + if (alignRule.alignWith && alignRule.alignWith->IsTemplate()) { + size_t originalId = alignRule.alignWith->GetId(); + if (templateIdMapping.find(originalId) == templateIdMapping.end()) { + templateIdMapping[originalId] = nextTemplateId++; + } + } + } + } + + return templateIdMapping; +} + +// TODO: вычислять директивы разово заранее +double runLibpredictCalc(SgProject &project, + const vector& topology, + const string& clusterConfStr, + const vector ¶llelRegions, + map>& loopGraph, + map> &SPF_messages, + 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 library with cluster config: %s, return code: %d", - to_wstring(clusterConfStr).c_str(), (int)retInit); - __spf_printToLongBuf(messageR, R206); - getObjectForFileFromMap(clusterConfStr.c_str(), SPF_messages).push_back(Messages(ERROR, 1, messageR, messageE, 1063)); + __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 и align из parallelRegions + // 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(); @@ -60,7 +108,16 @@ double runLibpredictCalc(SgProject &project, const DistrVariant* variant = distrRule.second; if (array && variant && !array->IsNotDistribute()) { - size_t arrayId = array->GetId(); + size_t originalId = array->GetId(); + size_t arrayId = originalId; + + if (array->IsTemplate()) { + auto it = templateIdMapping.find(originalId); + if (it != templateIdMapping.end()) { + arrayId = it->second; + } + } + size_t elemSize = array->GetTypeSize(); vector axisDistributions; @@ -92,9 +149,9 @@ double runLibpredictCalc(SgProject &project, 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, R207); + __spf_printToLongBuf(messageR, R208); getObjectForFileFromMap(array->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back( - Messages(ERROR, array->GetDeclInfo().begin()->second, messageR, messageE, 1064)); + Messages(ERROR, array->GetDeclInfo().begin()->second, messageR, messageE, 1065)); } } } @@ -106,13 +163,24 @@ double runLibpredictCalc(SgProject &project, if (alignArray && alignWithArray && !alignArray->IsNotDistribute()) { size_t arrayId = alignArray->GetId(); - size_t distributedArrayId = alignWithArray->GetId(); + size_t originalDistributedArrayId = alignWithArray->GetId(); + size_t distributedArrayId = originalDistributedArrayId; + + if (alignWithArray->IsTemplate()) { + auto it = templateIdMapping.find(originalDistributedArrayId); + if (it != templateIdMapping.end()) { + distributedArrayId = it->second; + } + } + size_t elemSize = alignArray->GetTypeSize(); const auto& arraySizes = alignArray->GetSizes(); vector dimensions; - for (int dim = 0; dim < alignArray->GetDimSize(); ++dim) - dimensions.push_back(arraySizes[dim].second - arraySizes[dim].first + 1); + for (int dim = 0; dim < alignArray->GetDimSize(); ++dim) { + size_t dimSize = arraySizes[dim].second - arraySizes[dim].first + 1; + dimensions.push_back(dimSize); + } vector distributionExpressions; for (int dim = 0; dim < alignWithArray->GetDimSize(); ++dim) { @@ -155,9 +223,9 @@ double runLibpredictCalc(SgProject &project, __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, R208); + __spf_printToLongBuf(messageR, R209); getObjectForFileFromMap(alignArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back( - Messages(ERROR, alignArray->GetDeclInfo().begin()->second, messageR, messageE, 1065)); + Messages(ERROR, alignArray->GetDeclInfo().begin()->second, messageR, messageE, 1066)); } } } @@ -194,7 +262,6 @@ double runLibpredictCalc(SgProject &project, } bool corner = directive->shadowRenewCorner[shadowIdx]; - size_t number_loop_iterations = loopPtr ? static_cast(loopPtr->countOfIters) : 1; libpredict::RetShadowRenew retShadowRenew = libpredict::ShadowRenew(arrayId, shadow_renew, corner, number_loop_iterations); @@ -206,9 +273,9 @@ double runLibpredictCalc(SgProject &project, 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, R209); + __spf_printToLongBuf(messageR, R210); getObjectForFileFromMap(shadowArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back( - Messages(ERROR, shadowArray->GetDeclInfo().begin()->second, messageR, messageE, 1066)); + Messages(ERROR, shadowArray->GetDeclInfo().begin()->second, messageR, messageE, 1067)); } } } @@ -222,7 +289,7 @@ double runLibpredictCalc(SgProject &project, void runPredictScheme(SgProject &project, vector> &topologies, const vector ¶llelRegions, - map> &loopGraph, + map>& loopGraph, map> &SPF_messages) { // calculating maximum dimension of distribution @@ -254,22 +321,40 @@ void runPredictScheme(SgProject &project, clusterConfStr = firstFilePath.substr(0, lastSlash + 1) + "cluster.conf"; } + // creating template ID display to avoid conflicts + map templateIdMapping = createTemplateIdMapping(parallelRegions); + // iterating through topologies to find most optimal one topologies = vector>(); if (maxSizeDist) { if (maxSizeDist > 4) maxSizeDist = 4; - // TODO: look at cluster configuration - size_t n1max = 10; - size_t n2max = (maxSizeDist >= 2) ? 10 : 1; - size_t n3max = (maxSizeDist >= 3) ? 10 : 1; - size_t n4max = (maxSizeDist >= 4) ? 10 : 1; + // Initialize cluster + int procCount = 0; + libpredict::RetInitCluster retInitCluster = libpredict::InitCluster(clusterConfStr, procCount); + + 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); + __spf_printToLongBuf(messageR, R206); + getObjectForFileFromMap(clusterConfStr.c_str(), SPF_messages).push_back(Messages(ERROR, 1, messageR, messageE, 1063)); + return; + } + + 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; + + for (size_t n3 = 1; n3 <= n2 && n1 * n2 * n3 <= procCount; ++n3) { + 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; - for (size_t n1 = 1; n1 <= n1max; ++n1) { - for (size_t n2 = 1; n2 <= n2max; ++n2) { - for (size_t n3 = 1; n3 <= n3max; ++n3) { - for (size_t n4 = 1; n4 <= n4max; ++n4) { topologies.push_back(vector{n1, n2, n3, n4}); } } @@ -279,13 +364,12 @@ void runPredictScheme(SgProject &project, vector best; double bestTime = std::numeric_limits::max(); for (auto &topology : topologies) { - // if (DEBUG) { - // string outStr = ""; - // for (const auto &elem : top) - // outStr += std::to_string(elem) + " "; - // __spf_print(1, "topology %s has time %f\n", outStr.c_str(), currTime); - // } - double currTime = runLibpredictCalc(project, topology, clusterConfStr, parallelRegions, loopGraph, SPF_messages); + double currTime = runLibpredictCalc(project, topology, clusterConfStr, parallelRegions, loopGraph, SPF_messages, templateIdMapping); + + string outStr = ""; + 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) return; diff --git a/src/Predictor/PredictSchemeWithLibrary.h b/src/Predictor/PredictSchemeWithLibrary.h index 136d75d..4e8e84b 100644 --- a/src/Predictor/PredictSchemeWithLibrary.h +++ b/src/Predictor/PredictSchemeWithLibrary.h @@ -8,12 +8,13 @@ void runPredictScheme(SgProject &project, std::vector> &topologies, const std::vector ¶llelRegions, - std::map> &loopGraph, + std::map>& loopGraph, std::map> &SPF_messages); double runLibpredictCalc(SgProject &project, - const std::vector &topology, - const std::string &clusterConfStr, + const std::vector& topology, + const std::string& clusterConfStr, const std::vector ¶llelRegions, - std::map> &loopGraph, - std::map> &SPF_messages); + std::map>& loopGraph, + std::map> &SPF_messages, + const std::map &templateIdMapping); diff --git a/src/Utils/errors.h b/src/Utils/errors.h index c108a9e..a148ec5 100644 --- a/src/Utils/errors.h +++ b/src/Utils/errors.h @@ -78,11 +78,12 @@ enum typeMessage { WARR, ERROR, NOTE }; // 60 "Format misplaced" // 61 "Array has declaration area conflict" // 62 "need to move common declaration to main for DECLATE" -// 63 "Failed to initialize libpredict library" -// 64 "Failed to distribute array with libpredict" -// 65 "Failed to align array with libpredict" -// 66 "Failed to process shadow_renew with libpredict" -// +// 63 "Failed to initialize libpredict cluster" +// 64 "Failed to initialize libpredict grid" +// 65 "Failed to distribute array with libpredict" +// 66 "Failed to align array with libpredict" +// 67 "Failed to process shadow_renew with libpredict" +// // 20xx TRANSFORM GROUP // 01 "can not convert array assign to loop" // 02 "converted arithmetic IF to simple IF" @@ -309,7 +310,7 @@ static void printStackTrace() { }; } \ } while (0) -// Свободный - R209 +// Свободный - R210 // Гайд по русификации сообщений: При добавлении нового сообщения, меняется последний сводобный идентификатор. // В этом файле остаются только спецификаторы, для которых будет заполнен текст. Полный текст пишется в файле // russian_errors_text.txt. Спецификаторы там тоже сохраняются, по ним в визуализаторе будет восстановлен @@ -516,6 +517,8 @@ static const wchar_t* R207 = L"R207:"; static const wchar_t* R208 = L"R208:"; //1066 static const wchar_t* R209 = L"R209:"; +//1067 +static const wchar_t* R210 = L"R210:"; //2001 static const wchar_t *R94 = L"R94:"; diff --git a/src/Utils/russian_errors_text.txt b/src/Utils/russian_errors_text.txt index 5a0338b..081b4fb 100644 --- a/src/Utils/russian_errors_text.txt +++ b/src/Utils/russian_errors_text.txt @@ -189,11 +189,13 @@ R205 = "Массив '%s' состоящий в common блоке '%s' долж //1063 R206 = "Ошибка инициализации библиотеки libpredict с конфигурацией кластера: %s, код возврата: %d" //1064 -R207 = "Ошибка распределения массива '%s' с помощью libpredict, код возврата: %d" +R207 = "Ошибка инициализации сетки libpredict с топологией: %zu %zu %zu %zu, код возврата: %d" //1065 -R208 = "Ошибка выравнивания массива '%s' с массивом '%s' с помощью libpredict, код возврата: %d" +R208 = "Ошибка распределения массива '%s' с помощью libpredict, код возврата: %d" //1066 -R209 = "Ошибка обработки shadow_renew для массива '%s' с помощью libpredict, код возврата: %d" +R209 = "Ошибка выравнивания массива '%s' с массивом '%s' с помощью libpredict, код возврата: %d" +//1067 +R210 = "Ошибка обработки shadow_renew для массива '%s' с помощью libpredict, код возврата: %d" //2001 R94 = "Невозможно автоматически преобразовать данное присваивание к циклу"