Repository navigation
Add: rt_available_cluster_count / rt_available_aiv_count orch helpers - #1458
Merged
ChaoWao merged 2 commits intoJul 25, 2026
Merged
Conversation
📝 WalkthroughWalkthroughThe runtime ops tables now expose available cluster counts in both runtime variants. Orchestration adds helpers for AIC counts and derives AIV counts by doubling the AIC value. Implementations return ChangesRuntime cluster count query
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant Orchestration
participant RuntimeOps
participant RuntimeImplementation
participant PTO2Runtime
Orchestration->>RuntimeOps: query available_cluster_count
RuntimeOps->>RuntimeImplementation: dispatch callback
RuntimeImplementation->>PTO2Runtime: read orchestrator.total_cluster_count
RuntimeImplementation-->>Orchestration: return AIC count
Orchestration->>Orchestration: derive AIV count as AIC count * 2
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
yanghaoran29
force-pushed
the
rt-available-aic-aiv-counts-a2a3
branch
3 times, most recently
from
July 24, 2026 09:20
dd1ff28 to
2e29eb0
Compare
yanghaoran29
force-pushed
the
rt-available-aic-aiv-counts-a2a3
branch
4 times, most recently
from
July 25, 2026 01:05
3d2e974 to
5ab1df1
Compare
Expose this-run MIX cluster (= AIC) count to orchestration via
ops->available_cluster_count, sourced from the driver-reported worker_count
rather than a hardcoded constant:
- host_build_graph host path derives it from runtime->get_worker_count()
(was hardcoded 24/48), so the real per-die count (e.g. a 20-cluster SKU)
is latched into the arena image shipped to the device.
- tensormap_and_ringbuffer reads SchedulerContext::aic_count_/aiv_count_
(cores_total_num_/3 on the fixed 1:2 blocked layout; the core-type-
classified count on the serial path).
rt_available_cluster_count() is exposed on tensormap_and_ringbuffer only
(a2a3 + a5): orchestration runs on the AICPU where the count is known before
kernel launch. host_build_graph runs orchestration on the host under a
build-then-execute model, so it is not exposed there.
Adds tests/st/{a2a3,a5}/tensormap_and_ringbuffer/available_aicore_counts:
orchestration surfaces rt_available_cluster_count() into an output tensor
(via a dummy_task producer); the host compares it against the sim count.
ChaoWao
force-pushed
the
rt-available-aic-aiv-counts-a2a3
branch
from
July 25, 2026 05:34
5ab1df1 to
98d2a83
Compare
Orchestration had no way to ask how many clusters the current run actually
has, so MIX/AIV cohorts hardcoded 24 or 36. Expose the counts the runtime
already latches in runtime_finalize_after_wire through the ops table, on
tensormap_and_ringbuffer (a2a3, a5) and host_build_graph (a2a3).
Making the host_build_graph half real required fixing where the count comes
from. Its orchestrator runs on the host inside bind_callable_to_runtime, but
worker_count was not published until prepare_runtime_for_launch, one step
later in run(). Host orchestration therefore read the 0 a freshly constructed
Runtime carries, which silently disabled the require_sync_start block_num
deadlock guard (it treats a limit of 0 as "unknown, skip").
- DeviceRunner caches the AICore stream's block_dim ceiling once in
ensure_device_initialized(). resolve_block_dim() becomes pure arithmetic on
that ceiling, so the auto and explicit branches can share one range check
instead of the auto branch skipping validation to save an ACL round trip.
- The core-geometry half of prepare_runtime_for_launch splits out as
prepare_launch_shape() and runs before the bind; the task-address half stays
in run() as resolve_task_binary_addrs(), where the task table exists. The
move is a no-op for tensormap_and_ringbuffer, whose bind path reads neither
worker_count nor the handshake array.
- Sim resolves the auto sentinel to SIM_AUTO_BLOCKDIM (8) rather than the
modelled chip's full width. Sim runs one OS thread per AICore, so 24 or 36
clusters means 72-108 threads per case for no added coverage. An explicit
block_dim is unaffected and still honoured up to PLATFORM_MAX_BLOCKDIM.
- Cluster counts derive from PLATFORM_{AIC,AIV}_CORES_PER_BLOCKDIM instead of
open-coded /3 and *2/3 in the two scheduler cold paths and on the host.
The scene test spends the counts rather than pinning them: it reports them in
one tensor and launches a MIX cohort of exactly cluster_count blocks, each
writing its block index into another, then checks that many slots. The cohort
asks for require_sync_start, so an over-reported count trips the deadlock
guard on device instead of passing quietly.
ChaoWao
approved these changes
Jul 25, 2026
This was referenced Jul 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Orchestration had no way to ask how many clusters the current run actually has,
so MIX / AIV cohorts hardcoded 24 or 36. This exposes the counts the runtime
already latches in
runtime_finalize_after_wirethrough the ops table:Available on
tensormap_and_ringbuffer(a2a3, a5) andhost_build_graph(a2a3).Why the host path had to change first
host_build_graph's orchestrator runs on the host, insidebind_callable_to_runtime. Butworker_countwas not published untilprepare_runtime_for_launch, one step later inrun():So host orchestration read 0. That silently disabled the
require_sync_startblock_numdeadlock guard, whose only consumer treats a limit of 0 as"unknown, skip" — no in-repo hbg case uses
require_sync_starttoday, so CIstayed green while the check was off.
The fix is to resolve the geometry before the graph is built. The expensive
part is the device query, so that gets cached once:
DeviceRunnerlatches the AICore stream's block_dim ceiling inensure_device_initialized(). Nothing in the codebase callsaclrtSetStreamResLimit, so the limits hold for that stream's lifetime;finalize_common()clears them alongside the stream.resolve_block_dim()becomes pure arithmetic on that ceiling, so the autoand explicit branches share one range check instead of the auto branch
skipping validation to save an ACL round trip.
prepare_runtime_for_launchsplits out asprepare_launch_shape()and runs before the bind; the task-address halfstays in
run()asresolve_task_binary_addrs(), where the task tableexists.
The move is a no-op for
tensormap_and_ringbuffer:src/a2a3/runtime/host_build_graph/host/runtime_maker.cppis the onlybind-time reader of
worker_countin the tree.Also in this change
block_dim == 0sentinel toSIM_AUTO_BLOCKDIM(8) instead of the modelled chip's full width. Sim runsone OS thread per AICore, so 24 / 36 clusters is 72-108 threads per case for
no added coverage. It is not a ceiling — an explicit
block_dimis stillhonoured up to
PLATFORM_MAX_BLOCKDIM, so the 178 cases that pin a valuetoday are unaffected.
/3. Cluster counts derive fromPLATFORM_{AIC,AIV}_CORES_PER_BLOCKDIMinstead of open-coded/ 3and* 2 / 3in the two scheduler cold paths and on the host.Test
The scene test spends the counts rather than pinning them — there is no
constant to pin, since sim and onboard resolve different values and onboard's
comes from the driver. The orchestration reports what it saw in one tensor and
launches a MIX cohort of exactly
cluster_countblocks, each writing its blockindex into another; the host reads the width back out and checks that many
slots (via the
compare_outputshook from #1470).What would fail:
require_sync_startneeds every block co-resident → deadlock guard fires on deviceVerification
pytest examples tests/st --platform a2a3simpytest examples tests/st --platform a5simpytest examples tests/st --platform a2a3(onboard, task-submit)pytest tests/ut -m "not requires_hardware"ctestC++ unit testsConfirmed on a2a3sim that the sim auto width takes effect and is really spent:
One earlier onboard full-suite run had two
allreduceL3 cases fail with anAICore
ub address out of bounds; it did not reproduce (10/10 in isolation,54/54 on an immediate re-run) and cannot come from this change, since those
cases run on
tensormap_and_ringbufferwhose bind path never readsworker_count. Logged locally rather than dismissed.Follow-up
This is the groundwork for removing the user-specified
block_dimentirely, soruns always take the whole device and SPMD cohorts size themselves from
rt_available_cluster_count(). That flips the 178 pinned cases and reworks therequire_sync_startcases — see #1309.