diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/.gitignore b/plugins/tensorboard-plugins/tb_graph_ascend/.gitignore index 75bc12db6361869d36e80447322dde9292c0c761..70f4e767811d0d93c25fbb8ce2d2b29c4ba3b6e6 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/.gitignore +++ b/plugins/tensorboard-plugins/tb_graph_ascend/.gitignore @@ -5,4 +5,7 @@ dist/ build/ tb_graph_ascend.egg-info/ __pycache__/ -/server/static/index.html \ No newline at end of file +/server/static/index.html +report.html +assets/ +/htmlcov/ \ No newline at end of file diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/tf_graph/tf-graph-scene.ts b/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/tf_graph/tf-graph-scene.ts index a908f6ac61a671a71c83861727da0716dd64aad3..e7b12acc2f07454f9e89296800512186e0a93414 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/tf_graph/tf-graph-scene.ts +++ b/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/tf_graph/tf-graph-scene.ts @@ -306,6 +306,7 @@ class TfGraphScene2 extends LegacyElementMixin(DarkModeMixin(PolymerElement)) im }, tb_debug.GraphDebugEventId.RENDER_SCENE_BUILD_SCENE, ); + console.log('tf-graph-scene: built scene====', renderHierarchy); // Update the minimap again when the graph is done animating. setTimeout((): void => { this.minimap.update(); diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/tf_graph/tf-graph.ts b/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/tf_graph/tf-graph.ts index e16376056d37364161451c01e45a80d8effdf472..3eafa25502f9094c4b639989e6e532f897f854e7 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/tf_graph/tf-graph.ts +++ b/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/tf_graph/tf-graph.ts @@ -28,6 +28,7 @@ import * as tf_graph_render from '../tf_graph_common/render'; import * as tf_graph_util from '../tf_graph_common/util'; import * as tf_graph_layout from '../tf_graph_common/layout'; import './tf-graph-scene'; +import '../main_graph/index' import './components/legend/index'; import type { MinimapVis, Selection } from '../tf_graph_controls/tf-graph-controls'; import { fetchPbTxt, parseGraphPbTxt } from '../tf_graph_common/parser'; diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/server/app/controllers/match_nodes_controller.py b/plugins/tensorboard-plugins/tb_graph_ascend/server/app/controllers/match_nodes_controller.py index a61154c3ea813656a84f51ad8044d07025aea004..9517d252ca206722497d27ad10c2a4f9bd3c5222 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/server/app/controllers/match_nodes_controller.py +++ b/plugins/tensorboard-plugins/tb_graph_ascend/server/app/controllers/match_nodes_controller.py @@ -38,10 +38,12 @@ class MatchNodesController: # 在原始数据上,添加匹配节点,和匹配节点信息 npu_node_data['matched_node_link'] = [bench_node_name] bench_node_data['matched_node_link'] = [npu_node_name] - npu_node_data['data']['precision_index'] = precision_error + # 防止 KeyError 或 TypeError + npu_node_data.setdefault('data', {})['precision_index'] = precision_error # 后端维护一个匹配节点列表,前端展示 npu_match_nodes_list[npu_node_name] = bench_node_name bench_match_nodes_list[bench_node_name] = npu_node_name + graph_data['npu_match_nodes'] = npu_match_nodes_list graph_data['bench_match_nodes'] = bench_match_nodes_list return { @@ -81,8 +83,8 @@ class MatchNodesController: def process_summary_task_add(graph_data, npu_node_name, bench_node_name): npu_match_nodes_list = graph_data.get('npu_match_nodes', {}) bench_match_nodes_list = graph_data.get('bench_match_nodes', {}) - npu_node_data = graph_data.get('NPU', {}).get('node', {}).get(npu_node_name, {}) - bench_node_data = graph_data.get('Bench', {}).get('node', {}).get(bench_node_name, {}) + npu_node_data = graph_data.get('NPU', {}).get('node', {}).get(npu_node_name) + bench_node_data = graph_data.get('Bench', {}).get('node', {}).get(bench_node_name) # 计算统计误差 intput_statistical_diff = MatchNodesController.calculate_statistical_diff( npu_node_data.get('input_data'), bench_node_data.get('input_data'), npu_node_name, bench_node_name @@ -109,7 +111,8 @@ class MatchNodesController: bench_node_data['matched_node_link'] = [npu_node_name] MatchNodesController.update_graph_node_data(npu_node_data.get('input_data'), intput_statistical_diff) MatchNodesController.update_graph_node_data(npu_node_data.get('output_data'), output_statistical_diff) - npu_node_data['data']['precision_index'] = precision_error + # 防止 KeyError 或 TypeError + npu_node_data.setdefault('data', {})['precision_index'] = precision_error # 后端维护一个匹配节点列表,前端展示 npu_match_nodes_list[npu_node_name] = bench_node_name bench_match_nodes_list[bench_node_name] = npu_node_name @@ -138,7 +141,8 @@ class MatchNodesController: MatchNodesController.delete_matched_node_data(npu_node_data.get('output_data')) # 后端维护一个匹配节点列表,前端展示 try: - del npu_node_data['data']['precision_index'] + # 防止 KeyError 或 TypeError + npu_node_data.get('data', {}).pop('precision_index', None) del npu_match_nodes_list[npu_node_name] del bench_match_nodes_list[bench_node_name] except KeyError: @@ -219,6 +223,8 @@ class MatchNodesController: @staticmethod def calculate_md5_diff(npu_data, bench_data): + if npu_data == {} or bench_data == {}: + return 0 # 对比每个NPU和Bench所有数据md值,如果有一个不一样则返回0,否则返回1 for npu_key, bench_key in zip(npu_data, npu_data): npu_md5 = npu_data[npu_key].get('md5', '') diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/server/plugin.py b/plugins/tensorboard-plugins/tb_graph_ascend/server/plugin.py index ab9f5d3dacec68bc5c1f22133ab6217a728486b6..aefd06137b23cef484ec86967c1398dabc11aa4a 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/server/plugin.py +++ b/plugins/tensorboard-plugins/tb_graph_ascend/server/plugin.py @@ -354,7 +354,6 @@ class GraphsPlugin(base_plugin.TBPlugin): if json_data.get('StepList', {}) and 'ALL' not in json_data.get('StepList', {}): json_data['StepList'].insert(0, 'ALL') all_node_names = self.get_all_node_names(json_data, request) - # 读取第一个文件中的Colors和OverflowCheck first_run_tag = get_global_value("first_run_tag") first_file_data, _ = GraphUtils.safe_load_data(run, first_run_tag) diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/test/conftest.py b/plugins/tensorboard-plugins/tb_graph_ascend/test/conftest.py new file mode 100644 index 0000000000000000000000000000000000000000..894f9ce662475b507aaaf5042c412bc4c8aae8ec --- /dev/null +++ b/plugins/tensorboard-plugins/tb_graph_ascend/test/conftest.py @@ -0,0 +1,62 @@ +import pytest +import json +import os +from pathlib import Path + + +def load_st_test_cases(): + meta_path = Path(__file__).parent / "data/metadata_st.json" + with open(meta_path) as f: + return json.load(f)["test_cases"] + + +def load_ut_test_cases(): + meta_path = Path(__file__).parent / "data/metadata_ut.json" + with open(meta_path) as f: + return json.load(f)["test_cases"] + + +# 动态生成测试用例 +def pytest_generate_tests(metafunc): + if "meta_data" in metafunc.fixturenames and "operation" in metafunc.fixturenames: + ut_test_cases = load_st_test_cases() + params = [] + for case in ut_test_cases: + metaData = case["meta_data"] + metaData["run"] = Path(__file__).parent / metaData["run"] + for op in case["operations"]: + params.append(pytest.param( + metaData, + op, + id=f"{metaData['run']}-{op['type']}" + )) + # 确保参数名称与参数值数量一致 + metafunc.parametrize("meta_data, operation", params) + if "ut_test_case" in metafunc.fixturenames: + ut_test_cases = load_ut_test_cases() + params = [] + for case in ut_test_cases: + params.append(pytest.param( + case, + id=f"{case['type']}-{case['name']}" + )) + # 确保参数名称与参数值数量一致 + metafunc.parametrize("ut_test_case", params) + + +@pytest.fixture +def meta_data(meta_data): + # 返回当前测试的操作配置 + return meta_data + + +@pytest.fixture +def operation_config(operation): + # 返回当前测试的操作配置 + return operation + + +@pytest.fixture +def ut_test_case(ut_test_case): + # 返回当前测试的操作配置 + return ut_test_case diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/test/data/compare_statis.vis b/plugins/tensorboard-plugins/tb_graph_ascend/test/data/compare_statis.vis new file mode 100644 index 0000000000000000000000000000000000000000..5820af6ac01e2a20d36dd6921da9c82b8fd43513 --- /dev/null +++ b/plugins/tensorboard-plugins/tb_graph_ascend/test/data/compare_statis.vis @@ -0,0 +1,948 @@ +{ + "ToolTip": "{\"shape\": \"\\u6570\"}", + "NPU": { + "edge": [], + "node": { + "AddOne_0": { + "matched_node_link": [ + "AddOne_0" + ], + "data": { + "precision_index": 0.0 + }, + "id": "AddOne_0", + "inputs": [], + "input_data": { + "AddOne_0.input_arg.0": { + "type": "torch.Tensor", + "dtype": "", + "shape": [ + 32, + 512, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406", + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + }, + "AddOne_0.input_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406", + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + }, + "AddOne_0.1": {}, + "AddOne_0.2": {} + }, + "output_data": { + "AddOne_0.output_arg.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 32, + 512, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406", + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + }, + "AddOne_0.output_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406", + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + }, + "AddOne_0.1": {}, + "AddOne_0.2": {} + }, + "is_forward": true, + "node_type": 0, + "outputs": [], + "pair": "None", + "subnodes": [ + "Test.add_0_withlonglonglonglonglonglonglonglongname.tt.ee", + "add_51111" + ], + "type": "AddOne", + "upnode": "Test.maxpoolMaxPool2.maxpoolpo.tt.ee" + }, + "AddOne_1": { + "matched_node_link": [], + "data": { + "precision_index": 0.8 + }, + "id": "AddOne_1", + "inputs": [], + "input_data": { + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee.input_arg.0": { + "data_name": "-10", + "longlonglonglonglonglongName": "hah", + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": "[32, 512, 2, 2]", + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406", + "error_key": [ + "type", + "shape" + ] + }, + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee.kwrag_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "is_forward": true, + "node_type": 9, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [ + "add_1", + "add_4" + ], + "type": "AddOne", + "upnode": "Test.maxpoolMaxPool2.maxpoolpo.tt.ee" + }, + "Test.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.tt.ee": { + "matched_node_link": [], + "data": { + "precision_index": 0 + }, + "id": "Test.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.tt.ee", + "inputs": [], + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [ + "add_2" + ], + "type": "AddOne", + "upnode": "AddThree_0", + "micro_step_id": "3" + }, + "AddThree_0": { + "matched_node_link": [ + "B___AddThree_0" + ], + "data": { + "precision_index": 0.5 + }, + "id": "AddThree_0", + "input_data": {}, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [ + "arg0_1_0", + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee", + "Test.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.tt.ee", + "output_0" + ], + "type": "AddThree", + "upnode": "None" + }, + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee": { + "matched_node_link": [ + "B___Test.maxpoolMaxPool2.maxpoolpo.tt.ee" + ], + "data": { + "precision_status": false, + "Host Self Duration(us)": 56.24, + "Host Total Duration(us)": 56.24, + "Device Self Duration(us)": 0, + "Device Total Duration(us)": 0, + "overflow_level": "medium" + }, + "id": "Test.maxpoolMaxPool2.maxpoolpo.tt.ee", + "inputs": [], + "input_data": { + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee.input_arg.0": { + "data_name": "-10", + "longlonglonglonglonglongName": "hah", + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": "[32, 512, 2, 2]", + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406", + "error_key": [ + "type", + "shape" + ] + }, + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee.kwrag_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": { + "output.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 128, + 512, + 2, + 2 + ], + "Max": "538.2343242", + "Min": "-234.124124234", + "Mean": "-510.23432654", + "Norm": "3555.3406" + }, + "output.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 16, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "pair": "None", + "subnodes": [ + "AddOne_0", + "AddOne_1" + ], + "suggestions": { + "text": "test ptdbg工具 with longlong tenm tensldjta te alsejtka gaew jtljae tet jsdklfj.", + "ptdbg工具": "https://gitee.com/ascend/att/tree/master/debug/accuracy_tools/ptdbg_ascend" + }, + "stack_info": [ + "File /home/w3000/xxxx/subnodes/sdd/adad/srit-sda/artar/prased, line 136. om het, \n dada = rtens/sda.ddd(asdw)", + "File /home/w3000/xxxx/subnodes/sdd/adad/srit-sda/artar/prased, line 136. om het, \n dada = rtens/sda.ddd(asdw)", + "File /home/w3000/xxxx/subnodes/sdd/adad/srit-sda/artar/prased, line 136. om het, \n dada = rtens/sda.ddd(asdw)" + ], + "type": "AddTwo", + "upnode": "AddThree_0", + "micro_step_id": "0" + }, + "Test.add_0_withlonglonglonglonglonglonglonglongname.tt.ee": { + "matched_node_link": [ + "B___AddThree_0", + "B___Test.maxpoolMaxPool2.maxpoolpo.tt.ee", + "B___AddOne_0", + "B___Test.add_0_withlonglonglonglonglonglonglonglongname.tt.ee" + ], + "data": { + "precision_index": 0.35 + }, + "id": "Test.add_0_withlonglonglonglonglonglonglonglongname.tt.ee", + "inputs": [], + "input_data": { + "input_arg.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 32, + 512, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + }, + "input_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + }, + "input_arg.2": "None" + }, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": { + "output.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 128, + 512, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + }, + "output.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 16, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "pair": "None", + "subnodes": [], + "type": "addlongtingmelasidngkonklajelkjsakljgskadtest", + "upnode": "AddOne_0" + }, + "add_51111": { + "matched_node_link": [], + "data": { + "precision_status": true, + "precision_index": 1, + "md5 Compare Result": "Pass" + }, + "id": "add_51111", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "add", + "upnode": "AddOne_0" + }, + "add_1": { + "matched_node_link": [], + "data": { + "precision_status": false, + "precision_index": 0, + "md5 Compare Result": "Pass" + }, + "id": "add_1", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "add", + "upnode": "AddOne_1" + }, + "add_4": { + "matched_node_link": [], + "data": {}, + "id": "add_4", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "add", + "upnode": "AddOne_1" + }, + "add_2": { + "matched_node_link": [], + "data": {}, + "id": "add_2", + "inputs": [], + "input_data": { + "add_2.input_arg.0": { + "longlonglonglonglonglongName": "hah", + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": "[32, 512, 2, 2]", + "Max": "6408.2343242", + "Min": "-3134.124124234", + "Mean": "-501.23432654", + "Norm": "3555.3406", + "error_key": [ + "type", + "shape" + ] + }, + "add_2.kwrag_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "add", + "upnode": "Test.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.tt.ee" + }, + "arg0_1_0": { + "matched_node_link": [], + "data": {}, + "id": "arg0_1_0", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "arg0_1", + "upnode": "AddThree_0", + "micro_step_id": "2", + "suggestions": { + "text": "test ptdbg工" + }, + "stack_info": [ + "File /home/w3000/xxxx/subnodes/sdd/adad/srit-sda/artar/prased, line 136. om het, \n dada = rtens/sda.ddd(asdw)" + ] + }, + "output_0": { + "matched_node_link": [], + "data": {}, + "id": "output_0", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "output", + "upnode": "AddThree_0", + "micro_step_id": "3" + } + }, + "root": "AddThree_0" + }, + "Bench": { + "edge": [], + "node": { + "AddOne_0": { + "matched_node_link": [ + "AddOne_0" + ], + "data": {}, + "id": "AddOne_0", + "inputs": [], + "input_data": { + "AddOne_0.input_arg.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 32, + 512, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + }, + "AddOne_0.input_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "output_data": { + "AddOne_0.output_arg.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 32, + 512, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + }, + "AddOne_0.output_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "is_forward": true, + "node_type": 0, + "outputs": [], + "pair": "None", + "subnodes": [ + "Test.add_0_withlonglonglonglonglonglonglonglongname.tt.ee" + ], + "type": "AddOne", + "upnode": "Test.maxpoolMaxPool2.maxpoolpo.tt.ee" + }, + "AddOne_1": { + "matched_node_link": [], + "data": {}, + "id": "AddOne_1", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [ + "add_1" + ], + "type": "AddOne", + "upnode": "Test.maxpoolMaxPool2.maxpoolpo.tt.ee" + }, + "Test.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.tt.ee": { + "matched_node_link": [], + "data": {}, + "id": "Test.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.tt.ee", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [ + "add_2" + ], + "type": "AddOne", + "upnode": "AddThree_0" + }, + "AddThree_0": { + "matched_node_link": [ + "N___AddThree_0" + ], + "data": {}, + "id": "AddThree_0", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [ + "arg0_1_0", + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee", + "Test.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.tt.ee", + "output_0" + ], + "type": "AddThree", + "upnode": "root" + }, + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee": { + "matched_node_link": [], + "data": {}, + "id": "Test.maxpoolMaxPool2.maxpoolpo.tt.ee", + "inputs": [], + "input_data": { + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee.input_arg.0": { + "longlonglonglonglonglongName": "hah", + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": "[32, 512, 2, 2]", + "Max": "548.2343242", + "Min": "-234.124124234", + "Mean": "-5.23432654", + "Norm": "35555.3406", + "error_key": [ + "type", + "shape" + ] + }, + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee.kwrag_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": { + "output.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 128, + 512, + 2, + 2 + ], + "Max": "5038.2343242", + "Min": "-1234.124124234", + "Mean": "-410.23432654", + "Norm": "3255.3406" + }, + "output.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 16, + 256, + 2, + 2 + ], + "Max": "538.2343242", + "Min": "-234.124124234", + "Mean": "-51.23432654", + "Norm": "35555.3406" + } + }, + "pair": "None", + "subnodes": [ + "AddOne_0", + "AddOne_1" + ], + "type": "AddTwo", + "upnode": "AddThree_0" + }, + "Test.add_0_withlonglonglonglonglonglonglonglongname.tt.ee": { + "matched_node_link": [ + "N___AddThree_0", + "N___Test.maxpoolMaxPool2.maxpoolpo.tt.ee", + "N___AddOne_0", + "N___Test.add_0_withlonglonglonglonglonglonglonglongname.tt.ee" + ], + "data": {}, + "id": "Test.add_0_withlonglonglonglonglonglonglonglongname.tt.ee", + "inputs": [], + "input_data": { + "input_arg.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 32, + 512, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + }, + "input_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "is_forward": true, + "node_type": 1, + "outputs": [], + "output_data": { + "output.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 128, + 512, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + }, + "output.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 16, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "pair": "None", + "subnodes": [], + "type": "add", + "upnode": "AddOne_0" + }, + "add_1": { + "matched_node_link": [], + "data": {}, + "id": "add_1", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 1, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "add", + "upnode": "AddOne_1" + }, + "add_2": { + "matched_node_link": [], + "data": {}, + "id": "add_2", + "inputs": [], + "input_data": { + "add_2.input_arg.0": { + "longlonglonglonglonglongName": "hah", + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": "[32, 512, 2, 2]", + "Max": "548.2343242", + "Min": "-234.124124234", + "Mean": "-5.23432654", + "Norm": "35555.3406", + "error_key": [ + "type", + "shape" + ] + }, + "add_2.kwrag_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "is_forward": true, + "node_type": 1, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "add", + "upnode": "Test.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.tt.ee" + }, + "arg0_1_0": { + "matched_node_link": [], + "data": {}, + "id": "arg0_1_0", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 1, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "arg0_1", + "upnode": "AddThree_0" + }, + "output_0": { + "matched_node_link": [], + "data": {}, + "id": "output_0", + "inputs": [], + "input_data": {}, + "is_forward": true, + "node_type": 1, + "outputs": [], + "output_data": {}, + "pair": "None", + "subnodes": [], + "type": "output", + "upnode": "AddThree_0" + } + }, + "root": "AddThree_0" + }, + "Colors": { + "#FF9B3D": { + "value": [ + 0, + 0.5 + ], + "description": "此节点所有输入输出的统计量相对误差,值越大代表测量值与标杆值的偏差越大,相对误差计算方式:|(测量值-标杆值)/标杆值|" + }, + "#FFDC7F": { + "value": [ + 0.5, + 1 + ], + "description": "此节点所有输入输出的统计量相对误差,值越大代表测量值与标杆值的偏差越大,相对误差计算方式:|(测量值-标杆值)/标杆值|" + }, + "#C7C7C7": { + "value": "无匹配节点", + "description": "对比过程中节点未匹配上" + } + }, + "MicroSteps": 5, + "StepList": [ + "ALL", + 0, + 1, + 2, + 3 + ], + "task": "summary", + "match": [], + "npu_match_nodes": { + "AddOne_0": "AddOne_0" + }, + "bench_match_nodes": { + "AddOne_0": "AddOne_0" + }, + "OverflowCheck": true +} \ No newline at end of file diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/test/data/metadata_st.json b/plugins/tensorboard-plugins/tb_graph_ascend/test/data/metadata_st.json new file mode 100644 index 0000000000000000000000000000000000000000..820e11cc39b7c4ed4111690970d2714a82bf1899 --- /dev/null +++ b/plugins/tensorboard-plugins/tb_graph_ascend/test/data/metadata_st.json @@ -0,0 +1,237 @@ +{ + "test_cases": [ + { + "meta_data": { + "run": "data", + "tag": "compare_statis" + }, + "operations": [ + { + "type": "get_node_info", + "node_info": { + "nodeName": "Test.maxpoolMaxPool2.maxpoolpo.tt.ee", + "nodeType": "Bench" + }, + "expected": { + "success": true, + "data": { + "matched_node_link": [], + "data": {}, + "id": "Test.maxpoolMaxPool2.maxpoolpo.tt.ee", + "inputs": [], + "input_data": { + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee.input_arg.0": { + "longlonglonglonglonglongName": "hah", + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": "[32, 512, 2, 2]", + "Max": "548.2343242", + "Min": "-234.124124234", + "Mean": "-5.23432654", + "Norm": "35555.3406", + "error_key": [ + "type", + "shape" + ] + }, + "Test.maxpoolMaxPool2.maxpoolpo.tt.ee.kwrag_arg.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 64, + 256, + 2, + 2 + ], + "Max": "5348.2343242", + "Min": "-2344.124124234", + "Mean": "-51.23432654", + "Norm": "355555.3406" + } + }, + "is_forward": true, + "node_type": 0, + "outputs": [], + "output_data": { + "output.0": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 128, + 512, + 2, + 2 + ], + "Max": "5038.2343242", + "Min": "-1234.124124234", + "Mean": "-410.23432654", + "Norm": "3255.3406" + }, + "output.1": { + "type": "torch.Tensor", + "dtype": "torch.float32", + "shape": [ + 16, + 256, + 2, + 2 + ], + "Max": "538.2343242", + "Min": "-234.124124234", + "Mean": "-51.23432654", + "Norm": "35555.3406" + } + }, + "pair": "None", + "subnodes": [ + "AddOne_0", + "AddOne_1" + ], + "type": "AddTwo", + "upnode": "AddThree_0" + } + } + }, + { + "type": "add_match_nodes", + "npu_node_name": "AddOne_0", + "bench_node_name": "AddOne_0", + "expected": { + "success": true, + "data": { + "precision_error": 0.0, + "intput_statistical_diff": { + "AddOne_0.input_arg.0": { + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + }, + "AddOne_0.input_arg.1": { + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + } + }, + "output_statistical_diff": { + "AddOne_0.output_arg.0": { + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + }, + "AddOne_0.output_arg.1": { + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + } + } + } + } + }, + { + "type": "delete_match_nodes", + "npu_node_name": "AddOne_0", + "bench_node_name": "AddOne_0", + "expected": { + "success": true, + "data": {} + } + }, + { + "type": "add_match_nodes", + "npu_node_name": "AddOne_0", + "bench_node_name": "AddOne_0", + "expected": { + "success": true, + "data": { + "precision_error": 0.0, + "intput_statistical_diff": { + "AddOne_0.input_arg.0": { + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + }, + "AddOne_0.input_arg.1": { + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + } + }, + "output_statistical_diff": { + "AddOne_0.output_arg.0": { + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + }, + "AddOne_0.output_arg.1": { + "MaxAbsErr": 0.0, + "MinAbsErr": 0.0, + "MeanAbsErr": 0.0, + "NormAbsErr": 0.0, + "MaxRelativeErr": "0.0000%", + "MinRelativeErr": "0.0000%", + "MeanRelativeErr": "0.0000%", + "NormRelativeErr": "0.0000%" + } + } + } + } + }, + { + "type": "get_matched_state_list", + "expected": { + "success": true, + "data": { + "npu_match_nodes": { + "AddOne_0": "AddOne_0" + }, + "bench_match_nodes": { + "AddOne_0": "AddOne_0" + } + } + } + }, + { + "type": "save_data", + "expected": { + "success": true + } + } + ] + } + ] +} \ No newline at end of file diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/test/data/metadata_ut.json b/plugins/tensorboard-plugins/tb_graph_ascend/test/data/metadata_ut.json new file mode 100644 index 0000000000000000000000000000000000000000..025fbd14c5fdf5307928ffe4bf3ebd0f102c36f9 --- /dev/null +++ b/plugins/tensorboard-plugins/tb_graph_ascend/test/data/metadata_ut.json @@ -0,0 +1,174 @@ +{ + "test_cases": [ + { + "name": "md5_full_match_success", + "type": "process_md5_task_add", + "input": { + "graph_data": { + "NPU": { + "node": { + "npu_conv2d": { + "input_data": { + "npu_conv2d.data1": { + "md5": "a1b2c3" + }, + "npu_conv2d.data2": { + "md5": "d4e5f6" + } + }, + "output_data": { + "npu_conv2d.out1": { + "md5": "x7y8z9" + } + } + } + } + }, + "Bench": { + "node": { + "bench_conv2d": { + "input_data": { + "bench_conv2d.data1": { + "md5": "a1b2c3" + }, + "bench_conv2d.data2": { + "md5": "d4e5f6" + } + }, + "output_data": { + "bench_conv2d.out1": { + "md5": "x7y8z9" + } + } + } + } + } + }, + "npu_node_name": "npu_conv2d", + "bench_node_name": "bench_conv2d" + }, + "expected": { + "success": true, + "data": { + "precision_error": 1 + } + } + }, + { + "name": "md5_partial_mismatch_failure", + "type": "process_md5_task_add", + "input": { + "graph_data": { + "NPU": { + "node": { + "npu_conv2d": { + "input_data": { + "npu_conv2d.data1": { + "md5": "a1b2c3" + }, + "npu_conv2d.data2": { + "md5": "xxxxxx" + } + } + } + } + }, + "Bench": { + "node": { + "bench_conv2d": { + "input_data": { + "bench_conv2d.data1": { + "md5": "a1b2c3" + }, + "bench_conv2d.data2": { + "md5": "d4e5f6" + } + } + } + } + } + }, + "npu_node_name": "npu_conv2d", + "bench_node_name": "bench_conv2d" + }, + "expected": { + "success": true, + "data": { + "precision_error": 0 + } + } + }, + { + "name": "delete_existing_node_success", + "type": "process_md5_task_delete", + "input": { + "graph_data": { + "npu_match_nodes": { + "npu_conv2d": "bench_conv2d" + }, + "bench_match_nodes": { + "bench_conv2d": "npu_conv2d" + }, + "NPU": { + "node": { + "npu_conv2d": { + "data": { + "precision_index": 1 + }, + "matched_node_link": [ + "bench_conv2d" + ] + } + } + } + }, + "npu_node_name": "npu_conv2d", + "bench_node_name": "bench_conv2d" + }, + "expected": { + "success": true, + "data": {} + } + }, + { + "name": "delete_non_existent_node_failure", + "type": "process_md5_task_delete", + "input": { + "graph_data": { + "NPU": { + "node": { + "npu_conv2d": {} + } + } + }, + "npu_node_name": "npu_conv2d", + "bench_node_name": "bench_conv2d" + }, + "expected": { + "success": false, + "error": "操作失败:删除节点信息失败" + } + }, + { + "name": "missing_input_data_handling", + "type": "process_md5_task_add", + "input": { + "graph_data": { + "NPU": { + "node": { + "npu_conv2d": {} + } + } + }, + "npu_node_name": "npu_conv2d", + "bench_node_name": "bench_conv2d" + }, + "expected": { + "success": true, + "data": { + "precision_error": 0 + } + } + } + ] +} \ No newline at end of file diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/test/integration/service/test_graph_service.py b/plugins/tensorboard-plugins/tb_graph_ascend/test/integration/service/test_graph_service.py new file mode 100644 index 0000000000000000000000000000000000000000..35e3883ac5c3f33a69cc6c6e57899f4dbce67215 --- /dev/null +++ b/plugins/tensorboard-plugins/tb_graph_ascend/test/integration/service/test_graph_service.py @@ -0,0 +1,42 @@ +import pytest +from server.app.service.graph_service import GraphService + + +class TestMatchNodesService: + + def test_service(self, meta_data, operation_config): + op_type = operation_config["type"] + expected = operation_config["expected"] + # 执行操作 + try: + if op_type == "get_node_info": + result = GraphService.get_node_info( + node_info=operation_config["node_info"], + meta_data=meta_data + ) + elif op_type == "add_match_nodes": + result = GraphService.add_match_nodes( + npu_node_name=operation_config["npu_node_name"], + bench_node_name=operation_config["bench_node_name"], + meta_data=meta_data + ) + elif op_type == "delete_match_nodes": + result = GraphService.delete_match_nodes( + npu_node_name=operation_config["npu_node_name"], + bench_node_name=operation_config["bench_node_name"], + meta_data=meta_data + ) + elif op_type == "get_matched_state_list": + result = GraphService.get_matched_state_list( + meta_data=meta_data + ) + elif op_type == "save_data": + result = GraphService.save_data( + meta_data=meta_data + ) + except Exception as e: + result = {"error": type(e).__name__} + + # 验证结果 + assert result == expected, \ + f"Operation {op_type} failed on {operation_config}" diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/test/pytest.ini b/plugins/tensorboard-plugins/tb_graph_ascend/test/pytest.ini new file mode 100644 index 0000000000000000000000000000000000000000..ddb991b93410d7fb17d45cfe3d1e74a9a9b92e3a --- /dev/null +++ b/plugins/tensorboard-plugins/tb_graph_ascend/test/pytest.ini @@ -0,0 +1,9 @@ +[pytest] +testpaths = tests +python_files = test_*.py +norecursedirs = .* venv build dist +addopts = -v --strict-markers +log_cli = true +log_level = DEBUG +markers = + slow: marks tests as slow (deselect with -m 'not slow') \ No newline at end of file diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/test/units/controllers/test_match_nodes_controller.py b/plugins/tensorboard-plugins/tb_graph_ascend/test/units/controllers/test_match_nodes_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ac568d821d436efc27f29a58c9d8131cb4ab44 --- /dev/null +++ b/plugins/tensorboard-plugins/tb_graph_ascend/test/units/controllers/test_match_nodes_controller.py @@ -0,0 +1,72 @@ +import pytest +from server.app.controllers.match_nodes_controller import MatchNodesController +from server.app.utils.graph_utils import GraphUtils + + +class TestMatchNodesController: + + def test_match_node_controller(self, ut_test_case): + op_type = ut_test_case.get("type") + input = ut_test_case.get('input') + expected = ut_test_case.get("expected") + # 执行操作 + try: + if op_type == "process_md5_task_add": + result = MatchNodesController.process_md5_task_add( + graph_data=input.get("graph_data"), + npu_node_name=input.get("npu_node_name"), + bench_node_name=input.get("bench_node_name"), + ) + elif op_type == "process_md5_task_delete": + result = MatchNodesController.process_md5_task_delete( + graph_data=input.get("graph_data"), + npu_node_name=input.get("npu_node_name"), + bench_node_name=input.get("bench_node_name"), + ) + elif op_type == "process_summary_task_add": + + result = MatchNodesController.process_summary_task_add( + graph_data=input.get("graph_data"), + npu_node_name=input.get("npu_node_name"), + bench_node_name=input.get("bench_node_name"), + ) + elif op_type == "process_summary_task_delete": + result = MatchNodesController.process_summary_task_delete( + npu_data=input.get("npu_data"), + bench_data=input.get("bench_data"), + npu_node_name=input.get("npu_node_name"), + bench_node_name=input.get("bench_node_name"), + ) + elif op_type == "calculate_statistical_diff": + result = MatchNodesController.calculate_statistical_diff( + npu_data=input.get("npu_data"), + bench_data=input.get("bench_data"), + npu_node_name=input.get("npu_node_name"), + bench_node_name=input.get("bench_node_name"), + ) + elif op_type == "calculate_max_relative_error": + result = MatchNodesController.calculate_max_relative_error( + result=input.get("result"), + ) + elif op_type == "calculate_md5_diff": + result = MatchNodesController.calculate_md5_diff( + npu_data=input.get("npu_data"), + bench_data=input.get("bench_data"), + ) + elif op_type == "update_graph_node_data": + result = MatchNodesController.update_graph_node_data( + graph_npu_node_data=input.get("graph_npu_node_data"), + statistical_diff=input.get("statistical_diff"), + ) + elif op_type == "delete_matched_node_data": + result = MatchNodesController.delete_matched_node_data( + graph_npu_node_data=input.get("graph_npu_node_data"), + ) + else: + return + except Exception as e: + result = {"error": type(e).__name__} + + # 验证结果 + assert result == expected, \ + f"Operation {op_type} failed on {ut_test_case}" diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/test/units/test_plugin.py b/plugins/tensorboard-plugins/tb_graph_ascend/test/units/test_plugin.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/test/units/utils/test_graph_utils.py b/plugins/tensorboard-plugins/tb_graph_ascend/test/units/utils/test_graph_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391