From f7b4a42a8bee008884716b6c8553b962222038ae Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 7 Nov 2025 12:18:13 -0800 Subject: [PATCH 01/13] add config --- .../components/SideBarMainSection.tsx | 47 +++++++++++++++---- .../commits/CommitWorkfowSelectSection.tsx | 16 ++++++- ...nchmarkTimeSeriesComparisonTableSlider.tsx | 2 +- .../configs/teams/compilers/config.ts | 8 +++- .../defaults/default_dashboard_config.ts | 3 +- .../configs/teams/helion/config.ts | 6 ++- .../configs/teams/torchao/config.ts | 2 +- .../store/benchmark_regression_store.ts | 32 +++++++++++++ 8 files changed, 100 insertions(+), 16 deletions(-) diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx index 77a1d9a68c..093dbb8fac 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx @@ -17,6 +17,7 @@ import { DenseAlert } from "../../common/styledComponents"; import { BranchDropdowns } from "./commits/BranchDropdown"; import { SamplingSetting } from "./filters/sampling/SamplingSetting"; import { useUrlStoreSync } from "./useUrlSync"; +import { FormControlLabel, Switch } from "@mui/material"; const styles = { root: { @@ -93,6 +94,8 @@ export function SideBarMainSection() { setStagedRBranch, setEnableSamplingSetting, setStagedMaxSampling, + setBranchOptionType, + lcommit, rcommit, committedTime, @@ -100,6 +103,8 @@ export function SideBarMainSection() { committedLbranch, committedRbranch, committedMaxSampling, + branchOptionType, + enableMultiBranchOption, enableSamplingSetting, commitMainOptions, revertMainOptions, @@ -109,12 +114,15 @@ export function SideBarMainSection() { stagedLbranch: s.stagedLbranch, stagedRbranch: s.stagedRbranch, stagedMaxSampling: s.stagedMaxSampling, + enableMultiBranchOption: s.enableMultiBranchOption, + branchOptionType: s.branchOptionType, setStagedTime: s.setStagedTime, setStagedLBranch: s.setStagedLbranch, setStagedRBranch: s.setStagedRbranch, setStagedMaxSampling: s.setStagedMaxSampling, setEnableSamplingSetting: s.setEnableSamplingSetting, + setBranchOptionType: s.setBranchOptionType, committedTime: s.committedTime, committedFilters: s.committedFilters, @@ -135,6 +143,9 @@ export function SideBarMainSection() { const [samplingDirty, setSamplingDirty] = useState(false); const prevEnableRef = useRef(enableSamplingSetting); + + const prevBranchOption = useRef(branchOptionType); + useEffect(() => { if (enableSamplingSetting !== prevEnableRef.current) { setSamplingDirty(true); // mark dirty when toggled @@ -265,15 +276,33 @@ export function SideBarMainSection() { - {!isCommitsLoading && !commitsError && ( - + {!isCommitsLoading && !commitsError && ( + <> + {enableMultiBranchOption && ( + setBranchOptionType(e.target.checked?'multiple':'single')} + /> + } + label={ + + Enable Multi Branch + + } + /> + )} + + )} {isCommitsLoading && ( diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/CommitWorkfowSelectSection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/CommitWorkfowSelectSection.tsx index 7588430fea..5046547ec5 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/CommitWorkfowSelectSection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/CommitWorkfowSelectSection.tsx @@ -1,5 +1,5 @@ import { Typography } from "@mui/material"; -import { Stack } from "@mui/system"; +import { Box, Stack } from "@mui/system"; import { useBenchmarkBook } from "components/benchmark_v3/configs/benchmark_config_book"; import { QueryParameterConverterInputs } from "components/benchmark_v3/configs/utils/dataBindingRegistration"; import { CenteredLoader } from "components/common/LoadingIcon"; @@ -147,6 +147,13 @@ export function CommitWorflowSelectSection() { Commit Range: + + {lcommit?.branch}: + + + {rcommit?.branch}: + ; + export type BenchmarkCommitMeta = { commit: string; date: string; @@ -44,6 +45,10 @@ export interface BenchmarkDashboardState { // TODO(elainewy): may allow user to set a different max sampling threshold based on their needs. stagedMaxSampling?: number; + + enableMultiBranchOption?:boolean; + branchOptionType: string + // may key to track of the benchamrk benchmarkId: string; type: BenchmarkPageType; @@ -67,6 +72,7 @@ export interface BenchmarkDashboardState { setEnableSamplingSetting: (enable: boolean) => void; + setBranchOptionType:(type:string) => void; setLcommit: (commit: BenchmarkCommitMeta | null) => void; setRcommit: (commit: BenchmarkCommitMeta | null) => void; @@ -108,6 +114,7 @@ export function createDashboardStore(initial: { rcommit?: BenchmarkCommitMeta | null; renderGroupId?: string; maxSampling?: number; + enableMultiBranchOption?: boolean }) { const idItem = BENCHMARK_ID_MAPPING[initial.benchmarkId]; return createWithEqualityFn()((set, get) => ({ @@ -122,6 +129,11 @@ export function createDashboardStore(initial: { // default main means render the page with renders option renderGroupId: initial.renderGroupId ?? "main", + // multi branch setting + enableMultiBranchOption: (initial.enableMultiBranchOption ?? false), + branchOptionType: "single", + + // set only with initial config enableSamplingSetting: (initial.maxSampling ?? 0) > 0, // max sampling threshold, if null, no limit. @@ -174,6 +186,26 @@ export function createDashboardStore(initial: { setStagedFilters: (filters) => set((s) => ({ stagedFilters: { ...s.stagedFilters, ...filters } })), + setBranchOptionType:(type) => { + set((s) => { + if (!s.enableMultiBranchOption) return s; + if (type === s.branchOptionType){ + return s; + } + if (type == "single"){ + return { + branchOptionType:type, + committedRbranch: s.committedLbranch, + stagedRbranch: s.stagedLbranch + } + } else{ + return { + branchOptionType:type, + } + } + }); + }, + commitMainOptions: () => { set((s) => { let newState: any = { From 7728d0bb6945d6056139795f24ed95dfba479ea0 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 7 Nov 2025 13:03:18 -0800 Subject: [PATCH 02/13] add config --- .../benchmarkSideBar/BenchmarkTopBar.tsx | 2 +- .../components/SideBarMainSection.tsx | 42 ++++++++++++------- .../components/commits/BranchDropdown.tsx | 1 + .../commits/CommitWorkfowSelectSection.tsx | 2 +- .../configs/teams/compilers/config.ts | 16 ++++--- .../defaults/default_dashboard_config.ts | 4 +- .../configs/teams/helion/config.ts | 6 +-- .../configs/teams/torchao/config.ts | 2 +- torchci/components/layout/NavBar.module.css | 2 +- .../components/layout/NavBarGroupDropdown.tsx | 4 +- .../store/benchmark_regression_store.ts | 35 +++++++--------- 11 files changed, 64 insertions(+), 52 deletions(-) diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx index 8cd81706af..2447ab29f4 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx @@ -22,7 +22,7 @@ export function BenchmarkTopBar({ position: "sticky", top: 0, paddingTop: 2, - zIndex: 1100, + zIndex: 1, borderBottom: "1px solid", borderColor: "divider", px: 2, diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx index 093dbb8fac..a9c7b83838 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx @@ -1,7 +1,9 @@ // components/Sidebar.tsx +import { FormControlLabel, Switch } from "@mui/material"; import Divider from "@mui/material/Divider"; import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; +import { Box } from "@mui/system"; import { useBenchmarkBook } from "components/benchmark_v3/configs/benchmark_config_book"; import { QueryParameterConverterInputs } from "components/benchmark_v3/configs/utils/dataBindingRegistration"; import { CenteredLoader } from "components/common/LoadingIcon"; @@ -17,7 +19,6 @@ import { DenseAlert } from "../../common/styledComponents"; import { BranchDropdowns } from "./commits/BranchDropdown"; import { SamplingSetting } from "./filters/sampling/SamplingSetting"; import { useUrlStoreSync } from "./useUrlSync"; -import { FormControlLabel, Switch } from "@mui/material"; const styles = { root: { @@ -276,23 +277,32 @@ export function SideBarMainSection() { - {!isCommitsLoading && !commitsError && ( + {!isCommitsLoading && !commitsError && ( <> {enableMultiBranchOption && ( - setBranchOptionType(e.target.checked?'multiple':'single')} - /> - } - label={ - - Enable Multi Branch - - } - /> + + + TYPE:{branchOptionType}{" "} + + + setBranchOptionType( + e.target.checked ? "comparison" : "single" + ) + } + /> + } + label={ + + Enable Multi Branch + + } + /> + )} + {type} {empty ? ( No branch is found, please select other features. diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/CommitWorkfowSelectSection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/CommitWorkfowSelectSection.tsx index 5046547ec5..e8e09ef70c 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/CommitWorkfowSelectSection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/CommitWorkfowSelectSection.tsx @@ -163,7 +163,7 @@ export function CommitWorflowSelectSection() { setCommit={setLcommit} /> diff --git a/torchci/components/benchmark_v3/configs/teams/compilers/config.ts b/torchci/components/benchmark_v3/configs/teams/compilers/config.ts index db7c62c978..554e5172dc 100644 --- a/torchci/components/benchmark_v3/configs/teams/compilers/config.ts +++ b/torchci/components/benchmark_v3/configs/teams/compilers/config.ts @@ -16,6 +16,7 @@ import { QueryParameterConverterInputs, } from "../../utils/dataBindingRegistration"; import { toNumberArray } from "../../utils/helper_methods"; +import { DEFAULT_DASHBOARD_BENCHMARK_INITIAL } from "../defaults/default_dashboard_config"; dayjs.extend(utc); const PASSRATE_COMPARISON_POLICY: BenchmarkComparisonPolicyConfig = { @@ -197,8 +198,11 @@ export const COMPILTER_PRECOMPUTE_BENCHMARK_INITIAL = { export const COMPILTER_BENCHMARK_NAME = "compiler_inductor"; -const COMPILER_BENCHMARK_DATABINDING = { - initial: COMPILTER_PRECOMPUTE_BENCHMARK_INITIAL, +const COMPILER_DASHBOARD_BENCHMARK_DATABINDING = { + initial: { + ...DEFAULT_DASHBOARD_BENCHMARK_INITIAL, + ...COMPILTER_PRECOMPUTE_BENCHMARK_INITIAL, + }, required_filter_fields: REQUIRED_COMPLIER_LIST_COMMITS_KEYS, filter_options: { customizedDropdown: { @@ -214,7 +218,7 @@ const COMPILER_BENCHMARK_DATABINDING = { const DASHBOARD_COMPARISON_TABLE_METADATA_COLUMNS = [ { - field:"branch", + field: "branch", displayName: "branch", }, { @@ -232,7 +236,7 @@ export const CompilerDashboardBenchmarkUIConfig: BenchmarkUIConfig = { apiId: COMPILTER_BENCHMARK_NAME, title: "Compiler Inductor Dashboard", type: "dashboard", - dataBinding: COMPILER_BENCHMARK_DATABINDING, + dataBinding: COMPILER_DASHBOARD_BENCHMARK_DATABINDING, dataRender: { type: "auto", subSectionRenders: { @@ -244,7 +248,7 @@ export const CompilerDashboardBenchmarkUIConfig: BenchmarkUIConfig = { config: { type: "line", groupByFields: ["metric"], - lineKey: ["model", "compiler", "suite","branch"], + lineKey: ["model", "compiler", "suite", "branch"], chart: { renderOptions: { chartRenderBook: DashboardRenderBook, @@ -378,7 +382,7 @@ export const CompilerPrecomputeBenchmarkUIConfig: BenchmarkUIConfig = { chartGroup: { type: "line", groupByFields: ["metric"], - lineKey: ["compiler","branch"], + lineKey: ["compiler", "branch"], chart: { enableDialog: true, customizedConfirmDialog: { diff --git a/torchci/components/benchmark_v3/configs/teams/defaults/default_dashboard_config.ts b/torchci/components/benchmark_v3/configs/teams/defaults/default_dashboard_config.ts index 6699d8bbbf..95aa53b968 100644 --- a/torchci/components/benchmark_v3/configs/teams/defaults/default_dashboard_config.ts +++ b/torchci/components/benchmark_v3/configs/teams/defaults/default_dashboard_config.ts @@ -31,7 +31,7 @@ export const DEFAULT_DASHBOARD_BENCHMARK_INITIAL = { }, lbranch: "main", rbranch: "main", - enableMultiBranchOption:true, + enableMultiBranchOption: true, }; export const DEFAULT_COMPARISON_TABLE_METADATA_COLUMNS = [ @@ -83,7 +83,7 @@ export const defaultDashboardBenchmarkUIConfig: BenchmarkUIConfig | any = { config: { type: "line", groupByFields: ["metric"], - lineKey: ["dtype", "metric","branch"], + lineKey: ["dtype", "metric", "branch"], chart: { renderOptions: { showLegendDetails: true, diff --git a/torchci/components/benchmark_v3/configs/teams/helion/config.ts b/torchci/components/benchmark_v3/configs/teams/helion/config.ts index 48a86caa9d..c62cb79913 100644 --- a/torchci/components/benchmark_v3/configs/teams/helion/config.ts +++ b/torchci/components/benchmark_v3/configs/teams/helion/config.ts @@ -18,9 +18,9 @@ const COMPARISON_TABLE_METADATA_COLUMNS = [ displayName: "Hardware model", }, { - field:"branch", + field: "branch", displayName: "branch", - } + }, ] as const; const RENDER_MAPPING_BOOK = { @@ -83,7 +83,7 @@ export const PytorchHelionDashboardConfig: BenchmarkUIConfig = { config: { type: "line", groupByFields: ["metric"], - lineKey: ["metric","branch"], + lineKey: ["metric", "branch"], chart: { renderOptions: { chartRenderBook: RENDER_MAPPING_BOOK, diff --git a/torchci/components/benchmark_v3/configs/teams/torchao/config.ts b/torchci/components/benchmark_v3/configs/teams/torchao/config.ts index 7e7cf541b0..6c429f14be 100644 --- a/torchci/components/benchmark_v3/configs/teams/torchao/config.ts +++ b/torchci/components/benchmark_v3/configs/teams/torchao/config.ts @@ -90,7 +90,7 @@ export const PytorchOperatorMicroBenchmarkDashoboardConfig: BenchmarkUIConfig = config: { type: "line", groupByFields: ["metric"], - lineKey: ["extra_key.use_compile", "dtype", "metric","branch"], + lineKey: ["extra_key.use_compile", "dtype", "metric", "branch"], chart: { renderOptions: { chartRenderBook: RENDER_MAPPING_BOOK, diff --git a/torchci/components/layout/NavBar.module.css b/torchci/components/layout/NavBar.module.css index 37ba56b31e..80b9bb1d8f 100644 --- a/torchci/components/layout/NavBar.module.css +++ b/torchci/components/layout/NavBar.module.css @@ -8,7 +8,7 @@ min-height: 60px; align-items: center; position: relative; - z-index: 1000; + z-index: 1300; backdrop-filter: blur(1px); -webkit-backdrop-filter: blur(1px); flex-wrap: wrap; diff --git a/torchci/components/layout/NavBarGroupDropdown.tsx b/torchci/components/layout/NavBarGroupDropdown.tsx index 75ae90f5e0..b2bc2187ca 100644 --- a/torchci/components/layout/NavBarGroupDropdown.tsx +++ b/torchci/components/layout/NavBarGroupDropdown.tsx @@ -60,7 +60,7 @@ export function NavBarGroupDropdown({ ); return ( -
setAnchorEl(e.currentTarget)} onMouseLeave={() => setAnchorEl(null)} > @@ -162,6 +162,6 @@ export function NavBarGroupDropdown({ -
+
); } diff --git a/torchci/lib/benchmark/store/benchmark_regression_store.ts b/torchci/lib/benchmark/store/benchmark_regression_store.ts index d390ac0ae8..9c2a913fd8 100644 --- a/torchci/lib/benchmark/store/benchmark_regression_store.ts +++ b/torchci/lib/benchmark/store/benchmark_regression_store.ts @@ -8,7 +8,6 @@ import { BENCHMARK_ID_MAPPING } from "../../../components/benchmark_v3/configs/c export type TimeRange = { start: Dayjs; end: Dayjs }; type KV = Record; - export type BenchmarkCommitMeta = { commit: string; date: string; @@ -45,9 +44,8 @@ export interface BenchmarkDashboardState { // TODO(elainewy): may allow user to set a different max sampling threshold based on their needs. stagedMaxSampling?: number; - - enableMultiBranchOption?:boolean; - branchOptionType: string + enableMultiBranchOption?: boolean; + branchOptionType: string; // may key to track of the benchamrk benchmarkId: string; @@ -72,7 +70,7 @@ export interface BenchmarkDashboardState { setEnableSamplingSetting: (enable: boolean) => void; - setBranchOptionType:(type:string) => void; + setBranchOptionType: (type: string) => void; setLcommit: (commit: BenchmarkCommitMeta | null) => void; setRcommit: (commit: BenchmarkCommitMeta | null) => void; @@ -114,7 +112,7 @@ export function createDashboardStore(initial: { rcommit?: BenchmarkCommitMeta | null; renderGroupId?: string; maxSampling?: number; - enableMultiBranchOption?: boolean + enableMultiBranchOption?: boolean; }) { const idItem = BENCHMARK_ID_MAPPING[initial.benchmarkId]; return createWithEqualityFn()((set, get) => ({ @@ -130,10 +128,9 @@ export function createDashboardStore(initial: { renderGroupId: initial.renderGroupId ?? "main", // multi branch setting - enableMultiBranchOption: (initial.enableMultiBranchOption ?? false), + enableMultiBranchOption: initial.enableMultiBranchOption ?? false, branchOptionType: "single", - // set only with initial config enableSamplingSetting: (initial.maxSampling ?? 0) > 0, // max sampling threshold, if null, no limit. @@ -186,23 +183,23 @@ export function createDashboardStore(initial: { setStagedFilters: (filters) => set((s) => ({ stagedFilters: { ...s.stagedFilters, ...filters } })), - setBranchOptionType:(type) => { + setBranchOptionType: (type) => { set((s) => { if (!s.enableMultiBranchOption) return s; - if (type === s.branchOptionType){ + if (type === s.branchOptionType) { return s; } - if (type == "single"){ + if (type == "single") { return { - branchOptionType:type, - committedRbranch: s.committedLbranch, - stagedRbranch: s.stagedLbranch - } - } else{ - return { - branchOptionType:type, + branchOptionType: type, + committedRbranch: s.committedLbranch, + stagedRbranch: s.stagedLbranch, + }; + } else { + return { + branchOptionType: type, + }; } - } }); }, From 1146e4abccfeffc20bc1746a150b43c84cf289c2 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 7 Nov 2025 13:07:06 -0800 Subject: [PATCH 03/13] add config --- .../benchmarkSideBar/components/SideBarMainSection.tsx | 3 --- .../configs/teams/defaults/default_dashboard_config.ts | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx index a9c7b83838..fb6b4b7e87 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx @@ -281,9 +281,6 @@ export function SideBarMainSection() { <> {enableMultiBranchOption && ( - - TYPE:{branchOptionType}{" "} - Date: Fri, 7 Nov 2025 13:15:03 -0800 Subject: [PATCH 04/13] add config --- .../configs/teams/defaults/default_dashboard_config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchci/components/benchmark_v3/configs/teams/defaults/default_dashboard_config.ts b/torchci/components/benchmark_v3/configs/teams/defaults/default_dashboard_config.ts index d95e6305cc..7b43e0091f 100644 --- a/torchci/components/benchmark_v3/configs/teams/defaults/default_dashboard_config.ts +++ b/torchci/components/benchmark_v3/configs/teams/defaults/default_dashboard_config.ts @@ -36,7 +36,7 @@ export const DEFAULT_DASHBOARD_BENCHMARK_INITIAL = { export const DEFAULT_COMPARISON_TABLE_METADATA_COLUMNS = [ { - field:"branch", + field: "branch", displayName: "Branch", }, { From 98507077628bde52b190a73a16699e487adda3c4 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 7 Nov 2025 14:01:13 -0800 Subject: [PATCH 05/13] add config --- .../benchmarkSideBar/components/SideBarMainSection.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx index fb6b4b7e87..24358eb956 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx @@ -145,8 +145,6 @@ export function SideBarMainSection() { const [samplingDirty, setSamplingDirty] = useState(false); const prevEnableRef = useRef(enableSamplingSetting); - const prevBranchOption = useRef(branchOptionType); - useEffect(() => { if (enableSamplingSetting !== prevEnableRef.current) { setSamplingDirty(true); // mark dirty when toggled From 9a83c31ee4292b49d7c96d498473102e6867d0b2 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 7 Nov 2025 18:11:36 -0800 Subject: [PATCH 06/13] add config --- .../benchmarkSideBar/BenchmarkTopBar.tsx | 6 +- .../commits/SingleCommitSelectSelection.tsx | 176 +++++++++ .../dataRender/auto/autoComponents.tsx | 80 +++- .../components/BenchmarkRawDataTable.tsx | 13 + .../components/BenchmarkSingleDataTable.tsx | 366 ++++++++++++++++++ .../ComparisonTable.tsx | 8 +- .../components/benchmarkTimeSeries/helper.tsx | 2 +- .../configs/benchmark_config_book.tsx | 20 +- .../defaults/default_single_view_config.ts | 55 +++ .../configs/teams/helion/config.ts | 42 +- .../configs/utils/autoRegistration.tsx | 4 + .../pages/BenchmarkSinglePage.tsx | 70 ++++ torchci/pages/benchmark/v3/single/[id].tsx | 14 + 13 files changed, 841 insertions(+), 15 deletions(-) create mode 100644 torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx create mode 100644 torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleDataTable.tsx create mode 100644 torchci/components/benchmark_v3/configs/teams/defaults/default_single_view_config.ts create mode 100644 torchci/components/benchmark_v3/pages/BenchmarkSinglePage.tsx create mode 100644 torchci/pages/benchmark/v3/single/[id].tsx diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx index 2447ab29f4..1d69ca4aff 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx @@ -4,13 +4,16 @@ import { BenchmarkUIConfigHandler } from "components/benchmark_v3/configs/benchm import { BenchmarkReportFeatureNotification } from "../benchmarkRegressionReport/BenchmarkReportFeatureNotification"; import { BenchmarkReportFeatureSidePanel } from "../benchmarkRegressionReport/BenchmarkReportFeatureSidePanel"; import { CommitWorflowSelectSection } from "./components/commits/CommitWorkfowSelectSection"; +import { SingleCommitSelectSelection } from "./components/commits/SingleCommitSelectSelection"; export function BenchmarkTopBar({ config, title = "", + mode = "default", }: { config: BenchmarkUIConfigHandler; title?: string; + mode?: string; }) { const reportFeature = config.raw.dataRender?.sideRender?.RegressionReportFeature; @@ -43,7 +46,8 @@ export function BenchmarkTopBar({ )} - + {mode == "default" && } + {mode == "single" && } ); diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx new file mode 100644 index 0000000000..e5db461db2 --- /dev/null +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx @@ -0,0 +1,176 @@ +import { Typography } from "@mui/material"; +import { Box, Stack } from "@mui/system"; +import { useBenchmarkBook } from "components/benchmark_v3/configs/benchmark_config_book"; +import { QueryParameterConverterInputs } from "components/benchmark_v3/configs/utils/dataBindingRegistration"; +import { CenteredLoader } from "components/common/LoadingIcon"; +import { UMDenseCommitDropdown } from "components/uiModules/UMDenseComponents"; +import { useBenchmarkCommitsData } from "lib/benchmark/api_helper/fe/hooks"; +import { useDashboardSelector } from "lib/benchmark/store/benchmark_dashboard_provider"; +import { BenchmarkCommitMeta } from "lib/benchmark/store/benchmark_regression_store"; +import { useEffect, useState } from "react"; + +export function SingleCommitSelectSelection() { + const { + repo, + type, + benchmarkName, + benchmarkId, + committedTime, + committedFilters, + lcommit, + rcommit, + committedLBranch, + committedRBranch, + committedMaxSampling, + enableSamplingSetting, + setLcommit, + setRcommit, + } = useDashboardSelector((s) => ({ + type: s.type, + benchmarkId: s.benchmarkId, + committedTime: s.committedTime, + committedFilters: s.committedFilters, + committedMaxSampling: s.committedMaxSampling, + enableSamplingSetting: s.enableSamplingSetting, + repo: s.repo, + benchmarkName: s.benchmarkName, + lcommit: s.lcommit, + rcommit: s.rcommit, + committedLBranch: s.committedLbranch, + committedRBranch: s.committedRbranch, + setLcommit: s.setLcommit, + setRcommit: s.setRcommit, + })); + + const [leftList, setLeftList] = useState([]); + const [rightList, setRightList] = useState([]); + + const getConfig = useBenchmarkBook((s) => s.getConfig); + const config = getConfig(benchmarkId, type); + const dataBinding = config.dataBinding; + const required_filter_fields = config.raw?.required_filter_fields ?? []; + + const ready = + !!committedTime?.start && + !!committedTime?.end && + !!committedLBranch && + committedLBranch.length > 0 && + !!committedRBranch && + committedRBranch.length > 0 && + (enableSamplingSetting ? committedMaxSampling : true) && + required_filter_fields.every((k) => !!committedFilters[k]); + + // Fetch data + const branches = [ + ...new Set( + [committedLBranch, committedRBranch].filter((b) => b.length > 0) + ), + ]; + + // Convert to query params + const params = dataBinding.toQueryParams({ + repo: repo, + benchmarkName: benchmarkName, + branches, + timeRange: committedTime, + filters: committedFilters, + maxSampling: enableSamplingSetting ? committedMaxSampling : undefined, + } as QueryParameterConverterInputs); + if (!params) { + throw new Error(`Failed to convert to query params for ${benchmarkId}`); + } + + const queryParams: any | null = ready ? params : null; + + // Fetch data + const { data, isLoading, error } = useBenchmarkCommitsData( + benchmarkId, + queryParams + ); + + useEffect(() => { + if (isLoading || !data) return; + + const groups = data?.data?.branch ?? []; + const branchMap = convertToBranchMap(groups); + + const L: BenchmarkCommitMeta[] = branchMap[committedLBranch] ?? []; + + // update list + setLeftList(L); + + if (L.length === 0) return; + + // check if user has selected a commit that is not in the list + const lSelected = lcommit?.workflow_id ?? null; + + const lHas = !!lSelected && L.some((c) => c.workflow_id === lSelected); + + // rule left and right both pick left option + const nextAutoL = lHas ? lSelected : L[0]?.workflow_id ?? null; + + if (!lHas) { + setLcommit( + nextAutoL ? L.find((c) => c.workflow_id === nextAutoL) ?? null : null + ); + // tho this is single commit comopnent, we use same store as comparison mode, + // update rcommit for data consistency + setRcommit( + nextAutoL ? L.find((c) => c.workflow_id === nextAutoL) ?? null : null + ); + } + }, [ + isLoading, + data, + committedLBranch, + committedRBranch, + lcommit?.workflow_id, + rcommit?.workflow_id, + setLcommit, + setRcommit, + ]); + + if (error) return
Error: {error.message}
; + if (isLoading || !data) return ; + + return ( + + + Commit: + + + {lcommit?.branch}: + + { + setLcommit(c); + setRcommit(c); + }} + /> + + ); +} + +export const convertToBranchMap = ( + raw: any[] +): Record => { + return raw.reduce((acc, g) => { + const branch = g?.group_info?.branch ?? "unknown"; + acc[branch] = g.rows.map((r: any) => ({ + commit: r.commit, + workflow_id: String(r.workflow_id), + date: r.date, + branch, + })); + return acc; + }, {} as Record); +}; diff --git a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx index 78fc593f75..efefe6a82c 100644 --- a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx @@ -15,6 +15,7 @@ import { BenchmarkLogSidePanelWrapper } from "../../common/BenchmarkLogViewer/Be import { RenderRawContent } from "../../common/RawContentDialog"; import BenchmarkTimeSeriesChartGroup from "../components/benchmarkTimeSeries/components/BenchmarkTimeSeriesChart/BenchmarkTimeSeriesChartGroup"; import { ComparisonTable } from "../components/benchmarkTimeSeries/components/BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTable"; +import BenchmarkSingleDataTable from "../components/benchmarkTimeSeries/components/BenchmarkSingleDataTable"; export function AutoBenchmarkTimeSeriesTable({ config }: AutoComponentProps) { const ctx = useBenchmarkCommittedContext(); @@ -557,7 +558,7 @@ export function AutoBenchmarkRawDataTable({ config }: AutoComponentProps) { return ( - + !!ctx.committedFilters[k]); + + const dataBinding = ctx?.configHandler.dataBinding; + const uiRenderConfig = config as UIRenderConfig; + + const branches = [ + ...new Set([ctx.committedLbranch].filter((b) => b.length > 0)), + ]; + const workflows = ctx.lcommit?.workflow_id ? [ctx.lcommit?.workflow_id] : []; + + // convert to the query params + const params = dataBinding.toQueryParams({ + repo: ctx.repo, + branches: branches, + benchmarkName: ctx.benchmarkName, + timeRange: ctx.committedTime, + filters: ctx.committedFilters, + maxSampling: ctx.committedMaxSampling, + workflows, + }); + + const queryParams: any | null = ready ? params : null; + // fetch the bechmark data + const { + data: resp, + isLoading, + error, + } = useBenchmarkTimeSeriesData(ctx.benchmarkId, queryParams, ["table"]); + + if (isLoading) { + return ( + + ); + } + + if (error) { + return ( + + (AutoBenchmarkSingleDataTable){error.message} + + ); + } + + if (!resp?.data?.data) { + return
no data
; + } + const data = resp?.data?.data; + return ( + + + + + + ); +} + export function collectJobGroupInfoUniques( rows: any[], fields: string[] diff --git a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkRawDataTable.tsx b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkRawDataTable.tsx index ea92ef8529..70ad0e2594 100644 --- a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkRawDataTable.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkRawDataTable.tsx @@ -62,6 +62,16 @@ export default function BenchmarkRawDataTable({ [allColumns, config] ); + const tableRenderingBook = config?.renderOptions?.tableRenderingBook as + | Record + | undefined; + + const columnVisibilityModel = Object.fromEntries( + Object.entries(tableRenderingBook ?? {}) + .filter(([_, v]) => v?.hide) + .map(([k]) => [k, false]) + ); + return ( {title?.text} @@ -100,6 +110,9 @@ export default function BenchmarkRawDataTable({ pagination: { paginationModel: { pageSize: 25 }, }, + columns: { + columnVisibilityModel: columnVisibilityModel, + }, }} sx={{ "& .MuiDataGrid-virtualScroller": { scrollbarGutter: "stable" }, diff --git a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleDataTable.tsx b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleDataTable.tsx new file mode 100644 index 0000000000..29ae82dde4 --- /dev/null +++ b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleDataTable.tsx @@ -0,0 +1,366 @@ +import { Button, Tooltip, Typography } from "@mui/material"; +import { Box } from "@mui/system"; +import { + DataGrid, + GridColDef, + GridRenderCellParams, + useGridApiRef, +} from "@mui/x-data-grid"; +import { RenderRawContent } from "components/benchmark_v3/components/common/RawContentDialog"; +import Link from "next/link"; +import { useMemo } from "react"; +import { + formatHeaderName, + getBenchmarkTimeSeriesComparisionTableRenderingConfig, + renderBasedOnUnitConifg, +} from "../helper"; +import { groupKeyAndLabel } from "./BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTableHelpers"; +import { ParamSelector } from "lib/ParamSelector"; + +const GOOD_COLOR = "#e8f5e9"; // green[50] +export default function BenchmarkSingleDataTable({ + config, + data, + title, + isDebug = false, +}: { + config: any; + data: any; + title?: { + text: string; + description?: string; + }; + isDebug?: boolean; +}) { + const apiRef = useGridApiRef(); + + const rows: any[] = useMemo(() => { + return ToRawTableRow(config, data); + }, [data]); + + const allColumns = useMemo(() => { + const s = new Set(); + rows.forEach((r) => + r.rowItem.forEach((i: any) => { + Object.keys(i ?? {}).forEach((k) => { + const groupItem = i[k]; + // helps debuging if the group item has more than one data item + if (groupItem?.data?.length > 1) { + groupItem.data.forEach((d: any, idx: number) => { + s.add(`${k}||${idx}`); + }); + } else { + s.add(k); + } + }); + }) + ); + const auto = Array.from(s).sort(); + return auto; + }, [rows]); + + const columns: GridColDef[] = useMemo( + () => getTableConlumnRendering(config, allColumns), + [allColumns, config] + ); + + const tableRenderingBook = config?.renderOptions?.tableRenderingBook as + | Record + | undefined; + + const columnVisibilityModel = Object.fromEntries( + Object.entries(tableRenderingBook ?? {}) + .filter(([_, v]) => v?.hide) + .map(([k]) => [k, false]) + ); + + return ( + + {title?.text} + {title?.description && ( + {title.description} + )} + {isDebug && ( + + )} + + + + ); +} + +/** + * function to get the table column rendering logics + * + * @param config + * @param metricFields + * @returns + */ +function getTableConlumnRendering( + config: any, + metricFields: string[] = [] +): GridColDef[] { + const metadataColumns: any[] = [ + { + field: "workflow_run", + headerName: "Workflow Run", + minWidth: 140, + valueGetter: (_value: any, row: any) => { + const wf = row?.workflow_id ?? ""; + const job = row?.job_id ?? ""; + return `${wf}/${job}`; + }, + valueFormatter: (value: any, row: any) => { + return value ?? ""; + }, + renderCell: (params: GridRenderCellParams) => { + const tooltipText = `navigate to github page for job ${params.value} + }`; + return ( + + + {params.value} + + + ); + }, + }, + { + field: "commit", + headerName: "Commit", + renderCell: (params: GridRenderCellParams) => { + const tooltipText = `navigate to job run in hud commit page`; + return ( + + + + {String(params.value)} + + + + ); + }, + }, + ]; + + const metadata = config?.extraMetadata ?? []; + const metadataCols: GridColDef[] = metadata + .filter((k: any) => !!k.field) // skip fields that are not defined + .map((k: any) => ({ + field: k.field, + headerName: k.displayName ?? k.field, + renderCell: (p: any) => ( + {p.row[k.field]} + ), + })); + + const metricCols: GridColDef[] = metricFields.map((field) => ({ + field, + headerName: formatHeaderName( + field, + config?.renderOptions?.tableRenderingBook + ), + flex: 0.5, + sortable: false, + filterable: false, + valueGetter: (_value: any, row: any) => { + const data = row.rowItem; + if (data.length == 0) { + return undefined; + } + let fieldName = field; + let idx = 0; + if (field.split("||").length > 1) { + idx = Number(field.split("||")[1]); + fieldName = field.split("||")[0]; + } + const value = data[0][fieldName]?.data[idx]?.value; + return value; + }, + valueFormatter: (value: any, row: any) => { + let fieldName = field; + const rc = getBenchmarkTimeSeriesComparisionTableRenderingConfig( + fieldName, + config + ); + return renderBasedOnUnitConifg(value, rc?.unit); + }, + renderCell: (params: GridRenderCellParams) => { + if (config?.renderOptions?.highlightPolicy){ + const policy = config?.renderOptions?.highlightPolicy + return renderHighlight(policy,params) + } + return {params.formattedValue ?? ""}; + }, + })); + + return [...metadataColumns, ...metadataCols, ...metricCols]; +} + +function renderHighlight(highlightPolicy:any, params: GridRenderCellParams){ + if (highlightPolicy.direction !='row'){ + return {params.formattedValue ?? ""}; + } + const policy= highlightPolicy?.policy?? "max" + const regex = highlightPolicy?.regex + const highlighColor=highlightPolicy?.color?? GOOD_COLOR + const highlight = shouldHighlightCellByRowExtrema(params, policy,regex) + console.log("highlight",params.field ,highlight ) + return ( + + {params.formattedValue ?? params.value ?? ""} + + ); +} + +/** + * Transform the data into a table row item for rendering + * @param config + * @param data + * @returns + */ +export function ToRawTableRow(config: any, data: any) { + const m = new Map(); + for (const d of data ?? []) { + const i = d.group_info; + const wf = String(i?.workflow_id ?? ""); + const jobId = String(i?.job_id ?? ""); + const sourceRepo = i?.repo ?? ""; + const hudCommitUrl = `/${sourceRepo}/commit/${ + i?.commit ?? "" + }#${jobId}-box`; + const gitRepoUrl = `https://github.com/${sourceRepo}`; + const jobUrl = `${gitRepoUrl}/actions/runs/${wf}/job/${jobId}`; + const rawData = d.data ?? []; + const { key } = groupKeyAndLabel(i); + if (!m.has(key)) { + m.set(key, { + ...i, + job_id: jobId, + workflow_id: wf, + commit: i?.commit ?? "", + commit_url: hudCommitUrl, + job_url: jobUrl, + repo: String(i?.repo ?? ""), + timestamp: i?.granularity_bucket ?? "", + id: key, + rowItem: [], + }); + } + m.get(key)!.rowItem.push(rawData); + } + return Array.from(m.values()); +} + +export function shouldHighlightCellByRowExtrema( + params: GridRenderCellParams, + policy: "min" | "max", + regexString?: string +): boolean { + const rowItems = params.row?.rowItem; + if (!Array.isArray(rowItems) || rowItems.length === 0) return false; + + // parse "field||idx" -> base name + index + const [baseField, idxStr] = String(params.field).split("||"); + const idx = Number.isFinite(Number(idxStr)) ? Number(idxStr) : 0; + + // flatten rowItem[0] + const root = rowItems[0] ?? {}; + const flattened: Record = {}; + + for (const key of Object.keys(root)) { + const arr = root[key]?.data; + if (!Array.isArray(arr) || arr.length <= idx) continue; + const v = arr[idx]?.value; + if (typeof v === "number" && Number.isFinite(v)) { + flattened[key] = v; + } + } + + const current = flattened[baseField]; + console.log("baseField",baseField,current,flattened,) + + if (current == null) return false; + + // optional regex filter + let regex: RegExp | null = null; + if (regexString) { + try { + regex = new RegExp(regexString); + } catch { + regex = null; + } + } + + const entries = Object.entries(flattened).filter(([k]) => + regex ? regex.test(k) : true + ); + + console.log(entries) + if (entries.length === 0) return false; + + const values = entries.map(([, v]) => v); + const minV = Math.min(...values); + const maxV = Math.max(...values); + + return policy === "min" ? current === minV : current === maxV; +} diff --git a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTable.tsx b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTable.tsx index 6a723896f5..6ed5fdcb9d 100644 --- a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTable.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTable.tsx @@ -87,11 +87,15 @@ export function ComparisonTable({ [allColumns, lWorkflowId, rWorkflowId, title] ); + const tableRenderingBook = config?.renderOptions?.tableRenderingBook as + | Record + | undefined; const columnVisibilityModel = Object.fromEntries( - Object.entries(config?.renderOptions?.tableRenderingBook ?? {}) - .filter(([_, v]) => v?.hide === true) + Object.entries(tableRenderingBook ?? {}) + .filter(([_, v]) => v?.hide) .map(([k]) => [k, false]) ); + return ( {title.text} diff --git a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/helper.tsx b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/helper.tsx index 2d48b40c6e..b18f04594a 100644 --- a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/helper.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/helper.tsx @@ -38,7 +38,7 @@ export interface BenchmarkTimeSeriesChartRenderingConfig { export interface BenchmarkComparisonTableRenderingConfig { displayName?: string; unit: BenchmarkUnitConfig; - hide: boolean; // hide the column in the table + hide?: boolean; // hide the column in the table failure: { value: any; dependence?: string; // the field name to check the failure condition diff --git a/torchci/components/benchmark_v3/configs/benchmark_config_book.tsx b/torchci/components/benchmark_v3/configs/benchmark_config_book.tsx index 9afbc36d24..4010ea267c 100644 --- a/torchci/components/benchmark_v3/configs/benchmark_config_book.tsx +++ b/torchci/components/benchmark_v3/configs/benchmark_config_book.tsx @@ -19,6 +19,7 @@ import { defaultDashboardBenchmarkUIConfig } from "components/benchmark_v3/confi import { PYTORCH_HELION_BENCHMARK_ID, PytorchHelionDashboardConfig, + PytorchHelionSingleConfig, } from "components/benchmark_v3/configs/teams/helion/config"; import { PYTORCH_OPERATOR_MICROBENCHMARK_ID, @@ -27,6 +28,7 @@ import { import { DataBinding } from "components/benchmark_v3/configs/utils/dataBindingRegistration"; import { create } from "zustand"; +import { defaultSingleBenchmarkUIConfig } from "./teams/defaults/default_single_view_config"; const PREDEFINED_BENCHMARK_CONFIG: BenchmarkConfigMap = { [COMPILTER_BENCHMARK_NAME]: { @@ -41,6 +43,7 @@ const PREDEFINED_BENCHMARK_CONFIG: BenchmarkConfigMap = { }, [PYTORCH_HELION_BENCHMARK_ID]: { [BenchmarkPageType.DashboardPage]: PytorchHelionDashboardConfig, + [BenchmarkPageType.SinglePage]: PytorchHelionSingleConfig, }, }; @@ -135,7 +138,6 @@ interface State { export const useBenchmarkBook = create()((set, get) => ({ predefined: PREDEFINED_BENCHMARK_CONFIG, temps: {}, - initTempConfig: ( id, type: BenchmarkPageType = BenchmarkPageType.DashboardPage, @@ -147,13 +149,16 @@ export const useBenchmarkBook = create()((set, get) => ({ case BenchmarkPageType.DashboardPage: defaultConfig = defaultDashboardBenchmarkUIConfig; break; + case BenchmarkPageType.SinglePage: + defaultConfig = defaultSingleBenchmarkUIConfig; + break; default: throw new Error( - `Cannot create default page, We currently only support default Dashboard Page, but you request page type: ${type}` + `Cannot create default page, We currently only support default Dashboard Page and Single Page, but you request page type: ${type}` ); } const cfg: BenchmarkUIConfig = { - ...defaultDashboardBenchmarkUIConfig, + ...defaultConfig, type, benchmarkId: id, apiId: params.apiId ?? id, @@ -181,6 +186,7 @@ export const useBenchmarkBook = create()((set, get) => ({ [id]: updatedGroup, }, }); + console.log("initialed", cfg); return cfg; }, @@ -204,12 +210,14 @@ export const useBenchmarkBook = create()((set, get) => ({ if (!type) throw new Error("getConfig: type is required"); const { predefined, temps } = get(); - const group = predefined[id] ?? temps[id]; - const cfg = group?.[type]; + const pg = predefined[id]; + const tmpg = temps[id]; + + const cfg = pg?.[type] ?? tmpg?.[type]; if (!cfg) throw new Error( `No config found for id: ${id} and ${type}, Group: ${ - group ? "found the group" : "missing the group" + pg || tmpg ? "found the group" : "missing the group" }` ); return new BenchmarkUIConfigHandler(cfg); diff --git a/torchci/components/benchmark_v3/configs/teams/defaults/default_single_view_config.ts b/torchci/components/benchmark_v3/configs/teams/defaults/default_single_view_config.ts new file mode 100644 index 0000000000..ec3b834f41 --- /dev/null +++ b/torchci/components/benchmark_v3/configs/teams/defaults/default_single_view_config.ts @@ -0,0 +1,55 @@ +import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc"; +import { BenchmarkUIConfig } from "../../config_book_types"; +dayjs.extend(utc); + +export const DEFAULT_SINGLE_VIEW_ID = "default-single"; + +// The initial config for the compiler benchmark regression page +export const DEFAULT_SINGLE_VIEW_BENCHMARK_INITIAL = { + time: { + start: dayjs.utc().startOf("day").subtract(7, "day"), + end: dayjs.utc().endOf("day"), + }, + filters: { + }, + lbranch: "main", + rbranch: "main", +}; + +export const DEFAULT_TABLE_METADATA_COLUMNS = [ + { + field: "branch", + displayName: "Branch", + }, + { + field: "device", + displayName: "Hardware type", + }, + { + field: "arch", + displayName: "Hardware model", + }, +] as const; + +export const defaultSingleBenchmarkUIConfig: BenchmarkUIConfig | any = { + benchmarkId: DEFAULT_SINGLE_VIEW_ID, + apiId: DEFAULT_SINGLE_VIEW_ID, + title: "Default Single View", + dataBinding: { + initial: DEFAULT_SINGLE_VIEW_BENCHMARK_INITIAL, + required_filter_fields: [], + }, + dataRender: { + type: "auto", + renders: [ + { + type: "AutoBenchmarkSingleDataTable", + title: "Single Table", + config: { + extraMetadata: DEFAULT_TABLE_METADATA_COLUMNS, + }, + }, + ], + }, +}; diff --git a/torchci/components/benchmark_v3/configs/teams/helion/config.ts b/torchci/components/benchmark_v3/configs/teams/helion/config.ts index c62cb79913..f792f0b3cd 100644 --- a/torchci/components/benchmark_v3/configs/teams/helion/config.ts +++ b/torchci/components/benchmark_v3/configs/teams/helion/config.ts @@ -1,5 +1,6 @@ import { BenchmarkUIConfig } from "../../config_book_types"; import { DEFAULT_DASHBOARD_BENCHMARK_INITIAL } from "../defaults/default_dashboard_config"; +import { DEFAULT_SINGLE_VIEW_BENCHMARK_INITIAL } from "../defaults/default_single_view_config"; export const PYTORCH_HELION_BENCHMARK_ID = "pytorch_helion"; @@ -17,10 +18,6 @@ const COMPARISON_TABLE_METADATA_COLUMNS = [ field: "arch", displayName: "Hardware model", }, - { - field: "branch", - displayName: "branch", - }, ] as const; const RENDER_MAPPING_BOOK = { @@ -52,6 +49,43 @@ const RENDER_MAPPING_BOOK = { hide: true, }, }; + +export const PytorchHelionSingleConfig: BenchmarkUIConfig | any = { + benchmarkId: PYTORCH_HELION_BENCHMARK_ID, + apiId: "pytorch_helion", + title: "Helion Single View", + dataBinding: { + initial: DEFAULT_SINGLE_VIEW_BENCHMARK_INITIAL, + required_filter_fields: [], + }, + dataRender: { + type: "auto", + renders: [ + { + type: "AutoBenchmarkSingleDataTable", + title: "Single Table", + config: { + extraMetadata: [ + { + field: "branch", + displayName: "branch", + }, + ...COMPARISON_TABLE_METADATA_COLUMNS + ], + renderOptions: { + tableRenderingBook: RENDER_MAPPING_BOOK, + highlightPolicy:{ + direction:"row", + regex:"_speedup$", + policy:"max" + } + }, + }, + }, + ], + }, +}; + export const PytorchHelionDashboardConfig: BenchmarkUIConfig = { benchmarkId: PYTORCH_HELION_BENCHMARK_ID, apiId: "pytorch_helion", diff --git a/torchci/components/benchmark_v3/configs/utils/autoRegistration.tsx b/torchci/components/benchmark_v3/configs/utils/autoRegistration.tsx index 1a5cc9f708..3deeb7a1cb 100644 --- a/torchci/components/benchmark_v3/configs/utils/autoRegistration.tsx +++ b/torchci/components/benchmark_v3/configs/utils/autoRegistration.tsx @@ -2,6 +2,7 @@ import { AutoBenchmarkLogs, AutoBenchmarkPairwiseTable, AutoBenchmarkRawDataTable, + AutoBenchmarkSingleDataTable, AutoBenchmarkTimeSeriesChartGroup, AutoBenchmarkTimeSeriesTable, } from "components/benchmark_v3/components/dataRender/auto/autoComponents"; @@ -55,6 +56,9 @@ export class AutoComponentRegistry { AutoBenchmarkRawDataTable: { Component: AutoBenchmarkRawDataTable, }, + AutoBenchmarkSingleDataTable: { + Component: AutoBenchmarkSingleDataTable, + }, AutoBenchmarkLogs: { Component: AutoBenchmarkLogs, }, diff --git a/torchci/components/benchmark_v3/pages/BenchmarkSinglePage.tsx b/torchci/components/benchmark_v3/pages/BenchmarkSinglePage.tsx new file mode 100644 index 0000000000..cf1b4593ae --- /dev/null +++ b/torchci/components/benchmark_v3/pages/BenchmarkSinglePage.tsx @@ -0,0 +1,70 @@ +import { Box } from "@mui/system"; +import { + BenchmarkUIConfigHandler, + useBenchmarkBook, +} from "components/benchmark_v3/configs/benchmark_config_book"; +import LoadingPage from "components/common/LoadingPage"; +import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc"; +import { BenchmarkDashboardStoreProvider } from "lib/benchmark/store/benchmark_dashboard_provider"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; +import BenchmarkSideBar from "../components/benchmarkSideBar/BenchmarkSideBar"; +import { BenchmarkTopBar } from "../components/benchmarkSideBar/BenchmarkTopBar"; +import { BenchmarkIdNotRegisterError } from "../components/common/BenchmarkIdNotRegisterError"; +import { BenchmarkPageType } from "../configs/config_book_types"; +import { getBenchmarkIdMappingItem } from "../configs/configurations"; +dayjs.extend(utc); + +export default function BenchmarkSinglePage({ + benchmarkId, + type, +}: { + benchmarkId: string; + type: BenchmarkPageType; +}) { + const router = useRouter(); + + // ensure config will read the config from the store if it's predefined, + // otherwise it will create a new config based on default template + const ensureConfig = useBenchmarkBook((s) => s.ensureConfig); + const [config, setConfig] = useState(); + + useEffect(() => { + if (!router.isReady) return; + const configHandler = ensureConfig(benchmarkId, type, {}); + setConfig(configHandler); + }, [router.isReady, benchmarkId]); + + if (!config) return ; + + const mappingItem = getBenchmarkIdMappingItem(benchmarkId); + if (!mappingItem) { + return ( + + ); + } + + const Comp = config.getDataRenderComponent(); + return ( + + + + + + + + + + + + ); +} diff --git a/torchci/pages/benchmark/v3/single/[id].tsx b/torchci/pages/benchmark/v3/single/[id].tsx new file mode 100644 index 0000000000..76aaf6e6d5 --- /dev/null +++ b/torchci/pages/benchmark/v3/single/[id].tsx @@ -0,0 +1,14 @@ +import { Alert } from "@mui/material"; +import { BenchmarkPageType } from "components/benchmark_v3/configs/config_book_types"; +import BenchmarkSinglePage from "components/benchmark_v3/pages/BenchmarkSinglePage"; +import { useRouter } from "next/router"; + +export default function Page() { + const router = useRouter(); + const { id } = router.query; + const type: BenchmarkPageType = BenchmarkPageType.SinglePage; + if (!id) { + return Cannot find the page ; + } + return ; +} From 31464fd25255a9f0a8a7afc6532bc76b024783b5 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 7 Nov 2025 18:12:37 -0800 Subject: [PATCH 07/13] add config --- .../dataRender/auto/autoComponents.tsx | 2 +- .../components/BenchmarkSingleDataTable.tsx | 27 +++++++++---------- .../defaults/default_single_view_config.ts | 3 +-- .../configs/teams/helion/config.ts | 16 +++++------ 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx index efefe6a82c..c93a46fa2f 100644 --- a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx @@ -13,9 +13,9 @@ import { LOG_PREFIX } from "components/benchmark/common"; import { UIRenderConfig } from "components/benchmark_v3/configs/config_book_types"; import { BenchmarkLogSidePanelWrapper } from "../../common/BenchmarkLogViewer/BenchmarkSidePanel"; import { RenderRawContent } from "../../common/RawContentDialog"; +import BenchmarkSingleDataTable from "../components/benchmarkTimeSeries/components/BenchmarkSingleDataTable"; import BenchmarkTimeSeriesChartGroup from "../components/benchmarkTimeSeries/components/BenchmarkTimeSeriesChart/BenchmarkTimeSeriesChartGroup"; import { ComparisonTable } from "../components/benchmarkTimeSeries/components/BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTable"; -import BenchmarkSingleDataTable from "../components/benchmarkTimeSeries/components/BenchmarkSingleDataTable"; export function AutoBenchmarkTimeSeriesTable({ config }: AutoComponentProps) { const ctx = useBenchmarkCommittedContext(); diff --git a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleDataTable.tsx b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleDataTable.tsx index 29ae82dde4..b908dcb006 100644 --- a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleDataTable.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleDataTable.tsx @@ -15,7 +15,6 @@ import { renderBasedOnUnitConifg, } from "../helper"; import { groupKeyAndLabel } from "./BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTableHelpers"; -import { ParamSelector } from "lib/ParamSelector"; const GOOD_COLOR = "#e8f5e9"; // green[50] export default function BenchmarkSingleDataTable({ @@ -237,9 +236,9 @@ function getTableConlumnRendering( return renderBasedOnUnitConifg(value, rc?.unit); }, renderCell: (params: GridRenderCellParams) => { - if (config?.renderOptions?.highlightPolicy){ - const policy = config?.renderOptions?.highlightPolicy - return renderHighlight(policy,params) + if (config?.renderOptions?.highlightPolicy) { + const policy = config?.renderOptions?.highlightPolicy; + return renderHighlight(policy, params); } return {params.formattedValue ?? ""}; }, @@ -248,16 +247,18 @@ function getTableConlumnRendering( return [...metadataColumns, ...metadataCols, ...metricCols]; } -function renderHighlight(highlightPolicy:any, params: GridRenderCellParams){ - if (highlightPolicy.direction !='row'){ +function renderHighlight( + highlightPolicy: any, + params: GridRenderCellParams +) { + if (highlightPolicy.direction != "row") { return {params.formattedValue ?? ""}; } - const policy= highlightPolicy?.policy?? "max" - const regex = highlightPolicy?.regex - const highlighColor=highlightPolicy?.color?? GOOD_COLOR - const highlight = shouldHighlightCellByRowExtrema(params, policy,regex) - console.log("highlight",params.field ,highlight ) - return ( + const policy = highlightPolicy?.policy ?? "max"; + const regex = highlightPolicy?.regex; + const highlighColor = highlightPolicy?.color ?? GOOD_COLOR; + const highlight = shouldHighlightCellByRowExtrema(params, policy, regex); + return ( v); diff --git a/torchci/components/benchmark_v3/configs/teams/defaults/default_single_view_config.ts b/torchci/components/benchmark_v3/configs/teams/defaults/default_single_view_config.ts index ec3b834f41..1859ec5e11 100644 --- a/torchci/components/benchmark_v3/configs/teams/defaults/default_single_view_config.ts +++ b/torchci/components/benchmark_v3/configs/teams/defaults/default_single_view_config.ts @@ -11,8 +11,7 @@ export const DEFAULT_SINGLE_VIEW_BENCHMARK_INITIAL = { start: dayjs.utc().startOf("day").subtract(7, "day"), end: dayjs.utc().endOf("day"), }, - filters: { - }, + filters: {}, lbranch: "main", rbranch: "main", }; diff --git a/torchci/components/benchmark_v3/configs/teams/helion/config.ts b/torchci/components/benchmark_v3/configs/teams/helion/config.ts index f792f0b3cd..c11a925a16 100644 --- a/torchci/components/benchmark_v3/configs/teams/helion/config.ts +++ b/torchci/components/benchmark_v3/configs/teams/helion/config.ts @@ -66,20 +66,20 @@ export const PytorchHelionSingleConfig: BenchmarkUIConfig | any = { title: "Single Table", config: { extraMetadata: [ - { + { field: "branch", displayName: "branch", }, - ...COMPARISON_TABLE_METADATA_COLUMNS + ...COMPARISON_TABLE_METADATA_COLUMNS, ], renderOptions: { tableRenderingBook: RENDER_MAPPING_BOOK, - highlightPolicy:{ - direction:"row", - regex:"_speedup$", - policy:"max" - } - }, + highlightPolicy: { + direction: "row", + regex: "_speedup$", + policy: "max", + }, + }, }, }, ], From 0a415ec88c093fa4d4c2e37bfa6a9cfa7d93b0c5 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 7 Nov 2025 18:19:44 -0800 Subject: [PATCH 08/13] add config --- .../dataRender/auto/autoComponents.tsx | 1 + .../benchmark_v3/configs/teams/helion/config.ts | 16 +++++----------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx index c93a46fa2f..73fe871c4c 100644 --- a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx @@ -636,6 +636,7 @@ export function AutoBenchmarkSingleDataTable({ config }: AutoComponentProps) { return ( + Date: Fri, 7 Nov 2025 18:30:13 -0800 Subject: [PATCH 09/13] add config --- .../components/dataRender/auto/autoComponents.tsx | 2 +- .../components/BenchmarkSingleDataTable.tsx | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx index 73fe871c4c..7e846bbecc 100644 --- a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx @@ -636,7 +636,7 @@ export function AutoBenchmarkSingleDataTable({ config }: AutoComponentProps) { return ( - + ) => { From ef05c15da6efda41bd45446779e3e57e7329fade Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Mon, 10 Nov 2025 09:33:50 -0800 Subject: [PATCH 10/13] add config --- .../commits/SingleCommitSelectSelection.tsx | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx index e5db461db2..2d8011c3ba 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx @@ -18,13 +18,10 @@ export function SingleCommitSelectSelection() { committedTime, committedFilters, lcommit, - rcommit, committedLBranch, - committedRBranch, committedMaxSampling, enableSamplingSetting, setLcommit, - setRcommit, } = useDashboardSelector((s) => ({ type: s.type, benchmarkId: s.benchmarkId, @@ -37,14 +34,10 @@ export function SingleCommitSelectSelection() { lcommit: s.lcommit, rcommit: s.rcommit, committedLBranch: s.committedLbranch, - committedRBranch: s.committedRbranch, setLcommit: s.setLcommit, - setRcommit: s.setRcommit, })); const [leftList, setLeftList] = useState([]); - const [rightList, setRightList] = useState([]); - const getConfig = useBenchmarkBook((s) => s.getConfig); const config = getConfig(benchmarkId, type); const dataBinding = config.dataBinding; @@ -55,15 +48,13 @@ export function SingleCommitSelectSelection() { !!committedTime?.end && !!committedLBranch && committedLBranch.length > 0 && - !!committedRBranch && - committedRBranch.length > 0 && (enableSamplingSetting ? committedMaxSampling : true) && required_filter_fields.every((k) => !!committedFilters[k]); // Fetch data const branches = [ ...new Set( - [committedLBranch, committedRBranch].filter((b) => b.length > 0) + [committedLBranch].filter((b) => b.length > 0) ), ]; @@ -113,21 +104,13 @@ export function SingleCommitSelectSelection() { setLcommit( nextAutoL ? L.find((c) => c.workflow_id === nextAutoL) ?? null : null ); - // tho this is single commit comopnent, we use same store as comparison mode, - // update rcommit for data consistency - setRcommit( - nextAutoL ? L.find((c) => c.workflow_id === nextAutoL) ?? null : null - ); } }, [ isLoading, data, committedLBranch, - committedRBranch, lcommit?.workflow_id, - rcommit?.workflow_id, setLcommit, - setRcommit, ]); if (error) return
Error: {error.message}
; @@ -146,14 +129,13 @@ export function SingleCommitSelectSelection() { {lcommit?.branch}:
{ - setLcommit(c); - setRcommit(c); + setLcommit(c) }} /> From 241f009c8f7674c2a4096b7d42a41e099278b0e5 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Mon, 10 Nov 2025 12:07:16 -0800 Subject: [PATCH 11/13] add config --- .../benchmarkSideBar/BenchmarkTopBar.tsx | 6 +- .../components/commits/BranchDropdown.tsx | 1 - .../commits/SingleCommitSelectSelection.tsx | 77 +++++++++++++---- .../components/common/BenchmarkLinkButton.tsx | 43 ++++++++++ .../components/common/RawContentDialog.tsx | 10 ++- .../dataRender/auto/autoComponents.tsx | 33 +++++++- .../components/BenchmarkRawDataTable.tsx | 22 ++--- .../components/BenchmarkSingleDataTable.tsx | 24 ++++-- .../BenchmarkSingleViewNatigation.tsx | 84 +++++++++++++++++++ .../ComparisonTable.tsx | 18 ++++ .../configs/teams/helion/config.ts | 8 ++ .../configs/utils/autoRegistration.tsx | 4 + .../uiModules/UMDenseComponents.tsx | 11 +++ 13 files changed, 299 insertions(+), 42 deletions(-) create mode 100644 torchci/components/benchmark_v3/components/common/BenchmarkLinkButton.tsx create mode 100644 torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleViewNatigation.tsx diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx index 1d69ca4aff..516edcf555 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/BenchmarkTopBar.tsx @@ -44,8 +44,10 @@ export function BenchmarkTopBar({ )} - - + {reportFeature && } + {reportFeature && ( + + )} {mode == "default" && } {mode == "single" && } diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/BranchDropdown.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/BranchDropdown.tsx index d68a4a142f..c8da8fe1c8 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/BranchDropdown.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/BranchDropdown.tsx @@ -49,7 +49,6 @@ export function BranchDropdowns({ return ( - {type} {empty ? ( No branch is found, please select other features. diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx index 2d8011c3ba..9134167f9c 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx @@ -1,12 +1,18 @@ +import OpenInNewIcon from "@mui/icons-material/OpenInNew"; import { Typography } from "@mui/material"; import { Box, Stack } from "@mui/system"; import { useBenchmarkBook } from "components/benchmark_v3/configs/benchmark_config_book"; import { QueryParameterConverterInputs } from "components/benchmark_v3/configs/utils/dataBindingRegistration"; import { CenteredLoader } from "components/common/LoadingIcon"; -import { UMDenseCommitDropdown } from "components/uiModules/UMDenseComponents"; +import { + UMDenseCommitDropdown, + UMDenseSingleButton, +} from "components/uiModules/UMDenseComponents"; import { useBenchmarkCommitsData } from "lib/benchmark/api_helper/fe/hooks"; import { useDashboardSelector } from "lib/benchmark/store/benchmark_dashboard_provider"; import { BenchmarkCommitMeta } from "lib/benchmark/store/benchmark_regression_store"; +import { stateToQuery } from "lib/helpers/urlQuery"; +import { NextRouter, useRouter } from "next/router"; import { useEffect, useState } from "react"; export function SingleCommitSelectSelection() { @@ -52,11 +58,7 @@ export function SingleCommitSelectSelection() { required_filter_fields.every((k) => !!committedFilters[k]); // Fetch data - const branches = [ - ...new Set( - [committedLBranch].filter((b) => b.length > 0) - ), - ]; + const branches = [...new Set([committedLBranch].filter((b) => b.length > 0))]; // Convert to query params const params = dataBinding.toQueryParams({ @@ -105,13 +107,7 @@ export function SingleCommitSelectSelection() { nextAutoL ? L.find((c) => c.workflow_id === nextAutoL) ?? null : null ); } - }, [ - isLoading, - data, - committedLBranch, - lcommit?.workflow_id, - setLcommit, - ]); + }, [isLoading, data, committedLBranch, lcommit?.workflow_id, setLcommit]); if (error) return
Error: {error.message}
; if (isLoading || !data) return ; @@ -135,9 +131,10 @@ export function SingleCommitSelectSelection() { selectedCommit={lcommit} commitList={leftList} setCommit={(c) => { - setLcommit(c) + setLcommit(c); }} /> + ); } @@ -156,3 +153,55 @@ export const convertToBranchMap = ( return acc; }, {} as Record); }; + +export function NavigateToDashboardButton({ + benchmarkId, + commit, +}: { + benchmarkId: string; + commit: BenchmarkCommitMeta | null; +}) { + const router = useRouter(); + if (!commit) { + return <>; + } + return ( + } + > + View {commit.workflow_id} ({commit.commit.slice(0, 7)}) in Dashboard + + ); +} + +export function toDashboardUrl( + benchmarkId: string, + commit: BenchmarkCommitMeta, + router: NextRouter +) { + const pathname = `/benchmark/v3/dashboard/${benchmarkId}`; + const lcommit: BenchmarkCommitMeta = commit; + const rcommit: BenchmarkCommitMeta = commit; + const reformattedPrams = stateToQuery({ + lcommit, + rcommit, + }); + + const nextDashboardMainQuery = { + ...router.query, // keep existing params + ...reformattedPrams, + renderGroupId: "main", + }; + const params = new URLSearchParams( + Object.entries(nextDashboardMainQuery) + .filter(([_, v]) => v != null && v !== "") + .map(([k, v]) => [k, String(v)]) + ); + const url = `${pathname}?${params.toString()}`; + return url; +} diff --git a/torchci/components/benchmark_v3/components/common/BenchmarkLinkButton.tsx b/torchci/components/benchmark_v3/components/common/BenchmarkLinkButton.tsx new file mode 100644 index 0000000000..255813d25e --- /dev/null +++ b/torchci/components/benchmark_v3/components/common/BenchmarkLinkButton.tsx @@ -0,0 +1,43 @@ +import type { ButtonProps } from "@mui/material/Button"; +import Button from "@mui/material/Button"; +import { styled } from "@mui/material/styles"; +import * as React from "react"; + +/** Anchor-style MUI Button with proper typing for href/target/rel. */ +export interface BenchmarkLinkButtonProps + extends Omit, "component"> { + href: string; + /** Default: "_self". Use "_blank" for new tab. */ + target?: "_self" | "_blank" | "_parent" | "_top"; + /** Default: added automatically for _blank */ + rel?: string; +} + +export const LinkButton = React.forwardRef< + HTMLAnchorElement, + BenchmarkLinkButtonProps +>(({ href, target = "_self", rel, ...props }, ref) => { + // Security for new-tab links + const finalRel = target === "_blank" ? rel ?? "noopener noreferrer" : rel; + return ( + + JSX.Element; }) { @@ -167,6 +170,7 @@ export function RenderRawContent({ type={type} component={component} buttonName={buttonName} + sx={buttonSx} /> ); } diff --git a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx index 7e846bbecc..a5617e5384 100644 --- a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx @@ -11,9 +11,10 @@ import BenchmarkRawDataTable from "../components/benchmarkTimeSeries/components/ import { LOG_PREFIX } from "components/benchmark/common"; import { UIRenderConfig } from "components/benchmark_v3/configs/config_book_types"; +import { useRouter } from "next/router"; import { BenchmarkLogSidePanelWrapper } from "../../common/BenchmarkLogViewer/BenchmarkSidePanel"; -import { RenderRawContent } from "../../common/RawContentDialog"; import BenchmarkSingleDataTable from "../components/benchmarkTimeSeries/components/BenchmarkSingleDataTable"; +import { BenchmarkSingleViewNavigation } from "../components/benchmarkTimeSeries/components/BenchmarkSingleViewNatigation"; import BenchmarkTimeSeriesChartGroup from "../components/benchmarkTimeSeries/components/BenchmarkTimeSeriesChart/BenchmarkTimeSeriesChartGroup"; import { ComparisonTable } from "../components/benchmarkTimeSeries/components/BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTable"; @@ -270,7 +271,6 @@ export function AutoBenchmarkPairwiseTable({ config }: AutoComponentProps) { return ( - ; + } + return ( + + ); +} + export function AutoBenchmarkLogs({ config }: AutoComponentProps) { const ctx = useBenchmarkCommittedContext(); @@ -636,7 +664,6 @@ export function AutoBenchmarkSingleDataTable({ config }: AutoComponentProps) { return ( - {title.description} )} - {isDebug && ( - - )} - + {title.description} )} - {isDebug && ( - - )} + )} + ({ textTransform: "none", // optional: avoids uppercase })); +export const UMDenseSingleButton = styled(Button)(({ theme }) => ({ + px: 0.5, + py: 0, + mx: 1, + minWidth: "auto", + lineHeight: 2, + fontSize: "0.75rem", + textTransform: "none", +})); + // Reusable dense menu style (affects the dropdown list items) export const DENSE_MENU_STYLE = { // shrink the whole list From d6431af45d0cbb5212142bcc68e5bac7ab4e3139 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Mon, 10 Nov 2025 12:37:28 -0800 Subject: [PATCH 12/13] add config --- .../components/SideBarMainSection.tsx | 24 ++++++++++++------- .../commits/SingleCommitSelectSelection.tsx | 3 +++ .../configs/teams/compilers/config.ts | 1 + .../store/benchmark_regression_store.ts | 14 +++++++++-- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx index 24358eb956..becfb1d86f 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/SideBarMainSection.tsx @@ -107,6 +107,7 @@ export function SideBarMainSection() { branchOptionType, enableMultiBranchOption, enableSamplingSetting, + enableSamplingFeature, commitMainOptions, revertMainOptions, } = useDashboardSelector((s) => ({ @@ -115,6 +116,7 @@ export function SideBarMainSection() { stagedLbranch: s.stagedLbranch, stagedRbranch: s.stagedRbranch, stagedMaxSampling: s.stagedMaxSampling, + enableSamplingFeature: s.enableSamplingFeature, enableMultiBranchOption: s.enableMultiBranchOption, branchOptionType: s.branchOptionType, @@ -253,15 +255,19 @@ export function SideBarMainSection() { end={stagedTime.end} gap={0} /> - {/* Fetch Settings */} - - Fetch Settings - + {enableSamplingFeature && ( + <> + {/* Fetch Settings */} + + Fetch Settings{" "} + + + )} {showSamplinginfo && ( {`Data Sampling: subsample from ${sampling_info?.origin ?? 0} to ${ diff --git a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx index 9134167f9c..1d01d82009 100644 --- a/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx +++ b/torchci/components/benchmark_v3/components/benchmarkSideBar/components/commits/SingleCommitSelectSelection.tsx @@ -173,6 +173,9 @@ export function NavigateToDashboardButton({ variant="outlined" color="primary" endIcon={} + sx={{ + whiteSpace: "nowrap", + }} > View {commit.workflow_id} ({commit.commit.slice(0, 7)}) in Dashboard diff --git a/torchci/components/benchmark_v3/configs/teams/compilers/config.ts b/torchci/components/benchmark_v3/configs/teams/compilers/config.ts index 554e5172dc..823661646e 100644 --- a/torchci/components/benchmark_v3/configs/teams/compilers/config.ts +++ b/torchci/components/benchmark_v3/configs/teams/compilers/config.ts @@ -193,6 +193,7 @@ export const COMPILTER_PRECOMPUTE_BENCHMARK_INITIAL = { }, lbranch: "main", rbranch: "main", + enableSamplingFeature: true, maxSampling: 110, // max number of job run results to show in the table, this avoid out of memory issue }; diff --git a/torchci/lib/benchmark/store/benchmark_regression_store.ts b/torchci/lib/benchmark/store/benchmark_regression_store.ts index 9c2a913fd8..085d0da792 100644 --- a/torchci/lib/benchmark/store/benchmark_regression_store.ts +++ b/torchci/lib/benchmark/store/benchmark_regression_store.ts @@ -36,6 +36,7 @@ export interface BenchmarkDashboardState { committedLbranch: string; committedRbranch: string; + enableSamplingFeature?: boolean; enableSamplingSetting?: boolean; // max sampling threshold, if null, no limit. // otherwise, we subsampling data in backend to fit the limit during the data @@ -112,6 +113,7 @@ export function createDashboardStore(initial: { rcommit?: BenchmarkCommitMeta | null; renderGroupId?: string; maxSampling?: number; + enableSamplingFeature?: boolean; enableMultiBranchOption?: boolean; }) { const idItem = BENCHMARK_ID_MAPPING[initial.benchmarkId]; @@ -132,11 +134,19 @@ export function createDashboardStore(initial: { branchOptionType: "single", // set only with initial config - enableSamplingSetting: (initial.maxSampling ?? 0) > 0, + enableSamplingFeature: initial.enableSamplingFeature, + enableSamplingSetting: + initial?.enableSamplingFeature && + initial?.maxSampling && + initial?.maxSampling > 0 + ? true + : false, // max sampling threshold, if null, no limit. // otherwise, we subsampling data in backend to fit the limit during the data // the min sampling threshold is 10 - committedMaxSampling: initial.maxSampling, + committedMaxSampling: initial.enableSamplingFeature + ? initial.maxSampling + : undefined, // todo(elainewy): may allow user to set a different max sampling threshold based on their needs stagedMaxSampling: initial.maxSampling, From ee97fe11b0087c297a47d70924ac39685cda9fb0 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Mon, 10 Nov 2025 12:58:08 -0800 Subject: [PATCH 13/13] add config --- .../components/dataRender/auto/autoComponents.tsx | 8 ++++++-- .../components/BenchmarkSingleViewNatigation.tsx | 9 ++++++--- .../components/benchmark_v3/configs/config_book_types.ts | 1 + .../benchmark_v3/configs/teams/helion/config.ts | 9 +++------ 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx index a5617e5384..727823870f 100644 --- a/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx @@ -311,6 +311,10 @@ export function AutoBenchmarkSingleViewNavigation({ lcommit={lcommit} rcommit={rcommit} config={uiRenderConfig} + title={{ + text: config?.title, + description: config?.description, + }} /> ); } @@ -668,8 +672,8 @@ export function AutoBenchmarkSingleDataTable({ config }: AutoComponentProps) { data={data["table"]} config={uiRenderConfig.config} title={{ - text: uiRenderConfig?.title ?? "Single Table", - description: "list single workflow run data", + text: config?.title ?? "Single Table", + description: config?.description ?? "list single workflow run data", }} /> diff --git a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleViewNatigation.tsx b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleViewNatigation.tsx index 239a898ed0..bfe0fcf8a6 100644 --- a/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleViewNatigation.tsx +++ b/torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkSingleViewNatigation.tsx @@ -11,25 +11,28 @@ export function BenchmarkSingleViewNavigation({ lcommit, rcommit, config, + title, }: { benchmarkId: string; lcommit?: BenchmarkCommitMeta | null; rcommit?: BenchmarkCommitMeta | null; + title?: { + text?: string; + description?: string; + }; config: UIRenderConfig; }) { const router = useRouter(); const uiRenderConfig = config as UIRenderConfig; - const title = uiRenderConfig.config?.title; - if (!lcommit || !rcommit) { return <>; } return ( - {title?.text} + {title?.text && {title?.text}} {title?.description && ( {title.description} )} diff --git a/torchci/components/benchmark_v3/configs/config_book_types.ts b/torchci/components/benchmark_v3/configs/config_book_types.ts index e161eecb36..6e9dea2823 100644 --- a/torchci/components/benchmark_v3/configs/config_book_types.ts +++ b/torchci/components/benchmark_v3/configs/config_book_types.ts @@ -46,6 +46,7 @@ export type BenchmarkUIConfigFilterConstarintConfig = { export type UIRenderConfig = { title?: string; // title of the component to render + description?: string; // description of the component to render id?: string; // id of the component to render type: string; // type of the component to render config: any; // config of the component to render diff --git a/torchci/components/benchmark_v3/configs/teams/helion/config.ts b/torchci/components/benchmark_v3/configs/teams/helion/config.ts index 7cbf34f051..4236085a6e 100644 --- a/torchci/components/benchmark_v3/configs/teams/helion/config.ts +++ b/torchci/components/benchmark_v3/configs/teams/helion/config.ts @@ -67,7 +67,7 @@ export const PytorchHelionSingleConfig: BenchmarkUIConfig | any = { renders: [ { type: "AutoBenchmarkSingleDataTable", - title: "Single Table", + title: "Single Run Table", config: { extraMetadata: COMPARISON_TABLE_METADATA_COLUMNS, renderOptions: { @@ -157,11 +157,8 @@ export const PytorchHelionDashboardConfig: BenchmarkUIConfig = { renders: [ { type: "AutoBenchmarkSingleViewNavigation", - config: { - title: { - description: "See single view for left and right runs", - }, - }, + description: "See single view for left and right runs", + config: {}, }, { type: "AutoBenchmarkPairwiseTable",