33 const std::string placement_filename)
36 , l_isElastic(isElastic)
37 , l_placement_filename(placement_filename)
42 for (
const auto& mrrg_node : classes.routing_nodes) {
45 double baseCost = 1.0;
52 Mapping mapping_result = placed;
76 bool operator<(
const NetInfo& rhs)
const {
77 return fanout > rhs.fanout && max_cycles > rhs.max_cycles;
81 std::vector<NetInfo> nets;
89 auto& src_op = val_node->input;
91 for (
auto& sink_op : val_node->output) {
94 nets.push_back({val_node,
false, max_cycles, (unsigned)val_node->output.size()});
96 std::sort(nets.begin(), nets.end());
100 while (!mapped && i < 70 && routed) {
104 for (
auto& net : nets) {
105 auto& val_node = net.val_node;
106 if (
l_verbosity > 0) std::cout <<
"Ripping out node: " << val_node->getName() << std::endl;
110 if (
l_verbosity > 0) std::cout <<
"Routing node: " << val_node->getName() << std::endl;
114 if (!routed && i > 1) {
115 throw cgrame_error(
"ERR: net: " + val_node->getName() +
" could not be routed");
123 mapped = mrrg_overuse && opgraph_covered;
124 std::cout <<
"overuse_ok=" << mrrg_overuse;
125 std::cout <<
" opgraph_covered=" << opgraph_covered << std::endl;
142 mrrg_node.second.hCost = 0;
149 return mapping_result;
153 bool is_covered =
true;
156 if (lookup ==
l_mapping.end() || lookup->second.empty()) {
164 int num_of_resources_used = 0;
166 int occupancy = nodelist.second.occupancy;
167 const MRRGNode* node = nodelist.first;
169 num_of_resources_used++;
172 std::cout <<
"Number of routing resoucres used: " << num_of_resources_used << std::endl;
178 int num_of_overuse = 0;
180 int occupancy = nodelist.second.occupancy;
181 const MRRGNode* node = nodelist.first;
182 bool overuse = occupancy > node->
capacity;
186 for (
auto& value : nodelist.second.mapped_values) {
210 throw cgrame_error(
"Cannot find value (" + val->getName() +
") mapped to the mrrg node (" + n->getFullName() +
")\n");
232 double oc_cost = (
l_p_factor*(oc <= cap ? 1 : (oc - cap)));
233 return base_cost + h_cost + oc_cost;
246 struct SinkAndLatency {
251 bool operator<(
const SinkAndLatency& rhs)
const {
252 if (cycles == rhs.cycles) {
253 return sink_op < rhs.sink_op;
255 return cycles > rhs.cycles;
264 const auto& the_single_fanout =
l_mrrg.
fanout(src).at(0);
267 std::priority_queue<SinkAndLatency> sinks;
268 std::map<SinkAndLatency, std::vector<OperandTag>> sink_tags;
269 for (
int isink_op = 0; isink_op != val->
output.size(); ++isink_op) {
270 const auto& sink_op = val->
output.at(isink_op);
273 SinkAndLatency sl = {
l_placement.at(sink_op), sink_op, cycles_to_sink};
274 if (sink_tags.find(sl) == sink_tags.end()) {
278 throw cgrame_error(
"Operation: " + sink_op->getName() +
" have two similar tags: " + op_tag +
279 " from operation: " + src_op->
getName());
281 sink_tags[sl].push_back(op_tag);
284 std::cout <<
"MAPPING From: "<< val->
input->
getName() <<
" ";
285 for (
auto op : val->
output) {
286 std::cout << op->getName() <<
" ";
288 std::cout << sinks.size() <<
" " << sink_tags.size() << std::endl;
289 std::set<const MRRGNode*> routes;
291 while (!sinks.empty()) {
292 auto sink = sinks.top();
294 std::cout << *sink.sink_node << std::endl;
295 for (
auto tag : sink_tags[sink]) {
296 std::cout << src_op->
getName() <<
" " << sink.sink_op->getName() <<
" " << sink.cycles << tag << std::endl;
297 std::vector<const MRRGNode*> route =
dijkstraVisit(the_single_fanout, sink.sink_node, tag,
298 val, routes, sink.cycles, latency_of_src);
299 if (route.empty())
return false;
300 std::copy(route.begin(), route.end(), std::inserter(routes, routes.end()));
304 for (
const auto& node : routes) {
319 std::set<const MRRGNode*> routes,
int cycles_to_sink,
int latency_of_src) {
324 std::vector<const MRRGNode*> fanin;
325 Cost lowest_known_cost;
328 bool operator==(
const VertexData& rhs)
const {
329 return this->lowest_known_cost == rhs.lowest_known_cost && this->fanin == rhs.fanin
330 && num_of_cycles == rhs.num_of_cycles && tag_found == rhs.tag_found;
335 struct VertexAndCost {
340 bool operator<(
const VertexAndCost& rhs)
const {
341 return cost_to_here > rhs.cost_to_here;
346 auto data = std::unordered_map<std::pair<MRRGNodeDesc, Latency>, VertexData,
pair_hash>();
348 std::priority_queue<VertexAndCost> to_visit;
350 std::set<std::pair<MRRGNodeDesc, Latency>> visited;
353 to_visit.push({source, 0, latency_of_src});
354 data.insert({{source, latency_of_src}, {{source}, 0, latency_of_src,
false}});
356 bool tag_found =
false;
357 while (!to_visit.empty() && !found) {
359 const auto queue_top = to_visit.top();
361 Latency cycles_to_curr = queue_top.cycles;
365 if (visited.find({explore_curr, cycles_to_curr}) != visited.end())
continue;
369 if (!found && sink == explore_curr) {
370 if (cycles_to_sink == cycles_to_curr || cycles_to_sink ==
kUndefLatency) {
371 found = explore_curr;
373 visited.emplace(explore_curr, cycles_to_curr);
374 data.erase({explore_curr, cycles_to_curr});
382 if (fanout == source)
continue;
386 if (
l_routing_nodes[explore_curr].mapped_values.size() != 0 && fanout == sink)
continue;
393 if (fanout->bitwidth < val->
bitwidth)
continue;
397 if (!routes.count(explore_curr) && routes.count(fanout))
continue;
400 auto data_curr = data[{explore_curr, cycles_to_curr}];
403 if (data_curr.tag_found && fanout != sink)
continue;
406 Cost cost = queue_top.cost_to_here +
getCost(fanout);
407 Latency cycles = data_curr.num_of_cycles;
409 if (std::find(data_curr.fanin.begin(), data_curr.fanin.end(), fanout)
410 != data_curr.fanin.end())
continue;
418 if (cycles > cycles_to_sink && cycles_to_sink !=
kUndefLatency)
continue;
420 if (data.find({fanout, cycles}) != data.end()) {
421 if (data[{fanout, cycles}].lowest_known_cost <= cost) {
424 data.erase({fanout, cycles});
431 if (fanout->supported_operand_tags.find(tag_to_find) == fanout->supported_operand_tags.end()) {
434 if (
l_routing_nodes[fanout].mapped_values.size() == 0 && routes.count(fanout) == 0)
438 if (fanout->supported_operand_tags.find(tag_to_find) == fanout->supported_operand_tags.end()) {
441 if (
l_routing_nodes[fanout].mapped_values.size() == 0 && routes.count(fanout) == 0)
445 if (!tag_found)
continue;
449 data[{fanout, cycles}] = {data[{explore_curr, cycles_to_curr}].fanin, cost, cycles};
450 data[{fanout, cycles}].fanin.push_back(explore_curr);
451 data[{fanout, cycles}].tag_found = tag_found;
452 to_visit.push({fanout, cost, cycles});
457 visited.emplace(explore_curr, cycles_to_curr);
458 data.erase({explore_curr, cycles_to_curr});
462 std::cout << to_visit.empty() << std::endl;
463 std::cout <<
"NOT FOUND" << std::endl;
464 std::cout << source <<
" " << sink->
getFullName() <<
" " << data.size() << std::endl;
466 std::cout <<
"cost " << data[{sink, cycles_to_sink}].lowest_known_cost << std::endl;
467 for (
auto data_i : data[{sink, cycles_to_sink}].fanin) {
468 std::cout << data_i->getFullName() << std::endl;
470 return data[{sink, cycles_to_sink}].fanin;
476 std::cout <<
"[INFO] Getting placement information from DOT file: " <<
l_placement_filename<< std::endl;
482 for (
const auto& v : parsed_placement_dot.
allNodes()) {
483 const auto& v_attrs = parsed_placement_dot.
attributes(v);
484 const bool isOp = v_attrs.
hasKey(
"maps_to_op");
487 throw make_from_stream<cgrame_error>([&](
auto&& s) {
488 s <<
"mrrg node: " << parsed_placement_dot.
name(v) <<
" is not mapped to anything";
492 std::string mrrg_node_name = parsed_placement_dot.
name(v);
494 op_name = v_attrs.getString(
"maps_to_op");
497 if (mrrg_ndesc ==
nullptr) {
498 throw make_from_stream<cgrame_error>([&](
auto&& s) {
499 s <<
"[ERROR]: mrrg node: " << v_attrs.getInt(
"cycle") <<
":" <<
500 v_attrs.getString(
"name") <<
" is not part of specified architecture";
505 if (op_ndesc ==
nullptr) {
506 throw make_from_stream<cgrame_error>([&](
auto&& s) {
507 s <<
"[ERROR]: op node: "<< op_name <<
" is not part of specified dfg graph";