Skip to content

[None][feat] align time metrics between cpp and python cache transceiver#15871

Merged
chuangz0 merged 8 commits into
NVIDIA:mainfrom
chuangz0:feat_cache_transceiver_time_sync
Jul 24, 2026
Merged

[None][feat] align time metrics between cpp and python cache transceiver#15871
chuangz0 merged 8 commits into
NVIDIA:mainfrom
chuangz0:feat_cache_transceiver_time_sync

Conversation

@chuangz0

@chuangz0 chuangz0 commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added generation-side KV cache transfer timing summary CSV output (one merged row per completed request) gated by TRTLLM_KVCACHE_TIME_OUTPUT_PATH.
    • Introduced a per-session UUID-style instanceId propagated through C++ cache sender/receiver to generate per-instance/per-rank CSV filenames.
    • Exposed KV transfer timing fields to Python via nanobind:
      • GenericLlmRequest.get_kv_cache_transfer_start()
      • GenericLlmRequest.get_kv_cache_transfer_end()
    • Extended native KV agent result framing to include transfer_size, enabling accurate KV-cache size accumulation and logging.
    • Added Python-side generation sync for transfer timing metadata (allgather + merge-by-request-id) and per-request gen-side CSV logging.
  • Bug Fixes / Correctness Improvements

    • Implemented cross-rank transfer timing synchronization using consistent merge semantics:
      • min transfer start time
      • max transfer end time
      • sum KV transfer size
    • Reworked timing synchronization from per-request collection to batched allgather/allgatherv + merge, then written back to all local request objects.
    • Calibrated steady-clock offsets across ranks using shared/global offset storage and ensured callers don’t apply the offset twice.
    • Generation-side CSV writing is mutex-guarded and lazily opens/writes after synchronization.
  • Tests

    • Added unit tests for Python _sync_transfer_timing merge behavior and gating (tests/unittest/disaggregated/test_sync_transfer_timing.py).
    • Added unit tests for C++ PerfLogManager.log_gen_transfer_summary CSV creation and disabled/no-op behavior (tests/unittest/disaggregated/test_perf_logger.py).
    • Updated native protocol roundtrip tests to include/validate transfer_size in the KV result binary prefix (tests/unittest/disaggregated/test_bounce.py).
    • Updated CSV parsing/harness tests to accept UUID-based C++ recv CSV filenames while keeping legacy rank_* pattern support (tests/unittest/disaggregated/test_cache_transceiver_harness_report.py).
    • Updated integration test artifact discovery to handle UUID-prefixed CSV filenames dynamically (tests/integration/defs/disaggregated/test_disaggregated.py).
    • Added the new sync-timing unit test to the H100 pre-merge MPI/pytorch test list (tests/integration/test_lists/test-db/l0_h100.yml).

Dev Engineer Review

  • Correctness

    • Timing merge semantics: both Python and C++ implement the same merge rules (min start, max end, sum size) keyed by requestId, and write merged timing/size back into the corresponding local request objects.
    • KV accounting: native transfer_size is carried end-to-end (sender perf-derived value → receiver unpack → kv_cache_size_bytes accumulation). Generation-side request kv_cache_size/transfer_end are stamped from the session state before subsequent processing.
    • Steady-clock calibration: introduces shared/global steady-clock offset storage and recalibration gating when the offset is unset, with rank synchronization before computing the offset.
    • CSV output contract: gen-side summary CSV writes are gated by TRTLLM_KVCACHE_TIME_OUTPUT_PATH, use deterministic {instanceId}_{rank} naming, and are serialized with a mutex to avoid concurrent write corruption.
  • API / Consistency

    • instanceId is consistently threaded through C++ sender/receiver construction and used for output naming, with Python-side logging using the same C++-set naming scheme when enabled.
    • nanobind bindings expose the newly required timing accessors to support Python merge/writeback.
  • Performance / Concurrency

    • Batched timing synchronization reduces collective overhead vs per-request collection by:
      • serializing (requestId, start, end, size) tuples for local completed requests
      • using allgather/allgatherv and a single merge pass per batch.
    • CSV writer uses lazy file opening and a mutex to reduce contention and prevent partial/corrupted output under concurrency.
  • Error Handling / Robustness

    • Sync/logging paths are environment-gated; unit tests cover the disabled behavior (no exceptions, no logging) when TRTLLM_KVCACHE_TIME_OUTPUT_PATH is not set.
    • Output directories are created before writing CSVs.
  • Potential risks to review

    • Wire compatibility for transfer_size: ensure all producers/consumers agree on the extended KV agent result frame and that older behavior correctly defaults transfer_size (tests cover framing/prefix roundtrip, but multi-version interoperability should be confirmed if relevant).
    • MPI vs process-group parity: verify that both synchronization implementations follow the same merge semantics and handle variable-length allgather buffers equivalently.
    • Filename determinism / parsing: downstream CSV discovery/parsing and harness/report scripts were updated to handle UUID-prefixed names while preserving legacy rank_* patterns—verify no remaining call sites assume the old naming.

QA Engineer Review

Test changes detected

Unit test code (outside test-list files)

  • tests/unittest/disaggregated/test_perf_logger.py
    • Added tests:
      • test_log_gen_transfer_summary_writes_csv
      • test_log_gen_transfer_summary_disabled_without_env
      • test_cpp_env_takes_priority_over_legacy_for_log
  • tests/unittest/disaggregated/test_sync_transfer_timing.py (new)
    • Added suite TestSyncTransferTiming validating:
      • request merge correctness (min/max/sum)
      • request list writeback to all provided request objects
      • allgather called only when TRTLLM_KVCACHE_TIME_OUTPUT_PATH is set and sync is required (_gen_need_sync)
      • immediate return when input list is empty
  • tests/unittest/disaggregated/test_bounce.py
    • Updated/extended:
      • test_kv_result_prefix_roundtrip to include packed size
      • test_make_kv_result_msg_uses_binary_frame to assert encoded transfer_size
  • tests/unittest/disaggregated/test_cache_transceiver_harness_report.py
    • Updated CSV filename expectations/parsing for UUID-based C++ recv files while preserving legacy rank_* parsing.

Integration test code

  • tests/integration/defs/disaggregated/test_disaggregated.py
    • Updated test_disaggregated_kv_cache_time_output to discover UUID-prefixed *_send.csv / *_recv.csv artifacts dynamically.

Integration test list

  • tests/integration/test_lists/test-db/l0_h100.yml
    • Added unittest/disaggregated/test_sync_transfer_timing.py.

Coverage / Verdict

  • Integration coverage: test_sync_transfer_timing.py is included in tests/integration/test_lists/test-db/l0_h100.yml.
  • Unit coverage: additional unit tests were added/modified (perf logger, native framing, harness parsing), but no corresponding test-db/qa coverage entries are reflected in the provided change set.
  • Verdict: needs follow-up.

Adds cross-rank time synchronization for KV-cache transfer metrics in disaggregated serving, so the per-request transfer timing recorded on different ranks/nodes becomes directly comparable and can be dumped for offline analysis.

Motivation: in disaggregated serving a single KV-cache transfer spans multiple ranks (TP/DP/PP). Each rank records its own transfer_start/transfer_end, but the local steady_clock epochs differ across processes/nodes, so the raw timestamps are not comparable, and the previous per-request all-gather to reconcile them was expensive at high request counts.

What this PR does:

  • Global steady-clock calibration — on CacheTransceiver construction, ranks barrier + all-gather local timestamps and set a per-rank sGlobalSteadyClockOffset (relative to rank 0). This is redone in the C++ library because the nanobind module and libtensorrt_llm.so hold separate inline-static copies of the offset across .so boundaries.
  • Batched timing sync — batchUpdateKVCacheTransferBW() reconciles a whole batch of completed requests in a single allgatherv (MPI and PG paths), merging by requestId (min start / max end / sum size) instead of one collective per request. Integrated into the existing consensus-based checkGenTransferStatus() flow. KvCacheTransceiverV2._sync_transfer_timing() is the equivalent for the Python transceiver runtime.
  • Gen-side transfer summary CSV — after sync, each gen instance appends one row per completed request (RequestID, gen_side_transfer_time(ms), kv_cache_size) via CacheTransceiver::writeGenTransferSummary() (C++) / PerfLogManager.log_gen_transfer_summary() (Python).
  • Per-instance UUID for file naming — rank 0 generates a UUID broadcast to the instance, used as the CSV filename prefix ({uuid}{rank}...csv) to avoid collisions across ctx/gen instances (previously rank_{n}_... could clobber).
  • Transfer-size propagation (native transfer path) — the actual transferred byte count is returned with KV_AGENT_RESULT and accumulated into kv_cache_size_bytes; transfer_start_time/transfer_end_time recorded on the session.
  • Bindings — expose get/set_kv_cache_transfer_start/end and set_kv_cache_size on the request so the Python transceiver can read/write these time points.

The whole feature is gated by the env var TRTLLM_KVCACHE_TIME_OUTPUT_PATH (set it to an output directory to enable; unset = complete no-op, no effect on inference). perf_logger.py also now recognizes this C++-standard env var as the primary switch, falling back to the existing TLLM_ENABLE_CACHE_TRANSFER_PERF_INFO / TLLM_KV_TRANSFER_PERF_LOG_FILE.

This is a performance-observability feature only — it does not change inference numerics.

Test Coverage

  • tests/unittest/disaggregated/test_sync_transfer_timing.py (new) — unit-tests the batched merge logic (min(start)/max(end)/sum(size) across simulated multi-rank data, multi-request batching, env-gate off, single-rank skip, empty list). Registered in tests/integration/test_lists/test-db/l0_h100.yml.
  • tests/unittest/disaggregated/test_perf_logger.py — added test_log_gen_transfer_summary_writes_csv and test_log_gen_transfer_summary_disabled_without_env.
  • End-to-end verified locally: TinyLlama-1.1B disagg (1 ctx + 1 gen, NIXL, PYTHON transceiver runtime) with TRTLLM_KVCACHE_TIME_OUTPUT_PATH set; 128-prompt benchmark completed and produced {uuid}_0_gen_transfer_summary.csv with 129 rows whose RequestIDs and kv_cache_size cross-check consistently against the recv detail CSV; ctx/gen used distinct UUIDs (no collision); /steady_clock_offset calibration confirmed in server logs

PR Checklist

Please review the following before submitting your PR:

  • PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.

  • PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.

  • Test cases are provided for new code paths (see test instructions)

  • If PR introduces API changes, an appropriate PR label is added - either api-compatible or api-breaking. For api-breaking, include BREAKING in the PR title.

  • Any new dependencies have been scanned for license and vulnerabilities

  • CODEOWNERS updated if ownership changes

  • Documentation updated as needed

  • Update tava architecture diagram if there is a significant design change in PR.

  • The reviewers assigned automatically/manually are appropriate for the PR.

  • Please check this after reviewing the above items as appropriate for this PR.

GitHub Bot Help

To see a list of available CI bot commands, please comment /bot help.

@chuangz0
chuangz0 requested review from a team as code owners July 2, 2026 06:06
@chuangz0
chuangz0 force-pushed the feat_cache_transceiver_time_sync branch from 3da38fc to 5171454 Compare July 2, 2026 06:07
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Introduces instance-scoped cache-transfer output, synchronized clock and transfer metrics, generation-side CSV summaries, Python transfer-session tracking, and tests for cross-rank timing aggregation.

Changes

KV cache transfer timing and instance-scoped output

Layer / File(s) Summary
Instance ID and clock calibration
cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp, cpp/tensorrt_llm/batch_manager/dataTransceiver.{h,cpp}, cpp/include/tensorrt_llm/batch_manager/llmRequest.{h,cpp}, cpp/tensorrt_llm/nanobind/bindings.cpp
Generates and synchronizes instance IDs, calibrates steady-clock offsets, and uses instance IDs in sender/receiver output filenames.
C++ batched timing and summary output
cpp/include/tensorrt_llm/batch_manager/{cacheTransceiver.h,llmRequest.h}, cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp, cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp
Batches cross-rank timing and size aggregation, writes generation-side CSV rows, stores normalized timestamps, and exposes timestamp accessors.
Native transfer session tracking
tensorrt_llm/_torch/disaggregation/native/transfer.py, tests/unittest/disaggregated/test_bounce.py
Propagates transfer sizes through KV_AGENT_RESULT messages and records transfer start/end times and accumulated cache sizes.
Python transceiver synchronization
tensorrt_llm/_torch/disaggregation/transceiver.py
Synchronizes completed request timing and size across ranks and logs generation-side summaries.
Perf logging and validation
tensorrt_llm/_torch/disaggregation/native/perf_logger.py, tests/unittest/disaggregated/*, tests/integration/defs/disaggregated/test_disaggregated.py, tests/integration/test_lists/test-db/l0_h100.yml, examples/disaggregated/slurm/cache_transceiver_test/*
Adds C++-style output-path handling, generation-summary CSV logging, filename compatibility updates, unit tests, and integration test registration.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant KvCacheTransceiverV2
  participant GenerationRanks
  participant PerfLogManager
  KvCacheTransceiverV2->>GenerationRanks: allgather request timing and size
  GenerationRanks-->>KvCacheTransceiverV2: merged metrics
  KvCacheTransceiverV2->>PerfLogManager: log generation summary
Loading

Possibly related PRs

Suggested labels: api-compatible

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change and follows the required [None][feat] format.
Description check ✅ Passed The description includes the issue, solution, test coverage, and PR checklist with concrete details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp (1)

187-201: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use the PG rank fallback here too getTransferOutputPath() unconditionally reads mpi::MpiComm::world().getRank(), but this codebase has a non-MPI path. That can make the send/recv timing CSV names collide when MPI is disabled; mirror the useMPI() ? ... : pg_utils::get_world_pg()->getRank() branch used in writeGenTransferSummary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp` around lines 187 - 201,
getTransferOutputPath() always uses mpi::MpiComm::world().getRank(), which
breaks the non-MPI path and can cause send/recv timing CSV name collisions.
Update the rank lookup in this helper to mirror writeGenTransferSummary by using
the PG rank fallback when useMPI() is false, and keep the rest of the
prefix/path construction in getTransferOutputPath() unchanged.
tensorrt_llm/_torch/disaggregation/transceiver.py (1)

58-108: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Env-var gate for the timing-sync collective is read per-process, not synchronized across ranks — deadlock risk.

Both _sync_transfer_timing (Line 403) and its call site in check_gen_transfer_status (Line 687) decide whether to invoke the blocking self._gen_allgather(...) collective by independently calling os.getenv("TRTLLM_KVCACHE_TIME_OUTPUT_PATH") on each process. completed is already made consistent across ranks via _gen_consensus_outcome, but the env var itself is never synchronized. If this variable is set on some ranks/processes and not others (e.g. inconsistent env propagation across nodes in a multi-node TP/PP job), some ranks will call the collective while others skip it — a classic mismatched-collective-call hang, since allgather requires every participant to call it in lockstep.

The class already has an established pattern for this exact problem — broadcasting a rank-0 decision once at construction (see _broadcast_instance_name, _broadcast_context_endpoint). Consider doing the same for this flag instead of re-reading os.getenv on every iteration from every rank independently.

🔒 Proposed fix
     def _init_sync_policy(self):
         m = self._mapping
         self._ctx_need_tp_sync = m.tp_size > 1 and not m.enable_attention_dp
         self._ctx_need_pp_sync = m.pp_size > 1
         self._gen_need_sync = not (m.world_size == 1 or (m.enable_attention_dp and m.pp_size == 1))
         pp_allgather: Callable = getattr(self._dist, "pp_allgather")
         self._gen_allgather: Callable = (
             pp_allgather if m.enable_attention_dp else self._dist.allgather
         )
+        self._kv_time_output_enabled = self._broadcast_kv_time_output_enabled()
+
+    def _broadcast_kv_time_output_enabled(self) -> bool:
+        if self._dist.rank == 0:
+            enabled = bool(os.getenv("TRTLLM_KVCACHE_TIME_OUTPUT_PATH"))
+            self._dist.broadcast(enabled, 0)
+            return enabled
+        return cast(bool, self._dist.broadcast(None, 0))

Then replace the per-call os.getenv("TRTLLM_KVCACHE_TIME_OUTPUT_PATH") checks at Line 403 and Line 687 with self._kv_time_output_enabled.

Also applies to: 124-132, 393-406, 686-699

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/_torch/disaggregation/transceiver.py` around lines 58 - 108, The
timing-sync collective gate is being decided independently on each rank via
os.getenv, which can mismatch across processes and deadlock the allgather. Add a
one-time, rank-synchronized flag in KvCacheTransceiverV2 (similar to
_broadcast_instance_name and _broadcast_context_endpoint), store it on the
instance as _kv_time_output_enabled, and use that cached value in
_sync_transfer_timing and check_gen_transfer_status instead of re-reading the
environment each time.
🧹 Nitpick comments (4)
cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp (1)

193-200: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicate accessors for the same values.

kv_cache_transfer_start/kv_cache_transfer_end are already exposed as read-only properties (lines 194-195); the new get_kv_cache_transfer_start/get_kv_cache_transfer_end methods (196-197) bind to the identical getters. Consider standardizing on one style (likely the explicit get_*/set_* method pairing, matching the existing setters at lines 199-200) and dropping the redundant property to avoid two ways to read the same field.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp` around lines 193 - 200,
The batch manager bindings expose the same KV cache transfer timestamps twice,
once as read-only properties and again as explicit getters. In bindings.cpp,
update the GenLlmReq nanobind definitions to use one consistent API style only:
keep the get_kv_cache_transfer_start/get_kv_cache_transfer_end and matching
setters, or keep the properties, but remove the redundant duplicate accessor set
so the same value is not read through two parallel bindings.
cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp (2)

350-364: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hard-coded kUuidLen = 36 duplicates the format assumption from generateInstanceId().

Nothing ties this constant to the actual output width of generateInstanceId() (lines 75-87). If that formatting ever changes, this broadcast path silently truncates/corrupts the instance ID with no compile-time or runtime guard.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp` around lines 350 - 364,
The PG broadcast path in cacheTransceiver.cpp hard-codes the UUID length
separately from generateInstanceId(), so it can silently truncate or corrupt
instance IDs if the format changes. Replace the local kUuidLen assumption in the
allgather path with a single shared source of truth tied to
generateInstanceId()’s output size, and use that same value when allocating
sendBuf/recvBuf and reconstructing mInstanceId. Add a guard or assertion in
CacheTransceiver to ensure the received instance ID length matches the expected
generated length.

755-812: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

batchUpdateKVCacheTransferBW always performs the allgather/allgatherv, unlike other collectives in this file.

gatherRequestIds and reduceTransferStates both guard collective calls with comm->getSize() > 1 before invoking them; this new function unconditionally calls comm->allgather/allgatherv regardless of worldSize. For single-rank deployments that still enable TRTLLM_KVCACHE_TIME_OUTPUT_PATH, this issues an unnecessary (and, depending on the PG backend, potentially unsupported) size-1 collective.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp` around lines 755 - 812,
batchUpdateKVCacheTransferBW currently unconditionally runs comm->allgather and
comm->allgatherv even when there is only one rank. Update this function to
mirror gatherRequestIds and reduceTransferStates by guarding the collective path
with worldSize > 1, and for the single-rank case skip the distributed merge and
just use the local serialized data to populate/update the cache transfer
bandwidth state. Locate the change in batchUpdateKVCacheTransferBW and keep the
useMPI/non-MPI branches inside the multi-rank-only path.
tensorrt_llm/_torch/disaggregation/native/perf_logger.py (1)

369-395: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Catch a narrower exception type than bare Exception.

The try block only does filesystem/logging setup (os.makedirs, logging.FileHandler, stream writes), which realistically raises OSError (including PermissionError). Catching Exception broadly can mask unrelated bugs.

♻️ Proposed fix
-                    except Exception as e:
+                    except OSError as e:
                         sys.stderr.write(
                             f"[KV Transfer] Warning: Failed to create gen summary log file {log_file}: {e}\n"
                         )
                         return

Based on learnings and coding guidelines: "Avoid broad exception handling — catch specific exceptions, not bare except:" and "limit the except to the smallest set of errors possible; use specific exception types."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/_torch/disaggregation/native/perf_logger.py` around lines 369 -
395, The exception handling in the gen summary log setup is too broad, so narrow
the `except` in `perf_logger.py` around the `try` block that creates the
`file_logger` and `file_handler`. Catch only the filesystem/logging errors this
code can realistically raise, such as `OSError` (including `PermissionError`),
and keep the existing warning/return path in the `self._file_loggers` setup
unchanged.

Sources: Coding guidelines, Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp`:
- Around line 1246-1266: `CacheTransceiver::writeGenTransferSummary` opens
`mGenTransferSummaryFile` without verifying success, so add an `is_open()` check
immediately after `open(filePath)` and fail with an explicit
`TLLM_CHECK_WITH_INFO` message if the file cannot be opened. Use the same
pattern already used in `dataTransceiver.cpp` (`release()`/`receiveSync()`) and
keep the fix localized to the `writeGenTransferSummary` path so missing
permissions or bad output paths are surfaced instead of silently dropping
writes.
- Around line 366-401: The steady-clock calibration in CacheTransceiver has a
race and inconsistent synchronization: the
`LlmRequest::sGlobalSteadyClockOffset` check/set in this block is
unsynchronized, and the PG path in `CacheTransceiverComm` skips the
pre-timestamp barrier used by the MPI path. Protect the one-time initialization
with the same kind of mutex/guard used elsewhere in `CacheTransceiver`, and make
the collective calibration path synchronize all ranks immediately before reading
`steady_clock::now()` so both `useMPI()` and non-MPI branches measure from a
consistent point.

In `@tests/unittest/disaggregated/test_perf_logger.py`:
- Around line 109-123: The test
`test_log_gen_transfer_summary_disabled_without_env` is mutating global
environment state by popping `TRTLLM_KVCACHE_TIME_OUTPUT_PATH` without restoring
it. Update the test to scope the env change with `patch.dict` (as in the sibling
env-isolation test) so `PerfLogManager` can be exercised without leaking state
into other tests; keep the call to `log_gen_transfer_summary` unchanged.

In `@tests/unittest/disaggregated/test_sync_transfer_timing.py`:
- Around line 118-131: The test `test_skips_when_no_env` mutates `os.environ`
directly by popping `TRTLLM_KVCACHE_TIME_OUTPUT_PATH` without restoring it,
which can leak state into other tests. Update this test to use the same isolated
environment approach used elsewhere in the class, such as
`@patch.dict("os.environ", {}, clear=False)` with the pop inside the context or
`monkeypatch.delenv`, and keep the assertions around `_sync_transfer_timing` and
`allgather_mock` unchanged.

---

Outside diff comments:
In `@cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp`:
- Around line 187-201: getTransferOutputPath() always uses
mpi::MpiComm::world().getRank(), which breaks the non-MPI path and can cause
send/recv timing CSV name collisions. Update the rank lookup in this helper to
mirror writeGenTransferSummary by using the PG rank fallback when useMPI() is
false, and keep the rest of the prefix/path construction in
getTransferOutputPath() unchanged.

In `@tensorrt_llm/_torch/disaggregation/transceiver.py`:
- Around line 58-108: The timing-sync collective gate is being decided
independently on each rank via os.getenv, which can mismatch across processes
and deadlock the allgather. Add a one-time, rank-synchronized flag in
KvCacheTransceiverV2 (similar to _broadcast_instance_name and
_broadcast_context_endpoint), store it on the instance as
_kv_time_output_enabled, and use that cached value in _sync_transfer_timing and
check_gen_transfer_status instead of re-reading the environment each time.

---

Nitpick comments:
In `@cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp`:
- Around line 350-364: The PG broadcast path in cacheTransceiver.cpp hard-codes
the UUID length separately from generateInstanceId(), so it can silently
truncate or corrupt instance IDs if the format changes. Replace the local
kUuidLen assumption in the allgather path with a single shared source of truth
tied to generateInstanceId()’s output size, and use that same value when
allocating sendBuf/recvBuf and reconstructing mInstanceId. Add a guard or
assertion in CacheTransceiver to ensure the received instance ID length matches
the expected generated length.
- Around line 755-812: batchUpdateKVCacheTransferBW currently unconditionally
runs comm->allgather and comm->allgatherv even when there is only one rank.
Update this function to mirror gatherRequestIds and reduceTransferStates by
guarding the collective path with worldSize > 1, and for the single-rank case
skip the distributed merge and just use the local serialized data to
populate/update the cache transfer bandwidth state. Locate the change in
batchUpdateKVCacheTransferBW and keep the useMPI/non-MPI branches inside the
multi-rank-only path.

In `@cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp`:
- Around line 193-200: The batch manager bindings expose the same KV cache
transfer timestamps twice, once as read-only properties and again as explicit
getters. In bindings.cpp, update the GenLlmReq nanobind definitions to use one
consistent API style only: keep the
get_kv_cache_transfer_start/get_kv_cache_transfer_end and matching setters, or
keep the properties, but remove the redundant duplicate accessor set so the same
value is not read through two parallel bindings.

In `@tensorrt_llm/_torch/disaggregation/native/perf_logger.py`:
- Around line 369-395: The exception handling in the gen summary log setup is
too broad, so narrow the `except` in `perf_logger.py` around the `try` block
that creates the `file_logger` and `file_handler`. Catch only the
filesystem/logging errors this code can realistically raise, such as `OSError`
(including `PermissionError`), and keep the existing warning/return path in the
`self._file_loggers` setup unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 933ba7bb-bd93-47aa-ab78-5cf8e314c058

📥 Commits

Reviewing files that changed from the base of the PR and between 4605402 and 5171454.

📒 Files selected for processing (12)
  • cpp/include/tensorrt_llm/batch_manager/cacheTransceiver.h
  • cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.h
  • cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp
  • cpp/tests/unit_tests/multi_gpu/cacheTransceiverTest.cpp
  • tensorrt_llm/_torch/disaggregation/native/perf_logger.py
  • tensorrt_llm/_torch/disaggregation/native/transfer.py
  • tensorrt_llm/_torch/disaggregation/transceiver.py
  • tests/integration/test_lists/test-db/l0_h100.yml
  • tests/unittest/disaggregated/test_perf_logger.py
  • tests/unittest/disaggregated/test_sync_transfer_timing.py

Comment thread cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp
Comment thread cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp
Comment thread tests/unittest/disaggregated/test_perf_logger.py Outdated
Comment thread tests/unittest/disaggregated/test_sync_transfer_timing.py Outdated
@chuangz0
chuangz0 force-pushed the feat_cache_transceiver_time_sync branch from 5171454 to eb692a9 Compare July 3, 2026 02:15
@chuangz0

chuangz0 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57307 [ run ] triggered by Bot. Commit: eb692a9 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57307 [ run ] completed with state FAILURE. Commit: eb692a9
/LLM/main/L0_MergeRequest_PR pipeline #46067 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@chuangz0
chuangz0 requested a review from Shixiaowei02 July 3, 2026 05:21
@chuangz0
chuangz0 force-pushed the feat_cache_transceiver_time_sync branch from eb692a9 to 488b581 Compare July 3, 2026 05:22
@chuangz0

chuangz0 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57368 [ run ] triggered by Bot. Commit: 488b581 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57368 [ run ] completed with state FAILURE. Commit: 488b581
/LLM/main/L0_MergeRequest_PR pipeline #46119 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@chuangz0
chuangz0 force-pushed the feat_cache_transceiver_time_sync branch from 488b581 to 5979c4f Compare July 3, 2026 08:39
@chuangz0

chuangz0 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57424 [ run ] triggered by Bot. Commit: 5979c4f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57424 [ run ] completed with state FAILURE. Commit: 5979c4f
/LLM/main/L0_MergeRequest_PR pipeline #46166 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@chuangz0
chuangz0 force-pushed the feat_cache_transceiver_time_sync branch from 5979c4f to cb412f3 Compare July 6, 2026 01:56
@chuangz0

chuangz0 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57651 [ run ] triggered by Bot. Commit: cb412f3 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #57651 [ run ] completed with state FAILURE. Commit: cb412f3
/LLM/main/L0_MergeRequest_PR pipeline #46374 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@chuangz0
chuangz0 requested a review from a team as a code owner July 6, 2026 06:01
@chuangz0
chuangz0 force-pushed the feat_cache_transceiver_time_sync branch from fba6ee9 to 1c80fd3 Compare July 6, 2026 06:02
@chuangz0

chuangz0 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #60680 [ run ] completed with state FAILURE. Commit: 064ae71
/LLM/main/L0_MergeRequest_PR pipeline #48975 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

Comment thread cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp Outdated
Comment thread cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp Outdated
@chuangz0
chuangz0 force-pushed the feat_cache_transceiver_time_sync branch from 064ae71 to 441d88c Compare July 23, 2026 03:23

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp (1)

1319-1324: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Protect the async-resource registry with one mutex. cancelRequest() reads mInstanceToAsyncResource while requestAndReceiveAsyncMultiThreads() inserts into it and ~Impl() iterates it, so concurrent access can race on std::unordered_map. Guard all accesses with the same lock.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp` around lines 1319 - 1324,
Protect every access to mInstanceToAsyncResource with one shared mutex: update
cancelRequest() around its lookup, requestAndReceiveAsyncMultiThreads() around
insertion, and ~Impl() around iteration or clearing. Use the same lock for all
three paths and preserve the existing cancellation, registration, and cleanup
behavior.
🧹 Nitpick comments (1)
cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp (1)

794-804: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Move agent-only control-path operations behind the connection interface.

dataTransceiver.cpp repeatedly probes AgentConnectionManager/AgentConnection with dynamic_cast, and line 1235 also needs const_cast to call a mutating method. Expose these agent-specific operations on the interface or resolve the backend once during construction so the transceiver can call them directly.

  • cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp#L794-L804
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp#L1232-L1236
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp#L1401-L1407
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp` around lines 794 - 804,
Replace the repeated AgentConnectionManager/AgentConnection dynamic_cast checks
in dataTransceiver.cpp with agent-specific operations exposed through the
connection interface, or resolve the backend once during DataTransceiver
construction. Update sites 794-804, 1232-1236, and 1401-1407 to call the
interface directly, including a non-const mutating method so the const_cast at
1232-1236 is removed; preserve the existing agent and non-agent send behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp`:
- Around line 1319-1324: Protect every access to mInstanceToAsyncResource with
one shared mutex: update cancelRequest() around its lookup,
requestAndReceiveAsyncMultiThreads() around insertion, and ~Impl() around
iteration or clearing. Use the same lock for all three paths and preserve the
existing cancellation, registration, and cleanup behavior.

---

Nitpick comments:
In `@cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp`:
- Around line 794-804: Replace the repeated
AgentConnectionManager/AgentConnection dynamic_cast checks in
dataTransceiver.cpp with agent-specific operations exposed through the
connection interface, or resolve the backend once during DataTransceiver
construction. Update sites 794-804, 1232-1236, and 1401-1407 to call the
interface directly, including a non-const mutating method so the const_cast at
1232-1236 is removed; preserve the existing agent and non-agent send behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 59caa2ba-133b-4dbd-b0b6-14d8fdddfe1c

📥 Commits

Reviewing files that changed from the base of the PR and between 5171454 and 441d88c.

📒 Files selected for processing (5)
  • cpp/include/tensorrt_llm/batch_manager/cacheTransceiver.h
  • cpp/include/tensorrt_llm/batch_manager/llmRequest.h
  • cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.h
🚧 Files skipped from review as they are similar to previous changes (3)
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.h
  • cpp/include/tensorrt_llm/batch_manager/cacheTransceiver.h
  • cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp

@chuangz0
chuangz0 force-pushed the feat_cache_transceiver_time_sync branch from d4ea8a9 to 016e3de Compare July 23, 2026 08:04
@chuangz0

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/tensorrt_llm/batch_manager/llmRequest.cpp`:
- Around line 25-33: Protect the process-global steady-clock offset with
synchronized accessors: in cpp/tensorrt_llm/batch_manager/llmRequest.cpp:25-33,
add mutex-guarded getter/setter or equivalent write-once atomic publication; in
cpp/include/tensorrt_llm/batch_manager/llmRequest.h:87-94, replace the raw
mutable reference with those accessors; in
cpp/include/tensorrt_llm/batch_manager/llmRequest.h:2398-2401, read a
synchronized snapshot; and in
cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp:484-488, bind the
synchronized accessors instead of the field.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0ec334ea-fa71-4b50-a5bf-aae27a6906e8

📥 Commits

Reviewing files that changed from the base of the PR and between 441d88c and d4ea8a9.

📒 Files selected for processing (7)
  • cpp/include/tensorrt_llm/batch_manager/llmRequest.h
  • cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp
  • cpp/tensorrt_llm/batch_manager/llmRequest.cpp
  • cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp
  • cpp/tensorrt_llm/nanobind/bindings.cpp
  • tests/unittest/disaggregated/test_perf_logger.py
  • tests/unittest/disaggregated/test_sync_transfer_timing.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/unittest/disaggregated/test_perf_logger.py
  • tests/unittest/disaggregated/test_sync_transfer_timing.py
  • cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp

Comment thread cpp/tensorrt_llm/batch_manager/llmRequest.cpp
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61247 [ run ] triggered by Bot. Commit: 016e3de Link to invocation

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/unittest/disaggregated/test_perf_logger.py (1)

82-107: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover C++-path priority for normal perf logs.

This only exercises log_gen_transfer_summary, which reads the environment directly; it does not cover the changed initialization and normal file naming paths. Add a test with both C++ and legacy variables set, call log(), and assert {tmpdir}/test_inst_0.csv is used instead of the legacy filename.

As per path instructions, test coverage feedback must be actionable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/disaggregated/test_perf_logger.py` around lines 82 - 107, Add
a test for the normal perf-log path that sets both the C++ output-path variable
and the legacy variable, constructs `PerfLogManager`, and calls `log()`. Assert
that the C++ path produces `{tmpdir}/test_inst_0.csv` and that the legacy
filename is not used, covering initialization priority and normal file naming
rather than `log_gen_transfer_summary`.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/disaggregated/slurm/cache_transceiver_test/README.md`:
- Line 67: Update the CSV artifact pattern documentation near the C++
transceiver timing entry to include the optional __c<ci> suffix produced by
_preserve_cpp_csvs, while retaining the existing unsuffixed form for
single-combination runs.

In `@tensorrt_llm/_torch/disaggregation/native/perf_logger.py`:
- Around line 391-395: In the gen summary log file creation error handler,
replace the broad Exception catch with filesystem-specific OSError handling,
including PermissionError through its existing subclass relationship. Keep the
warning output and return behavior unchanged, while allowing unexpected
programming errors to propagate.
- Around line 334-341: Annotate every newly introduced function: add -> None to
perf_logger.py’s log_gen_transfer_summary, the new test methods in
test_perf_logger.py, and all test methods in test_sync_transfer_timing.py; add
precise parameter and return types to the fake-request helpers and
_make_transceiver in test_sync_transfer_timing.py. Apply the annotations at all
four identified sites without changing behavior.

---

Nitpick comments:
In `@tests/unittest/disaggregated/test_perf_logger.py`:
- Around line 82-107: Add a test for the normal perf-log path that sets both the
C++ output-path variable and the legacy variable, constructs `PerfLogManager`,
and calls `log()`. Assert that the C++ path produces `{tmpdir}/test_inst_0.csv`
and that the legacy filename is not used, covering initialization priority and
normal file naming rather than `log_gen_transfer_summary`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d7f0e955-0e0a-4840-9288-5c22f0776a87

📥 Commits

Reviewing files that changed from the base of the PR and between d4ea8a9 and 016e3de.

📒 Files selected for processing (22)
  • cpp/include/tensorrt_llm/batch_manager/cacheTransceiver.h
  • cpp/include/tensorrt_llm/batch_manager/llmRequest.h
  • cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.h
  • cpp/tensorrt_llm/batch_manager/llmRequest.cpp
  • cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp
  • cpp/tensorrt_llm/nanobind/bindings.cpp
  • cpp/tests/unit_tests/multi_gpu/cacheTransceiverTest.cpp
  • examples/disaggregated/slurm/cache_transceiver_test/README.md
  • examples/disaggregated/slurm/cache_transceiver_test/report.py
  • examples/disaggregated/slurm/cache_transceiver_test/run_cache_transceiver_test.py
  • tensorrt_llm/_torch/disaggregation/native/perf_logger.py
  • tensorrt_llm/_torch/disaggregation/native/transfer.py
  • tensorrt_llm/_torch/disaggregation/transceiver.py
  • tensorrt_llm/_torch/pyexecutor/py_executor.py
  • tests/integration/defs/disaggregated/test_disaggregated.py
  • tests/integration/test_lists/test-db/l0_h100.yml
  • tests/unittest/disaggregated/test_bounce.py
  • tests/unittest/disaggregated/test_cache_transceiver_harness_report.py
  • tests/unittest/disaggregated/test_perf_logger.py
  • tests/unittest/disaggregated/test_sync_transfer_timing.py
🚧 Files skipped from review as they are similar to previous changes (10)
  • tests/integration/test_lists/test-db/l0_h100.yml
  • cpp/tensorrt_llm/batch_manager/llmRequest.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.h
  • cpp/tests/unit_tests/multi_gpu/cacheTransceiverTest.cpp
  • cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp
  • cpp/tensorrt_llm/nanobind/bindings.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp
  • cpp/include/tensorrt_llm/batch_manager/llmRequest.h
  • tensorrt_llm/_torch/disaggregation/native/transfer.py
  • tensorrt_llm/_torch/disaggregation/transceiver.py

Comment thread examples/disaggregated/slurm/cache_transceiver_test/README.md Outdated
Comment thread tensorrt_llm/_torch/disaggregation/native/perf_logger.py Outdated
Comment thread tensorrt_llm/_torch/disaggregation/native/perf_logger.py Outdated

@chzblych chzblych 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.

Approved for the testing part changes.

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61247 [ run ] completed with state FAILURE. Commit: 016e3de
/LLM/main/L0_MergeRequest_PR pipeline #49485 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

chuangz0 added 7 commits July 24, 2026 02:20
Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
…naming

The cache transceiver now writes per-transfer timing CSVs as
<instanceId>_<rank>_<tag>.csv (instanceId is a runtime UUID that
disambiguates instances sharing an output directory). Update all
consumers that previously assumed the fixed rank_<rank>_<tag>.csv name:

- integration test test_disaggregated_kv_cache_time_output: match the
  send/recv files by their _<tag>.csv suffix instead of rank_0_*.
- report.py: glob *_recv*.csv (still matches legacy rank_* names).
- run_cache_transceiver_test.py _preserve_cpp_csvs: rename by the
  _<rank>_<tag>.csv suffix, keeping the per-rank no-race guarantee.
- README: document the <instanceId>_* file names.
- harness report unittest: use realistic UUID-named fixtures and keep a
  legacy rank_ case for backward compatibility.

Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
…alibration

Address PR review comments on the cache-transceiver time-sync feature:

- Collapse the global steady-clock offset into a single process-global copy
  reached through globalSteadyClockOffset() (storage in llmRequest.cpp) instead
  of an inline-static member that each .so duplicated; nanobind binds to that
  single storage so libtensorrt_llm.so and the extension module share one value.
- Guard the one-time offset calibration in CacheTransceiver with a mutex to
  avoid a check-and-set race, and add a pre-timestamp pseudo-barrier for the
  process-group path (the MPI path already barriers).
- Reuse a thread_local RNG in generateInstanceId to avoid re-seeding per call.
- Fail loudly with TLLM_CHECK_WITH_INFO when the gen transfer summary file
  cannot be opened.
- Scope TRTLLM_KVCACHE_TIME_OUTPUT_PATH with patch.dict in the two unit tests
  so they no longer leak environment state.

Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
… CSV suffix doc

Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
@chuangz0
chuangz0 force-pushed the feat_cache_transceiver_time_sync branch from 016e3de to 6771229 Compare July 24, 2026 02:29
@chuangz0

Copy link
Copy Markdown
Collaborator Author

/bot run --stage-list "DGX_B200-PyTorch-9, DGX_H100-PyTorch-3"

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
cpp/tensorrt_llm/batch_manager/dataTransceiver.h (1)

271-272: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the new instanceId parameter.

Add an @param instanceId entry to both constructor comments describing its role in instance-scoped transfer output naming.

As per coding guidelines, public C++ interfaces should use Doxygen comments and document their arguments.

Also applies to: 335-336

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tensorrt_llm/batch_manager/dataTransceiver.h` around lines 271 - 272, Add
Doxygen `@param` instanceId documentation to both CacheSender and corresponding
constructor comments, describing that it controls instance-scoped transfer
output naming. Preserve the existing documentation and parameter behavior.

Source: Coding guidelines

tests/unittest/disaggregated/test_sync_transfer_timing.py (1)

17-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Narrow the override type instead of using Any.

_make_transceiver only accepts known override values, but Any disables static checking for them and for subsequent overrides.get(...) results. Define a typed override shape and callable alias, or use a narrower protocol, so invalid test doubles are caught during type checking.

As per coding guidelines, avoid Any and unnecessary type ignores.

Also applies to: 54-61

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/disaggregated/test_sync_transfer_timing.py` around lines 17 -
18, Replace Any in _make_transceiver and its override handling with a typed
override shape and callable alias or narrower protocol that describes the
accepted values and get results. Update the related overrides.get usage around
lines 54–61 so static checking catches invalid test doubles, without adding type
ignores.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unittest/disaggregated/test_perf_logger.py`:
- Around line 82-108: Update the affected perf logger tests, including
test_log_gen_transfer_summary_writes_csv and the test at the referenced second
range, to remove and close every FileHandler before each TemporaryDirectory
context exits. Add a shared teardown/helper that accesses the configured logger,
removes its handlers, closes them, and resets the PerfLogManager singleton as
needed, then invoke it in both tests.

---

Nitpick comments:
In `@cpp/tensorrt_llm/batch_manager/dataTransceiver.h`:
- Around line 271-272: Add Doxygen `@param` instanceId documentation to both
CacheSender and corresponding constructor comments, describing that it controls
instance-scoped transfer output naming. Preserve the existing documentation and
parameter behavior.

In `@tests/unittest/disaggregated/test_sync_transfer_timing.py`:
- Around line 17-18: Replace Any in _make_transceiver and its override handling
with a typed override shape and callable alias or narrower protocol that
describes the accepted values and get results. Update the related overrides.get
usage around lines 54–61 so static checking catches invalid test doubles,
without adding type ignores.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d0a6f39c-cc90-42ad-87ff-a4ab94d73ff5

📥 Commits

Reviewing files that changed from the base of the PR and between 016e3de and 6771229.

📒 Files selected for processing (22)
  • cpp/include/tensorrt_llm/batch_manager/cacheTransceiver.h
  • cpp/include/tensorrt_llm/batch_manager/llmRequest.h
  • cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.h
  • cpp/tensorrt_llm/batch_manager/llmRequest.cpp
  • cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp
  • cpp/tensorrt_llm/nanobind/bindings.cpp
  • cpp/tests/unit_tests/multi_gpu/cacheTransceiverTest.cpp
  • examples/disaggregated/slurm/cache_transceiver_test/README.md
  • examples/disaggregated/slurm/cache_transceiver_test/report.py
  • examples/disaggregated/slurm/cache_transceiver_test/run_cache_transceiver_test.py
  • tensorrt_llm/_torch/disaggregation/native/perf_logger.py
  • tensorrt_llm/_torch/disaggregation/native/transfer.py
  • tensorrt_llm/_torch/disaggregation/transceiver.py
  • tensorrt_llm/_torch/pyexecutor/py_executor.py
  • tests/integration/defs/disaggregated/test_disaggregated.py
  • tests/integration/test_lists/test-db/l0_h100.yml
  • tests/unittest/disaggregated/test_bounce.py
  • tests/unittest/disaggregated/test_cache_transceiver_harness_report.py
  • tests/unittest/disaggregated/test_perf_logger.py
  • tests/unittest/disaggregated/test_sync_transfer_timing.py
🚧 Files skipped from review as they are similar to previous changes (16)
  • tests/integration/test_lists/test-db/l0_h100.yml
  • cpp/tensorrt_llm/nanobind/bindings.cpp
  • cpp/tests/unit_tests/multi_gpu/cacheTransceiverTest.cpp
  • cpp/tensorrt_llm/batch_manager/llmRequest.cpp
  • tensorrt_llm/_torch/pyexecutor/py_executor.py
  • examples/disaggregated/slurm/cache_transceiver_test/README.md
  • tests/unittest/disaggregated/test_bounce.py
  • cpp/include/tensorrt_llm/batch_manager/cacheTransceiver.h
  • cpp/tensorrt_llm/nanobind/batch_manager/bindings.cpp
  • tensorrt_llm/_torch/disaggregation/native/perf_logger.py
  • cpp/include/tensorrt_llm/batch_manager/llmRequest.h
  • cpp/tensorrt_llm/batch_manager/dataTransceiver.cpp
  • examples/disaggregated/slurm/cache_transceiver_test/run_cache_transceiver_test.py
  • tensorrt_llm/_torch/disaggregation/transceiver.py
  • tensorrt_llm/_torch/disaggregation/native/transfer.py
  • cpp/tensorrt_llm/batch_manager/cacheTransceiver.cpp

Comment thread tests/unittest/disaggregated/test_perf_logger.py
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61471 [ run ] triggered by Bot. Commit: 6771229 Link to invocation

Signed-off-by: Chuang Zhu <111838961+chuangz0@users.noreply.github.com>
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61471 [ run ] completed with state SUCCESS. Commit: 6771229
/LLM/main/L0_MergeRequest_PR pipeline #49692 (Partly Tested) completed with status: 'SUCCESS'

CI Report

Link to invocation

@chuangz0

Copy link
Copy Markdown
Collaborator Author

/bot skip --comment "all tests have passed"

@chuangz0
chuangz0 enabled auto-merge (squash) July 24, 2026 06:48
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61525 [ skip ] triggered by Bot. Commit: 300f897 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61525 [ skip ] completed with state SUCCESS. Commit: 300f897
Skipping testing for commit 300f897

Link to invocation

@chuangz0
chuangz0 merged commit 8514fa3 into NVIDIA:main Jul 24, 2026
8 checks passed
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.

5 participants