Skip to content

Commit 96daee6

Browse files
Merge pull request #33 from InfiniTensor/feat/read_mongodb_data
feat: dashboard reads data from MongoDB
2 parents af857b1 + 2170103 commit 96daee6

15 files changed

Lines changed: 1085 additions & 296 deletions

.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)
@@ -102,8 +128,9 @@ def render_dashboard(run_id_filter: str):
102128
">
103129
<strong>InfiniMetrics Dashboard</strong> 用于统一展示
104130
<strong>通信(NCCL / 集合通信)</strong>、
105-
<strong>推理(Direct / Service)</strong>、
106-
<strong>算子(核心算子性能)</strong>
131+
<strong>推理(直接推理 / 服务性能)</strong>、
132+
<strong>算子(核心算子性能)</strong>、
133+
<strong>硬件(内存带宽 / 缓存性能)</strong>
107134
等 AI 加速卡性能测试结果。
108135
<br/>
109136
测试框架输出 <code>JSON</code>(环境 / 配置 / 标量指标) +
@@ -230,10 +257,10 @@ def _latest(lst):
230257
st.dataframe(df, use_container_width=True, hide_index=True)
231258

232259
# ========== Dispatcher summary ==========
233-
summaries = load_summary_file()
260+
summaries = st.session_state.data_loader.load_summaries()
234261

235262
if not summaries:
236-
st.info("No dispatcher_summary file found")
263+
st.info("未找到 Dispatcher 汇总记录")
237264
return
238265

239266
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: 7 additions & 3 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
@@ -17,14 +17,16 @@
1717
create_summary_table_infer,
1818
)
1919

20-
init_page("推理测试分析 | InfiniMetrics", "🔗")
20+
init_page("通信测试分析 | InfiniMetrics", "🔗")
2121

2222

2323
def main():
2424
"""Main function for communication tests page."""
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
selected_runs.append(run_info)
123127

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)