已合并
【PR】: feat:增加report match接口 #4360
hugo111创建于 26 天前
【PR】: feat:增加report match接口 #4360
已合并
共 13 个文件变更+305-5
| @@ -144,7 +144,30 @@ Status GraphFuseInspectorUtils::ReportFuse(const std::vector<GNode> &nodes_befor | |||
| 144 | } | 144 | } |
| 145 | RecordDatadumpAttrsIdempotently(before_nodes, after_nodes, pass_name_str); | 145 | RecordDatadumpAttrsIdempotently(before_nodes, after_nodes, pass_name_str); |
| 146 | FusionUtils::RecordFusionStatistic(owner_graph->GetSessionID(), std::to_string(owner_graph->GetGraphID()), | 146 | FusionUtils::RecordFusionStatistic(owner_graph->GetSessionID(), std::to_string(owner_graph->GetGraphID()), |
| 147 | - pass_name_str, 1, 1); | 147 | + pass_name_str, 0, 1); |
| 148 | + return SUCCESS; | ||
| 149 | +} | ||
| 150 | + | ||
| 151 | +Status GraphFuseInspectorUtils::ReportMatch(const std::vector<GNode> &matched_nodes, CustomPassContext &ctx) { | ||
| 152 | + std::string error_msg; | ||
| 153 | + std::vector<NodePtr> nodes; | ||
| 154 | + if (!ConvertGNodes(matched_nodes, nodes, error_msg)) { | ||
| 155 | + GELOGW("%s", error_msg.c_str()); | ||
| 156 | + return FAILED; | ||
| 157 | + } | ||
| 158 | + ComputeGraphPtr owner_graph = nullptr; | ||
| 159 | + if (!CheckOwnerGraph(nodes, owner_graph, error_msg)) { | ||
| 160 | + GELOGW("%s", error_msg.c_str()); | ||
| 161 | + return FAILED; | ||
| 162 | + } | ||
| 163 | + const auto pass_name = ctx.GetPassName(); | ||
| 164 | + const auto *pass_name_cstr = pass_name.GetString(); | ||
| 165 | + const std::string pass_name_str = (pass_name_cstr == nullptr) ? "" : pass_name_cstr; | ||
| 166 | + if (pass_name_str.empty()) { | ||
| 167 | + return FAILED; | ||
| 168 | + } | ||
| 169 | + FusionUtils::RecordFusionStatistic(owner_graph->GetSessionID(), std::to_string(owner_graph->GetGraphID()), | ||
| 170 | + pass_name_str, 1, 0); | ||
| 148 | return SUCCESS; | 171 | return SUCCESS; |
| 149 | } | 172 | } |
| 150 | } // namespace fusion | 173 | } // namespace fusion |
| @@ -0,0 +1,53 @@ | |||
| 1 | +# CanFuse | ||
| 2 | + | ||
| 3 | +## Product Support Status | ||
| 4 | + | ||
| 5 | +All chips supported. | ||
| 6 | + | ||
| 7 | +## Header/Library | ||
| 8 | + | ||
| 9 | +- Header: \#include <ge/fusion/graph\_fuse\_inspector\_utils.h> | ||
| 10 | +- Library: libgraph\_base.so | ||
| 11 | + | ||
| 12 | +## Functionality Description | ||
| 13 | + | ||
| 14 | +Determines whether the set of nodes to be fused can be fused. The judgment conditions are: | ||
| 15 | + | ||
| 16 | +1. The stream label on a node expresses the shunting strategy on the graph. When the incoming nodes have inconsistent stream labels, the user intent cannot be determined, that is, it cannot be determined whose label the new node should inherit. Therefore, when the stream labels of the incoming node list are inconsistent, it is judged as not fusible. | ||
| 17 | + | ||
| 18 | +2. If fusing the incoming node list into a single node creates a cycle, it is judged as not fusible. Note that other scenarios such as replacing incoming nodes with multiple nodes are not covered by the cycle detection here. | ||
| 19 | + | ||
| 20 | +## Function Prototype | ||
| 21 | + | ||
| 22 | +```c++ | ||
| 23 | +static bool CanFuse(const std::vector<GNode> &nodes_before_fuse, AscendString &failed_reason) | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +## Parameters | ||
| 27 | + | ||
| 28 | +| Parameter | Input/Output | Description | | ||
| 29 | +| --- | --- | --- | | ||
| 30 | +| nodes_before_fuse | Input | Node list before fusion (all nodes in the list must be connected). | | ||
| 31 | +| failed_reason | Output | The reason why fusion is not supported. | | ||
| 32 | + | ||
| 33 | +## Return Value | ||
| 34 | + | ||
| 35 | +| Parameter | Type | Description | | ||
| 36 | +| --- | --- | --- | | ||
| 37 | +| - | bool | - true: can be fused.<br> - false: cannot be fused (failed_reason is filled with the specific reason). | | ||
| 38 | + | ||
| 39 | +The above reason needs to be printed by the user. The following code can be added below the interface: | ||
| 40 | + | ||
| 41 | +```c++ | ||
| 42 | +// Perform CanFuse check | ||
| 43 | + AscendString failed_reason; | ||
| 44 | + bool can_fuse = fusion::GraphFuseInspectorUtils::CanFuse(nodes_before_fuse, failed_reason); | ||
| 45 | + if (!can_fuse) { | ||
| 46 | + std::cerr << "[FuseNodes] CanFuse check failed: " << failed_reason.GetString() << std::endl; | ||
| 47 | + return false; | ||
| 48 | + } | ||
| 49 | +``` | ||
| 50 | + | ||
| 51 | +## Constraints | ||
| 52 | + | ||
| 53 | +None | ||
| @@ -0,0 +1,44 @@ | |||
| 1 | +# ReportFuse | ||
| 2 | + | ||
| 3 | +## Product Support Status | ||
| 4 | + | ||
| 5 | +All chips supported. | ||
| 6 | + | ||
| 7 | +## Header/Library | ||
| 8 | + | ||
| 9 | +- Header: \#include <ge/fusion/graph\_fuse\_inspector\_utils.h> | ||
| 10 | +- Library: libgraph\_base.so | ||
| 11 | + | ||
| 12 | +## Functionality Description | ||
| 13 | + | ||
| 14 | +Reports the fusion result. After completing modifications to the graph, the fusion result must be reported to update the graph connection matrix and record diagnostic information. | ||
| 15 | + | ||
| 16 | +The internal logic of the interface is briefly as follows: | ||
| 17 | + | ||
| 18 | +1. The opdesc of the new node records the pass name. | ||
| 19 | +2. Updates the connection matrix used by CanFuse to detect cycles. | ||
| 20 | +3. Records the match count and effect count, and persists the corresponding information to fusion\_result.json. | ||
| 21 | + | ||
| 22 | +## Function Prototype | ||
| 23 | + | ||
| 24 | +```c++ | ||
| 25 | +static Status ReportFuse(const std::vector<GNode> &nodes_before_fuse, const std::vector<GNode> &nodes_after_fuse, CustomPassContext &ctx) | ||
| 26 | +``` | ||
| 27 | + | ||
| 28 | +## Parameters | ||
| 29 | + | ||
| 30 | +| Parameter | Input/Output | Description | | ||
| 31 | +| --- | --- | --- | | ||
| 32 | +| nodes_before_fuse | Input | Node list before fusion (all nodes in the list must be connected). | | ||
| 33 | +| nodes_after_fuse | Input | New node list after fusion (all nodes in the list must be connected). An empty nodes_after_fuse indicates the scenario of deletion without adding new nodes. | | ||
| 34 | +| ctx | Input | Pass context, uses ctx.GetPassName() to record the pass name. | | ||
| 35 | + | ||
| 36 | +## Return Value | ||
| 37 | + | ||
| 38 | +| Parameter | Type | Description | | ||
| 39 | +| --- | --- | --- | | ||
| 40 | +| - | Status | SUCCESS: report succeeded<br>FAILED: report failed | | ||
| 41 | + | ||
| 42 | +## Constraints | ||
| 43 | + | ||
| 44 | +This API must be called after modifying the graph and before releasing the deleted nodes. | ||
| @@ -0,0 +1,39 @@ | |||
| 1 | +# ReportMatch | ||
| 2 | + | ||
| 3 | +## Product Support Status | ||
| 4 | + | ||
| 5 | +All chips supported. | ||
| 6 | + | ||
| 7 | +## Header/Library | ||
| 8 | + | ||
| 9 | +- Header: \#include <ge/fusion/graph\_fuse\_inspector\_utils.h> | ||
| 10 | +- Library: libgraph\_base.so | ||
| 11 | + | ||
| 12 | +## Functionality Description | ||
| 13 | + | ||
| 14 | +Reports a structure match. Called when a target structure is found during graph traversal, counted regardless of whether fusion conditions pass. Internally increments match\_time automatically, does not change effect\_time, corresponding information is persisted to fusion\_result.json. | ||
| 15 | + | ||
| 16 | +Used together with [ReportFuse](ReportFuse.md) to calculate structure match hit rate: match\_time is the total number of structure matches (superset), effect\_time is the number of fusions actually applied (subset), match\_time - effect\_time reflects the number of fusions abandoned due to condition filtering. | ||
| 17 | + | ||
| 18 | +## Function Prototype | ||
| 19 | + | ||
| 20 | +```c++ | ||
| 21 | +static Status ReportMatch(const std::vector<GNode> &matched_nodes, CustomPassContext &ctx) | ||
| 22 | +``` | ||
| 23 | + | ||
| 24 | +## Parameters | ||
| 25 | + | ||
| 26 | +| Parameter | Input/Output | Description | | ||
| 27 | +| --- | --- | --- | | ||
| 28 | +| matched_nodes | Input | List of nodes hit by structure matching (all nodes in the list must be connected). | | ||
| 29 | +| ctx | Input | Pass context, uses ctx.GetPassName() to record pass name. | | ||
| 30 | + | ||
| 31 | +## Return Value | ||
| 32 | + | ||
| 33 | +| Parameter | Type | Description | | ||
| 34 | +| --- | --- | --- | | ||
| 35 | +| - | Status | SUCCESS: report succeeded<br>FAILED: report failed | | ||
| 36 | + | ||
| 37 | +## Constraints | ||
| 38 | + | ||
| 39 | +This API should be called after discovering the target structure and before [CanFuse](CanFuse.md). | ||
| @@ -317,10 +317,11 @@ This layer of encapsulation only changes Python-side usability, does not change | |||
| 317 | 317 | ||
| 318 | For mechanism explanation and development steps for developers, see [Fusion Pattern Pass Mechanism](../../features/fusion_pattern_pass.md). | 318 | For mechanism explanation and development steps for developers, see [Fusion Pattern Pass Mechanism](../../features/fusion_pattern_pass.md). |
| 319 | 319 | ||
| 320 | -To lower custom `FusionBasePass` integration cost, `ge/fusion/graph_fuse_inspector_utils.h` adds `GraphFuseInspectorUtils` public utility class. It converges key steps originally scattered in `ComputeGraph::IsSupportFuse`, `FusionUtils::WillCauseCycleIfFuse`, `FusionUtils::UpdateToCycleDetector` and fusion statistics logic into two open capabilities: | 320 | +To lower custom `FusionBasePass` integration cost, `ge/fusion/graph_fuse_inspector_utils.h` adds `GraphFuseInspectorUtils` public utility class. It converges key steps originally scattered in `ComputeGraph::IsSupportFuse`, `FusionUtils::WillCauseCycleIfFuse`, `FusionUtils::UpdateToCycleDetector` and fusion statistics logic into three open capabilities: |
| 321 | 321 | ||
| 322 | - `CanFuse(nodes_before_fuse, failed_reason)`: Execute fusionability validation (attribute consistency + cycle detection), failure reason returned through `failed_reason`. | 322 | - `CanFuse(nodes_before_fuse, failed_reason)`: Execute fusionability validation (attribute consistency + cycle detection), failure reason returned through `failed_reason`. |
| 323 | - `ReportFuse(nodes_before_fuse, nodes_after_fuse, ctx)`: Called after graph modification and before releasing old nodes, use `pass_name` in `ctx` to mark new node fusion source, update cycle detector and record fusion debugging; when `nodes_after_fuse` is empty indicates only deleting nodes. | 323 | - `ReportFuse(nodes_before_fuse, nodes_after_fuse, ctx)`: Called after graph modification and before releasing old nodes, use `pass_name` in `ctx` to mark new node fusion source, update cycle detector and record fusion debugging; when `nodes_after_fuse` is empty indicates only deleting nodes. |
| 324 | +- `ReportMatch(matched_nodes, ctx)`: Called when target subgraph structure is found during graph traversal (counted regardless of whether fusion conditions pass), internally increments `match_time`; combined with `effect_time` recorded by `ReportFuse` can calculate structure match hit rate, `match_time - effect_time` reflects fusions abandoned due to condition filtering. | ||
| 324 | 325 | ||
| 325 | In `SubgraphRewriter` added `Replace(subgraph, replacement, ctx)` overload, chaining `CanFuse` and `ReportFuse` into unified graph modification flow: check fusionability before modification, report fusion result after modification, then delete old nodes. | 326 | In `SubgraphRewriter` added `Replace(subgraph, replacement, ctx)` overload, chaining `CanFuse` and `ReportFuse` into unified graph modification flow: check fusionability before modification, report fusion result after modification, then delete old nodes. |
| 326 | 327 | ||
| @@ -483,6 +483,7 @@ | |||
| 483 | - [简介](cpp/ge/fusion/GraphFuseInspectorUtils/overview.md) | 483 | - [简介](cpp/ge/fusion/GraphFuseInspectorUtils/overview.md) |
| 484 | - [CanFuse](cpp/ge/fusion/GraphFuseInspectorUtils/CanFuse.md) | 484 | - [CanFuse](cpp/ge/fusion/GraphFuseInspectorUtils/CanFuse.md) |
| 485 | - [ReportFuse](cpp/ge/fusion/GraphFuseInspectorUtils/ReportFuse.md) | 485 | - [ReportFuse](cpp/ge/fusion/GraphFuseInspectorUtils/ReportFuse.md) |
| 486 | + - [ReportMatch](cpp/ge/fusion/GraphFuseInspectorUtils/ReportMatch.md) | ||
| 486 | 487 | ||
| 487 | - [GNode](cpp/ge/GNode/GNode.md) | 488 | - [GNode](cpp/ge/GNode/GNode.md) |
| 488 | - [简介](cpp/ge/GNode/overview.md) | 489 | - [简介](cpp/ge/GNode/overview.md) |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 判断待融合节点集合是否可融合。判断条件: | 14 | 判断待融合节点集合是否可融合。判断条件: |
| 15 | 15 | ||
| 16 | -1. 节点上的stream lable表达图上的分流策略,当传入节点stream label不一致时,无法确定用户意图,即无法确定新节点该继承谁的标签,因此传入节点列表的stream label不一致时,判断为无法融合。 | 16 | +1. 节点上的stream label表达图上的分流策略,当传入节点stream label不一致时,无法确定用户意图,即无法确定新节点该继承谁的标签,因此传入节点列表的stream label不一致时,判断为无法融合。 |
| 17 | 17 | ||
| 18 | 2. 如果传入节点列表融合成单个节点出现环,判断为无法融合,注意传入节点替换为多个节点等其他场景不在此处的成环检测范围内。 | 18 | 2. 如果传入节点列表融合成单个节点出现环,判断为无法融合,注意传入节点替换为多个节点等其他场景不在此处的成环检测范围内。 |
| 19 | 19 | ||
| @@ -11,7 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | ## 功能说明 | 12 | ## 功能说明 |
| 13 | 13 | ||
| 14 | -上报融合结果,在完成对图的修改后,需要上报融合结果以完成图连接矩阵的更新、维测信息记录等操作。 | 14 | +在完成对图的修改后,需要上报融合结果以完成图连接矩阵的更新和维测信息记录等操作。 |
| 15 | 15 | ||
| 16 | 接口内部逻辑简要如下: | 16 | 接口内部逻辑简要如下: |
| 17 | 17 | ||
| @@ -0,0 +1,39 @@ | |||
| 1 | +# ReportMatch | ||
| 2 | + | ||
| 3 | +## 产品支持情况 | ||
| 4 | + | ||
| 5 | +全量芯片支持。 | ||
| 6 | + | ||
| 7 | +## 头文件/库文件 | ||
| 8 | + | ||
| 9 | +- 头文件:\#include <ge/fusion/graph\_fuse\_inspector\_utils.h\> | ||
| 10 | +- 库文件:libgraph\_base.so | ||
| 11 | + | ||
| 12 | +## 功能说明 | ||
| 13 | + | ||
| 14 | +上报一次结构匹配,在图遍历中发现目标结构后调用,无论融合条件是否通过均计入。内部自动累加 match\_time,不改变 effect\_time,对应信息落盘至fusion\_result.json。 | ||
| 15 | + | ||
| 16 | +与 [ReportFuse](ReportFuse.md) 配合使用可统计结构匹配的命中率:match\_time 为结构匹配总次数(全集),effect\_time 为融合实际生效次数(子集),match\_time - effect\_time 反映因条件过滤而放弃融合的数量。 | ||
| 17 | + | ||
| 18 | +## 函数原型 | ||
| 19 | + | ||
| 20 | +```c++ | ||
| 21 | +static Status ReportMatch(const std::vector<GNode> &matched_nodes, CustomPassContext &ctx) | ||
| 22 | +``` | ||
| 23 | + | ||
| 24 | +## 参数说明 | ||
| 25 | + | ||
| 26 | +| 参数名 | 输入/输出 | 说明 | | ||
| 27 | +| --- | --- | --- | | ||
| 28 | +| matched_nodes | 输入 | 结构匹配命中的节点列表(列表内所有节点需连通)。 | | ||
| 29 | +| ctx | 输入 | Pass上下文,使用ctx.GetPassName()记录pass name。 | | ||
| 30 | + | ||
| 31 | +## 返回值说明 | ||
| 32 | + | ||
| 33 | +| 参数名 | 类型 | 说明 | | ||
| 34 | +| --- | --- | --- | | ||
| 35 | +| - | Status | SUCCESS:上报成功<br>FAILED:上报失败 | | ||
| 36 | + | ||
| 37 | +## 约束说明 | ||
| 38 | + | ||
| 39 | +该接口应在发现目标结构后、[CanFuse](CanFuse.md) 之前调用。 | ||
| @@ -322,6 +322,7 @@ Python 层会自动创建 ES `GraphBuilder`、图输入、图输出和 pattern c | |||
| 322 | 322 | ||
| 323 | - `CanFuse(nodes_before_fuse, failed_reason)`:执行可融合性校验(属性一致性 + 成环检测),失败原因通过 `failed_reason` 返回。 | 323 | - `CanFuse(nodes_before_fuse, failed_reason)`:执行可融合性校验(属性一致性 + 成环检测),失败原因通过 `failed_reason` 返回。 |
| 324 | - `ReportFuse(nodes_before_fuse, nodes_after_fuse, ctx)`:在改图后且释放旧节点前调用,使用 `ctx` 中的 `pass_name` 标记新节点融合来源,更新成环检测器并记录融合维测;当 `nodes_after_fuse` 为空时表示仅删除节点。 | 324 | - `ReportFuse(nodes_before_fuse, nodes_after_fuse, ctx)`:在改图后且释放旧节点前调用,使用 `ctx` 中的 `pass_name` 标记新节点融合来源,更新成环检测器并记录融合维测;当 `nodes_after_fuse` 为空时表示仅删除节点。 |
| 325 | +- `ReportMatch(matched_nodes, ctx)`:在图遍历中发现目标子图结构后调用(无论融合条件是否通过均计入),内部累加 `match_time`;与 `ReportFuse` 记录的 `effect_time` 配合可统计结构匹配命中率,`match_time - effect_time` 反映因条件过滤而放弃融合的数量。 | ||
| 325 | 326 | ||
| 326 | 在 `SubgraphRewriter` 中新增了 `Replace(subgraph, replacement, ctx)` 重载,将 `CanFuse` 和 `ReportFuse` 串联到统一改图流程中:改图前检查可融合性,改图后上报融合结果,再删除旧节点。 | 327 | 在 `SubgraphRewriter` 中新增了 `Replace(subgraph, replacement, ctx)` 重载,将 `CanFuse` 和 `ReportFuse` 串联到统一改图流程中:改图前检查可融合性,改图后上报融合结果,再删除旧节点。 |
| 327 | 328 | ||
| @@ -83,6 +83,10 @@ bool JudgeTransposeNode(const GNodePtr &node_ptr, int &cnt) { | |||
| 83 | 83 | ||
| 84 | bool RemoveTransposeAndRelink(const GraphPtr &graph, const GNodePtr &node_ptr, CustomPassContext &pass_context) { | 84 | bool RemoveTransposeAndRelink(const GraphPtr &graph, const GNodePtr &node_ptr, CustomPassContext &pass_context) { |
| 85 | AscendString failed_reason; | 85 | AscendString failed_reason; |
| 86 | + // 结构匹配上报,无论融合条件是否通过均计入match_time | ||
| 87 | + if (GraphFuseInspectorUtils::ReportMatch({*node_ptr}, pass_context) != SUCCESS) { | ||
| 88 | + std::cout << "ReportMatch failed" << std::endl; | ||
| 89 | + } | ||
| 86 | if (!GraphFuseInspectorUtils::CanFuse({*node_ptr}, failed_reason)) { | 90 | if (!GraphFuseInspectorUtils::CanFuse({*node_ptr}, failed_reason)) { |
| 87 | std::cout << failed_reason.GetString() << std::endl; | 91 | std::cout << failed_reason.GetString() << std::endl; |
| 88 | return false; | 92 | return false; |
| @@ -44,7 +44,7 @@ class GraphFuseInspectorUtils { | |||
| 44 | * 行为: | 44 | * 行为: |
| 45 | * 1.新节点的opdesc记录pass name。 | 45 | * 1.新节点的opdesc记录pass name。 |
| 46 | * 2.更新在CanFuse中用于检测成环的连接矩阵。 | 46 | * 2.更新在CanFuse中用于检测成环的连接矩阵。 |
| 47 | - * 3.记录匹配次数与生效次数,对应信息落盘至fusion_result.json。 | 47 | + * 3.记录生效次数,对应信息落盘至fusion_result.json。 |
| 48 | * | 48 | * |
| 49 | * @param nodes_before_fuse 融合前节点列表(列表内所有节点需连通) | 49 | * @param nodes_before_fuse 融合前节点列表(列表内所有节点需连通) |
| 50 | * @param nodes_after_fuse 融合后新节点列表(列表内所有节点需连通) | 50 | * @param nodes_after_fuse 融合后新节点列表(列表内所有节点需连通) |
| @@ -54,6 +54,19 @@ class GraphFuseInspectorUtils { | |||
| 54 | */ | 54 | */ |
| 55 | static Status ReportFuse(const std::vector<GNode> &nodes_before_fuse, const std::vector<GNode> &nodes_after_fuse, | 55 | static Status ReportFuse(const std::vector<GNode> &nodes_before_fuse, const std::vector<GNode> &nodes_after_fuse, |
| 56 | CustomPassContext &ctx); | 56 | CustomPassContext &ctx); |
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * 上报一次结构匹配 | ||
| 60 | + * 在图遍历中发现目标子图结构后调用,无论融合条件是否通过均计入。 | ||
| 61 | + * 内部自动累加 match_time,不改变 effect_time,对应信息落盘至fusion_result.json。 | ||
| 62 | + * 典型用法:在CanFuse之前调用,与ReportFuse配合可统计结构匹配的命中率。 | ||
| 63 | + * | ||
| 64 | + * @param matched_nodes 结构匹配命中的节点列表(列表内所有节点需连通) | ||
| 65 | + * @param ctx pass上下文,使用ctx.GetPassName()记录pass name | ||
| 66 | + * @return SUCCESS: 上报成功; FAILED: 上报失败 | ||
| 67 | + * @since 9.2.0(2026-08) | ||
| 68 | + */ | ||
| 69 | + static Status ReportMatch(const std::vector<GNode> &matched_nodes, CustomPassContext &ctx); | ||
| 57 | }; | 70 | }; |
| 58 | } // namespace fusion | 71 | } // namespace fusion |
| 59 | } // namespace ge | 72 | } // namespace ge |
| @@ -19,6 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | + | ||
| 22 | 23 | ||
| 23 | 24 | ||
| 24 | 25 | ||
| @@ -276,5 +277,86 @@ TEST_F(UtestGraphFuseInspectorUtils, ReportFuseWritesDatadumpAttrs) { | |||
| 276 | ASSERT_FALSE(pass_names.empty()); | 277 | ASSERT_FALSE(pass_names.empty()); |
| 277 | EXPECT_EQ(pass_names.back(), "ut_rewrite_pass"); | 278 | EXPECT_EQ(pass_names.back(), "ut_rewrite_pass"); |
| 278 | } | 279 | } |
| 280 | + | ||
| 281 | +TEST_F(UtestGraphFuseInspectorUtils, ReportMatchFailedWhenNodesEmpty) { | ||
| 282 | + CustomPassContext ctx; | ||
| 283 | + ctx.SetPassName("ut_pass"); | ||
| 284 | + EXPECT_EQ(GraphFuseInspectorUtils::ReportMatch({}, ctx), FAILED); | ||
| 285 | +} | ||
| 286 | + | ||
| 287 | +TEST_F(UtestGraphFuseInspectorUtils, ReportMatchFailedOnInvalidGNode) { | ||
| 288 | + CustomPassContext ctx; | ||
| 289 | + ctx.SetPassName("ut_pass"); | ||
| 290 | + EXPECT_EQ(GraphFuseInspectorUtils::ReportMatch({GNode()}, ctx), FAILED); | ||
| 291 | +} | ||
| 292 | + | ||
| 293 | +TEST_F(UtestGraphFuseInspectorUtils, ReportMatchFailedWhenPassNameEmpty) { | ||
| 294 | + std::vector<NodePtr> before_nodes; | ||
| 295 | + const auto graph = BuildLinearGraph(before_nodes); | ||
| 296 | + ASSERT_NE(graph, nullptr); | ||
| 297 | + CustomPassContext ctx; | ||
| 298 | + EXPECT_EQ(GraphFuseInspectorUtils::ReportMatch(ToGNodes(before_nodes), ctx), FAILED); | ||
| 299 | +} | ||
| 300 | + | ||
| 301 | +TEST_F(UtestGraphFuseInspectorUtils, ReportMatchFailedOnNodesBelongToDifferentGraphs) { | ||
| 302 | + std::vector<NodePtr> graph1_nodes; | ||
| 303 | + std::vector<NodePtr> graph2_nodes; | ||
| 304 | + const auto graph1 = BuildTwoGraphs(graph1_nodes, graph2_nodes); | ||
| 305 | + ASSERT_NE(graph1, nullptr); | ||
| 306 | + ASSERT_EQ(graph1_nodes.size(), 1U); | ||
| 307 | + ASSERT_EQ(graph2_nodes.size(), 1U); | ||
| 308 | + | ||
| 309 | + CustomPassContext ctx; | ||
| 310 | + ctx.SetPassName("ut_pass"); | ||
| 311 | + EXPECT_EQ(GraphFuseInspectorUtils::ReportMatch(ToGNodes({graph1_nodes[0], graph2_nodes[0]}), ctx), FAILED); | ||
| 312 | +} | ||
| 313 | + | ||
| 314 | +TEST_F(UtestGraphFuseInspectorUtils, ReportMatchSuccess) { | ||
| 315 | + std::vector<NodePtr> before_nodes; | ||
| 316 | + const auto graph = BuildLinearGraph(before_nodes); | ||
| 317 | + ASSERT_NE(graph, nullptr); | ||
| 318 | + CustomPassContext ctx; | ||
| 319 | + ctx.SetPassName("ut_pass"); | ||
| 320 | + EXPECT_EQ(GraphFuseInspectorUtils::ReportMatch(ToGNodes(before_nodes), ctx), SUCCESS); | ||
| 321 | +} | ||
| 322 | + | ||
| 323 | +TEST_F(UtestGraphFuseInspectorUtils, ReportMatchOnlyIncrementsMatchTimes) { | ||
| 324 | + std::vector<NodePtr> before_nodes; | ||
| 325 | + const auto graph = BuildLinearGraph(before_nodes); | ||
| 326 | + ASSERT_NE(graph, nullptr); | ||
| 327 | + CustomPassContext ctx; | ||
| 328 | + ctx.SetPassName("ut_match_pass"); | ||
| 329 | + EXPECT_EQ(GraphFuseInspectorUtils::ReportMatch(ToGNodes(before_nodes), ctx), SUCCESS); | ||
| 330 | + EXPECT_EQ(GraphFuseInspectorUtils::ReportMatch(ToGNodes(before_nodes), ctx), SUCCESS); | ||
| 331 | + | ||
| 332 | + const std::string key = std::to_string(graph->GetSessionID()) + "_" + std::to_string(graph->GetGraphID()); | ||
| 333 | + std::map<std::string, fe::FusionInfo> graph_fusion_info_map; | ||
| 334 | + std::map<std::string, fe::FusionInfo> buffer_fusion_info_map; | ||
| 335 | + fe::FusionStatisticRecorder::Instance().GetFusionInfo(key, graph_fusion_info_map, buffer_fusion_info_map); | ||
| 336 | + const auto iter = graph_fusion_info_map.find("ut_match_pass"); | ||
| 337 | + ASSERT_NE(iter, graph_fusion_info_map.end()); | ||
| 338 | + EXPECT_EQ(iter->second.GetMatchTimes(), 2); | ||
| 339 | + EXPECT_EQ(iter->second.GetEffectTimes(), 0); | ||
| 340 | + fe::FusionStatisticRecorder::Instance().GetAndClearFusionInfo(key, graph_fusion_info_map, buffer_fusion_info_map); | ||
| 341 | +} | ||
| 342 | + | ||
| 343 | +TEST_F(UtestGraphFuseInspectorUtils, ReportFuseOnlyIncrementsEffectTimes) { | ||
| 344 | + std::vector<NodePtr> before_nodes; | ||
| 345 | + const auto graph = BuildLinearGraph(before_nodes); | ||
| 346 | + ASSERT_NE(graph, nullptr); | ||
| 347 | + CustomPassContext ctx; | ||
| 348 | + ctx.SetPassName("ut_effect_pass"); | ||
| 349 | + EXPECT_EQ(GraphFuseInspectorUtils::ReportFuse(ToGNodes(before_nodes), {}, ctx), SUCCESS); | ||
| 350 | + | ||
| 351 | + const std::string key = std::to_string(graph->GetSessionID()) + "_" + std::to_string(graph->GetGraphID()); | ||
| 352 | + std::map<std::string, fe::FusionInfo> graph_fusion_info_map; | ||
| 353 | + std::map<std::string, fe::FusionInfo> buffer_fusion_info_map; | ||
| 354 | + fe::FusionStatisticRecorder::Instance().GetFusionInfo(key, graph_fusion_info_map, buffer_fusion_info_map); | ||
| 355 | + const auto iter = graph_fusion_info_map.find("ut_effect_pass"); | ||
| 356 | + ASSERT_NE(iter, graph_fusion_info_map.end()); | ||
| 357 | + EXPECT_EQ(iter->second.GetMatchTimes(), 0); | ||
| 358 | + EXPECT_EQ(iter->second.GetEffectTimes(), 1); | ||
| 359 | + fe::FusionStatisticRecorder::Instance().GetAndClearFusionInfo(key, graph_fusion_info_map, buffer_fusion_info_map); | ||
| 360 | +} | ||
| 279 | } // namespace fusion | 361 | } // namespace fusion |
| 280 | } // namespace ge | 362 | } // namespace ge |