Skip to content

feat: Dual-level accelerated domain support - Design and Prototype - #416

Open
ravisoundar wants to merge 10 commits into
mainfrom
rs-multi-level-block
Open

feat: Dual-level accelerated domain support - Design and Prototype#416
ravisoundar wants to merge 10 commits into
mainfrom
rs-multi-level-block

Conversation

@ravisoundar

@ravisoundar ravisoundar commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Description

Design and Prototype for the dual level accelerated domain support.
Addresses #415

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.
  • All commits are signed off per DCO (git commit -s).

@ravisoundar
ravisoundar requested a review from dmitsh as a code owner July 22, 2026 01:30
@copy-pr-bot

copy-pr-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test 24e80de

@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.00000% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.93%. Comparing base (8468abe) to head (9c7ec47).
⚠️ Report is 41 commits behind head on main.

Files with missing lines Patch % Lines
pkg/translate/block_tree.go 83.33% 13 Missing and 9 partials ⚠️
pkg/providers/oci/provider_imds.go 0.00% 3 Missing ⚠️
pkg/topology/domain.go 95.12% 1 Missing and 1 partial ⚠️
pkg/topology/graph.go 88.23% 1 Missing and 1 partial ⚠️
pkg/engines/k8s/labeler.go 95.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #416      +/-   ##
==========================================
+ Coverage   72.15%   75.93%   +3.77%     
==========================================
  Files          89       95       +6     
  Lines        5689     6739    +1050     
==========================================
+ Hits         4105     5117    +1012     
+ Misses       1382     1355      -27     
- Partials      202      267      +65     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR implements dual-level accelerated domain support ("XCLR") in topograph. It renames the single AcceleratorID concept to a two-level XclrDomainID / XclrSubDomainID hierarchy across all providers, engines, and the translate layer, and rewrites the block-tree builder to pack hosts into one- or two-level domain trees using three dispatch strategies.

  • Label rename and migration: network.topology.nvidia.com/acceleratorxclr.topology.nvidia.com/domain (+ new xclr.topology.nvidia.com/sub-domain); the old label is added to the managed set so it is cleaned up on the first reconcile after upgrade.
  • New BlockVertex / GetDomainTree in pkg/topology/domain.go builds a typed one- or two-level tree from DomainMap, computing ActualNodeCount and MaxChildNodeCount for every vertex; the translate layer uses this to drive three packing strategies (leaf pack, combine-small-sub-domains, recurse-per-child) and GCD-based root padding.
  • OCI dual-level: convertHost now sets XclrDomainID = gpuMemoryFabricID and XclrSubDomainID = domain + "." + rack, cleanly separating the two levels; the IMDS path sets only XclrDomainID (no rack info available there).

Confidence Score: 5/5

Safe to merge; all providers, engines, and the block translate layer are updated consistently and the label migration path for existing nodes is covered.

The rename from AcceleratorID to XclrDomainID/XclrSubDomainID is applied uniformly across all six providers and both engines. The legacy label constant is added to the managed set so old nodes are cleaned up on the next reconcile. The new three-strategy block packer is backed by a comprehensive suite of unit and integration tests including the dual-level simulation model. The only finding is a cosmetic string-description mismatch in Validate().

Files Needing Attention: pkg/engines/k8s/labeler.go — minor description-string issue in Validate(); no functional impact.

Important Files Changed

Filename Overview
pkg/topology/domain.go Adds BlockVertex type and GetDomainTree(); correctly builds one- or two-level trees with ActualNodeCount/MaxChildNodeCount; fallback for missing SubDomain is well-handled and tested.
pkg/translate/block_tree.go Rewrites buildBlockTree using three dispatch strategies and GCD-based root padding; logic is correct and extensively covered by the new complement tests.
pkg/translate/block_complement.go Removes groupSizeFromDomains; complementBlocks now delegates to GetDomainTree/toRootAggregate; contract comment for domainsForBlocks clearly documents the block-name key requirement.
pkg/topology/graph.go InstanceTopology fields renamed to XclrDomainID/XclrSubDomainID; toInstance correctly gates XclrSubDomain on XclrDomain presence; GPU-clique precedence preserved.
pkg/engines/k8s/labeler.go TopologyLabelKeys gains XclrSubDomain (hardcoded, consistent with new standardised label); Validate() passes the label key constant as the description argument instead of a human-readable string.
pkg/engines/k8s/kubernetes.go Correctly renames skipAcceleratorLabelWhenGPUCliqueExists; removeManagedTopologyLabels now covers XclrDomain, XclrSubDomain, and the legacy label; legacyXclrDomainLabel migration constant is well-placed.
pkg/providers/oci/instance_topology.go Cleanly splits old AcceleratorID = domain+'.'+rack into XclrDomainID = domain and XclrSubDomainID = domain+'.'+rack; rack-absent hosts get no XclrSubDomainID (correct).
pkg/engines/nfd/objects.go Renames topologyTypeAccelerator to topologyTypeXclrDomain and adds topologyTypeXclrSubDomain; GPU-clique skip extended to both xclr kinds; uses strings.CutPrefix (cleaner).
tests/models/dual-level.yaml New simulation model for dual-level test; embedded via tests/model.go so TestComplementDualLevel resolves it correctly without filesystem assumptions.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Provider: InstanceTopology\nXclrDomainID / XclrSubDomainID] --> B[ClusterTopology.ToGraph]
    B --> C[DomainMap\nmap domain → hostName → HostInfo\nHostInfo.SubDomain set when XclrSubDomainID present]
    C --> D[GetDomainTree]
    D --> E{Hosts have\nSubDomain?}
    E -- No --> F[One-level BlockVertex\nLeaf: domain → Hosts]
    E -- Yes --> G[Two-level BlockVertex\nDomain → SubDomain → Hosts]
    F --> H[toDomainAggregate]
    G --> H
    H --> I{Strategy\nselection}
    I -- Hosts != nil Leaf --> J[Strategy 1:\npackHostsIntoAggregate]
    I -- MaxChildNodeCount\n≤ baseBlockSize/2 --> K[Strategy 2:\ncombineChildHostsIntoAggregate]
    I -- MaxChildNodeCount\n> baseBlockSize/2 --> L[Strategy 3:\nrecurseChildrenIntoAggregate]
    J --> M[toRootAggregate\nGCD-based padding to blockSizes-last]
    K --> M
    L --> M
    M --> N[complementBlocks → flat blockInfo list]
    C --> O[getDomainLabels]
    O --> P[K8s node labels:\nxclr.topology.nvidia.com/domain\nxclr.topology.nvidia.com/sub-domain]
Loading

Reviews (35): Last reviewed commit: "Fix - root level padding when the domain..." | Re-trigger Greptile

Comment thread pkg/translate/block_tree.go Outdated
Comment thread pkg/topology/domain.go Outdated
@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from 24e80de to 507afeb Compare July 22, 2026 02:31
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test 507afeb

@github-actions

Copy link
Copy Markdown
Contributor

@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from 507afeb to 664c001 Compare July 22, 2026 02:51
Comment thread docs/design/nvl576-multi-level-topology-sdd.md Outdated
@dmitsh dmitsh changed the title feat: NVL576 - Multi Level Topology Support - Design and Prototype feat: Dual-level accelerated domain support - Design and Prototype Jul 23, 2026
@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from 664c001 to 1411514 Compare July 23, 2026 18:23
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test 1411514

@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from 1411514 to efa3725 Compare July 23, 2026 18:51
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test efa3725

@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from efa3725 to fae6059 Compare July 23, 2026 20:40
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test fae6059

@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from fae6059 to bdd65e8 Compare July 23, 2026 22:09
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test bdd65e8

@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from bdd65e8 to 84b8b2c Compare July 23, 2026 22:17
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test 84b8b2c

@ravisoundar
ravisoundar requested a review from dmitsh July 23, 2026 22:32

@dmitsh dmitsh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness Issues

1. SDD documents the wrong label name

docs/design/dual-level-topology-sdd.md (Data Model / Simulation model YAML section) states:

network.topology.nvidia.com/group → HostInfo.SubDomain (parent domain)

But pkg/models/model.go defines:

LabelTopologySubDomain = "network.topology.nvidia.com/sub-domain"

The SDD name (/group) and the implementation name (/sub-domain) don't match. Providers reading the SDD to opt in will use the wrong label.


2. convert: nil return value not guarded (latent panic)

In the interior-node path of convert (pkg/translate/block_tree.go):

for _, name := range slices.Sorted(maps.Keys(src.Children)) {
    converted := convert(src.Children[name], baseBlockSize)
    target.children = append(target.children, converted)
    target.nodeCount += converted.nodeCount  // panics if converted == nil

convert returns nil when src == nil. src.Children[name] can't be nil today (all values are set by GetDomainTree), but this is a latent panic for any future caller. A guard if converted == nil { continue } eliminates the footgun at zero cost.


3. childCapacity can stay zero, silently suppressing padding

childCapacity := 0
for _, name := range slices.Sorted(maps.Keys(src.Children)) {
    converted := convert(src.Children[name], baseBlockSize)
    ...
    if childCapacity == 0 {
        childCapacity = converted.nodeCount
    }
}

for target.nodeCount < src.DesiredNodeCount && childCapacity > 0 {
    ...
}

childCapacity is sampled only from the first child. If that child has nodeCount == 0 (e.g. its DesiredNodeCount was never set because blockSizes was empty, or it's a leaf domain with zero hosts), childCapacity stays 0 and the padding loop never fires. Absent base domains are silently omitted from the output rather than getting placeholder slots. The fix is to sample childCapacity from the first child with nodeCount > 0, not just the first child unconditionally.


4. domainsForBlocks interaction with SubDomain (pre-existing, but worth noting)

complementBlocks calls domainsForBlocks(nt.domains, blocks) which filters nt.domains by matching b.name (block name) against domain map keys. In the single-level case b.name is the accelerator domain name, so the lookup works. In the dual-level case b.name will be the parent domain name (domain-01, etc.) which IS the key in DomainMap, so it still works — but only because the test fixture uses the accelerator domain as the outer key.

If a future provider populates the block name as the sub-domain (base rack name) instead of the parent domain, all[b.name] will return nil and hosts will be silently dropped. The pairing between blockInfo.name and DomainMap keys is an undocumented contract worth making explicit (or enforcing in tests).


5. Placeholder positions diverge from alphabetical slot positions

rack-1-03 and rack-1-13 are alphabetically positions 3 and 13 within domain-01, but their placeholder blocks appear as block015 and block016 (the last two slots). The SDD documents this as a known limitation, but it means Slurm's position-based aggregate inference will be wrong for those specific slots — a real operational impact. The limitation callout in the SDD should be elevated to the PR description so reviewers and operators are not surprised.

@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch 2 times, most recently from 1b32609 to 785bc8d Compare July 24, 2026 18:04
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test 785bc8d

@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch 2 times, most recently from e8209f9 to cf7f184 Compare July 25, 2026 00:35
Comment thread pkg/models/model.go Outdated
@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from 22de1b7 to a778d23 Compare July 29, 2026 00:56
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test a778d23

@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch 2 times, most recently from 0941487 to 902bbd6 Compare July 29, 2026 03:29
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test 0fbdffe

@ArangoGutierrez ArangoGutierrez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found 6 issues. The first two are worth settling before merge; the rest are docs and API-surface fixes.

  1. The padding loop steps by childCapacity and stops at >= targetCount, so it lands on a multiple of desiredNodeCount only when every child has the same capacity. Dual-level domains break that: with blockSizes=[18,144,1152], domain aaa (72 hosts, 8 sub-domains) converts to nodeCount 576 while bbb (144 hosts, 2 sub-domains) converts to 144, so the root goes 720 -> 1296 and stops, emitting 72 base blocks where 1296 % 1152 = 144. A sweep of 784 two-domain shapes over that list hits it in 22, and the output then declares BlockSizes=18,144,1152 over a block list that does not tile into 1152. It needs unequal sub-domain counts per domain, so tests/models/dual-level.yaml does not catch it on any block-size list I tried - but that is the shape a real OCI cluster with uneven racks per fabric domain produces. (pkg/translate/block_tree.go:299)
  2. buildNFDObjects skips both xclr-domain and xclr-sub-domain when nvidia.com/gpu.clique is present, so a provider-supplied sub-domain attribute is not published. This PR's own TestBuildNFDObjectsSuppressesSubDomainWhenGPUCliqueExists asserts that suppression, and docs/reference/node-labels.md describes it correctly, so this line is the outlier. (docs/engines/nfd.md:152)
  3. This location string is the Go field name, while the other two are operator-facing config keys (fabricLabels[N] and acceleratorLabel). Pointing acceleratorLabel at the sub-domain key yields configured for both acceleratorLabel and XclrSubDomain, which names a parameter operators cannot set. (pkg/engines/k8s/labeler.go:61)
  4. The comment says each depth receives the smallest blockSize >= max actualNodeCount, but getDesiredCountByLevel calls pow2GroupCapacity, which returns the smallest 2^n x base. With blockSizes=[18,144] and a depth max of 20 that is 36, not 144, so the documented rule and the code disagree on a value that drives block padding. The same claim is repeated on setDesiredCountByLevel. (pkg/topology/domain.go:140)
  5. This entry records what simulation models moved away from, and that key was network.topology.nvidia.com/accelerator - xclr.topology.nvidia.com/domain did not exist when that change landed. The rename swept up a historical reference, so the entry now describes models leaving a key they never used. (CHANGELOG.md:32)
  6. asBlockVertex is sound only while every *Vertex in Vertices is &child.Vertex, but Vertices is an exported field on an exported type, so nothing outside this file enforces that. A children map[string]*BlockVertex field, or an unexported child map with ChildAt as the only reader, would let the compiler hold the invariant instead of a doc comment. (pkg/topology/domain.go:60)

Comment thread pkg/translate/block_tree.go Outdated
Comment thread docs/engines/nfd.md Outdated
Comment thread pkg/engines/k8s/labeler.go Outdated
Comment thread pkg/topology/domain.go Outdated
Comment thread CHANGELOG.md Outdated
Comment thread pkg/topology/domain.go Outdated
@dmitsh
dmitsh force-pushed the rs-multi-level-block branch 3 times, most recently from adfa820 to ec96faf Compare July 30, 2026 11:42
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test acb00d4

@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from acb00d4 to 8742ee0 Compare July 31, 2026 03:04
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test 8742ee0

ravisoundar and others added 9 commits August 3, 2026 08:55
Signed-off-by: Ravi Shankar <ravish@nvidia.com>
…6 domain

Signed-off-by: Ravi Shankar <ravish@nvidia.com>
Signed-off-by: Ravi Shankar <ravish@nvidia.com>
Signed-off-by: Ravi Shankar <ravish@nvidia.com>
Signed-off-by: Dmitry Shmulevich <dshmulevich@nvidia.com>
…rID is present

Signed-off-by: Ravi Shankar <ravish@nvidia.com>
Signed-off-by: Dmitry Shmulevich <dshmulevich@nvidia.com>
Signed-off-by: Ravi Shankar <ravish@nvidia.com>
…nodes

Signed-off-by: Ravi Shankar <ravish@nvidia.com>
Signed-off-by: Dmitry Shmulevich <dshmulevich@nvidia.com>
Signed-off-by: Ravi Shankar <ravish@nvidia.com>
@dmitsh
dmitsh force-pushed the rs-multi-level-block branch from 76d262d to 8c36950 Compare August 3, 2026 15:57
Signed-off-by: Ravi Shankar <ravish@nvidia.com>
@ravisoundar
ravisoundar force-pushed the rs-multi-level-block branch from 7169038 to 9c7ec47 Compare August 3, 2026 16:44
@ravisoundar

Copy link
Copy Markdown
Collaborator Author

/ok-to-test 9c7ec47

@ArangoGutierrez ArangoGutierrez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through the graph conversion, the labeler upgrade path, and the block packing. The dual-level model itself holds up — I verified the three ToGraph cases and confirmed no host is dropped or duplicated across even, uneven, tiny-sub-domain, and one-level layouts. One blocker: the new sub-domain combining and the new blockName.format feature are mutually incompatible.

  1. [must-fix] Strategy 2 packs hosts from several sub-domains into one base block and names it with a +-joined compound, but formatBlockName errors when nodes in one block derive different names. Both features are new in this release, so a dual-level cluster that sets blockName.nodeNameRegexp/format fails topology generation outright. Reproduced with one domain, four racks of two hosts, blockSizes=[8,16], and format $rack: block001 came out as r1+r2+r3 and formatBlockNames returned nodes in block "block001" (domain "r1+r2+r3") produce different block names "r1" and "r2". Either skip the combining when a block-name formatter is configured, or make the formatter tolerate a combined block. (pkg/translate/block_tree.go:411)
  2. [should-fix] The flush fires once the already-accumulated count passes baseBlockSize/2 rather than looking ahead at the next child, so a block closes early. The docstring above says it flushes "whenever the running host count reaches baseBlockSize", and the SDD says "No host slots are wasted" — neither matches. Concretely, four sub-domains of two hosts with baseBlockSize=8 produce two blocks (6 hosts, then 2) where one full block would do. Worth either fixing the threshold or correcting both descriptions. (pkg/translate/block_tree.go:409)
  3. [should-fix] This entry announces kubeQPS and kubeBurst parameters on the DRA provider and Slinky engine, but no such parameters exist — the only matches in the tree are the KUBE_QPS/KUBE_BURST env vars in internal/k8s/client.go and the Helm kubeClient.qps/kubeClient.burst values. The entry five lines above already describes the real mechanism correctly, so this one looks like it should just be dropped. (CHANGELOG.md:16)
  4. [should-fix] This warning sits inside the per-host loop, so a partially-racked domain logs one line per node on every regeneration — and the node observer retriggers generation on node and pod changes. The SDD names partially-racked OCI domains as an expected condition, so this is normal operation rather than an anomaly. Consider aggregating to one line per domain with a count. (pkg/topology/domain.go:140)
  5. [should-fix] Both cases here carry a rack (rack01, rack12), so the rackless branch of convertComputeHost is never exercised. Deleting the if rack != "" guard in instance_topology.go leaves go test ./pkg/providers/oci/ green — I checked. That guard implements documented behavior: docs/providers/oci.md says hosts without rack metadata keep single-level topology, and without it every rackless host gets the sub-domain <GpuMemoryFabricId>. with a trailing dot. A third case with an empty rack asserting XclrSubDomainID stays empty would cover it. (pkg/providers/oci/provider_sim_test.go:258)
  6. [consider] This BREAKING entry is a verbatim duplicate of the one five lines above, so the simulation-model annotation change is listed twice in the same Changed section. (CHANGELOG.md:35)
  7. [consider] A few comments still describe an earlier block-tree design. This one says buildBlockTree "assigns DesiredNodeCount to every node via a BFS pass" — there is no DesiredNodeCount field anywhere and GetDomainTree computes ActualNodeCount/MaxChildNodeCount inline, which its own docstring says avoids a separate BFS pass. Same category: the strategy-3 docstring says the recursion passes child.MaxChildNodeCount() when recurseChildrenIntoAggregate passes the parent's value, and the placed counter is described as excluding unplaced hosts when the fallback branch places every host, so it always equals len(hosts). (pkg/translate/block_complement.go:22; also pkg/translate/block_tree.go:272, pkg/topology/domain.go:152)
  8. [consider] The first argument to validate is a human-readable config location — the other call sites pass fabricLabels[0] and acceleratorLabel — but this one passes the label key itself. Setting fabricLabels: ["xclr.topology.nvidia.com/sub-domain"] yields: topology label key "xclr.topology.nvidia.com/sub-domain" is configured for both fabricLabels[0] and xclr.topology.nvidia.com/sub-domain. The collision is still caught; only the message is confusing. (pkg/engines/k8s/labeler.go:61)

// Flush pending hosts into a base block once their count exceeds half the base block size.
if len(pendingHosts) > baseBlockSize/2 {
blockName := strings.Join(pendingNames, "+")
bb := newBaseBlock(blockName, pendingHosts, baseBlockSize)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strategy 2 packs hosts from several sub-domains into one base block and names it with a +-joined compound, but formatBlockName errors when nodes in one block derive different names. Both features are new in this release, so a dual-level cluster that sets blockName.nodeNameRegexp/format fails topology generation outright. Reproduced with one domain, four racks of two hosts, blockSizes=[8,16], and format $rack: block001 came out as r1+r2+r3 and formatBlockNames returned nodes in block "block001" (domain "r1+r2+r3") produce different block names "r1" and "r2". Either skip the combining when a block-name formatter is configured, or make the formatter tolerate a combined block.

sortHostsByName(childHosts)

// Flush pending hosts into a base block once their count exceeds half the base block size.
if len(pendingHosts) > baseBlockSize/2 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flush fires once the already-accumulated count passes baseBlockSize/2 rather than looking ahead at the next child, so a block closes early. The docstring above says it flushes "whenever the running host count reaches baseBlockSize", and the SDD says "No host slots are wasted" — neither matches. Concretely, four sub-domains of two hosts with baseBlockSize=8 produce two blocks (6 hosts, then 2) where one full block would do. Worth either fixing the threshold or correcting both descriptions.

Comment thread CHANGELOG.md
- The NFD engine now publishes separate `xclr-domain` and `xclr-sub-domain` attributes and groups.
- The graph engine now includes `xclr.topology.nvidia.com/sub-domain` in instance labels when supplied alongside an XCLR domain.
- Exported Go constant `topology.KeyTopologyXclrSubDomain` for the `xclr.topology.nvidia.com/sub-domain` label key.
- DRA provider and Slinky engine `kubeQPS` and `kubeBurst` parameters for tuning their independent Kubernetes client rate limits on large clusters.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entry announces kubeQPS and kubeBurst parameters on the DRA provider and Slinky engine, but no such parameters exist — the only matches in the tree are the KUBE_QPS/KUBE_BURST env vars in internal/k8s/client.go and the Helm kubeClient.qps/kubeClient.burst values. The entry five lines above already describes the real mechanism correctly, so this one looks like it should just be dropped.

Comment thread pkg/topology/domain.go
// info). Place it in a fallback sub-domain vertex keyed by the
// accelerator domain name so the host is always emitted rather than
// silently dropped.
klog.Warningf("domain %q: host %q has no SubDomain; placing in fallback sub-domain %q", domain, host.HostName, domain)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning sits inside the per-host loop, so a partially-racked domain logs one line per node on every regeneration — and the node observer retriggers generation on node and pod changes. The SDD names partially-racked OCI domains as an expected condition, so this is normal operation rather than an anomaly. Consider aggregating to one line per domain with a count.

require.Equal(t, tc.parentDomain, instanceTopology.ParentAcceleratorID)
require.Equal(t, tc.parentDomain+"."+tc.rack, instanceTopology.AcceleratorID)
require.Equal(t, tc.domain, instanceTopology.XclrDomainID)
require.Equal(t, tc.domain+"."+tc.rack, instanceTopology.XclrSubDomainID)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both cases here carry a rack (rack01, rack12), so the rackless branch of convertComputeHost is never exercised. Deleting the if rack != "" guard in instance_topology.go leaves go test ./pkg/providers/oci/ green — I checked. That guard implements documented behavior: docs/providers/oci.md says hosts without rack metadata keep single-level topology, and without it every rackless host gets the sub-domain <GpuMemoryFabricId>. with a trailing dot. A third case with an empty rack asserting XclrSubDomainID stays empty would cover it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants