Skip to content

Commit 733a786

Browse files
committed
Handle FlashInfer workspace size arrays
Signed-off-by: lesj0610 <lesj0610@users.noreply.github.com>
1 parent 99c0875 commit 733a786

2 files changed

Lines changed: 66 additions & 4 deletions

File tree

tests/v1/worker/test_cudagraph_memory_profiling.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ def reset_workspace_buffer(
5151
self.reset_calls += 1
5252

5353

54+
class _FakeWorkspaceSizeArray:
55+
def __init__(self, values: list[int]) -> None:
56+
self.values = values
57+
58+
def __len__(self) -> int:
59+
return len(self.values)
60+
61+
def __getitem__(self, index: int) -> int:
62+
return self.values[index]
63+
64+
5465
def _make_flashinfer_builder(flashinfer_backend):
5566
FlashInferMetadataBuilder = flashinfer_backend.FlashInferMetadataBuilder
5667
builder = FlashInferMetadataBuilder.__new__(FlashInferMetadataBuilder)
@@ -61,6 +72,44 @@ def _make_flashinfer_builder(flashinfer_backend):
6172
return builder
6273

6374

75+
def test_flashinfer_workspace_size_parses_sequence_like_array():
76+
pytest.importorskip("flashinfer")
77+
from vllm.v1.attention.backends import flashinfer as flashinfer_backend
78+
79+
WorkspaceSizes = flashinfer_backend.WorkspaceSizes
80+
81+
assert flashinfer_backend._parse_workspace_sizes(
82+
_FakeWorkspaceSizeArray([1024, 64])
83+
) == WorkspaceSizes(1024, 64)
84+
85+
86+
def test_flashinfer_workspace_size_float_only_keeps_default_int_workspace():
87+
pytest.importorskip("flashinfer")
88+
from vllm.v1.attention.backends import flashinfer as flashinfer_backend
89+
90+
builder = _make_flashinfer_builder(flashinfer_backend)
91+
wrapper = _FakeFlashInferWrapper(int_workspace_bytes=64)
92+
sizes = flashinfer_backend._parse_workspace_sizes(_FakeWorkspaceSizeArray([1024]))
93+
94+
reset_workspace_manager()
95+
init_workspace_manager(torch.device("cpu"))
96+
try:
97+
builder._ensure_flashinfer_wrapper_workspace(wrapper, sizes)
98+
finally:
99+
reset_workspace_manager()
100+
101+
assert wrapper._float_workspace_buffer.numel() == 1024
102+
assert wrapper._int_workspace_buffer.numel() == 64
103+
104+
105+
def test_flashinfer_workspace_size_rejects_invalid_sequence_length():
106+
pytest.importorskip("flashinfer")
107+
from vllm.v1.attention.backends import flashinfer as flashinfer_backend
108+
109+
with pytest.raises(ValueError, match="workspace_size"):
110+
flashinfer_backend._parse_workspace_sizes(_FakeWorkspaceSizeArray([1, 2, 3]))
111+
112+
64113
def test_flashinfer_separate_cudagraph_memory_profile_gate():
65114
pytest.importorskip("flashinfer")
66115
from vllm.v1.attention.backends.flashinfer import FlashInferMetadataBuilder

vllm/v1/attention/backends/flashinfer.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,23 @@ def total_bytes(self) -> int:
112112

113113

114114
def _parse_workspace_sizes(workspace_size: Any) -> WorkspaceSizes:
115-
if isinstance(workspace_size, (tuple, list)):
116-
float_bytes = int(workspace_size[0])
117-
int_bytes = int(workspace_size[1]) if len(workspace_size) > 1 else 0
118-
return WorkspaceSizes(float_bytes, int_bytes)
115+
if not isinstance(workspace_size, (str, bytes)):
116+
try:
117+
workspace_size_len = len(workspace_size)
118+
except TypeError:
119+
pass
120+
else:
121+
if workspace_size_len == 0:
122+
raise ValueError("FlashInfer workspace_size returned an empty result")
123+
if workspace_size_len > 2:
124+
raise ValueError(
125+
"FlashInfer workspace_size must return a scalar or a "
126+
"(float_bytes, int_bytes) pair"
127+
)
128+
float_bytes = int(workspace_size[0])
129+
int_bytes = int(workspace_size[1]) if workspace_size_len == 2 else 0
130+
return WorkspaceSizes(float_bytes, int_bytes)
131+
119132
return WorkspaceSizes(int(workspace_size), 0)
120133

121134

0 commit comments

Comments
 (0)