16 #include <unordered_map>
17 #include <unordered_set>
34 return os <<
"MappingStatus{" <<
static_cast<int>(ms) <<
'}';
62 mapping[opnode].push_back(node);
64 catch(
const std::exception & e)
66 throw cgrame_error(std::string(
"Mapping Exception Thrown by: [") + e.what() +
"] at File: " + std::string(__FILE__) +
" Line: " +
std::to_string(__LINE__));
80 catch(
const std::exception & e)
82 throw cgrame_error(std::string(
"Mapping Exception Thrown by: [") + e.what() +
"] at File: " + std::string(__FILE__) +
" Line: " +
std::to_string(__LINE__));
92 this->mapping[node] = std::move(
mapping);
105 for(
auto & fo : src->
fanout)
107 if(fo == sink && std::find(sink->
fanin.begin(), sink->
fanin.end(), src) != sink->
fanin.end())
112 if(std::find(val_map.begin(), val_map.end(), fo) != val_map.end())
113 if(visited.find(fo) == visited.end())
115 if(
find_sink(val_map, visited, fo, sink))
126 for(
auto & op :
opgraph->opNodes())
130 std::cout <<
"Verify FAILED: Op mapped to more than FU. Op=\'" << *op <<
"\'" << std::endl;
133 else if(
mapping[op].size() == 0)
135 std::cout <<
"Verify FAILED: Op mapped to no FU. Op=\'" << *op <<
"\'" << std::endl;
140 if(!
mapping[op][0]->canMapOp(op))
142 std::cout <<
"Verify FAILED: Op mapped to more illegal FU. Op=\'" << *op <<
"\'" << std::endl;
148 for(
auto & val1 :
opgraph->valNodes())
150 for(
auto & val2 :
opgraph->valNodes())
154 for(
auto & node1 :
mapping[val1])
156 for(
auto & node2 :
mapping[val2])
160 std::cout <<
"Verify FAILED: Different vals mapped to same route. Val1=\'" << *val1 <<
"\' Val2=\'" << *val2 <<
"\'" << std::endl;
169 for(
auto & val :
opgraph->valNodes())
171 std::cout <<
"Verifying Value: " << *val << std::endl;
172 for(
int i = 0; i < (std::ptrdiff_t)val->output.size(); i++)
176 std::cout <<
"Finding sink \'" << *sinkfu <<
"(operand=" << val->output_operand[i] <<
")" << std::endl;
177 std::map<MRRG::NodeDescriptor,bool> visited;
180 std::cout <<
"Verify FAILED: Disconnect between " << *(val->input) <<
"/" << *srcfu <<
" -> " << *(val->output[i]) <<
"/" << *sinkfu <<
"(operand=" <<val->output_operand[i] <<
")" << std::endl;
181 std::cout <<
"Could not find sink \'" << *sinkfu <<
"(operand=" << val->output_operand[i] <<
")" << std::endl;
188 std::cout <<
"Found sink \'" << *sinkfu <<
"(operand=" << val->output_operand[i] <<
")" << std::endl;
196 template<
typename STREAM,
typename MAPPING,
typename KEY>
197 void if_found_print_single_mapping_else_print_message(STREAM& o, MAPPING&& m, KEY&& k) {
198 auto find_result = m.find(k);
199 if (find_result ==
end(m)) {
200 o <<
"__NOT_MAPPED__";
202 auto& mapping_list = m.at(k);
203 if (mapping_list.size() == 1) {
204 o << **
begin(mapping_list);
211 template<
typename STREAM,
typename MAPPING,
typename KEY>
212 void if_found_print_mapping_else_print_message(STREAM& o, MAPPING&& m, KEY&& k) {
213 auto find_result = m.find(k);
214 if (find_result ==
end(m)) {
215 o <<
"__NOT_MAPPED__";
217 for(
auto & node : m.at(k)) {
218 o <<
" " << *node << std::endl;
226 o <<
"Operation Mapping Result:" << std::endl;
227 for(
auto & op :
opgraph.opNodes())
230 if_found_print_mapping_else_print_message(o,
mapping, op);
234 o <<
"Connection Mapping Result:" << std::endl;
235 for(
auto & val :
opgraph.valNodes())
237 o << *val <<
":" << std::endl;
238 if_found_print_mapping_else_print_message(o,
mapping, val);
245 o <<
"Operation Mapping Result:" << std::endl;
246 for(
auto & op :
opgraph->opNodes())
249 if_found_print_mapping_else_print_message(o,
mapping, op);
269 o <<
"digraph G {\n";
270 for(
auto & r :
mapping.at(val))
272 for(
auto & fo : r->fanout)
276 o <<
"\"" << *r <<
"\""<<
"->" <<
"\""<< *fo <<
"\""<<
"\n";
290 const std::unordered_map<OpGraph::NodeDescriptor, OpGraph::NodeDescriptor>& forward_mappings
292 Mapping result(std::shared_ptr<CGRA>(), src.
getII(), std::shared_ptr<OpGraph>());
293 for (
const auto& src_and_dest_og_nodes : forward_mappings) {
294 if (not src.
hasMapping(src_and_dest_og_nodes.first)) {
continue; }
295 for (
const auto& mrrg_node : src.
getMappingList(src_and_dest_og_nodes.first)) {
296 result.
mapMRRGNode(src_and_dest_og_nodes.second, mrrg_node);
304 nodes.emplace(nextId, std::move(node));
305 fanout_lists.emplace(nextId, std::vector<NodeDescriptor>());
306 fanin_lists.emplace(nextId, std::vector<NodeDescriptor>());
308 auto thisId = nextId;
310 return {thisId,
true};
318 if (driver ==
fanout)
return;
360 return nodes.at(ndesc);
364 return nodes.at(ndesc);
373 std::vector<VerifyMessage> verifyMessages;
374 std::queue<MappingGraph::NodeDescriptor> toVisit;
375 std::unordered_set<MappingGraph::NodeDescriptor, NodeDescriptorHash> visited;
376 for (
auto & node:
nodes) {
379 toVisit.push(node.first);
382 while (!toVisit.empty()) {
383 auto currentNode = toVisit.front();
384 if (visited.find(currentNode) != visited.end()) {
388 visited.emplace(currentNode);
390 if (visited.find(
fanout) != visited.end()) {
continue; }
394 if (visited.find(
fanin) != visited.end()) {
continue; }
401 int isolatedNodeNum = 0;
402 for (
auto node:
nodes) {
403 if (visited.find(node.first) == visited.end()) {
409 if (isolatedNodeNum > 0) {
416 return verifyMessages;
420 os <<
"digraph {\ngraph[";
423 for (
auto & attr : archAttrs) {
424 os << attr.first <<
"=\"" << attr.second <<
"\", ";
427 os <<
"splines=ortho, concentrate=true, landscape=false];\nnode[shape=record, fixedsize=true, height=0.8, width=2, fontsize=7, fontname=\"times bold\"];\n";
430 std::unordered_map<Module*, std::vector<NodeDescriptor>> moduleToMG;
431 for (
const auto& mg_ndesc_and_node : this->
allNodes()) {
432 auto& mg_ndesc = mg_ndesc_and_node.first;
433 const auto& mrrg_node = mrrg.
getNodeRef(toMRRG.at(mg_ndesc));
434 const auto mrrg_node_name = mrrg_node.
getFullName();
442 os <<
", cycle=" << mrrg_node.cycle;
444 os <<
", maps_to_op=";
447 os <<
", maps_to_val=";
450 os <<
", label=\"{" << mrrg_node_name <<
"|" << op_name <<
"}\"";
456 for (
const auto& mg_ndesc_and_node : this->
allNodes()) {
457 const auto& mg_ndesc = mg_ndesc_and_node.first;
458 const auto& mg_ndesc_fanout = this->
fanout(mg_ndesc);
471 std::unordered_map<MRRG::NodeDescriptor, MappingGraph::NodeDescriptor> fromMRRG;
472 std::unordered_map<MappingGraph::NodeDescriptor, MRRG::NodeDescriptor, MappingGraph::NodeDescriptorHash> toMRRG;
475 for (
auto & opToMRRGNodeList : mapping) {
476 for (
auto & mrrgNode : opToMRRGNodeList.second) {
477 auto mgNode = mg.
insert({opToMRRGNodeList.first}).first;
478 toMRRG.emplace(mgNode, mrrgNode);
479 fromMRRG.emplace(mrrgNode, mgNode);
484 for (
auto & opToMRRGNodeList1: mapping) {
485 for (
auto & mrrgNodeA : opToMRRGNodeList1.second) {
486 for (
auto & opToMRRGNodeList2: mapping) {
487 for (
auto & mrrgNodeB : opToMRRGNodeList2.second) {
488 if (mrrgNodeA == mrrgNodeB)
continue;
491 const auto& nodeAfanout = mrrg.
fanout(mrrgNodeA);
492 if (std::find(nodeAfanout.begin(), nodeAfanout.end(), mrrgNodeB) != nodeAfanout.end()) {
494 mg.
link(fromMRRG.at(mrrgNodeA), fromMRRG.at(mrrgNodeB));
501 return {mg, fromMRRG, toMRRG};
508 std::queue<MappingGraph::NodeDescriptor> toVisit;
510 std::unordered_set<MappingGraph::NodeDescriptor, MappingGraph::NodeDescriptorHash> visited;
513 for (
auto & node: fixedGraph.
allNodes()) {
516 toVisit.push(node.first);
519 while (!toVisit.empty()) {
520 auto currentNode = toVisit.front();
521 if (visited.find(currentNode) != visited.end()) {
525 visited.emplace(currentNode);
526 for (
auto & fanout: fixedGraph.
fanout(currentNode)) {
527 if (visited.find(fanout) != visited.end()) {
continue; }
528 toVisit.push(fanout);
530 for (
auto & fanin: fixedGraph.
fanin(currentNode)) {
531 if (visited.find(fanin) != visited.end()) {
continue; }
538 std::vector<MappingGraph::NodeDescriptor> nodesToDelete;
539 for (
auto node: fixedGraph.
allNodes()) {
540 if (visited.find(node.first) == visited.end()) {
541 nodesToDelete.emplace_back(node.first);
544 for (
auto node: nodesToDelete) {
545 fixedGraph.
erase(node);
548 return std::move(fixedGraph);
554 bool latencyCheckBFS(
557 std::set<MappingGraph::NodeDescriptor>& checkCycle,
558 std::set<MappingGraph::NodeDescriptor>& check0Cycle,
566 bool latencyCheckBFSCycle(
575 bool latencyCheck0Cycle(
597 bool balanced =
true;
600 std::set<MappingGraph::NodeDescriptor> checkCycle;
601 std::set<MappingGraph::NodeDescriptor> check0Cycle;
604 std::deque<MappingGraph::NodeDescriptor> toSearch;
605 for (
auto node: mapping.
allNodes()) {
606 if (mapping.
fanin(node.first).empty()) {
607 toSearch.push_front(node.first);
610 toSearch.push_back(node.first);
615 while (!toSearch.empty()) {
616 if (latenciesInfo.find(toSearch.front()) == latenciesInfo.end()) {
617 if (!latencyCheckBFS(mapping, latenciesInfo, toSearch.front(), checkCycle, check0Cycle, mrrg, toMRRG)) {
621 toSearch.pop_front();
624 for (
auto node : checkCycle) {
625 if (!latencyCheckBFSCycle(mapping, node, mrrg, toMRRG)) {
630 std::unordered_set<MappingGraph::NodeDescriptor, MappingGraph::NodeDescriptorHash> check0CycleLeft;
631 for (
auto node: check0Cycle) {
632 check0CycleLeft.insert(node);
634 for (
auto node : check0Cycle) {
635 if (check0CycleLeft.find(node) != check0CycleLeft.end()) {
636 if (!latencyCheck0Cycle(mapping, node, mrrg, toMRRG, check0CycleLeft)) {
642 return {balanced, latenciesInfo};
647 bool latencyCheckBFS(
650 std::set<MappingGraph::NodeDescriptor>& checkCycle,
651 std::set<MappingGraph::NodeDescriptor>& check0Cycle,
658 bool balanced =
true;
661 using nodeLatencyPair = std::pair<MappingGraph::NodeDescriptor, int>;
662 std::queue<nodeLatencyPair> toVisit;
663 toVisit.emplace(start, 0);
664 std::queue<bool> isFanout;
665 isFanout.emplace(
true);
670 while (!toVisit.empty()) {
671 auto currentNodeLatencyP = toVisit.front();
672 bool canCycleCheck = isFanout.front();
677 if (currentNodeLatencyP.second < offset) {
678 offset = currentNodeLatencyP.second;
682 if (latenciesInfo.find(currentNodeLatencyP.first) != latenciesInfo.end()) {
683 if (latenciesInfo[currentNodeLatencyP.first] < currentNodeLatencyP.second) {
685 latenciesInfo[currentNodeLatencyP.first] = currentNodeLatencyP.second;
689 latenciesInfo.emplace(currentNodeLatencyP);
693 if (latencies.find(currentNodeLatencyP.first) != latencies.end()) {
695 if (latencies.at(currentNodeLatencyP.first) == currentNodeLatencyP.second) {
696 check0Cycle.emplace(currentNodeLatencyP.first);
700 else if (latencies.at(currentNodeLatencyP.first) + II == currentNodeLatencyP.second) {
702 checkCycle.emplace(currentNodeLatencyP.first);
706 else if (latencies.at(currentNodeLatencyP.first) - II == currentNodeLatencyP.second) {
708 checkCycle.emplace(currentNodeLatencyP.first);
717 latencies.insert(currentNodeLatencyP);
718 for (
auto & fanout: mapping.
fanout(currentNodeLatencyP.first)) {
720 if (latencies.find(fanout) != latencies.end() && latencies.at(fanout) == currentNodeLatencyP.second + getMRRGNode(currentNodeLatencyP.first).latency) {
725 toVisit.emplace(fanout, currentNodeLatencyP.second+getMRRGNode(currentNodeLatencyP.first).latency);
726 isFanout.emplace(
true);
729 for (
auto & fanin: mapping.
fanin(currentNodeLatencyP.first)) {
730 if (latencies.find(fanin) != latencies.end()) {
736 toVisit.emplace(fanin, currentNodeLatencyP.second - getMRRGNode(fanin).latency);
737 isFanout.emplace(
false);
745 for (
auto node: latencies) {
746 latenciesInfo[node.first] -= offset;
753 bool latencyCheckBFSCycle(
757 using nodeLatencyPair = std::pair<MappingGraph::NodeDescriptor, int>;
758 std::queue<nodeLatencyPair> toVisit;
769 for (
auto & fanout: mapping.
fanout(start)) {
770 toVisit.emplace(fanout, getMRRGNode(start).latency);
773 while (!toVisit.empty()) {
774 auto currentNodeLatencyP = toVisit.front();
776 if (visited.find(currentNodeLatencyP.first) != visited.end()) {
777 if (visited[currentNodeLatencyP.first].find(currentNodeLatencyP.second) != visited[currentNodeLatencyP.first].end()) {
780 visited[currentNodeLatencyP.first].emplace(currentNodeLatencyP.second);
783 visited.emplace(currentNodeLatencyP.first, std::unordered_set<int>() = {currentNodeLatencyP.second});
786 if (currentNodeLatencyP.first == start) {
789 if (currentNodeLatencyP.second != II) {
798 else if (currentNodeLatencyP.second <= II) {
799 for (
auto & fanout: mapping.
fanout(currentNodeLatencyP.first)) {
800 toVisit.emplace(fanout, currentNodeLatencyP.second+getMRRGNode(currentNodeLatencyP.first).latency);
809 bool latencyCheck0Cycle(
812 std::unordered_set<MappingGraph::NodeDescriptor, MappingGraph::NodeDescriptorHash> & nodesToCheck
815 using nodeLatencyPair = std::pair<MappingGraph::NodeDescriptor, int>;
816 std::queue<nodeLatencyPair> toVisit;
822 for (
auto & fanout: mapping.
fanout(start)) {
823 toVisit.emplace(fanout, getMRRGNode(start).latency);
826 while (!toVisit.empty()) {
827 auto currentNodeLatencyP = toVisit.front();
829 if (nodesToCheck.find(currentNodeLatencyP.first) != nodesToCheck.end()) {
830 nodesToCheck.erase(nodesToCheck.find(currentNodeLatencyP.first));
833 if (currentNodeLatencyP.first == start) {
834 if (currentNodeLatencyP.second == 0) {
842 else if (currentNodeLatencyP.second <= II) {
843 for (
auto & fanout: mapping.
fanout(currentNodeLatencyP.first)) {
844 toVisit.emplace(fanout, currentNodeLatencyP.second+getMRRGNode(currentNodeLatencyP.first).latency);