19#ifndef BF_P4C_PHV_PARSER_EXTRACT_BALANCE_SCORE_H_
20#define BF_P4C_PHV_PARSER_EXTRACT_BALANCE_SCORE_H_
32#include "backends/tofino/bf-p4c/common/table_printer.h"
33#include "backends/tofino/bf-p4c/phv/phv.h"
41 std::map<PHV::Size, unsigned> use = {
42 {PHV::Size::b8, 0}, {PHV::Size::b16, 0}, {PHV::Size::b32, 0}};
47 for (
auto c : containers) use[c.type().size()]++;
112 BUG_CHECK(use.size() == 3 && b.use.size() == 3,
"malformed extractor use");
114 if (total_bytes() < b.total_bytes())
return true;
115 if (total_bytes() > b.total_bytes())
return false;
117 auto a_sorted = sorted();
118 auto b_sorted = b.sorted();
120 unsigned a_delta = a_sorted[2] - a_sorted[0];
121 unsigned b_delta = b_sorted[2] - b_sorted[0];
123 if (a_delta < b_delta)
return true;
124 if (a_delta > b_delta)
return false;
126 unsigned a_over_four = 0;
127 unsigned b_over_four = 0;
130 if (u.second > 4) a_over_four++;
133 for (
auto u : b.use) {
134 if (u.second > 4) b_over_four++;
137 if (a_over_four < b_over_four)
return true;
138 if (a_over_four > b_over_four)
return false;
140 if (total_extracts() < b.total_extracts())
return true;
141 if (total_extracts() > b.total_extracts())
return false;
143 for (
int i = 2; i >= 0; i--) {
144 if (a_sorted[i] > b_sorted[i])
return true;
145 if (a_sorted[i] < b_sorted[i])
return false;
153 unsigned total_extracts()
const {
160 unsigned total_bytes()
const {
162 for (
auto sz :
extractor_sizes) total += (unsigned)sz / 8 * use.at(sz);
170 std::cout << std::endl;
173 std::vector<unsigned> sorted()
const {
174 std::vector<unsigned> rv;
178 std::sort(rv.begin(), rv.end());
183namespace ParserExtractScore {
186 BUG_CHECK(use.total_bytes() == num_bytes,
"number of bytes don't add up");
189std::string print_scoreboard(
unsigned num_bytes,
const std::set<StateExtractUsage> &combos) {
190 std::stringstream ss;
191 ss <<
"Scoreboard for " << num_bytes <<
" bytes:" << std::endl;
196 for (
auto &use : combos) {
197 tp.addRow({std::to_string(use.use.at(PHV::Size::b8)),
198 std::to_string(use.use.at(PHV::Size::b16)),
199 std::to_string(use.use.at(PHV::Size::b32)), std::to_string(score--)});
208std::set<StateExtractUsage> enumerate_extract_combinations(
209 unsigned num_bytes, std::map<
unsigned, std::set<StateExtractUsage>> &all_usages) {
210 std::set<StateExtractUsage> usages;
212 if (num_bytes == 0) {
218 if (all_usages.count(num_bytes))
return all_usages.at(num_bytes);
220 for (
auto sz : {PHV::Size::b8, PHV::Size::b16, PHV::Size::b32}) {
221 unsigned bytes = (unsigned)sz / 8;
223 if (num_bytes >= bytes) {
224 auto opt_sub = enumerate_extract_combinations(num_bytes - bytes, all_usages);
226 for (
auto &u : opt_sub) {
234 for (
auto use : usages) verify(use, num_bytes);
236 all_usages[num_bytes] = usages;
238 LOG4(print_scoreboard(num_bytes, usages));
243std::set<StateExtractUsage> enumerate_extract_combinations(
unsigned num_bytes) {
244 static std::map<unsigned, std::set<StateExtractUsage>> all_usages;
246 if (all_usages.count(num_bytes))
return all_usages.at(num_bytes);
248 auto res = enumerate_extract_combinations(num_bytes, all_usages);
253 unsigned num_bytes = use.total_bytes();
254 auto combos = enumerate_extract_combinations(num_bytes);
256 auto it = combos.find(use);
258 BUG_CHECK(it != combos.end(),
"invalid extractor use?");
260 unsigned dis = std::distance(combos.begin(), it);
Definition table_printer.h:40