Skip to content

Commit 425e3a1

Browse files
authored
New benchmark category card page (#7247)
# Overview 1. List benchmark links within category 2. enable search benchmark nav link based on name, tags and description 3. prepare page view such as main page, comparison view etc Demo link https://torchci-git-newlistbenchmark-fbopensource.vercel.app/benchmark/benchmark_list # Demo: benchmarks <img width="513" height="99" alt="image" src="https://github.com/user-attachments/assets/7a3ccb66-ae38-4fb9-8a6b-c64a215e059b" /> # Demo: search ![benchmarklist_search](https://github.com/user-attachments/assets/f7893ee4-14a5-400b-86f1-c529e683d533) In this pr, Currently we only add the compiler and torchao related benchmarks in the new list ## Other fix Fix the query deviceName for correct data fetching Add formated title for compiler benchmark
1 parent db57fa6 commit 425e3a1

File tree

14 files changed

+515
-66
lines changed

14 files changed

+515
-66
lines changed

torchci/clickhouse_queries/compilers_benchmark_api_query/query.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ WHERE
3737
AND benchmark_dtype = {dtype: String}
3838
AND benchmark_mode = {mode: String}
3939
AND device = {device: String}
40-
AND multiSearchAnyCaseInsensitive(arch, {arch: Array(String)})
40+
AND (
41+
multiSearchAnyCaseInsensitive(arch, {arch: Array(String)})
42+
OR empty({arch: Array(String)})
43+
)
4144
ORDER BY timestamp
4245
SETTINGS session_timezone = 'UTC';
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { Box, Typography } from "@mui/material";
2+
import { BenchmarkCategoryGroup } from "./components/benchmarkList/BenchmarkCategoryCard";
3+
import BenchmarkCategoryCardList from "./components/benchmarkList/BenchmarkCategoryCardList";
4+
5+
export function BenchmarkListPage() {
6+
const categories: BenchmarkCategoryGroup[] = [
7+
{
8+
title: "PyTorch Benchmarks",
9+
subtitle: "Benchmarks related to repo pytorch/pytorch",
10+
tags: ["repo:pytorch/pytorch"],
11+
items: [
12+
{
13+
name: "PyTorch CacheBench Benchmark Dashboard",
14+
route:
15+
"/benchmark/llms?repoName=pytorch%2Fpytorch&benchmarkName=TorchCache+Benchmark",
16+
},
17+
{
18+
name: "Pytorch Compiler Inductor Benchmark Dashboard",
19+
route: "/benchmark/compilers_regression",
20+
description:
21+
"Use `legacy page` to see comparison view for different branches. It will be deprecated soon",
22+
actions: [
23+
{
24+
label: "Legacy Page/Playground",
25+
href: "/benchmark/compilers",
26+
},
27+
{
28+
label: "Docs",
29+
href: "https://docs.pytorch.org/docs/main/torch.compiler_performance_dashboard.html",
30+
},
31+
],
32+
},
33+
{
34+
name: "PyTorch LLMs Benchmark",
35+
route: "/benchmark/llms?repoName=pytorch%2Fpytorch",
36+
},
37+
{
38+
name: "PyTorch Operator Microbenchmark Dashboard",
39+
route:
40+
"/benchmark/llms?repoName=pytorch%2Fpytorch&benchmarkName=PyTorch+operator+microbenchmark",
41+
},
42+
{
43+
name: "Pytorch Triton Benchmark Dashboard",
44+
route: "/tritonbench/commit_view",
45+
},
46+
],
47+
},
48+
{
49+
title: "TorchAo Benchmarks",
50+
tags: ["repo:pytorch/torchao"],
51+
subtitle: "Benchmarks related to repo pytorch/torchao",
52+
items: [
53+
{
54+
name: "TorchAO Benchmark Danshboard",
55+
route: "/benchmark/llms?repoName=pytorch%2Fao",
56+
},
57+
{
58+
name: "TorchAO Micro API Benchmark Danshboard",
59+
route:
60+
"/benchmark/llms?repoName=pytorch%2Fao&benchmarkName=micro-benchmark+api",
61+
},
62+
],
63+
},
64+
{
65+
title: "ExecuTorch Benchmarks",
66+
tags: ["repo:pytorch/executorch"],
67+
subtitle: "Benchmarks related to repo pytorch/executorch",
68+
items: [
69+
{
70+
name: "ExecuTorch Benchmark Dashboard",
71+
route: "/benchmark/llms?repoName=pytorch%2Fexecutorch",
72+
},
73+
],
74+
},
75+
{
76+
title: "vLLM Benchmarks ",
77+
tags: ["repo:vllm-project/vllm"],
78+
subtitle: "Benchmarks related to repo vllm-project/vllm",
79+
items: [
80+
{
81+
name: "VLLM V1 Benchmark Dashboard",
82+
route: "/benchmark/llms?repoName=vllm-project%2Fvllm",
83+
},
84+
],
85+
},
86+
{
87+
title: "SGLang Benchmarks",
88+
subtitle: "Benchmarks related to repo sgl-project/sglang",
89+
tags: ["repo:sgl-project/sglang"],
90+
items: [
91+
{
92+
name: "SGLang Benchmark Dashboard",
93+
route: "/benchmark/llms?repoName=sgl-project%2Fsglang",
94+
},
95+
],
96+
},
97+
{
98+
title: "Helion Benchmarks",
99+
subtitle: "Benchmarks related to repo pytorch/helion",
100+
tags: ["repo:pytorch/helion"],
101+
items: [
102+
{
103+
name: "Helion Benchmark Dashboard",
104+
route:
105+
"/benchmark/llms?repoName=pytorch%2Fhelion&benchmarkName=Helion+Benchmark",
106+
},
107+
],
108+
},
109+
];
110+
111+
return (
112+
<Box sx={{ p: 2 }}>
113+
<Typography variant="h5" sx={{ mb: 1 }}>
114+
Benchmarks
115+
</Typography>
116+
<BenchmarkCategoryCardList categories={categories} />
117+
</Box>
118+
);
119+
}
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
import {
2+
Card,
3+
CardContent,
4+
CardHeader,
5+
Chip,
6+
Divider,
7+
List,
8+
ListItem,
9+
ListItemButton,
10+
ListItemText,
11+
Stack,
12+
Tooltip,
13+
Typography,
14+
} from "@mui/material";
15+
import { Box } from "@mui/system";
16+
import Link from "next/link";
17+
18+
// ============================
19+
// Styles (centralized)
20+
// ============================
21+
const styles = {
22+
root: { width: "100%" },
23+
searchBox: { mb: 2 },
24+
tip: { color: "text.secondary", mt: 0.5, display: "block" },
25+
grid: {},
26+
gridItem: {},
27+
card: { height: "100%", display: "flex", flexDirection: "column" },
28+
chipWrap: { flexWrap: "wrap" },
29+
chip: { mr: 0.5, mb: 0.5 },
30+
content: { pt: 0, flex: 1, display: "flex", flexDirection: "column" },
31+
list: { mt: 1 },
32+
};
33+
34+
// ============================
35+
// Types
36+
// ============================
37+
export interface BenchmarkLinkItem {
38+
name: string;
39+
route: string;
40+
description?: string;
41+
keys?: string[];
42+
actions?: {
43+
label: string;
44+
onClick?: () => void;
45+
href?: string;
46+
icon?: React.ReactNode;
47+
}[];
48+
}
49+
export interface BenchmarkCategoryGroup {
50+
/** Category title shown on the card header */
51+
title: string;
52+
/** Optional short blurb under the title */
53+
subtitle?: string;
54+
/** Optional category-level tags (rendered as chips) */
55+
tags?: string[];
56+
/** Items in this category */
57+
items: BenchmarkLinkItem[];
58+
/** Extra search keys for the whole category */
59+
keys?: string[];
60+
}
61+
62+
function BenchmarkCardItem({
63+
it,
64+
query,
65+
}: {
66+
it: BenchmarkLinkItem;
67+
query: string;
68+
}) {
69+
const buttonProps = isExternal(it.route)
70+
? {
71+
component: "a" as const,
72+
href: it.route,
73+
target: "_blank",
74+
rel: "noopener noreferrer",
75+
}
76+
: {
77+
component: Link as any,
78+
href: it.route,
79+
// optional Next.js tweaks:
80+
prefetch: false,
81+
};
82+
83+
return (
84+
<ListItem key={it.route} disablePadding>
85+
<Box sx={{ width: "100%" }}>
86+
<Tooltip title="Go to Main Page" arrow>
87+
<ListItemButton {...buttonProps}>
88+
<ListItemText
89+
primary={
90+
<Typography variant="subtitle1">
91+
{highlight(it.name, query)}
92+
</Typography>
93+
}
94+
secondary={
95+
it.description?.length ? (
96+
<>{highlight(it.description, query)}</>
97+
) : null
98+
}
99+
/>
100+
</ListItemButton>
101+
</Tooltip>
102+
103+
{/* Actions */}
104+
{it.actions && (
105+
<Stack direction="row" spacing={1} sx={{ px: 2, pb: 1, pt: 0.5 }}>
106+
{it.actions.map((a, idx) => {
107+
if (!a.href) {
108+
// non-link action (local click)
109+
return (
110+
<Chip
111+
key={idx}
112+
clickable
113+
size="small"
114+
color="secondary"
115+
label={a.label}
116+
onClick={a.onClick}
117+
/>
118+
);
119+
}
120+
const linkProps = isExternal(a.href)
121+
? {
122+
component: "a" as const,
123+
href: a.href,
124+
target: "_blank",
125+
rel: "noopener noreferrer",
126+
}
127+
: {
128+
component: Link as any,
129+
href: a.href,
130+
// optional Next.js tweaks:
131+
prefetch: false,
132+
};
133+
return (
134+
<Chip
135+
{...linkProps}
136+
key={idx}
137+
clickable
138+
size="small"
139+
color="primary"
140+
label={a.label}
141+
/>
142+
);
143+
})}
144+
</Stack>
145+
)}
146+
</Box>
147+
</ListItem>
148+
);
149+
}
150+
151+
export function BenchmarkCategoryCard({
152+
cat,
153+
query,
154+
}: {
155+
cat: BenchmarkCategoryGroup;
156+
query: string;
157+
}) {
158+
return (
159+
<Card variant="outlined" sx={styles.card}>
160+
<CardHeader
161+
title={highlight(cat.title, query)}
162+
subheader={cat.subtitle}
163+
action={
164+
cat.tags && cat.tags.length > 0 ? (
165+
<Stack direction="row" spacing={0.5} sx={styles.chipWrap}>
166+
{cat.tags.map((t) => (
167+
<Chip key={t} size="small" label={t} sx={styles.chip} />
168+
))}
169+
</Stack>
170+
) : null
171+
}
172+
/>
173+
<Divider />
174+
<CardContent sx={styles.content}>
175+
{cat.items.length === 0 ? (
176+
<Typography variant="body2" color="text.secondary">
177+
No matches in this category.
178+
</Typography>
179+
) : (
180+
<List dense disablePadding sx={styles.list}>
181+
{cat.items.map((it, index) => {
182+
// add "Main Page" action to all items
183+
const actions = [
184+
{ label: "Main Page", href: it.route },
185+
...(it.actions ?? []), // keep existing actions if any
186+
];
187+
return (
188+
<>
189+
<BenchmarkCardItem
190+
key={it.route}
191+
it={{ ...it, actions }}
192+
query={query}
193+
/>
194+
{index < cat.items.length - 1 && (
195+
<Divider key={`divider-${index}`} />
196+
)}
197+
</>
198+
);
199+
})}
200+
</List>
201+
)}
202+
</CardContent>
203+
</Card>
204+
);
205+
}
206+
207+
// ============================
208+
// Helpers
209+
// ============================
210+
211+
/**
212+
* Highlight a substring in a string based on a query string
213+
* @param text
214+
* @param q
215+
* @returns
216+
*/
217+
function highlight(text: string, q: string) {
218+
if (!q) return text;
219+
const idx = text.toLowerCase().indexOf(q.toLowerCase());
220+
if (idx === -1) return text;
221+
const before = text.slice(0, idx);
222+
const mid = text.slice(idx, idx + q.length);
223+
const after = text.slice(idx + q.length);
224+
return (
225+
<>
226+
{before}
227+
<Box
228+
component="mark"
229+
sx={{ bgcolor: "warning.light", px: 0.3, py: 0.1, borderRadius: 0.5 }}
230+
>
231+
{mid}
232+
</Box>
233+
{after}
234+
</>
235+
);
236+
}
237+
238+
const isExternal = (url: string) => /^https?:\/\//i.test(url);

0 commit comments

Comments
 (0)