Skip to content

Revert "feat(comm): preserve all-reduce graph VAs across checkpoint restore" - #3939

Closed
jiahanc wants to merge 1 commit into
mainfrom
revert-3745-schwinns/allreduce-graph-stable-checkpoint-adjacent
Closed

jiahanc wants to merge 1 commit into
mainfrom
revert-3745-schwinns/allreduce-graph-stable-checkpoint-adjacent

Conversation

@jiahanc

@jiahanc jiahanc commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Reverts #3745
There are some hangs, need further investigation

Summary by CodeRabbit

  • Breaking Changes

    • Removed checkpoint preparation and restoration APIs for TRT-LLM AllReduce fusion workspaces.
    • Removed related checkpoint lifecycle documentation and tests.
  • Improvements

    • Updated symmetric-memory allocation and cleanup for improved compatibility across supported CUDA environments.
    • Streamlined TRT-LLM and MNNVL AllReduce workspace initialization and buffer management.
    • Updated legacy MNNVL AllReduce pointer handling for correct buffer selection.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The changes remove TRT-LLM checkpoint lifecycle APIs and related validation, refactor SymmDeviceMemory allocation and cleanup, and update TRT-LLM/MNNVL workspace creation to use symmetric buffers with revised pointer, initialization, teardown, and metadata handling.

Changes

Symmetric-memory workspace changes

Layer / File(s) Summary
Remove checkpoint lifecycle support
flashinfer/comm/allreduce.py, docs/api/comm.rst
Removes TRT-LLM checkpoint methods, symmetric-memory dispatch validation, and corresponding API documentation.
Refactor symmetric-memory allocation
flashinfer/comm/mnnvl.py
Reorganizes multicast checks, handle exchange, unicast/multicast mapping, allocation sizing, access permissions, and destructor cleanup.
Update TRT-LLM workspace allocation
flashinfer/comm/trtllm_ar.py
Uses _alloc_symm_buffer_bytes consistently, removes legacy protocol initialization and synchronization, and drops control_flag_ptr metadata.
Update MNNVL workspace integration
flashinfer/comm/trtllm_mnnvl_ar.py, tests/comm/test_trtllm_mnnvl_allreduce.py
Updates symmetric-buffer initialization, pointer wiring, teardown, dispatch validation, documentation, and the legacy unicast pointer source.

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

Possibly related PRs

Suggested reviewers: yzh119, wenscarl, saltyminty

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is too sparse and does not follow the repository template's sections for related issues, checklist, tests, or reviewer notes. Expand the PR description to include the template sections, especially related issues, tests run, checklist status, and any reviewer notes.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: reverting the all-reduce graph VA checkpoint-restore feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch revert-3745-schwinns/allreduce-graph-stable-checkpoint-adjacent

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.

❤️ Share

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

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request refactors the communication backend by removing the checkpoint/restore lifecycle methods from the TRT-LLM and MNNVL all-reduce workspaces, transitioning instead to torch symmetric memory allocation. Feedback on these changes highlights several critical issues: first, removing torch.cuda.synchronize() before the barrier in the TRT-LLM workspace creation could lead to race conditions during asynchronous initialization; second, performing multicast checks and queries unconditionally in mnnvl.py will cause runtime failures on devices without multicast support when multicast is disabled; and finally, the type annotations for _symm_workspace_refs and symm_refs in trtllm_ar.py are incorrect as they store tuples of tensors and handles rather than just tensors.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 730 to 731
if use_symm_dev_mem:
torch.cuda.synchronize()
comm_backend.barrier() # must sync after create_workspace

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.

high

The asynchronous CUDA kernel trtllm_lamport_initialize is launched to initialize the lamport buffer on the GPU. Without calling torch.cuda.synchronize() before the host-side barrier, other ranks might proceed and attempt to read from this rank's lamport buffer before the initialization kernel has finished executing on the GPU, leading to race conditions or hangs. We should synchronize the CUDA stream before calling the barrier.

Suggested change
if use_symm_dev_mem:
torch.cuda.synchronize()
comm_backend.barrier() # must sync after create_workspace
if use_symm_dev_mem:
torch.cuda.synchronize()
comm_backend.barrier() # must sync after create_workspace

Comment thread flashinfer/comm/mnnvl.py
Comment on lines +1024 to 1033
multicast_supported = checkCudaErrors(
cuda.cuDeviceGetAttribute(
cuda.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MULTICAST_SUPPORTED,
device_idx,
)
)
if multicast_supported == 0:
raise RuntimeError(
"[SymmDeviceMemory] Device does not support multicasting."
)

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.

high

The multicast support check is now performed unconditionally. If enable_multicast is passed as False (for example, on devices that do not support multicasting), this will raise a RuntimeError and prevent SymmDeviceMemory from being initialized at all. We should wrap this check in if enable_multicast: and also store self._enable_multicast = enable_multicast so that helper methods can check it.

Suggested change
multicast_supported = checkCudaErrors(
cuda.cuDeviceGetAttribute(
cuda.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MULTICAST_SUPPORTED,
device_idx,
)
)
if multicast_supported == 0:
raise RuntimeError(
"[SymmDeviceMemory] Device does not support multicasting."
)
self._enable_multicast = enable_multicast
# Check if device supports multicasting
if enable_multicast:
multicast_supported = checkCudaErrors(
cuda.cuDeviceGetAttribute(
cuda.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MULTICAST_SUPPORTED,
device_idx,
)
)
if multicast_supported == 0:
raise RuntimeError(
"[SymmDeviceMemory] Device does not support multicasting."
)

Comment thread flashinfer/comm/mnnvl.py
Comment on lines +1229 to +1242
# Set up multicast properties
mc_prop = cuda.CUmulticastObjectProp()
mc_prop.numDevices = self.group_size
mc_prop.size = self.allocation_size
mc_prop.handleTypes = self._exchanger.handle_type

# Get multicast granularity and adjust allocation size
self._mc_granularity = checkCudaErrors(
cuda.cuMulticastGetGranularity(
mc_prop,
cuda.CUmulticastGranularity_flags.CU_MULTICAST_GRANULARITY_RECOMMENDED,
)
self.allocation_size = round_up(self.allocation_size, self._mc_granularity)
)
self.allocation_size = round_up(self.allocation_size, self._mc_granularity)

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.

high

In _get_allocation_prop, the multicast properties are set up and cuMulticastGetGranularity is called unconditionally. If enable_multicast is False (and multicast is not supported by the device), these calls will fail. We should wrap the multicast setup and granularity query in if self._enable_multicast: to avoid executing them when multicast is disabled.

Suggested change
# Set up multicast properties
mc_prop = cuda.CUmulticastObjectProp()
mc_prop.numDevices = self.group_size
mc_prop.size = self.allocation_size
mc_prop.handleTypes = self._exchanger.handle_type
# Get multicast granularity and adjust allocation size
self._mc_granularity = checkCudaErrors(
cuda.cuMulticastGetGranularity(
mc_prop,
cuda.CUmulticastGranularity_flags.CU_MULTICAST_GRANULARITY_RECOMMENDED,
)
self.allocation_size = round_up(self.allocation_size, self._mc_granularity)
)
self.allocation_size = round_up(self.allocation_size, self._mc_granularity)
self._mc_granularity = alloc_granularity
mc_prop = None
if self._enable_multicast:
# Set up multicast properties
mc_prop = cuda.CUmulticastObjectProp()
mc_prop.numDevices = self.group_size
mc_prop.size = self.allocation_size
mc_prop.handleTypes = self._exchanger.handle_type
# Get multicast granularity and adjust allocation size
self._mc_granularity = checkCudaErrors(
cuda.cuMulticastGetGranularity(
mc_prop,
cuda.CUmulticastGranularity_flags.CU_MULTICAST_GRANULARITY_RECOMMENDED,
)
)
self.allocation_size = round_up(self.allocation_size, self._mc_granularity)

LamportTokenNumThreshold = 16

_symm_workspace_refs: dict[int, list[object]] = {}
_symm_workspace_refs: dict[int, list[torch.Tensor]] = {}

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.

medium

The type annotation for _symm_workspace_refs is updated to dict[int, list[torch.Tensor]]. However, the list actually stores tuples of (tensor, handle) where handle is the symmetric memory handle. This mismatch will cause static type checking failures. It should be annotated as dict[int, list[tuple[torch.Tensor, object]]].

Suggested change
_symm_workspace_refs: dict[int, list[torch.Tensor]] = {}
_symm_workspace_refs: dict[int, list[tuple[torch.Tensor, object]]] = {}

if group is not None
else torch.distributed.group.WORLD.group_name
)
symm_refs: list[torch.Tensor] = []

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.

medium

The type annotation for symm_refs is updated to list[torch.Tensor]. However, the list actually stores tuples of (tensor, handle) returned by _alloc_symm_buffer_bytes. This mismatch will cause static type checking failures. It should be annotated as list[tuple[torch.Tensor, object]].

Suggested change
symm_refs: list[torch.Tensor] = []
symm_refs: list[tuple[torch.Tensor, object]] = []

@jiahanc jiahanc added the run-ci label Jul 13, 2026

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
flashinfer/comm/trtllm_ar.py (1)

617-733: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Initialize the symmetric flag buffer before use

flag_size is still allocated with symm_mem.empty(...) and never cleared here, so the Lamport/barrier flags can start with garbage. Zero that buffer before publishing the workspace; stale flag state can deadlock peers.

🤖 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 `@flashinfer/comm/trtllm_ar.py` around lines 617 - 733, In the workspace
initialization flow, explicitly zero the symmetric flag buffer allocated for
flag_size before publishing workspace_tensor or synchronizing peers. Use the
flag buffer tensor returned by _alloc_symm_buffer_bytes for the flag allocation,
preserving the existing allocation order and barrier behavior.
🧹 Nitpick comments (2)
flashinfer/comm/trtllm_ar.py (2)

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

Type hints for symm_refs/_symm_workspace_refs don't match stored tuples.

_symm_workspace_refs: dict[int, list[torch.Tensor]] (line 434) and symm_refs: list[torch.Tensor] (line 647) are declared to hold torch.Tensor, but symm_refs.append((tensor, handle)) (line 669) stores 2-tuples. The line-range details note this narrowed a previously more permissive list[object] type. Worth correcting for accuracy/static-typing tooling.

♻️ Proposed fix
-_symm_workspace_refs: dict[int, list[torch.Tensor]] = {}
+_symm_workspace_refs: dict[int, list[tuple[torch.Tensor, Any]]] = {}
...
-    symm_refs: list[torch.Tensor] = []
+    symm_refs: list[tuple[torch.Tensor, Any]] = []

Also applies to: 434-434, 642-647

🤖 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 `@flashinfer/comm/trtllm_ar.py` at line 19, Update the type annotations for
symm_refs and _symm_workspace_refs to represent their actual contents:
two-element tuples containing the tensor and handle values appended in the
symmetric workspace flow. Ensure the local declaration and persistent dictionary
annotation are consistent with the tuple shape used by symm_refs.append in the
surrounding method.

571-596: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

Align mem_handles with the actual handle type
_alloc_symm_buffer_bytes returns the symmetric-memory rendezvous handle, so the return annotation and docstring should describe that type instead of List[SymmDeviceMemory].

🤖 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 `@flashinfer/comm/trtllm_ar.py` around lines 571 - 596, Update the return
annotation and docstring for the surrounding allocation function to describe
mem_handles as the symmetric-memory rendezvous handle type returned by
_alloc_symm_buffer_bytes, replacing List[SymmDeviceMemory]. Keep the existing
tuple variants and other return descriptions unchanged.
🤖 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 `@flashinfer/comm/mnnvl.py`:
- Around line 1023-1033: Gate the multicast support check and all
multicast-specific allocation setup in the constructor around enable_multicast,
including cuDeviceGetAttribute and cuMulticastGetGranularity calls. When
enable_multicast is false, skip these operations entirely and preserve a
unicast-only initialization path that does not require multicast-capable
devices.

In `@flashinfer/comm/trtllm_mnnvl_ar.py`:
- Around line 181-183: Update the Lamport initialization in the relevant
workspace setup method to use the reduction dtype when writing the sentinel,
matching the existing cuMemsetD16/cuMemsetD32 behavior in mnnvl.py. Ensure fp16
and bf16 workspaces receive a uniform 0x8000 pattern while fp32 retains the
negative-zero initialization, and preserve the existing synchronization step.

---

Outside diff comments:
In `@flashinfer/comm/trtllm_ar.py`:
- Around line 617-733: In the workspace initialization flow, explicitly zero the
symmetric flag buffer allocated for flag_size before publishing workspace_tensor
or synchronizing peers. Use the flag buffer tensor returned by
_alloc_symm_buffer_bytes for the flag allocation, preserving the existing
allocation order and barrier behavior.

---

Nitpick comments:
In `@flashinfer/comm/trtllm_ar.py`:
- Line 19: Update the type annotations for symm_refs and _symm_workspace_refs to
represent their actual contents: two-element tuples containing the tensor and
handle values appended in the symmetric workspace flow. Ensure the local
declaration and persistent dictionary annotation are consistent with the tuple
shape used by symm_refs.append in the surrounding method.
- Around line 571-596: Update the return annotation and docstring for the
surrounding allocation function to describe mem_handles as the symmetric-memory
rendezvous handle type returned by _alloc_symm_buffer_bytes, replacing
List[SymmDeviceMemory]. Keep the existing tuple variants and other return
descriptions 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 864a4680-a31a-410a-a752-caf00814b99f

📥 Commits

Reviewing files that changed from the base of the PR and between e179800 and 372243a.

📒 Files selected for processing (7)
  • docs/api/comm.rst
  • flashinfer/comm/allreduce.py
  • flashinfer/comm/mnnvl.py
  • flashinfer/comm/trtllm_ar.py
  • flashinfer/comm/trtllm_mnnvl_ar.py
  • tests/comm/test_trtllm_allreduce_checkpoint.py
  • tests/comm/test_trtllm_mnnvl_allreduce.py
💤 Files with no reviewable changes (3)
  • docs/api/comm.rst
  • tests/comm/test_trtllm_allreduce_checkpoint.py
  • flashinfer/comm/allreduce.py

Comment thread flashinfer/comm/mnnvl.py
Comment on lines 1023 to 1033
# Check if device supports multicasting
if self._enable_multicast:
multicast_supported = checkCudaErrors(
cuda.cuDeviceGetAttribute(
cuda.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MULTICAST_SUPPORTED,
device_idx,
)
multicast_supported = checkCudaErrors(
cuda.cuDeviceGetAttribute(
cuda.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MULTICAST_SUPPORTED,
device_idx,
)
)
if multicast_supported == 0:
raise RuntimeError(
"[SymmDeviceMemory] Device does not support multicasting."
)

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the file structure first, then inspect the relevant ranges.
ast-grep outline flashinfer/comm/mnnvl.py --view expanded || true

echo
echo '--- lines 980-1085 ---'
sed -n '980,1085p' flashinfer/comm/mnnvl.py | cat -n

echo
echo '--- lines 1210-1265 ---'
sed -n '1210,1265p' flashinfer/comm/mnnvl.py | cat -n

echo
echo '--- search for enable_multicast and multicast-specific APIs ---'
rg -n "enable_multicast|cuMulticast|multicast_supported|_mc_granularity|_allocate_unicast_buffers|_get_allocation_prop" flashinfer/comm/mnnvl.py

Repository: flashinfer-ai/flashinfer

Length of output: 14662


🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline flashinfer/comm/mnnvl.py --view expanded || true

echo
echo '--- lines 980-1085 ---'
sed -n '980,1085p' flashinfer/comm/mnnvl.py | cat -n

echo
echo '--- lines 1210-1265 ---'
sed -n '1210,1265p' flashinfer/comm/mnnvl.py | cat -n

echo
echo '--- search for enable_multicast and multicast-specific APIs ---'
rg -n "enable_multicast|cuMulticast|multicast_supported|_mc_granularity|_allocate_unicast_buffers|_get_allocation_prop" flashinfer/comm/mnnvl.py

Repository: flashinfer-ai/flashinfer

Length of output: 14662


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1000,1055p' flashinfer/comm/mnnvl.py | cat -n
echo '---'
sed -n '1218,1258p' flashinfer/comm/mnnvl.py | cat -n

Repository: flashinfer-ai/flashinfer

Length of output: 4608


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- lines 1178-1368 ---'
sed -n '1178,1368p' flashinfer/comm/mnnvl.py | cat -n

echo
echo '--- lines 1368-1392 ---'
sed -n '1368,1392p' flashinfer/comm/mnnvl.py | cat -n

Repository: flashinfer-ai/flashinfer

Length of output: 10067


Gate multicast-only setup on enable_multicast
enable_multicast=False still hits cuDeviceGetAttribute(CU_DEVICE_ATTRIBUTE_MULTICAST_SUPPORTED) and cuMulticastGetGranularity(), so construction fails on devices without multicast support instead of falling back to unicast-only mode. Move the support check and multicast allocation setup behind the flag, or split the unicast path entirely.

🤖 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 `@flashinfer/comm/mnnvl.py` around lines 1023 - 1033, Gate the multicast
support check and all multicast-specific allocation setup in the constructor
around enable_multicast, including cuDeviceGetAttribute and
cuMulticastGetGranularity calls. When enable_multicast is false, skip these
operations entirely and preserve a unicast-only initialization path that does
not require multicast-capable devices.

Comment on lines +181 to +183
# lamport initialize tensor to negative zero.
self.tensor.fill_(-0.0)
# Wait until the initialization is done

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.

🩺 Stability & Availability | 🔴 Critical | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== outline trtllm_mnnvl_ar.py ==\n'
ast-grep outline flashinfer/comm/trtllm_mnnvl_ar.py --view expanded || true

printf '\n== outline mnnvl.py ==\n'
ast-grep outline flashinfer/comm/mnnvl.py --view expanded || true

printf '\n== relevant slices trtllm_mnnvl_ar.py ==\n'
sed -n '130,230p' flashinfer/comm/trtllm_mnnvl_ar.py | cat -n

printf '\n== relevant slices mnnvl.py ==\n'
sed -n '1,240p' flashinfer/comm/mnnvl.py | cat -n

Repository: flashinfer-ai/flashinfer

Length of output: 20722


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import struct
import numpy as np

# float32 -0.0 bytes
f32 = np.array([-0.0], dtype=np.float32).tobytes()
print("float32 -0.0 bytes:", f32.hex())

# reinterpret as two fp16 halfwords
h0 = np.frombuffer(f32, dtype=np.float16)
print("reinterpret as fp16:", [hex(x.view(np.uint16)) for x in h0], h0.tolist())

# bfloat16 isn't native in numpy; emulate by taking top 16 bits of float32 words
u32 = int.from_bytes(f32, "little")
print("float32 word:", hex(u32))
print("low16/high16:", hex(u32 & 0xffff), hex((u32 >> 16) & 0xffff))

# If a 4-byte -0.0 is stored and read as bf16 elements from each 16-bit lane,
# lane patterns are the two halves of the 32-bit word.
PY

Repository: flashinfer-ai/flashinfer

Length of output: 292


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '150,210p' flashinfer/comm/trtllm_mnnvl_ar.py | cat -n
printf '\n---\n'
sed -n '1,220p' flashinfer/comm/mnnvl.py | cat -n | sed -n '1,220p'

Repository: flashinfer-ai/flashinfer

Length of output: 11118


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== lamport_initialize in mnnvl.py ==\n'
sed -n '1360,1455p' flashinfer/comm/mnnvl.py | cat -n

printf '\n== search for tensor/buffer dtype usage in trtllm_mnnvl_ar.py ==\n'
rg -n "self\.tensor|dtype|buffer_size_bytes|lamport" flashinfer/comm/trtllm_mnnvl_ar.py

printf '\n== search for MNNVLAllReduceFusionWorkspace instantiation ==\n'
rg -n "MNNVLAllReduceFusionWorkspace\\(" -S .

Repository: flashinfer-ai/flashinfer

Length of output: 11351


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("flashinfer/comm/mnnvl.py")
lines = p.read_text().splitlines()
for i in range(1360, 1456):
    if i <= len(lines):
        print(f"{i:4d}: {lines[i-1]}")
PY

Repository: flashinfer-ai/flashinfer

Length of output: 4379


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "self\.tensor|lamport_initialize|buffer_flags|MNNVLAllReduceFusionWorkspace" flashinfer/comm/trtllm_mnnvl_ar.py

Repository: flashinfer-ai/flashinfer

Length of output: 1915


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '62,130p' flashinfer/comm/trtllm_mnnvl_ar.py | cat -n

Repository: flashinfer-ai/flashinfer

Length of output: 4497


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "_alloc_symm_buffer_bytes|create_tensor_from_cuda_memory|view\\(|fill_\\(" flashinfer/comm -g '*.py'

printf '\n== _alloc_symm_buffer_bytes definition ==\n'
python3 - <<'PY'
from pathlib import Path
p = Path("flashinfer/comm/trtllm_mnnvl_ar.py")
lines = p.read_text().splitlines()
for i, line in enumerate(lines, 1):
    if "_alloc_symm_buffer_bytes" in line:
        start = max(1, i-25)
        end = min(len(lines), i+80)
        for j in range(start, end+1):
            print(f"{j:4d}: {lines[j-1]}")
        break
PY

Repository: flashinfer-ai/flashinfer

Length of output: 7061


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("flashinfer/comm/trtllm_mnnvl_ar.py")
lines = p.read_text().splitlines()
for needle in ["def _alloc_symm_buffer_bytes", "def get_allreduce_mnnvl_workspace", "def trtllm_mnnvl_all_reduce", "def trtllm_mnnvl_fused_allreduce_rmsnorm"]:
    for i, line in enumerate(lines, 1):
        if needle in line:
            print(f"\n== {needle} at line {i} ==")
            start = max(1, i-20)
            end = min(len(lines), i+60)
            for j in range(start, end+1):
                print(f"{j:4d}: {lines[j-1]}")
            break
PY

Repository: flashinfer-ai/flashinfer

Length of output: 11578


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("flashinfer/comm/trtllm_mnnvl_ar.py")
lines = p.read_text().splitlines()
for i, line in enumerate(lines, 1):
    if line.startswith("def _alloc_symm_buffer_bytes"):
        start = max(1, i-10)
        end = min(len(lines), i+120)
        for j in range(start, end+1):
            print(f"{j:4d}: {lines[j-1]}")
        break
PY

Repository: flashinfer-ai/flashinfer

Length of output: 162


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("flashinfer/comm/trtllm_mnnvl_ar.py")
lines = p.read_text().splitlines()
for i, line in enumerate(lines, 1):
    if "def _alloc_symm_buffer_bytes" in line:
        for j in range(i, min(len(lines), i+160)+1):
            print(f"{j:4d}: {lines[j-1]}")
        break
PY

Repository: flashinfer-ai/flashinfer

Length of output: 162


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("flashinfer/comm/trtllm_mnnvl_ar.py")
lines = p.read_text().splitlines()

for i, line in enumerate(lines, 1):
    if "def _alloc_symm_buffer_bytes" in line:
        print(f"== _alloc_symm_buffer_bytes at line {i} ==")
        for j in range(i, min(len(lines), i+140)+1):
            print(f"{j:4d}: {lines[j-1]}")
        break

print("\n== all uses of `tensor` field in MNNVLAllReduceFusionWorkspace ==")
for i, line in enumerate(lines, 1):
    if "self.tensor" in line:
        print(f"{i:4d}: {line}")
PY

Repository: flashinfer-ai/flashinfer

Length of output: 375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "negative zero|0x8000|0x80000000|buffer_flags|poll|wait until|dirty idx|cur idx|lamport" flashinfer/comm/trtllm_mnnvl_ar.py flashinfer/comm/mnnvl.py

Repository: flashinfer-ai/flashinfer

Length of output: 2610


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("flashinfer/comm/trtllm_mnnvl_ar.py")
lines = p.read_text().splitlines()

# print the main protocol methods around the reduction path
for needle in ["def trtllm_mnnvl_all_reduce", "def trtllm_mnnvl_fused_allreduce_add_rmsnorm", "def trtllm_mnnvl_fused_allreduce_rmsnorm"]:
    for i, line in enumerate(lines, 1):
        if needle in line:
            print(f"\n== {needle} at line {i} ==")
            for j in range(i, min(len(lines), i+120)+1):
                print(f"{j:4d}: {lines[j-1]}")
            break
PY

Repository: flashinfer-ai/flashinfer

Length of output: 16636


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("flashinfer/comm/torch_symmetric_memory.py")
lines = p.read_text().splitlines()
for i, line in enumerate(lines, 1):
    if "def _alloc_symm_buffer_bytes" in line:
        print(f"== _alloc_symm_buffer_bytes at line {i} ==")
        for j in range(i, min(len(lines), i+140)+1):
            print(f"{j:4d}: {lines[j-1]}")
        break
PY

Repository: flashinfer-ai/flashinfer

Length of output: 1599


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("flashinfer/comm/torch_symmetric_memory.py")
lines = p.read_text().splitlines()
for i, line in enumerate(lines, 1):
    if "def _alloc_symm_buffer_bytes" in line:
        print(f"== _alloc_symm_buffer_bytes at line {i} ==")
        for j in range(i, min(len(lines), i+160)+1):
            print(f"{j:4d}: {lines[j-1]}")
        break
PY

Repository: flashinfer-ai/flashinfer

Length of output: 1599


Use dtype-aware Lamport initialization here
flashinfer/comm/trtllm_mnnvl_ar.py:181-183 always writes float32 negative zero, so fp16/bf16 workspaces get alternating +0.0/-0.0 halfwords instead of a uniform 0x8000 sentinel. Keep the reduction dtype on the workspace and match the cuMemsetD16/cuMemsetD32 logic already used in flashinfer/comm/mnnvl.py.

🤖 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 `@flashinfer/comm/trtllm_mnnvl_ar.py` around lines 181 - 183, Update the
Lamport initialization in the relevant workspace setup method to use the
reduction dtype when writing the sentinel, matching the existing
cuMemsetD16/cuMemsetD32 behavior in mnnvl.py. Ensure fp16 and bf16 workspaces
receive a uniform 0x8000 pattern while fp32 retains the negative-zero
initialization, and preserve the existing synchronization step.

@jiahanc

jiahanc commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator Author

close because not a real issue

@jiahanc jiahanc closed this Jul 13, 2026
@zhyncs
zhyncs deleted the revert-3745-schwinns/allreduce-graph-stable-checkpoint-adjacent branch August 2, 2026 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants