P4C
The P4 Compiler
Loading...
Searching...
No Matches
allocator_base.h
1
19#ifndef BF_P4C_PHV_V2_ALLOCATOR_BASE_H_
20#define BF_P4C_PHV_V2_ALLOCATOR_BASE_H_
21
22#include "backends/tofino/bf-p4c/phv/phv.h"
23#include "backends/tofino/bf-p4c/phv/phv_fields.h"
24#include "backends/tofino/bf-p4c/phv/utils/utils.h"
25#include "backends/tofino/bf-p4c/phv/v2/allocator_metrics.h"
26#include "backends/tofino/bf-p4c/phv/v2/copacker.h"
27#include "backends/tofino/bf-p4c/phv/v2/phv_kit.h"
28#include "backends/tofino/bf-p4c/phv/v2/utils_v2.h"
29
30namespace PHV {
31namespace v2 {
32
39 ActionSourceCoPackMap action_hints;
40 Container c;
41 bool is_packing = false;
42 ContScopeAllocResult() : AllocResult(new AllocError(ErrorCode::NOT_ENOUGH_SPACE, ""_cs)) {}
43 explicit ContScopeAllocResult(const AllocError *err) : AllocResult(err) {}
45 bool is_packing)
46 : AllocResult(tx), action_hints(hints), c(c), is_packing(is_packing) {}
47 bool cont_is_whole_container_set_only() const {
48 BUG_CHECK(ok(), "cannot query this status on error");
49 return c.type().kind() == Kind::mocha || c.type().kind() == Kind::dark;
50 }
51};
52
60 const AllocError *err = nullptr;
61 std::vector<const TxScore *> scores;
62 std::vector<ContScopeAllocResult> results;
63 explicit SomeContScopeAllocResult(const AllocError *default_err) : err(default_err) {}
64 explicit SomeContScopeAllocResult(ContScopeAllocResult &rst, const TxScore *score)
65 : scores{score}, results{rst} {}
67 void collect(const ContScopeAllocResult &rst, const TxScore *score);
68 bool ok() const { return !results.empty(); }
69 ContScopeAllocResult &front() { return results.front(); }
70 size_t size() const { return results.size(); }
71};
72
78 protected:
79 const PhvKit &kit_i;
80
84 protected:
86 const AllocError *is_container_type_ok(const AllocSlice &sl, const Container &c) const;
87
89 const AllocError *is_container_gress_ok(const Allocation &alloc, const AllocSlice &sl,
90 const Container &c) const;
91
94 const AllocError *is_container_write_mode_ok(const Allocation &alloc, const AllocSlice &sl,
95 const Container &c) const;
96
98 const AllocError *is_container_solitary_ok(const Allocation &alloc, const AllocSlice &candidate,
99 const Container &c) const;
100
102 const AllocError *is_container_bytes_ok(const Allocation &alloc,
103 const std::vector<AllocSlice> &candidates,
104 const Container &c) const;
105
108 const std::vector<AllocSlice> &candidates,
109 const Container &c) const;
110
114 std::vector<const SuperCluster::SliceList *> *make_alloc_order(const ScoreContext &ctx,
115 const SuperCluster *sc,
116 const PHV::Size width) const;
117
125 const AllocError *verify_can_pack(const ScoreContext &ctx, const Allocation &alloc,
126 const SuperCluster *sc,
127 const std::vector<AllocSlice> &candidates, const Container &c,
128 ActionSourceCoPackMap &co_pack_hints) const;
129
137 const SuperCluster *sc,
138 const std::vector<AllocSlice> &candidates,
139 const Container &candidates_cont) const;
140
143 std::vector<int> make_start_positions(const ScoreContext &ctx,
144 const SuperCluster::SliceList *sl,
145 const PHV::Size width) const;
146
148 std::set<PHV::Size> compute_valid_container_sizes(const SuperCluster *sc) const;
149
188 const FieldSliceAllocStartMap &fs_starts,
189 const Container &c,
190 AllocatorMetrics &alloc_metrics,
191 const bool skip_mau_checks = false) const;
192
208 const Allocation &alloc,
209 const FieldSliceAllocStartMap &fs_starts,
210 const ContainerGroup &group,
211 AllocatorMetrics &alloc_metrics) const;
212
216 const FieldSliceAllocStartMap &fs_starts,
217 const ContainerGroup &group,
218 std::optional<Container> c,
219 AllocatorMetrics &alloc_metrics) const;
220
223 std::optional<Transaction> try_hints(const ScoreContext &ctx, const Allocation &alloc,
224 const ContainerGroup &group,
225 const ActionSourceCoPackMap &action_hints_map,
227 ScAllocAlignment &hint_enforced_alignments,
228 AllocatorMetrics &alloc_metrics) const;
229
233 const ScoreContext &ctx, const Allocation &alloc, const ScAllocAlignment &alignment,
234 const SuperCluster::SliceList *lo, const SuperCluster::SliceList *hi,
235 const ContainerGroup &group, AllocatorMetrics &alloc_metrics) const;
236
241 const Allocation &alloc,
242 const SuperCluster *sc,
243 const ContainerGroup &group,
244 AllocatorMetrics &alloc_metrics) const;
245
247 using DfsAllocCb = std::function<bool(const Transaction &)>;
248 struct DfsState {
249 ScAllocAlignment alignment;
250 std::vector<const SuperCluster::SliceList *> allocated;
251 std::vector<const SuperCluster::SliceList *> to_allocate;
252 DfsState(const ScAllocAlignment &alignment,
253 const std::vector<const SuperCluster::SliceList *> &allocated,
254 const std::vector<const SuperCluster::SliceList *> &to_allocate)
255 : alignment(alignment), allocated(allocated), to_allocate(to_allocate) {}
256 bool done() const { return to_allocate.empty(); }
257 const SuperCluster::SliceList *next_to_allocate() const { return to_allocate.front(); }
258 DfsState next_state(
259 const ScAllocAlignment &updated_alignment,
260 const ordered_set<const SuperCluster::SliceList *> &just_allocated) const;
261 };
263 const AllocatorBase &base;
264 const int n_step_limit;
265 DfsAllocCb yield;
266 int n_steps = 0;
267 bool caller_pruned = false; // pruned by caller.
268 const AllocError *deepest_err = nullptr; // will not be nullptr unless succeeded.
269 int deepest_depth = -1;
270 bool pruned() const { return caller_pruned || n_steps > n_step_limit; }
271 std::string depth_prefix(const int depth) const;
272 std::optional<ScAllocAlignment> new_alignment_with_start(
273 const ScoreContext &ctx, const SuperCluster::SliceList *target, const int sl_start,
274 const PHV::Size &width, const ScAllocAlignment &alignment) const;
275 bool allocate(const ScoreContext &ctx, const Transaction &tx, const DfsState &state,
276 const int depth, AllocatorMetrics &alloc_metrics);
277
278 public:
279 DfsListsAllocator(const AllocatorBase &base, int n_step_limit)
280 : base(base), n_step_limit(n_step_limit) {}
281 bool search_allocate(const ScoreContext &ctx, const Transaction &tx,
282 const ScAllocAlignment &alignment,
283 const std::vector<const SuperCluster::SliceList *> &allocated,
284 const std::vector<const SuperCluster::SliceList *> &to_allocate,
285 const DfsAllocCb &yield, AllocatorMetrics &alloc_metrics);
286 const AllocError *get_deepest_err() const { return deepest_err; }
287 };
288
289 AllocResult alloc_stride(const ScoreContext &ctx, const Allocation &alloc,
290 const std::vector<FieldSlice> &stride,
291 const ContainerGroupsBySize &groups,
292 AllocatorMetrics &alloc_metrics) const;
293
294 public:
295 explicit AllocatorBase(const PhvKit &kit) : kit_i(kit) {
296 kit_i.parser_packing_validator->set_trivial_pass(kit.settings.trivial_alloc);
297 };
298 virtual ~AllocatorBase(){};
299
303
312 const SuperCluster *sc,
313 const ContainerGroupsBySize &groups,
314 AllocatorMetrics &alloc_metrics) const;
315
323 const PHV::Allocation &alloc,
324 const PHV::SuperCluster *sc, PhvInfo &phv) const;
325
330 const SuperCluster *sc,
331 const ContainerGroupsBySize &groups,
332 AllocatorMetrics &alloc_metrics,
333 const int max_n_slicings = 64) const;
334};
335
336} // namespace v2
337} // namespace PHV
338
339#endif /* BF_P4C_PHV_V2_ALLOCATOR_BASE_H_ */
Definition ordered_set.h:32
Definition slice_alloc.h:136
Definition phv/utils/utils.h:117
Definition phv/utils/utils.h:37
Definition phv.h:176
Definition phv/utils/utils.h:1049
Definition phv/utils/utils.h:561
Definition allocator_base.h:262
Definition allocator_base.h:77
std::set< PHV::Size > compute_valid_container_sizes(const SuperCluster *sc) const
Definition allocator_base.cpp:1316
const AllocError * is_container_bytes_ok(const Allocation &alloc, const std::vector< AllocSlice > &candidates, const Container &c) const
Definition allocator_base.cpp:557
std::vector< const SuperCluster::SliceList * > * make_alloc_order(const ScoreContext &ctx, const SuperCluster *sc, const PHV::Size width) const
Definition allocator_base.cpp:1382
AllocResult try_sliced_super_cluster(const ScoreContext &ctx, const Allocation &alloc, const SuperCluster *sc, const ContainerGroupsBySize &groups, AllocatorMetrics &alloc_metrics) const
ALLOCATION functions common to trivial and greedy allocation.
Definition allocator_base.cpp:1436
std::optional< Transaction > try_hints(const ScoreContext &ctx, const Allocation &alloc, const ContainerGroup &group, const ActionSourceCoPackMap &action_hints_map, ordered_set< PHV::FieldSlice > &allocated, ScAllocAlignment &hint_enforced_alignments, AllocatorMetrics &alloc_metrics) const
Definition allocator_base.cpp:856
const AllocError * verify_can_pack(const ScoreContext &ctx, const Allocation &alloc, const SuperCluster *sc, const std::vector< AllocSlice > &candidates, const Container &c, ActionSourceCoPackMap &co_pack_hints) const
Definition allocator_base.cpp:322
Transaction make_speculated_alloc(const ScoreContext &ctx, const Allocation &alloc, const SuperCluster *sc, const std::vector< AllocSlice > &candidates, const Container &candidates_cont) const
Definition allocator_base.cpp:211
const AllocError * is_container_solitary_ok(const Allocation &alloc, const AllocSlice &candidate, const Container &c) const
Definition allocator_base.cpp:511
const AllocError * is_container_gress_ok(const Allocation &alloc, const AllocSlice &sl, const Container &c) const
Definition allocator_base.cpp:406
AllocResult try_super_cluster_to_container_group(const ScoreContext &ctx, const Allocation &alloc, const SuperCluster *sc, const ContainerGroup &group, AllocatorMetrics &alloc_metrics) const
Definition allocator_base.cpp:1187
ContScopeAllocResult try_slices_to_container(const ScoreContext &ctx, const Allocation &alloc, const FieldSliceAllocStartMap &fs_starts, const Container &c, AllocatorMetrics &alloc_metrics, const bool skip_mau_checks=false) const
Definition allocator_base.cpp:650
PHV::Transaction alloc_deparser_zero_cluster(const ScoreContext &ctx, const PHV::Allocation &alloc, const PHV::SuperCluster *sc, PhvInfo &phv) const
Definition allocator_base.cpp:1542
SomeContScopeAllocResult try_slices_adapter(const ScoreContext &ctx, const Allocation &alloc, const FieldSliceAllocStartMap &fs_starts, const ContainerGroup &group, std::optional< Container > c, AllocatorMetrics &alloc_metrics) const
Definition allocator_base.cpp:837
const AllocError * is_container_write_mode_ok(const Allocation &alloc, const AllocSlice &sl, const Container &c) const
Definition allocator_base.cpp:437
AllocResult alloc_strided_super_clusters(const ScoreContext &ctx, const Allocation &alloc, const SuperCluster *sc, const ContainerGroupsBySize &groups, AllocatorMetrics &alloc_metrics, const int max_n_slicings=64) const
Definition allocator_base.cpp:1694
std::vector< int > make_start_positions(const ScoreContext &ctx, const SuperCluster::SliceList *sl, const PHV::Size width) const
Definition allocator_base.cpp:1275
AllocResult try_wide_arith_slices_to_container_group(const ScoreContext &ctx, const Allocation &alloc, const ScAllocAlignment &alignment, const SuperCluster::SliceList *lo, const SuperCluster::SliceList *hi, const ContainerGroup &group, AllocatorMetrics &alloc_metrics) const
Definition allocator_base.cpp:923
SomeContScopeAllocResult try_slices_to_container_group(const ScoreContext &ctx, const Allocation &alloc, const FieldSliceAllocStartMap &fs_starts, const ContainerGroup &group, AllocatorMetrics &alloc_metrics) const
Definition allocator_base.cpp:729
const AllocError * is_container_type_ok(const AllocSlice &sl, const Container &c) const
CONSTRAINT CHECKING Functions common to trivial and greedy allocation.
Definition allocator_base.cpp:361
const AllocError * check_container_scope_constraints(const Allocation &alloc, const std::vector< AllocSlice > &candidates, const Container &c) const
Definition allocator_base.cpp:597
std::function< bool(const Transaction &)> DfsAllocCb
internal type of callback.
Definition allocator_base.h:247
AllocatorMetrics contains metrics useful in tracking Allocator efficiency and debug.
Definition allocator_metrics.h:30
ScoreContext is the allocation context that is updated and passed down during allocation.
Definition utils_v2.h:178
TxScore is the interface of an allocation score.
Definition tx_score.h:28
Definition phv_fields.h:1095
ScoreContext can compute a alloc score for an PHV::Transaction.
Definition allocate_phv.h:306
The namespace encapsulating PHV-related stuff.
Definition gateway.h:32
bool trivial_alloc
Definition alloc_setting.h:30
Size
all possible PHV container sizes in BFN devices
Definition phv.h:110
Definition allocate_phv.h:626
Definition utils_v2.h:92
Definition utils_v2.h:120
Definition allocator_base.h:248
Definition allocator_base.h:38
Definition phv_kit.h:46
const ParserPackingValidator * parser_packing_validator
parser packing validator checks whether a packing would break parser constraints.
Definition phv_kit.h:74
Definition utils_v2.h:134
Definition allocator_base.h:59
void collect(const ContScopeAllocResult &rst, const TxScore *score)
update the result list.
Definition allocator_base.cpp:166