|
4 | 4 | #include "NeuraDialect/NeuraOps.h" |
5 | 5 | #include "NeuraDialect/NeuraTypes.h" |
6 | 6 | #include "NeuraDialect/NeuraPasses.h" |
| 7 | +#include "NeuraDialect/mapping/mapping_util.h" |
7 | 8 | #include "mlir/Dialect/Func/IR/FuncOps.h" |
8 | 9 | #include "mlir/IR/PatternMatch.h" |
9 | 10 | #include "mlir/Pass/Pass.h" |
10 | 11 | #include "mlir/Transforms/GreedyPatternRewriteDriver.h" |
11 | 12 |
|
12 | 13 | using namespace mlir; |
| 14 | +using namespace mlir::neura; |
13 | 15 |
|
14 | 16 | #define GEN_PASS_DEF_MapToAccelerator |
15 | 17 | #include "NeuraDialect/NeuraPasses.h.inc" |
16 | 18 |
|
17 | 19 | namespace { |
18 | 20 |
|
19 | | -/// Represents a recurrence cycle rooted at a reserve operation and ending at a ctrl_mov. |
20 | | -/// The cycle consists of a sequence of operations and its corresponding length. |
21 | | -struct RecurrenceCycle { |
22 | | - SmallVector<Operation *> operations; // Ordered list of operations in the cycle. |
23 | | - int length = 0; // Number of operations excluding ctrl_mov and reserve_op. |
24 | | -}; |
25 | | - |
26 | | -// Traverses (backward) the operation graph starting from the given operation |
27 | | -// towards reserve_value. |
28 | | -void traverseAlongPath(Operation *op, Value reserve_value, |
29 | | - std::deque<Operation *> ¤t_path, |
30 | | - DenseSet<Operation *> &visited_in_path, |
31 | | - SmallVector<RecurrenceCycle, 4> &collected_paths) { |
32 | | - if (!op || visited_in_path.contains(op)) |
33 | | - return; |
34 | | - |
35 | | - visited_in_path.insert(op); |
36 | | - current_path.push_front(op); |
37 | | - |
38 | | - for (Value operand : op->getOperands()) { |
39 | | - if (operand == reserve_value) { |
40 | | - Operation *res_op = reserve_value.getDefiningOp(); |
41 | | - if (res_op) current_path.push_front(res_op); |
42 | | - |
43 | | - constexpr int kNumExcludedOps = 2; |
44 | | - collected_paths.push_back(RecurrenceCycle{ |
45 | | - operations: SmallVector<Operation *>(current_path.begin(), current_path.end()), |
46 | | - length: static_cast<int>(current_path.size()) - kNumExcludedOps |
47 | | - }); |
48 | | - |
49 | | - if (res_op) current_path.pop_front(); // Remove reserve before backtracking |
50 | | - continue; |
51 | | - } |
52 | | - |
53 | | - if (Operation *def_op = operand.getDefiningOp()) { |
54 | | - traverseAlongPath(def_op, reserve_value, current_path, visited_in_path, collected_paths); |
55 | | - } |
56 | | - } |
57 | | - |
58 | | - current_path.pop_front(); // Backtrack |
59 | | - visited_in_path.erase(op); // Unmark from path |
60 | | -} |
61 | | - |
62 | | -/// Collects all recurrence cycles rooted at reserve operations and closed by ctrl_mov. |
63 | | -/// Each cycle contains the operation sequence and its corresponding length. |
64 | | -SmallVector<RecurrenceCycle, 4> collectRecurrenceCycles(Operation *root_op) { |
65 | | - SmallVector<RecurrenceCycle, 4> recurrence_cycles; |
66 | | - |
67 | | - root_op->walk([&](neura::CtrlMovOp ctrl_mov_op) { |
68 | | - Value target = ctrl_mov_op.getTarget(); |
69 | | - auto reserve_op = target.getDefiningOp<neura::ReserveOp>(); |
70 | | - if (!reserve_op) |
71 | | - return; |
72 | | - |
73 | | - Value reserve_value = reserve_op.getResult(); |
74 | | - Value ctrl_mov_from = ctrl_mov_op.getValue(); |
75 | | - |
76 | | - Operation *parent_op = ctrl_mov_from.getDefiningOp(); |
77 | | - if (!parent_op) |
78 | | - return; |
79 | | - |
80 | | - std::deque<Operation *> current_path; |
81 | | - SmallVector<RecurrenceCycle, 4> collected_paths; |
82 | | - DenseSet<Operation *> visited_in_path; |
83 | | - traverseAlongPath(parent_op, reserve_value, current_path, visited_in_path, collected_paths); |
84 | | - |
85 | | - for (auto &cycle : collected_paths) { |
86 | | - cycle.operations.push_back(ctrl_mov_op); |
87 | | - ++cycle.length; |
88 | | - recurrence_cycles.push_back(std::move(cycle)); |
89 | | - } |
90 | | - }); |
91 | | - |
92 | | - return recurrence_cycles; |
93 | | -} |
94 | | - |
95 | 21 | struct MapToAcceleratorPass |
96 | 22 | : public PassWrapper<MapToAcceleratorPass, OperationPass<ModuleOp>> { |
97 | 23 | MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(MapToAcceleratorPass) |
@@ -127,10 +53,17 @@ struct MapToAcceleratorPass |
127 | 53 | << longest->length << "):\n"; |
128 | 54 | for (Operation *op : longest->operations) |
129 | 55 | op->print(llvm::errs()), llvm::errs() << "\n"; |
130 | | - IntegerAttr mii_attr = IntegerAttr::get( |
| 56 | + IntegerAttr rec_mii_attr = IntegerAttr::get( |
131 | 57 | IntegerType::get(func.getContext(), 32), longest->length); |
132 | | - func->setAttr("RecMII", mii_attr); |
| 58 | + func->setAttr("RecMII", rec_mii_attr); |
133 | 59 | } |
| 60 | + |
| 61 | + AcceleratorConfig config{/*numTiles=*/8}; // Example |
| 62 | + int res_mii = calculateResMii(func, config); |
| 63 | + IntegerAttr res_mii_attr = IntegerAttr::get( |
| 64 | + IntegerType::get(func.getContext(), 32), res_mii); |
| 65 | + func->setAttr("ResMII", res_mii_attr); |
| 66 | + |
134 | 67 | }); |
135 | 68 | } |
136 | 69 | }; |
|
0 commit comments