Skip to content

Commit 5732246

Browse files
rapsealkclaude
andcommitted
test(agent): Cover empty allocation and clarify k8s/dummy NUMA skip
Post-review follow-ups on PR #11222: - Add an `empty_allocation` scenario to `_NUMA_SCENARIOS` so the `cores=[]` path through `_resolve_node_local_mem` / `generate_docker_args` is locked in (must not emit `CpusetMems`). - Document in `kubernetes/intrinsic.py::CPUPlugin.generate_docker_args` why the NUMA pinning from the Docker backend is not mirrored (k8s drives node-local memory via the kubelet Topology Manager). - Document in `dummy/intrinsic.py::CPUPlugin.generate_docker_args` why dummy intentionally skips the NUMA pinning (never runs real containers). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 5d46d65 commit 5732246

3 files changed

Lines changed: 17 additions & 1 deletion

File tree

src/ai/backend/agent/dummy/intrinsic.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ async def generate_docker_args(
137137
docker: aiodocker.docker.Docker,
138138
device_alloc: DeviceAllocation,
139139
) -> Mapping[str, Any]:
140+
# The Docker backend pins ``CpusetMems`` to the allocation's NUMA node
141+
# when the allocation is node-local. The dummy backend intentionally
142+
# skips that because it never actually runs containers; the output is
143+
# only inspected by tests that exercise the plumbing, not NUMA policy.
140144
cores = [*map(int, device_alloc[SlotName("cpu")].keys())]
141145
sorted_core_ids = [*map(str, sorted(cores))]
142146
return {

src/ai/backend/agent/kubernetes/intrinsic.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,10 @@ async def generate_docker_args(
191191
device_alloc: Mapping[SlotName, Mapping[DeviceId, Decimal]],
192192
) -> Mapping[str, Any]:
193193
# This function might be needed later to apply fine-grained tuning for
194-
# K8s resource allocation
194+
# K8s resource allocation. NUMA memory pinning is intentionally not
195+
# mirrored from the Docker backend here: on Kubernetes, node-local
196+
# memory placement is driven by the kubelet Topology Manager
197+
# (via pod-level resource hints), not via per-container HostConfig.
195198
return {}
196199

197200
async def restore_from_container(

tests/unit/agent/test_docker_intrinsic.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,15 @@ class _NumaScenario:
683683
cores=[0, 1],
684684
expected_cpuset_mems=None,
685685
),
686+
# Empty allocation → no cores to pin; must not produce CpusetMems="" or
687+
# a spurious node id. Locks in the defensive behavior so a future
688+
# refactor of _resolve_node_local_mem cannot regress it.
689+
"empty_allocation": _NumaScenario(
690+
num_nodes=2,
691+
core_to_node={0: 0, 1: 0},
692+
cores=[],
693+
expected_cpuset_mems=None,
694+
),
686695
}
687696

688697

0 commit comments

Comments
 (0)