P4C
The P4 Compiler
Loading...
Searching...
No Matches
report.h
1
19#ifndef BF_P4C_PHV_UTILS_REPORT_H_
20#define BF_P4C_PHV_UTILS_REPORT_H_
21
22#include "backends/tofino/bf-p4c/phv/utils/utils.h"
23
24namespace PHV {
25
27 const PhvUse &uses;
28 const Allocation &alloc;
29 bool printMetricsOnly = false;
30
33 alloc_status;
34
35 ordered_map<PHV::Container, int> partial_containers_stat;
36
37 ordered_map<PHV::Container, int> container_to_bits_used;
38
39 ordered_map<PHV::Container, int> container_to_bits_allocated;
40
42
43 ordered_set<AllocSlice> alloc_slices;
44
45 int total_allocated_bits = 0;
46 int total_unallocated_bits = 0;
47 int valid_ingress_unallocated_bits = 0;
48 int valid_egress_unallocated_bits = 0;
49
50 static std::string formatPercent(int div, int den) {
51 std::stringstream ss;
52 ss << boost::format("(%=6.3g%%)") % (100.0 * div / den);
53 return ss.str();
54 }
55
56 static std::string formatUsage(int used, int total, bool show_total = false) {
57 std::stringstream ss;
58 ss << used << " ";
59 if (show_total) ss << "/ " << total << " ";
60 ss << formatPercent(used, total);
61 return ss.str();
62 }
63
64 struct PhvOccupancyMetricFields {
65 unsigned containersUsed = 0;
66 unsigned bitsUsed = 0;
67 unsigned bitsAllocated = 0;
68
69 inline PhvOccupancyMetricFields &operator+=(const PhvOccupancyMetricFields &src) {
70 containersUsed += src.containersUsed;
71 bitsUsed += src.bitsUsed;
72 bitsAllocated += src.bitsAllocated;
73
74 return *this;
75 }
76 };
77
79 struct PhvOccupancyMetric {
80 // in total
81 PhvOccupancyMetricFields total;
82 // per gress
83 std::map<gress_t, PhvOccupancyMetricFields> gress;
84
85 inline PhvOccupancyMetric &operator+=(const PhvOccupancyMetric &src) {
86 total += src.total;
87 for (const auto &gr : src.gress) {
88 gress[gr.first] += gr.second;
89 }
90
91 return *this;
92 }
93
94 inline std::string gressToSymbolString() const {
95 std::stringstream ss;
96 std::string sep = "";
97 for (const auto &gr : gress) {
98 ss << sep;
99 ss << toSymbol(gr.first);
100 sep = "/";
101 }
102 return ss.str();
103 }
104 };
105
107 struct MauGroupInfo {
108 size_t size = 0;
109 int groupID = 0;
110
111 PhvOccupancyMetric totalStats;
112 std::map<PHV::Kind, PhvOccupancyMetric, std::greater<PHV::Kind>> statsByContainerKind;
113
114 MauGroupInfo() {}
115
117 explicit MauGroupInfo(size_t sz, int i, PHV::Kind containerKind, bool cont, size_t used,
118 size_t allocated, std::optional<gress_t> gr)
119 : size(sz), groupID(i) {
120 update(containerKind, cont, used, allocated, gr);
121 }
122
124 void update(PHV::Kind containerKind, bool cont, size_t used, size_t allocated,
125 std::optional<gress_t> gr) {
126 auto &kindStats = statsByContainerKind[containerKind];
127
128 // Update total stats
129 auto &totalStatsTotal = totalStats.total;
130 auto &kindStatsTotal = kindStats.total;
131
132 if (cont) {
133 ++totalStatsTotal.containersUsed;
134 ++kindStatsTotal.containersUsed;
135 }
136
137 totalStatsTotal.bitsUsed += used;
138 kindStatsTotal.bitsUsed += used;
139
140 totalStatsTotal.bitsAllocated += allocated;
141 kindStatsTotal.bitsAllocated += allocated;
142
143 if (gr) {
144 // Update per gress stats
145 auto &totalStatsGress = totalStats.gress[*gr];
146 auto &kindStatsGress = kindStats.gress[*gr];
147
148 if (cont) {
149 ++totalStatsGress.containersUsed;
150 ++kindStatsGress.containersUsed;
151 }
152
153 totalStatsGress.bitsUsed += used;
154 kindStatsGress.bitsUsed += used;
155
156 totalStatsGress.bitsAllocated += allocated;
157 kindStatsGress.bitsAllocated += allocated;
158 }
159 }
160 };
161
163 struct TagalongCollectionInfo {
164 std::map<PHV::Type, size_t> containersUsed;
165 std::map<PHV::Type, size_t> bitsUsed;
166 std::map<PHV::Type, size_t> bitsAllocated;
167 std::map<PHV::Type, size_t> totalContainers;
168
169 std::optional<gress_t> gress;
170
171 size_t getTotalUsedBits() {
172 size_t rv = 0;
173 for (auto kv : bitsUsed) rv += kv.second;
174 return rv;
175 }
176
177 size_t getTotalAllocatedBits() {
178 size_t rv = 0;
179 for (auto kv : bitsAllocated) rv += kv.second;
180 return rv;
181 }
182
183 size_t getTotalAvailableBits() {
184 size_t rv = 0;
185 for (auto &kv : totalContainers) rv += (size_t)kv.first.size() * kv.second;
186 return rv;
187 }
188
189 std::string printUsage(PHV::Type type) {
190 auto used = containersUsed[type];
191 auto total = totalContainers[type];
192
193 return formatUsage(used, total);
194 }
195
196 std::string printTotalUsage() {
197 auto total = getTotalAvailableBits();
198 auto used = getTotalUsedBits();
199
200 return formatUsage(used, total);
201 }
202
203 std::string printTotalAlloc() {
204 auto total = getTotalAvailableBits();
205 auto alloced = getTotalAllocatedBits();
206
207 return formatUsage(alloced, total);
208 }
209 };
210
211 public:
212 explicit AllocationReport(const Allocation &alloc, bool printMetricsOnly = false)
213 : uses(*(alloc.uses_i)), alloc(alloc), printMetricsOnly(printMetricsOnly) {}
214
217 collectStatus();
218
219 std::stringstream ss;
220
221 if (!printMetricsOnly) ss << printAllocation() << std::endl;
222
223 if (!printMetricsOnly) ss << printAllocSlices() << std::endl;
224
225 ss << printContainerStatus() << std::endl;
226 ss << printOverlayStatus() << std::endl;
227 ss << printOccupancyMetrics() << std::endl;
228
229 return ss.str();
230 }
231
232 private:
233 void collectStatus();
234
235 cstring printAllocation() const;
236 cstring printAllocSlices() const;
237 cstring printOverlayStatus() const;
238 cstring printContainerStatus();
239 cstring printOccupancyMetrics() const;
240 cstring printMauGroupsOccupancyMetrics() const;
241 cstring printTagalongCollectionsOccupancyMetrics() const;
242};
243
244} // namespace PHV
245
246#endif /* BF_P4C_PHV_UTILS_REPORT_H_ */
Definition cstring.h:85
Definition ordered_map.h:32
Definition ordered_set.h:32
Definition phv/utils/utils.h:117
Definition report.h:26
cstring printSummary()
Definition report.h:216
Definition phv.h:114
Definition phv_parde_mau_use.h:154
The namespace encapsulating PHV-related stuff.
Definition gateway.h:32
Kind
Definition phv.h:44