mesytec-mnode/external/taskflow-3.8.0/3rd-party/ff/distributed/ff_dintermediate.hpp
2025-01-04 01:25:05 +01:00

179 lines
7.4 KiB
C++

#ifndef IR_HPP
#define IR_HPP
#include <ff/distributed/ff_network.hpp>
#include <ff/node.hpp>
#include <ff/all2all.hpp>
#include <list>
#include <vector>
#include <map>
#include <numeric>
namespace ff {
class ff_IR {
friend class dGroups;
protected:
// set to true if the group contains the whole parent building block
bool wholeParent = false;
void computeCoverage(){
if (!parentBB->isAll2All()) return;
ff_a2a* a2a = reinterpret_cast<ff_a2a*>(parentBB);
coverageL = coverageR = true;
for(ff_node* n : a2a->getFirstSet())
if (!L.contains(n)) {coverageL = false; break;}
for(ff_node* n : a2a->getSecondSet())
if (!R.contains(n)) {coverageR = false; break;}
}
void buildIndexes(){
if (!L.empty()){
if (parentBB->isPipe() && !wholeParent){
assert(L.size() == 1);
ff::svector<ff_node*> inputs, outputs;
for (ff_node* n : L){
n->get_in_nodes(inputs);
n->get_out_nodes(outputs);
}
for (size_t i = 0; i < inputs.size(); i++) inputL.push_back(i);
for (size_t i = 0; i < outputs.size(); i++) outputL.push_back(i);
return;
}
ff::svector<ff_node*> parentInputs;
parentBB->get_in_nodes(parentInputs);
ff::svector<ff_node*> LOutputs;
if (!parentBB->isAll2All() || wholeParent) parentBB->get_out_nodes(LOutputs);
else for(ff_node* n : reinterpret_cast<ff_a2a*>(parentBB)->getFirstSet()) n->get_out_nodes(LOutputs);
for(ff_node* n : L){
ff::svector<ff_node*> bbInputs; n->get_in_nodes(bbInputs);
for(ff_node* bbInput : bbInputs)
inputL.push_back(std::find(parentInputs.begin(), parentInputs.end(), bbInput) - parentInputs.begin());
ff::svector<ff_node*> bbOutputs; n->get_out_nodes(bbOutputs);
for(ff_node* bbOutput : bbOutputs)
outputL.push_back(std::find(LOutputs.begin(), LOutputs.end(), bbOutput) - LOutputs.begin());
}
}
if (!R.empty() && parentBB->isAll2All() && !wholeParent){
ff::svector<ff_node*> RInputs;
for(ff_node* n : reinterpret_cast<ff_a2a*>(parentBB)->getSecondSet()) n->get_in_nodes(RInputs);
ff::svector<ff_node*> parentOutputs;
parentBB->get_out_nodes(parentOutputs);
for(ff_node* n : R){
ff::svector<ff_node*> bbInputs; n->get_in_nodes(bbInputs);
for(ff_node* bbInput : bbInputs)
inputR.push_back(std::find(RInputs.begin(), RInputs.end(), bbInput) - RInputs.begin());
ff::svector<ff_node*> bbOutputs; n->get_out_nodes(bbOutputs);
for(ff_node* bbOutput : bbOutputs)
outputR.push_back(std::find(parentOutputs.begin(), parentOutputs.end(), bbOutput) - parentOutputs.begin());
}
}
}
public:
std::set<ff_node*> L, R;
bool coverageL = false, coverageR = false;
bool isSource = false, isSink = false;
bool hasReceiver = false, hasSender = false;
Proto protocol;
ff_node* parentBB;
ff_endpoint listenEndpoint;
std::vector<std::pair<ChannelType, ff_endpoint>> destinationEndpoints;
std::set<std::string> otherGroupsFromSameParentBB;
size_t expectedEOS = 0;
int outBatchSize = 1;
int messageOTF, internalMessageOTF;
// liste degli index dei nodi input/output nel builiding block in the shared memory context. The first list: inputL will become the rouitng table
std::vector<int> inputL, outputL, inputR, outputR;
// pre computed routing table for the sender module (shoud coincide with the one exchanged actually at runtime)
std::map<std::string, std::pair<std::vector<int>, ChannelType>> routingTable;
// TODO: implmentare l'assegnamento di questi campi
int leftTotalOuputs;
int rightTotalInputs;
bool isVertical(){return (L.empty() + R.empty()) == 1;}
bool hasLeftChildren() {return !L.empty();}
bool hasRightChildren() {return !R.empty();}
void insertInList(std::pair<ff_node*, SetEnum> bb, bool _wholeParent = false){
wholeParent = _wholeParent;
switch(bb.second){
case SetEnum::L: L.insert(bb.first); return;
case SetEnum::R: R.insert(bb.first); return;
}
}
std::vector<int> getInputIndexes(bool internal){
if ((isVertical() && hasRightChildren()) || (internal && !R.empty())) return inputR;
return inputL;
}
void print(){
ff::cout << "###### BEGIN GROUP ######\n";
ff::cout << "Group Orientation: " << (isVertical() ? "vertical" : "horizontal") << std::endl;
ff::cout << std::boolalpha << "Source group: " << isSource << std::endl;
ff::cout << std::boolalpha << "Sink group: " << isSink << std::endl;
ff::cout << std::boolalpha << "Coverage Left: " << coverageL << std::endl;
ff::cout << std::boolalpha << "Coverage Right: " << coverageR << std::endl << std::endl;
ff::cout << std::boolalpha << "Has Receiver: " << hasReceiver << std::endl;
ff::cout << "Expected input connections: " << expectedEOS << std::endl;
ff::cout << "Listen endpoint: " << listenEndpoint.address << ":" << listenEndpoint.port << std::endl << std::endl;
ff::cout << std::boolalpha << "Has Sender: " << hasSender << std::endl;
ff::cout << "Destination endpoints: " << std::endl;
for(auto& [ct, e] : destinationEndpoints)
ff::cout << "\t* " << e.groupName << "\t[[" << e.address << ":" << e.port << "]] - " << (ct==ChannelType::FBK ? "Feedback" : (ct==ChannelType::INT ? "Internal" : "Forward")) << std::endl;
ff::cout << "Precomputed routing table: \n";
for(auto& [gName, p] : routingTable){
ff::cout << "\t* " << gName << (p.second==ChannelType::FBK ? "Feedback" : (p.second==ChannelType::INT ? "Internal" : "Forward")) << ":";
for(auto i : p.first) ff::cout << i << " ";
ff::cout << std::endl;
}
ff::cout << "\nPrecomputed FWD destinations: " << std::accumulate(routingTable.begin(), routingTable.end(), 0, [](const auto& s, const auto& f){return s+(f.second.second == ChannelType::FWD ? f.second.first.size() : 0);}) << std::endl;
ff::cout << "Precomputed INT destinations: " << std::accumulate(routingTable.begin(), routingTable.end(), 0, [](const auto& s, const auto& f){return s+(f.second.second == ChannelType::INT ? f.second.first.size() : 0);}) << std::endl;
ff::cout << "Precomputed FBK destinations: " << std::accumulate(routingTable.begin(), routingTable.end(), 0, [](const auto& s, const auto& f){return s+(f.second.second == ChannelType::FBK ? f.second.first.size() : 0);}) << std::endl;
ff::cout << "\n\nIndex Input Left: ";
for(int i : inputL) ff::cout << i << " ";
ff::cout << "\n";
ff::cout << "Index Output Left: ";
for(int i : outputL) ff::cout << i << " ";
ff::cout << "\n";
ff::cout << "Index Input Right: ";
for(int i : inputR) ff::cout << i << " ";
ff::cout << "\n";
ff::cout << "Index Output Right: ";
for(int i : outputR) ff::cout << i << " ";
ff::cout << "\n";
ff::cout << "###### END GROUP ######\n";
}
};
}
#endif