Skip to content
Merged
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
ea9d654
feat(planner): add retune.objective to score retune on a DGDR objecti…
tedzhouhk Oct 28, 2026
ae43296
feat(planner): enable live retune through DGDR v1beta2
tedzhouhk Oct 29, 2026
1877356
Merge remote-tracking branch 'origin/main' into hzhou/live-retune
tedzhouhk Oct 29, 2026
8815c8a
pr-17262: squash aggregate GPU discovery
Pranjulcr7 Oct 26, 2026
3669d62
pr-17262: pr-1: separate selected-shape GPU capacity [upstream: Pranj…
sttts Oct 28, 2026
f4a03e2
pr-17262: pr-1: tolerate nominal VRAM discovery [upstream: Pranjulcr7…
sttts Oct 28, 2026
99cb26e
pr-16661: squash v1beta2 DGDR admission
devivasudevan Oct 26, 2026
9f79e53
pr-16661: pr-4: squash operator-owned AISimulate execution
sttts Oct 26, 2026
105feba
pr-16661: pr-4: enforce v1beta2 admission boundaries
sttts Oct 27, 2026
9d90eb0
pr-16661: pr-4: preserve AISimulate override integers
sttts Oct 27, 2026
9af8728
pr-16661: pr-3: squash aggregate v1beta2 GPU budget
sttts Oct 26, 2026
5a38e76
pr-16661: pr-3: cover aggregate GPU verification
sttts Oct 27, 2026
215c47b
pr-16661: pr-3: consolidate hardware discovery tests
sttts Oct 28, 2026
aabbfa7
pr-16661: pr-3: modernize hardware test literals
sttts Oct 28, 2026
d936456
pr-17191: squash align and document v1beta2 defaults
sttts Oct 26, 2026
35cb8ed
pr-17191: pr-4: align model-only objective defaults
sttts Oct 26, 2026
de45db8
pr-17191: satisfy current Go lint
sttts Oct 27, 2026
a152f0c
pr-16661: pr-4: make trial budget explicit
sttts Oct 28, 2026
2204938
pr-16661: pr-4: consolidate DGDR admission tests
sttts Oct 28, 2026
f7af2f7
pr-16661: pr-4: satisfy lint after admission test consolidation
sttts Oct 28, 2026
4bd0782
pr-16661: pr-4: document independent trial budget [upstream: devivasu…
sttts Oct 29, 2026
0b80339
pr-16661: pr-3: preserve external AISimulate hardware SKUs [upstream:…
sttts Oct 28, 2026
20d1abd
pr-16661: pr-3: make SKU catalog copyright-safe [upstream: devivasude…
sttts Oct 28, 2026
fe47d06
pr-16661: pr-3: modernize SKU catalog parser [upstream: devivasudevan…
sttts Oct 28, 2026
c323694
pr-16661: pr-3: use selected-shape GPU capacity [upstream: devivasude…
sttts Oct 28, 2026
7bc8fb4
pr-16661: pr-3: defer SKU catalog smoke test [upstream: devivasudevan…
sttts Oct 29, 2026
188a075
pr-16661: pr-3: synchronize operator SKU catalog [upstream: devivasud…
sttts Oct 29, 2026
390c89c
pr-16661: pr-3: persist selected node topology [upstream: devivasudev…
sttts Oct 29, 2026
093779d
pr-16661: pr-3: verify hardware admission semantics [upstream: deviva…
sttts Oct 29, 2026
48ba217
pr-16661: pr-3: bound discovered node width [upstream: devivasudevan/…
sttts Oct 29, 2026
bc6257e
pr-15895: squash DGDR live output adapter
devivasudevan Oct 26, 2026
048bffc
pr-15895: pr-7: bound AIC resource names [upstream: devivasudevan/dyn…
sttts Oct 27, 2026
a9b5a91
pr-15895: pr-7: require AISimulate lifecycle callbacks [upstream: dev…
sttts Oct 27, 2026
5e12670
pr-15894: squash DGDR Run publisher sidecar
devivasudevan Oct 26, 2026
eceeec6
pr-15894: pr-5: squash publisher terminal snapshot contract
sttts Oct 26, 2026
396fcdd
pr-15894: satisfy current Go lint
sttts Oct 27, 2026
f44ee5b
pr-15894: pr-5: consolidate Run publisher tests
sttts Oct 28, 2026
44c519f
pr-15894: pr-5: retry terminal publication [upstream: devivasudevan/d…
sttts Oct 28, 2026
b540fb0
pr-15894: pr-5: wait for publication cache echoes [upstream: devivasu…
sttts Oct 28, 2026
d3af812
pr-17097: squash v1beta2 DGDR Request controller
devivasudevan Oct 26, 2026
9a0c776
pr-17097: satisfy current Go lint
sttts Oct 27, 2026
e9aac60
pr-17097: pr-8: remove duplicate Request controller tests
sttts Oct 28, 2026
3a5cc85
pr-17097: pr-8: cancel superseded Request runs [upstream: devivasudev…
sttts Oct 28, 2026
455ec68
pr-17097: pr-8: retain superseded Request runs [upstream: devivasudev…
sttts Oct 28, 2026
ac6ca9b
pr-17097: pr-8: satisfy current operator lint [upstream: devivasudeva…
sttts Oct 28, 2026
cee8fce
pr-17407: squash derive sibling images from release tags
sttts Oct 27, 2026
e00a9ea
pr-17195: align shared image helper with pr-17407
sttts Oct 28, 2026
711a4ae
pr-17195: squash execute v1beta2 DGDR runs
sttts Oct 26, 2026
96d3dda
pr-17195: freeze v1beta2 Run execution contract
sttts Oct 27, 2026
3c2f3b6
pr-17195: satisfy current Go lint
sttts Oct 27, 2026
c79b97f
pr-17195: complete Run execution boundaries
sttts Oct 27, 2026
8f6bad5
pr-17195: grant Run owner-reference permissions
sttts Oct 28, 2026
078f9ec
pr-17195: simplify Run RBAC envtest literals
sttts Oct 28, 2026
cd9f3fa
pr-17195: harden immutable Run execution
sttts Oct 28, 2026
684261d
pr-17195: resolve publisher Run fixture [upstream: #17195]
sttts Oct 29, 2026
1a0e03c
pr-17195: finish review test hygiene [upstream: #17195]
sttts Oct 28, 2026
0ce597f
pr-17195: close retained Run failure boundaries [upstream: #17195]
sttts Oct 28, 2026
315da92
pr-17195: satisfy current operator lint [upstream: #17195]
sttts Oct 28, 2026
5052117
pr-17195: pin sweeper numeric non-root UID [upstream: #17195]
sttts Oct 28, 2026
71ea042
pr-15895: pr-7: consolidate output adapter tests [upstream: devivasud…
sttts Oct 28, 2026
61e0e58
pr-15895: pr-7: resolve candidate topology [upstream: devivasudevan/d…
sttts Oct 29, 2026
b9f0139
pr-17195: harden frozen Run execution [upstream: #17195]
sttts Oct 29, 2026
d2b683b
pr-17195: enforce resolved Run snapshot shape [upstream: #17195]
sttts Oct 29, 2026
32632ce
operator/dgdr: test v1beta2 candidates end to end
sttts Oct 27, 2026
ed4190b
operator/dgdr: verify frozen v1beta2 input end to end
sttts Oct 28, 2026
b5379fc
operator/dgdr: verify selected-shape budget end to end
sttts Oct 28, 2026
a2f69a0
operator/dgdr: verify selected node width end to end
sttts Oct 29, 2026
ab4b32b
feat(operator): replay recorded traces from a PVC in DGDR v1beta2 runs
tedzhouhk Oct 29, 2026
a95d1f3
fix(operator): keep legacy non-trace Run Jobs valid and cover the sta…
tedzhouhk Oct 29, 2026
8f4a340
fix(planner): satisfy mypy and CodeQL in live retune
tedzhouhk Oct 29, 2026
ad3bd30
Merge branch 'main' into hzhou/dgdr-trace-pvc
tedzhouhk Oct 29, 2026
2bb6b42
Merge remote-tracking branch 'origin/main' into hzhou/dgdr-trace-pvc
tedzhouhk Oct 30, 2026
6c56df3
Merge remote-tracking branch 'origin/main' into hzhou/live-retune
tedzhouhk Oct 30, 2026
3ecbb63
docs(planner): fix the live retune engine example and note zero credit
tedzhouhk Oct 30, 2026
bdf026f
fix(operator): protect trace claims per Run and cancel Runs on claim …
tedzhouhk Oct 30, 2026
bde7f19
test(operator): render the trace scenario through the default AIC gen…
tedzhouhk Oct 30, 2026
f73f4bb
fix(operator): finish a started trace-claim cancellation and never st…
tedzhouhk Oct 30, 2026
6e8087d
Merge remote-tracking branch 'origin/main' into hzhou/dgdr-trace-pvc
tedzhouhk Oct 30, 2026
e9ab6af
feat(replay): replay DGDR trace Runs with common random numbers
tedzhouhk Oct 30, 2026
30dd626
feat(planner): add the live retune configuration and deployment premises
tedzhouhk Oct 30, 2026
73c0e58
feat(planner): cut live retune windows and reconcile the trace claim
tedzhouhk Oct 30, 2026
2dce2a5
feat(planner): run a live retune sweep through DGDR v1beta2 Requests
tedzhouhk Oct 30, 2026
8d098be
Merge branch 'hzhou/live-retune-4-dgdr' into hzhou/live-retune
tedzhouhk Oct 30, 2026
fd45a85
fix(replay): address review on trace replay common random numbers
tedzhouhk Nov 2, 2026
dffb3a7
Merge #17733 review fixes into live-retune-2-config
tedzhouhk Nov 2, 2026
1f3bc6b
fix(planner): address review on the live retune configuration and pre…
tedzhouhk Nov 2, 2026
2d27a64
fix(planner): address review on the live retune window cut and reconc…
tedzhouhk Nov 2, 2026
3a41e94
Merge #17734 review fixes into live-retune-3-trace
tedzhouhk Nov 2, 2026
b57cf27
Merge #17735 review fixes into live-retune-4-dgdr
tedzhouhk Nov 2, 2026
c055696
fix(planner): address review on the live retune DGDR sweep
tedzhouhk Nov 2, 2026
12f4389
fix(operator): address review on the DGDR trace source API
tedzhouhk Nov 2, 2026
8e2df82
Merge #17483 review fixes into live-retune-1-crn
tedzhouhk Nov 2, 2026
ba2a372
Merge #17733 review fixes into live-retune-2-config
tedzhouhk Nov 2, 2026
165407d
Merge #17735 review fixes into live-retune-4-dgdr
tedzhouhk Nov 2, 2026
3b15e7d
Merge #17734 review fixes into live-retune-3-trace
tedzhouhk Nov 2, 2026
444ab6d
test(planner): check the DGDR sweep against the operator's lowering g…
tedzhouhk Nov 2, 2026
dadae47
fix(planner): address review on enabling live retune through DGDR v1b…
tedzhouhk Nov 2, 2026
92cee14
Merge #17736 review fixes into live-retune
tedzhouhk Nov 2, 2026
03106cf
test(operator): trim redundant trace tests and drop the golden -updat…
tedzhouhk Nov 2, 2026
0405a8f
fix(planner): address second review on the live retune configuration
tedzhouhk Nov 2, 2026
5e85925
Merge #17734 review fixes into live-retune-3-trace
tedzhouhk Nov 2, 2026
49d2b8f
fix(planner): address second review on the live retune window cut
tedzhouhk Nov 2, 2026
fd8334b
Merge #17735 review fixes into live-retune-4-dgdr
tedzhouhk Nov 2, 2026
e396992
fix(planner): address second review on the live retune DGDR sweep
tedzhouhk Nov 2, 2026
ce59903
Merge #17483 review fixes into live-retune-1-crn
tedzhouhk Nov 2, 2026
df3a979
Merge #17733 review fixes into live-retune-2-config
tedzhouhk Nov 2, 2026
2e6e39e
Merge #17734 review fixes into live-retune-3-trace
tedzhouhk Nov 2, 2026
dfe7edf
Merge #17735 review fixes into live-retune-4-dgdr
tedzhouhk Nov 2, 2026
9df8363
Merge #17736 review fixes into live-retune
tedzhouhk Nov 2, 2026
9ed9ebe
fix(planner): re-add the live retune DGD and Lease access moved up fr…
tedzhouhk Nov 2, 2026
dd46cb5
fix(planner): address second review on enabling live retune
tedzhouhk Nov 2, 2026
180e779
docs(planner): update the live retune guide for the lower-layer revie…
tedzhouhk Nov 2, 2026
08c5eb9
Merge #17736 review fixes into live-retune
tedzhouhk Nov 2, 2026
82ef714
Merge main into hzhou/dgdr-trace-pvc
tedzhouhk Nov 3, 2026
143a837
Merge branch 'main' into hzhou/dgdr-trace-pvc
tedzhouhk Nov 3, 2026
7d56f6a
fix(planner): renew live retune leases before the local leadership de…
tedzhouhk Nov 3, 2026
1477976
fix(planner): reject runtime updates of the live retune scoring SLA
tedzhouhk Nov 3, 2026
b24f116
fix(planner): bind live retune window files and Requests to the trace…
tedzhouhk Nov 3, 2026
1c666b7
fix(planner): apply the worker shell default and reject opaque worker…
tedzhouhk Nov 3, 2026
f070334
fix(examples): quote the GKE worker scripts' PATH exports
tedzhouhk Nov 3, 2026
a1437c0
fix(planner): reject context-parallel presets the pinned AISimulate c…
tedzhouhk Nov 3, 2026
1dc0a78
Merge main into hzhou/dgdr-trace-pvc
tedzhouhk Nov 3, 2026
b7f957f
fix(planner): read live retune worker launches as the operator render…
tedzhouhk Nov 3, 2026
76630c6
fix(planner): keep a released live retune Lease released
tedzhouhk Nov 3, 2026
835876e
Merge main into hzhou/dgdr-trace-pvc
tedzhouhk Nov 3, 2026
7ca7737
fix(planner): narrow worker P4 reference type for mypy
tedzhouhk Nov 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ rules:
- delete
- get
- list
- patch
- watch
- apiGroups:
- ""
Expand Down
38 changes: 38 additions & 0 deletions deploy/operator/.golangci-kal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Kubernetes API conventions for the v1beta2 API types, checked by kube-api-linter
# (sigs.k8s.io/kube-api-linter). It runs through the golangci-lint build that the
# kube-api-linter module ships, so `make lint-api` uses this configuration alone.

version: "2"

run:
timeout: 10m

linters:
default: none
enable:
- kubeapilinter
settings:
custom:
kubeapilinter:
type: module
description: kube-api-linter checks Kubernetes API conventions.
settings:
linters:
disable:
- "*"
enable:
# Every serialized field carries exactly one of +optional or +required.
- optionalorrequired
exclusions:
generated: strict
rules:
- linters:
- kubeapilinter
path-except: ^api/v1beta2/

issues:
max-issues-per-linter: 0
max-same-issues: 0
5 changes: 5 additions & 0 deletions deploy/operator/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ RUN go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.15.0
# Run linting
RUN golangci-lint run --timeout=5m

# Check the v1beta2 API types against Kubernetes API conventions. Keep the version in sync with
# KUBE_API_LINTER_VERSION in the Makefile.
RUN go install sigs.k8s.io/kube-api-linter/cmd/golangci-lint-kube-api-linter@v0.0.0-20261012124120-79b557aa8c8d && \
golangci-lint-kube-api-linter run --timeout=5m -c .golangci-kal.yml ./api/v1beta2/...

# Test stage
FROM base AS tester

Expand Down
14 changes: 13 additions & 1 deletion deploy/operator/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -385,13 +385,17 @@ integration: envtest setup-clustertest ## Run envtests and clustertests, creatin
$(MAKE) clustertest

.PHONY: lint
lint: golangci-lint ## Run golangci-lint linter & yamllint
lint: golangci-lint lint-api ## Run golangci-lint linter, the Kubernetes API linter & yamllint
$(GOLANGCI_LINT) run

.PHONY: lint-fix
lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
$(GOLANGCI_LINT) run --fix

.PHONY: lint-api
lint-api: kube-api-linter ## Check the v1beta2 API types against Kubernetes API conventions
$(KUBE_API_LINTER) run -c .golangci-kal.yml ./api/v1beta2/...

##@ Build

.PHONY: build
Expand Down Expand Up @@ -579,6 +583,8 @@ YQ_VERSION ?= v4.45.4
CONTROLLER_TOOLS_VERSION ?= v0.17.3
ENVTEST_VERSION ?= release-0.19
GOLANGCI_LINT_VERSION ?= v2.15.0
# kube-api-linter publishes no tags; this pseudo-version is its 2026-10-12 main.
KUBE_API_LINTER_VERSION ?= v0.0.0-20261012124120-79b557aa8c8d

## Tool Binaries
KUBECTL ?= $(LOCALBIN)/kubectl-$(KUBECTL_VERSION)
Expand All @@ -588,6 +594,7 @@ YQ ?= $(LOCALBIN)/yq-$(YQ_VERSION)
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen-$(CONTROLLER_TOOLS_VERSION)
ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION)
GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION)
KUBE_API_LINTER = $(LOCALBIN)/golangci-lint-kube-api-linter-$(KUBE_API_LINTER_VERSION)

## ---------- Binary download targets ----------

Expand Down Expand Up @@ -651,6 +658,11 @@ golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
$(GOLANGCI_LINT): $(LOCALBIN)
$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/v2/cmd/golangci-lint,${GOLANGCI_LINT_VERSION})

.PHONY: kube-api-linter
kube-api-linter: $(KUBE_API_LINTER) ## Build the golangci-lint that includes kube-api-linter locally if necessary.
$(KUBE_API_LINTER): $(LOCALBIN)
$(call go-install-tool,$(KUBE_API_LINTER),sigs.k8s.io/kube-api-linter/cmd/golangci-lint-kube-api-linter,${KUBE_API_LINTER_VERSION})

# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
# $1 - target path with name of binary (ideally with version)
# $2 - package url which can be installed
Expand Down
26 changes: 25 additions & 1 deletion deploy/operator/api/roundtrip_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,31 @@ func fuzzBeta2Hardware(hardware *v1beta2.HardwareSpec, c randfill.Continue) {
}

func fuzzBeta2Workload(workload *v1beta2.WorkloadSpec, c randfill.Continue) {
if workload == nil || workload.Static == nil {
if workload == nil {
return
}

// A trace is exclusive with static and names one admitted claim-relative file. When both are
// filled, keep one of them at random so static and trace are equally likely.
if workload.Trace != nil && workload.Static != nil {
if c.Bool() {
workload.Static = nil
} else {
workload.Trace = nil
}
}
if workload.Trace != nil {
workload.Trace.Format = v1beta2.TraceFormatDynamo
workload.Trace.Source.PersistentVolumeClaim = &v1beta2.TracePVCSource{
ClaimName: fmt.Sprintf("traces-%d", c.Uint32()),
SubPath: fmt.Sprintf("retune/window-%d.jsonl.gz", c.Uint32()),
}
if workload.Trace.Replay != nil && workload.Trace.Replay.ArrivalSpeedupRatio != nil {
workload.Trace.Replay.ArrivalSpeedupRatio = oneOfPtr(c, 0.5, 1.0, 4.0)
}
return
}
if workload.Static == nil {
return
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type DynamoGraphDeploymentCandidateSpec struct {
// Parameters are the resolved evaluation parameters for this point.
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Type=object
// +required
Parameters runtime.RawExtension `json:"parameters"`
}

Expand All @@ -52,10 +53,14 @@ type DynamoGraphDeploymentCandidateSpec struct {

// DynamoGraphDeploymentCandidate is one bounded, user-visible search result.
type DynamoGraphDeploymentCandidate struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec DynamoGraphDeploymentCandidateSpec `json:"spec"`
// +required
Spec DynamoGraphDeploymentCandidateSpec `json:"spec"`

// +optional
Status DynamoGraphDeploymentCandidateStatus `json:"status,omitempty"`
}

Expand Down
128 changes: 116 additions & 12 deletions deploy/operator/api/v1beta2/dynamographdeploymentrequest_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
type ModelSpec struct {
// Name identifies the model in the syntax accepted by the selected backend.
// +kubebuilder:validation:MinLength=1
// +required
Name string `json:"name"`
}

Expand Down Expand Up @@ -91,12 +92,14 @@ type KVCapacityFractionRange struct {
// +kubebuilder:validation:ExclusiveMinimum=true
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=1
// +required
Min float64 `json:"min"`

// Max is the upper end of the searched fraction range.
// +kubebuilder:validation:ExclusiveMinimum=true
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=1
// +required
Max float64 `json:"max"`
}

Expand Down Expand Up @@ -154,13 +157,99 @@ type StaticWorkloadSpec struct {
Load *StaticLoadSpec `json:"load,omitempty"`
}

// WorkloadSpec defines the synthetic traffic model used for every candidate evaluation.
// TraceFormat identifies the decoder of a recorded request trace. Lowering translates it to
// AISimulate's native traffic.source.format.
// +kubebuilder:validation:Enum=Dynamo
type TraceFormat string

const (
// TraceFormatDynamo is the Dynamo request trace (dynamo.request.trace.v1) that the frontend
// records, as JSON Lines or gzip-compressed JSON Lines. It lowers to AISimulate's dynamo format.
TraceFormatDynamo TraceFormat = "Dynamo"
)

// TracePVCSource names one trace file on a PersistentVolumeClaim in the Request namespace.
type TracePVCSource struct {
// ClaimName is the PersistentVolumeClaim, in the Request namespace, that holds the trace.
// The Run Job mounts only the trace file from it, read-only, and only into the AISimulate
// container. Each Run protects the claim with the finalizer `nvidia.com/dgdr-run-<run-uid>`
// until the Run completes or, for a Run deleted before it completes, until no Job of the Run
// is left. Garbage collection deletes the Job of a deleted Run before the Job's pod, so the
// finalizer of a deleted Run can be released while that pod still stops; Kubernetes
// PersistentVolumeClaim protection keeps the claim until no pod uses it. Deleting the claim
// cancels the Runs that read it.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
ClaimName string `json:"claimName"`

// SubPath names one trace file relative to the root of the claim; the Run Job mounts it as
// the subPath of the claim volume. It is neither a directory nor a glob. It must not start or
// end with '/' and must not contain empty, '.' or '..' segments or a NUL character, which no
// file name can hold. The file must be complete before the Request is created and must never
// be rewritten: every Run of the Request reads it when its Job starts.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=1024
// +kubebuilder:validation:XValidation:rule="!self.startsWith('/') && !self.endsWith('/') && !self.contains('//') && !self.matches('(^|/)[.][.]?(/|$)')",message="subPath must be relative to the claim root without empty, '.' or '..' segments"
// +kubebuilder:validation:XValidation:rule="!self.contains('\\u0000')",message="subPath must not contain a NUL character"
SubPath string `json:"subPath"`
}

// TraceSourceSpec identifies exactly one trace artifact. A PersistentVolumeClaim is the only
// source in this release.
// +kubebuilder:validation:XValidation:rule="has(self.persistentVolumeClaim)",message="persistentVolumeClaim is required"
type TraceSourceSpec struct {
// PersistentVolumeClaim reads the trace from a PersistentVolumeClaim in the Request
// namespace.
// +optional
PersistentVolumeClaim *TracePVCSource `json:"persistentVolumeClaim,omitempty"`
}

// TraceReplaySpec configures how AISimulate replays a decoded trace.
type TraceReplaySpec struct {
// ArrivalSpeedupRatio multiplies the recorded request-arrival rate. 1.0 preserves it.
// When omitted, the recorded arrival times are replayed unchanged.
// +optional
// +kubebuilder:validation:ExclusiveMinimum=true
// +kubebuilder:validation:Minimum=0
ArrivalSpeedupRatio *float64 `json:"arrivalSpeedupRatio,omitempty"`
}

// TraceWorkloadSpec replays a recorded request trace open loop at its recorded arrival times.
type TraceWorkloadSpec struct {
// Format identifies the trace decoder. Defaults to Dynamo.
// +optional
// +kubebuilder:default=Dynamo
Format TraceFormat `json:"format,omitempty"`

// Source identifies the trace artifact.
// +required
Source TraceSourceSpec `json:"source"`
Comment thread
tedzhouhk marked this conversation as resolved.
Resolved

// Replay configures how the decoded trace is replayed.
// +optional
Replay *TraceReplaySpec `json:"replay,omitempty"`
}

// WorkloadSpec defines the traffic model used for every candidate evaluation. static and
// trace are mutually exclusive.
// +kubebuilder:validation:XValidation:rule="!(has(self.static) && has(self.trace))",message="static and trace are mutually exclusive"
type WorkloadSpec struct {
// Static defines AISimulate synthetic traffic. When omitted, admission supplies the
// complete static default. An explicit empty object opts out; any nonempty object is
// completed with omitted inputTokens, outputTokens and load defaults.
// Static defines AISimulate synthetic traffic. When omitted without a trace, admission
// supplies the complete static default. An explicit empty object opts out; any nonempty
// object is completed with omitted inputTokens, outputTokens and load defaults.
// +optional
Static *StaticWorkloadSpec `json:"static,omitempty"`

// Trace replays a recorded request trace from a PersistentVolumeClaim in the Request
// namespace. Admission supplies no static default when it is set. The Run Job mounts only the
// trace file, read-only through a subPath of the claim, at /var/run/aisimulate/trace/trace.jsonl,
// or trace.jsonl.gz when subPath ends in .gz. The trace lowers to the default traffic.source
// and traffic.load, which spec.aisimulate.inputOverrides can replace or delete.
// +optional
Trace *TraceWorkloadSpec `json:"trace,omitempty"`
}

// ObjectiveMode selects the optimization mode. Pareto is reserved for a future
Expand Down Expand Up @@ -239,9 +328,18 @@ type AISimulateSpec struct {
// runtime_image, runtime_version_override, derive_runtime_images,
// num_gpus_per_node, and namespace are operator-owned. Request admission
// rejects them, and the Run controller enforces its values while lowering the
// immutable snapshot. The operator runs the AISimulate version from its
// configured planner image; Requests and Runs cannot select a different image
// or version.
// immutable snapshot. A typed spec.workload.trace is an underlay like the other
// typed fields: it supplies the default traffic.source (type trace, format
// dynamo and the mounted trace file in paths) and the recorded-arrival
// traffic.load. Overrides can replace those values, including
// traffic.source.type, format, and paths, and null deletes the named field or
// parent object; the Run controller does not restore it. The typed
// PersistentVolumeClaim source alone decides the Run Job's trace mount and its
// claim dependency, so overriding a native path adds no volume mount.
// AISimulate validates the resulting input when the Run's Job starts; admission
// does not validate it against the AISimulate schema yet. The operator runs
// the AISimulate version from its configured planner image; Requests and Runs
// cannot select a different image or version.
// +optional
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Type=object
Expand Down Expand Up @@ -279,12 +377,14 @@ type NativeSearchInput struct {
// +optional
Hardware *HardwareSpec `json:"hardware,omitempty"`

// Workload defines the synthetic traffic model used for every candidate evaluation.
// Workload defines the traffic model used for every candidate evaluation: synthetic static
// traffic or a recorded trace.
// When omitted, admission supplies 1024 input tokens, 128 output tokens and concurrency 10;
// an explicit empty workload receives the same shape. workload.static: {} opts out of all
// traffic defaults. Any other static object is completed with its missing defaults.
// traffic defaults. Any other static object is completed with its missing defaults, and a
// trace workload receives no static default.
// spec.aisimulate.inputOverrides is applied as an RFC 7386 JSON Merge Patch and wins over
// every lowered traffic field it names.
// every lowered traffic field it names, including the fields a trace lowers.
// The default evaluates a fixed concurrency, so it does not create a KV-capacity-fraction
// search. Lowering independently defaults optimizer.max_trials to 320.
// +optional
Expand Down Expand Up @@ -374,10 +474,14 @@ type DynamoGraphDeploymentRequestStatus struct {

// DynamoGraphDeploymentRequest is the Schema for simulation-backed deployment searches.
type DynamoGraphDeploymentRequest struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec DynamoGraphDeploymentRequestSpec `json:"spec"`
// +required
Spec DynamoGraphDeploymentRequestSpec `json:"spec"`

// +optional
Status DynamoGraphDeploymentRequestStatus `json:"status,omitempty"`
}

Expand Down
Loading
Loading