forked from tile-ai/TileOPs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworkload_base.py
More file actions
82 lines (58 loc) · 2.56 KB
/
Copy pathworkload_base.py
File metadata and controls
82 lines (58 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
"""Base classes for workload definitions shared between tests and benchmarks.
WorkloadBase defines the contract: gen_inputs() for input generation.
FixtureMeta / FixtureBase provide reusable pytest parametrize decorators.
Correctness-only logic (ref_program, check, tolerances) stays in tests/.
"""
from abc import ABC, abstractmethod
from typing import Any, Callable, TypeVar
import torch
_F = TypeVar("_F", bound=Callable[..., Any])
from tileops.utils import get_backend_name
class WorkloadBase(ABC):
"""Abstract base for workload definitions (input generation + parameters).
Subclass must implement gen_inputs().
Used by both tests (via TestBase) and benchmarks (via BenchmarkBase).
Correctness-only methods (ref_program, check, tolerances) belong in
tests/ — not here.
"""
@abstractmethod
def gen_inputs(self) -> tuple[Any, ...]:
raise NotImplementedError
class RandnTest(WorkloadBase):
"""Workload base for ops whose inputs are generated via ``torch.randn``."""
def __init__(self, shape: tuple, dtype: torch.dtype):
self.shape = shape
self.dtype = dtype
def gen_inputs(self) -> tuple[torch.Tensor]:
x = torch.randn(*self.shape, dtype=self.dtype, device=get_backend_name())
return (x,)
class FixtureMeta(type):
"""Metaclass that makes Fixture subclasses usable as @decorators.
Usage:
class MyFixture(FixtureBase):
@classmethod
def get_params(cls):
import pytest
return [("a, b", [
pytest.param(1, 2, marks=pytest.mark.smoke),
])]
@MyFixture
def test_something(a, b): ...
PARAMS may also be set as a plain class variable (list) for backwards
compatibility when pytest is already importable at module scope.
"""
def __call__(cls, fn: _F) -> _F:
import pytest # lazy import: pytest is only needed when applying parametrize decorators
params = cls.get_params() if hasattr(cls, "get_params") else cls.PARAMS
for names, values in reversed(params):
fn = pytest.mark.parametrize(names, values)(fn)
return fn
class FixtureBase(metaclass=FixtureMeta):
"""Base class for reusable parametrize decorators.
Subclass and set PARAMS (plain list) or override get_params() (classmethod
that lazily imports pytest) to provide a list of (names_str, values_list)
tuples.
- Single entry with multiple param names -> explicit combinations
- Multiple entries each with one param name -> cross-product
"""
PARAMS = []