diff --git a/src/pages/index.js b/src/pages/index.js index ce7866f4..e3052f8a 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -175,66 +175,142 @@ const heroDiagramCopy = { zh: "显存 / 核心利用趋势", }, }; -const runtimeLanes = [ - { - key: "control", - tone: "control", - title: { en: "Control Plane", zh: "控制面" }, - summary: { en: "Decision path", zh: "决策路径" }, - steps: [ - { - key: "webhook", - emphasis: "secondary", - label: { en: "MutatingWebhook", zh: "MutatingWebhook" }, - note: { en: "Admission Entry", zh: "准入入口" }, - }, +const runtimeModesData = { + hami: { + key: "hami", + label: { en: "HAMi (Device Plugin)", zh: "HAMi (Device Plugin 模式)" }, + title: { en: "HAMi Runtime Mechanism (Device Plugin)", zh: "HAMi 运行时机制 (Device Plugin)" }, + entryLabel: { en: "Request Entry / Runtime Interface", zh: "请求入口 / 运行时接口" }, + entryValue: { + en: "PodSpec + Extended Resources (nvidia.com/gpu + gpumem / gpucores)", + zh: "PodSpec + 扩展资源 (nvidia.com/gpu + gpumem / gpucores)", + }, + lanes: [ { - key: "scheduler", - emphasis: "primary", - label: { en: "HAMi Scheduler", zh: "HAMi Scheduler" }, - note: { en: "Policy / Topology", zh: "策略 / 拓扑" }, + key: "control", + tone: "control", + title: { en: "Control Plane", zh: "控制面" }, + summary: { en: "Decision path", zh: "决策路径" }, + steps: [ + { + key: "webhook", + emphasis: "secondary", + label: { en: "MutatingWebhook", zh: "MutatingWebhook" }, + note: { en: "Admission Entry", zh: "准入入口" }, + }, + { + key: "scheduler", + emphasis: "primary", + label: { en: "HAMi Scheduler", zh: "HAMi Scheduler" }, + note: { en: "Policy / Topology", zh: "策略 / 拓扑" }, + }, + { + key: "binding", + emphasis: "primary", + label: { en: "Device Binding Decision", zh: "设备绑定决策" }, + note: { en: "Target GPU Selected", zh: "完成目标设备选择" }, + }, + ], }, { - key: "binding", - emphasis: "primary", - label: { en: "Device Binding Decision", zh: "设备绑定决策" }, - note: { en: "Target GPU Selected", zh: "完成目标设备选择" }, + key: "data", + tone: "data", + title: { en: "Data Plane", zh: "数据面" }, + summary: { en: "Enforcement Path", zh: "执行路径" }, + steps: [ + { + key: "injection", + emphasis: "primary", + label: { en: "Device Plugin Injection", zh: "Device Plugin 注入" }, + note: { en: "Device Attached", zh: "完成设备注入" }, + }, + { + key: "isolation", + emphasis: "primary", + label: { en: "HAMi Core", zh: "HAMi Core" }, + note: { en: "Memory / Core Isolation", zh: "显存 / 核心隔离" }, + }, + { + key: "runtime", + emphasis: "secondary", + label: { en: "Container Workload", zh: "容器工作负载" }, + note: { en: "Execution Starts", zh: "开始运行" }, + }, + ], }, ], + resources: { + type: "extended", + label: { en: "Resource Semantics", zh: "资源语义" }, + }, }, - { - key: "data", - tone: "data", - title: { en: "Data Plane", zh: "数据面" }, - summary: { en: "Enforcement Path", zh: "执行路径" }, - steps: [ + "hami-dra": { + key: "hami-dra", + label: { en: "HAMi-DRA Mode", zh: "HAMi-DRA 模式" }, + title: { en: "HAMi-DRA Runtime Mechanism (DRA Mode)", zh: "HAMi-DRA 运行时机制 (DRA 模式)" }, + entryLabel: { en: "Request Entry / Runtime Interface", zh: "请求入口 / 运行时接口" }, + entryValue: { + en: "PodSpec + ResourceClaim / ResourceSlice + CDI", + zh: "PodSpec + ResourceClaim / ResourceSlice + CDI 声明", + }, + lanes: [ { - key: "injection", - emphasis: "primary", - label: { en: "Device Plugin + CDI Injection", zh: "Device Plugin + CDI 注入" }, - note: { en: "Device Attached", zh: "完成设备注入" }, + key: "control", + tone: "control", + title: { en: "Control Plane", zh: "控制面" }, + summary: { en: "Decision path", zh: "决策路径" }, + steps: [ + { + key: "webhook", + emphasis: "secondary", + label: { en: "HAMi-DRA Webhook", zh: "HAMi-DRA Webhook" }, + note: { en: "Auto-Conversion & Admission", zh: "资源改写与准入" }, + }, + { + key: "scheduler", + emphasis: "primary", + label: { en: "Native Kube-Scheduler", zh: "原生 Kube-Scheduler" }, + note: { en: "K8s DRA Plugin Scheduling", zh: "K8s 原生 DRA 调度" }, + }, + { + key: "binding", + emphasis: "primary", + label: { en: "ResourceClaim Allocation", zh: "ResourceClaim 绑定" }, + note: { en: "DeviceClass & Slice Selected", zh: "完成设备切片选择" }, + }, + ], }, { - key: "isolation", - emphasis: "primary", - label: { en: "HAMi Core", zh: "HAMi Core" }, - note: { en: "Memory / Core Isolation", zh: "显存 / 核心隔离" }, - }, - { - key: "runtime", - emphasis: "secondary", - label: { en: "Container Workload", zh: "容器工作负载" }, - note: { en: "Execution Starts", zh: "开始运行" }, + key: "data", + tone: "data", + title: { en: "Data Plane", zh: "数据面" }, + summary: { en: "Enforcement Path", zh: "执行路径" }, + steps: [ + { + key: "injection", + emphasis: "primary", + label: { en: "HAMi-DRA Driver + CDI", zh: "HAMi-DRA Driver + CDI 注入" }, + note: { en: "CDI Spec & Preload", zh: "CDI 设备与预加载注入" }, + }, + { + key: "isolation", + emphasis: "primary", + label: { en: "HAMi Core", zh: "HAMi Core" }, + note: { en: "Memory / Core Isolation", zh: "显存 / 核心隔离" }, + }, + { + key: "runtime", + emphasis: "secondary", + label: { en: "Container Workload", zh: "容器工作负载" }, + note: { en: "Execution Starts", zh: "开始运行" }, + }, + ], }, ], - }, -]; -const runtimeDiagramCopy = { - title: { en: "HAMi Runtime Mechanism", zh: "HAMi 运行时机制" }, - entryLabel: { en: "Request Entry / Runtime Interface", zh: "请求入口 / 运行时接口" }, - entryValue: { - en: "PodSpec + Device Plugin / DRA + CDI", - zh: "PodSpec + Device Plugin / DRA + CDI 运行时接口", + resources: { + type: "dra", + label: { en: "Resource Semantics", zh: "资源语义" }, + }, }, }; const architectureSectionCopy = { @@ -375,6 +451,7 @@ export default function Home() { const { i18n } = useDocusaurusContext(); const isZh = i18n.currentLocale === "zh"; const [starsCount, setStarsCount] = useState(3100); + const [archMode, setArchMode] = useState("hami"); // Static: Docker Hub's API sends no CORS header, so it cannot be read from the browser. const dockerPulls = 325000; const kubernetesLogo = useBaseUrl("img/kubernetes-logo.svg"); @@ -764,50 +841,96 @@ export default function Home() {

+
+
+ + +
+
+
-
-

- {pickLocalized(i18n.currentLocale, runtimeDiagramCopy.title)} -

-
- - {pickLocalized(i18n.currentLocale, runtimeDiagramCopy.entryLabel)} - -
- {pickLocalized(i18n.currentLocale, runtimeDiagramCopy.entryValue)} -
-
- -
-
- - -
-
-
- - {isZh ? "资源语义" : "Resource Semantics"} - -
- nvidia.com/gpu - + - gpumem - / - gpucores + {(() => { + const activeMode = runtimeModesData[archMode] || runtimeModesData.hami; + return ( +
+

+ {pickLocalized(i18n.currentLocale, activeMode.title)} +

+
+ + {pickLocalized(i18n.currentLocale, activeMode.entryLabel)} + +
+ {pickLocalized(i18n.currentLocale, activeMode.entryValue)} +
+
+ +
+
+ + +
+
+
+ + {pickLocalized(i18n.currentLocale, activeMode.resources.label)} + +
+ {activeMode.key === "hami" ? ( + <> + nvidia.com/gpu + + + gpumem + / + gpucores + + ) : ( + <> + ResourceClaim + + (DeviceClass + memory/cores) + + )} +
+
-
-
+ ); + })()}
diff --git a/src/pages/styles.module.css b/src/pages/styles.module.css index a8124fe5..a6e09830 100644 --- a/src/pages/styles.module.css +++ b/src/pages/styles.module.css @@ -689,6 +689,61 @@ margin-top: 22px; } +.archModeToggleRow { + display: flex; + justify-content: center; + margin-bottom: 20px; +} + +.archModeToggle { + display: inline-flex; + gap: 6px; + background: rgba(226, 232, 240, 0.7); + padding: 4px; + border-radius: 9999px; + border: 1px solid rgba(203, 213, 225, 0.6); +} + +.archModeBtn { + border: none; + background: transparent; + padding: 8px 20px; + font-size: 0.88rem; + font-weight: 600; + border-radius: 9999px; + color: #475569; + cursor: pointer; + transition: all 0.2s ease; +} + +.archModeBtn:hover { + color: #0f172a; +} + +.archModeBtnActive { + background: #10b981; + color: #ffffff !important; + box-shadow: 0 2px 8px rgba(16, 185, 129, 0.35); +} + +:global(html[data-theme="dark"]) .archModeToggle { + background: rgba(30, 41, 59, 0.85); + border-color: rgba(51, 65, 85, 0.8); +} + +:global(html[data-theme="dark"]) .archModeBtn { + color: #94a3b8; +} + +:global(html[data-theme="dark"]) .archModeBtn:hover { + color: #f8fafc; +} + +:global(html[data-theme="dark"]) .archModeBtnActive { + background: #10b981; + color: #ffffff !important; +} + .runtimeMechanism { margin-bottom: 0; padding: 0;