Skip to content

Commit 2e624f7

Browse files
authored
Merge branch 'master' into feat/dashboard-streamlit
2 parents cc804e9 + 90ec223 commit 2e624f7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+3207
-639
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,4 @@ summary_output/
211211
test_output/
212212
traces/
213213
test_*.json
214+
format*.json

.pre-commit-config.yaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ repos:
99
rev: 6.1.0
1010
hooks:
1111
- id: flake8
12-
# Use .flake8 for configuration (separate file to avoid TOML parsing issues)
13-
# --exit-zero: show warnings but don't fail pre-commit
14-
args: ['--config', '.flake8', '--exit-zero']
12+
# Match GitHub CI: check for syntax errors and undefined names
13+
# E9: Runtime errors (IndentationError, SyntaxError)
14+
# F63: Assertion errors
15+
# F7: Various errors
16+
# F82: Undefined names
17+
args: ['--select=E9,F63,F7,F82', '--show-source', '--statistics']
18+

dashboard/app.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
sys.path.append(str(project_root))
1414

1515
from components.header import render_header
16-
from utils.data_loader import InfiniMetricsDataLoader, load_summary_file
16+
from utils.data_loader import InfiniMetricsDataLoader
17+
from common import show_data_source_info
1718

1819
# Page configuration
1920
st.set_page_config(
@@ -28,6 +29,8 @@
2829
st.session_state.data_loader = InfiniMetricsDataLoader()
2930
if "selected_accelerators" not in st.session_state:
3031
st.session_state.selected_accelerators = []
32+
if "use_mongodb" not in st.session_state:
33+
st.session_state.use_mongodb = False
3134

3235

3336
def main():
@@ -40,11 +43,34 @@ def main():
4043
with st.sidebar:
4144
st.markdown("## ⚙️ 设置")
4245

46+
# Data source selection
47+
use_mongodb = st.toggle(
48+
"使用 MongoDB",
49+
value=st.session_state.use_mongodb,
50+
help="切换到 MongoDB 数据源(需要 MongoDB 服务运行中)",
51+
)
52+
53+
if use_mongodb != st.session_state.use_mongodb:
54+
st.session_state.use_mongodb = use_mongodb
55+
if use_mongodb:
56+
st.session_state.data_loader = InfiniMetricsDataLoader(
57+
use_mongodb=True, fallback_to_files=True
58+
)
59+
else:
60+
st.session_state.data_loader = InfiniMetricsDataLoader()
61+
62+
# Show current data source
63+
show_data_source_info(style="sidebar")
64+
65+
st.markdown("---")
66+
4367
results_dir = st.text_input(
44-
"测试结果目录", value="./test_output", help="包含 JSON/CSV 测试结果的目录"
68+
"测试结果目录", value="../output", help="包含 JSON/CSV 测试结果的目录"
4569
)
4670

47-
if results_dir != str(st.session_state.data_loader.results_dir):
71+
if not use_mongodb and results_dir != str(
72+
st.session_state.data_loader.results_dir
73+
):
4874
st.session_state.data_loader = InfiniMetricsDataLoader(results_dir)
4975

5076
auto_refresh = st.toggle("自动刷新", value=False)
@@ -103,8 +129,9 @@ def render_dashboard(run_id_filter: str):
103129
<strong>InfiniMetrics Dashboard</strong> 用于统一展示
104130
<strong>通信(NCCL / 集合通信)</strong>、
105131
<strong>训练(Training / 分布式训练)</strong>、
106-
<strong>推理(Direct / Service 推理)</strong>、
107-
<strong>算子(核心算子性能)</strong>
132+
<strong>推理(直接推理 / 服务性能)</strong>、
133+
<strong>算子(核心算子性能)</strong>、
134+
<strong>硬件(内存带宽 / 缓存性能)</strong>
108135
等 AI 加速卡性能测试结果。
109136
<br/>
110137
测试框架输出 <code>JSON</code>(环境 / 配置 / 标量指标) +
@@ -247,10 +274,10 @@ def _latest(lst):
247274
st.dataframe(df, use_container_width=True, hide_index=True)
248275

249276
# ========== Dispatcher summary ==========
250-
summaries = load_summary_file()
277+
summaries = st.session_state.data_loader.load_summaries()
251278

252279
if not summaries:
253-
st.info("No dispatcher_summary file found")
280+
st.info("未找到 Dispatcher 汇总记录")
254281
return
255282

256283
st.markdown("### 🧾 Dispatcher 汇总记录")

dashboard/common.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,35 @@ def init_page(page_title: str, page_icon: str):
2121
# Page configuration
2222
st.set_page_config(page_title=page_title, page_icon=page_icon, layout="wide")
2323

24-
# Initialize DataLoader
24+
# Initialize use_mongodb setting if not exists
25+
if "use_mongodb" not in st.session_state:
26+
st.session_state.use_mongodb = False
27+
28+
# Initialize DataLoader (respect MongoDB setting)
2529
if "data_loader" not in st.session_state:
2630
from utils.data_loader import InfiniMetricsDataLoader
2731

28-
st.session_state.data_loader = InfiniMetricsDataLoader()
32+
st.session_state.data_loader = InfiniMetricsDataLoader(
33+
use_mongodb=st.session_state.use_mongodb,
34+
fallback_to_files=True,
35+
)
36+
37+
38+
def show_data_source_info(style: str = "caption"):
39+
"""
40+
Display current data source info (MongoDB or file system).
41+
42+
Args:
43+
style: Display style - "caption" for pages, "sidebar" for main app sidebar
44+
"""
45+
dl = st.session_state.data_loader
46+
if dl.source_type == "mongodb":
47+
if style == "sidebar":
48+
st.success("🟢 数据源: MongoDB")
49+
else:
50+
st.caption("数据源: MongoDB")
51+
else:
52+
if style == "sidebar":
53+
st.info(f"📁 数据源: 文件系统 ({dl.results_dir})")
54+
else:
55+
st.caption(f"数据源: 文件系统 ({dl.results_dir})")

dashboard/pages/communication.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import streamlit as st
55
import pandas as pd
66

7-
from common import init_page
7+
from common import init_page, show_data_source_info
88
from components.header import render_header
99
from utils.data_loader import get_friendly_size
1010
from utils.metrics import extract_core_metrics
@@ -25,6 +25,8 @@ def main():
2525
render_header()
2626
st.markdown("## 🔗 通信性能测试分析")
2727

28+
show_data_source_info()
29+
2830
try:
2931
# Load communication test results
3032
comm_runs = st.session_state.data_loader.list_test_runs("comm")
@@ -117,7 +119,9 @@ def main():
117119
for name in selected_indices:
118120
idx = run_options[name]
119121
run_info = filtered_runs[idx]
120-
result = st.session_state.data_loader.load_test_result(run_info["path"])
122+
# Use path for file source, run_id for MongoDB
123+
identifier = run_info.get("path") or run_info.get("run_id")
124+
result = st.session_state.data_loader.load_test_result(identifier)
121125
run_info["data"] = result
122126

123127
selected_runs.append(run_info)

dashboard/pages/inference.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
import streamlit as st
55
import pandas as pd
66

7-
from common import init_page
7+
from common import init_page, show_data_source_info
88
from components.header import render_header
9-
from utils.data_loader import InfiniMetricsDataLoader, get_friendly_size
109
from utils.visualizations import (
1110
plot_timeseries_auto,
1211
create_summary_table_infer,
@@ -19,8 +18,9 @@ def main():
1918
render_header()
2019
st.markdown("## 🚀 推理性能测试分析")
2120

22-
dl = st.session_state.data_loader
23-
runs = dl.list_test_runs("infer")
21+
show_data_source_info()
22+
23+
runs = st.session_state.data_loader.list_test_runs("infer")
2424

2525
if not runs:
2626
st.info("未找到推理测试结果(testcase 需以 infer.* 开头)。")
@@ -91,7 +91,9 @@ def _mode_of(r):
9191
selected_runs = []
9292
for k in selected:
9393
ri = filtered[options[k]]
94-
data = dl.load_test_result(ri["path"])
94+
# Use path for file source, run_id for MongoDB
95+
identifier = ri.get("path") or ri.get("run_id")
96+
data = st.session_state.data_loader.load_test_result(identifier)
9597
ri = dict(ri)
9698
ri["data"] = data
9799
selected_runs.append(ri)

dashboard/pages/operator.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import streamlit as st
55
import pandas as pd
66

7-
from common import init_page
7+
from common import init_page, show_data_source_info
88
from components.header import render_header
99
from utils.visualizations import (
1010
create_summary_table_ops,
@@ -18,24 +18,18 @@ def main():
1818
render_header()
1919
st.markdown("## ⚡ 算子测试分析")
2020

21-
dl = st.session_state.data_loader
21+
show_data_source_info()
2222

23-
runs = dl.list_test_runs() # Load all test runs first
24-
# Identify operator runs by checking "operators" in path or testcase starting with operator/ops
23+
runs = st.session_state.data_loader.list_test_runs()
24+
# Identify operator runs by testcase starting with operator/ops
2525
ops_runs = []
2626
for r in runs:
27-
p = str(r.get("path", ""))
2827
tc = (r.get("testcase") or "").lower()
29-
if (
30-
("/operators/" in p.replace("\\", "/"))
31-
or tc.startswith("operator")
32-
or tc.startswith("operators")
33-
or tc.startswith("ops")
34-
):
28+
if tc.startswith(("operator", "operators", "ops")):
3529
ops_runs.append(r)
3630

3731
if not ops_runs:
38-
st.info("未找到算子测试结果(请确认 JSON 在 test_output/operators/ 下)。")
32+
st.info("未找到算子测试结果(请确认 JSON 在 output/operators 目录下)。")
3933
return
4034

4135
with st.sidebar:
@@ -62,7 +56,9 @@ def main():
6256
selected_runs = []
6357
for k in selected:
6458
ri = filtered[options[k]]
65-
data = dl.load_test_result(ri["path"])
59+
# Use path for file source, run_id for MongoDB
60+
identifier = ri.get("path") or ri.get("run_id")
61+
data = st.session_state.data_loader.load_test_result(identifier)
6662
ri = dict(ri)
6763
ri["data"] = data
6864
selected_runs.append(ri)

0 commit comments

Comments
 (0)