Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions vllm_spyre_next/tests/test_silu_and_mul.py

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.

Would we still need this file if we reuse the upstream tests?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

We might still need to check for forward_oot dispatch, but other tests can go

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Test SpyreSiluAndMul custom op correctness against a reference implementation.
"""

import pytest
import torch

@pytest.fixture
def dummy_tensor():
return torch.randn(4, 256, dtype=torch.float32) # 2*d=256, so d=128


def mock_forward_native(x):
"""Mock: return ones with output shape (halves last dim)."""
d = x.shape[-1] // 2
return torch.ones(x.shape[:-1] + (d,), dtype=x.dtype, device=x.device)


@pytest.mark.spyre
@pytest.mark.siluandmul
def test_siluandmul_oot_dispatch(default_vllm_config, monkeypatch, dummy_tensor):
"""Verify SiluAndMul OOT registration: class swap and forward_oot routing."""
from vllm.model_executor.layers.activation import SiluAndMul
from vllm_spyre_next.custom_ops.silu_and_mul import SpyreSiluAndMul

layer = SiluAndMul()

# OOT class swap: SiluAndMul.__new__ should produce SpyreSiluAndMul
assert isinstance(layer, SpyreSiluAndMul)

# dispatch_forward should have selected forward_oot
assert layer._forward_method == layer.forward_oot

# Mock forward_native (called by forward_oot) with a known transform
monkeypatch.setattr(layer, "forward_native", mock_forward_native)
out = layer.forward_oot(dummy_tensor)

# Expected: ones with shape [4, 128] (halved last dim)
expected = torch.ones(4, 128, dtype=dummy_tensor.dtype)
assert torch.allclose(out, expected)
24 changes: 23 additions & 1 deletion vllm_spyre_next/vllm_spyre_next/testing/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,28 @@ def sort_key(item: pytest.Item) -> tuple[int, int]:
items.sort(key=sort_key)


def _convert_yaml_value(value):

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is added for future compatibility in case we want to override the torch data types

"""Convert YAML string values to Python objects where appropriate.

Handles torch dtype strings like "torch.half" -> torch.half.
"""
if isinstance(value, str):
import torch

dtype_map = {
"torch.half": torch.half,
"torch.float16": torch.float16,
"torch.bfloat16": torch.bfloat16,
"torch.float32": torch.float32,
"torch.float": torch.float,
"torch.float64": torch.float64,
"torch.double": torch.double,
}
if value in dtype_map:
return dtype_map[value]
return value


@pytest.hookimpl(tryfirst=True)
def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Apply parameter overrides from YAML config."""
Expand Down Expand Up @@ -554,7 +576,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
for i, marker in enumerate(metafunc.definition.own_markers):
if marker.name == "parametrize" and marker.args[0] == po.param_name:
metafunc.definition.own_markers[i] = pytest.mark.parametrize(
po.param_name, list(po.values)
po.param_name, [_convert_yaml_value(v) for v in po.values]
).mark
break

Expand Down
12 changes: 12 additions & 0 deletions vllm_spyre_next/vllm_spyre_next/testing/upstream_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ tests:
# hidden_size: [64]
# block_list:
# - test: "test_fused_rms_norm_quant"
- rel_path: tests/kernels/core/test_activation.py
allow_list:
- test: "test_act_and_mul"
mode: mandatory_pass
tags: [siluandmul, upstream]
params:
allow:
activation: [silu_and_mul]
override:
num_tokens: [7, 83, 1024]
d: [8, 64, 128, 1024]

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is failing for odd values of d. Upstream had no odd values.
The failure comes from torch opcheck (ref) and not the numerical correctness check.

As far as numerical correctness goes, we are good to go

device: [cpu]
- rel_path: tests/models/language/generation/test_common.py
allow_list:
- test: "test_models"
Expand Down
Loading