Skip to content

Commit 93579ae

Browse files
authored
Add common VectorType alias (#762)
* Add common VectorType alias * export VectorAlias * fix
1 parent f5c50f4 commit 93579ae

3 files changed

Lines changed: 418 additions & 7 deletions

File tree

python/flydsl/expr/typing.py

Lines changed: 252 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
as_numeric,
4949
)
5050
from .primitive import *
51+
from .utils import lazy_classattr
5152
from .utils.arith import (
5253
ArithValue,
5354
_to_raw,
@@ -713,6 +714,10 @@ def to_py_value(self):
713714
leaf_iter = iter(leaves)
714715
return self._rebuild_py_value(leaf_iter)
715716

717+
@dsl_loc_tracing
718+
def unpack(self):
719+
return self.to_py_value()
720+
716721
@dsl_loc_tracing
717722
def __getitem__(self, mode):
718723
if isinstance(mode, int):
@@ -1034,7 +1039,7 @@ def __setitem__(self, coord, value):
10341039

10351040
@dsl_loc_tracing
10361041
def load(self):
1037-
return Vector(memref_load_vec(self), self.shape.to_py_value(), self.dtype)
1042+
return memref_load_vec(self)
10381043

10391044
@dsl_loc_tracing
10401045
def store(self, vector):
@@ -1408,9 +1413,9 @@ def __init__(self, value, shape=None, dtype=None):
14081413
vty = ir.VectorType(value.type)
14091414
if shape is None:
14101415
shape = tuple(vty.shape)
1416+
if dtype is None:
14111417
dtype = Numeric.from_ir_type(vty.element_type)
1412-
elif dtype is None:
1413-
dtype = Numeric.from_ir_type(vty.element_type)
1418+
14141419
shape = self._canonical_shape(shape)
14151420
if not all(isinstance(dim, int) for dim in self._flatten_static(shape)):
14161421
raise ValueError("dynamic vector shape is not supported")
@@ -1443,7 +1448,9 @@ def numel(self) -> int:
14431448

14441449
@staticmethod
14451450
def _canonical_shape(shape):
1446-
return (shape,) if isinstance(shape, int) else tuple(shape)
1451+
if isinstance(shape, int):
1452+
return (shape,)
1453+
return tuple(Vector._canonical_shape(dim) if isinstance(dim, (tuple, list)) else dim for dim in shape)
14471454

14481455
@staticmethod
14491456
def _flatten_static(value):
@@ -1566,13 +1573,18 @@ def with_signedness(self, signed):
15661573

15671574
def _wrap_op_result(self, result, shape):
15681575
if isinstance(result, ir.Value) and isinstance(result.type, ir.VectorType):
1569-
return Vector(result, shape, Numeric.from_ir_type(result.type.element_type))
1576+
return Vector(result, shape, self._result_dtype(result.type.element_type))
15701577
if isinstance(result, Numeric):
15711578
return result
15721579
if isinstance(result, ir.Value):
1573-
return Numeric.from_ir_type(result.type)(result)
1580+
return self._result_dtype(result.type)(result)
15741581
return result
15751582

1583+
def _result_dtype(self, elem_type) -> Type[Numeric]:
1584+
if self._dtype.ir_type == elem_type:
1585+
return self._dtype
1586+
return Numeric.from_ir_type(elem_type)
1587+
15761588
def _apply_op(self, method_name, op, other, flip=False):
15771589
lhs = self
15781590
rhs = other
@@ -2003,3 +2015,237 @@ def __class_getitem__(cls, params):
20032015
)
20042016
cls._cache[cache_key] = array_type
20052017
return array_type
2018+
2019+
2020+
# ===========================================================================
2021+
# Vector aliases
2022+
# ===========================================================================
2023+
2024+
2025+
def VectorAlias(alias_dtype: Type[Numeric], lanes: int):
2026+
expected_shape = (lanes,)
2027+
2028+
def __init__(self, value, shape=None, dtype=None):
2029+
if shape is not None and Vector._canonical_shape(shape) != expected_shape:
2030+
raise ValueError(f"{type(self).__name__} expects shape {expected_shape}, got {shape}")
2031+
if dtype is not None and dtype is not alias_dtype:
2032+
raise ValueError(f"{type(self).__name__} expects dtype {alias_dtype.__name__}, got {dtype.__name__}")
2033+
if isinstance(value, (int, float, bool, Numeric)):
2034+
value = Vector.filled(expected_shape, value, alias_dtype)
2035+
elif isinstance(value, (list, tuple)):
2036+
value = Vector.from_elements(value, alias_dtype)
2037+
Vector.__init__(self, value, expected_shape, alias_dtype)
2038+
2039+
return type(
2040+
f"{alias_dtype.__name__}x{lanes}",
2041+
(Vector,),
2042+
{
2043+
"__module__": Vector.__module__,
2044+
"__init__": __init__,
2045+
"ir_type": lazy_classattr(lambda: Vector.make_type(lanes, alias_dtype)),
2046+
},
2047+
)
2048+
2049+
2050+
Float4E2M1FNx2 = VectorAlias(Float4E2M1FN, 2)
2051+
Float4E2M1FNx4 = VectorAlias(Float4E2M1FN, 4)
2052+
Float4E2M1FNx8 = VectorAlias(Float4E2M1FN, 8)
2053+
Float4E2M1FNx16 = VectorAlias(Float4E2M1FN, 16)
2054+
Float4E2M1FNx32 = VectorAlias(Float4E2M1FN, 32)
2055+
2056+
Float8E4M3x1 = VectorAlias(Float8E4M3, 1)
2057+
Float8E4M3x2 = VectorAlias(Float8E4M3, 2)
2058+
Float8E4M3x4 = VectorAlias(Float8E4M3, 4)
2059+
Float8E4M3x8 = VectorAlias(Float8E4M3, 8)
2060+
Float8E4M3x16 = VectorAlias(Float8E4M3, 16)
2061+
2062+
Float8E4M3B11FNUZx1 = VectorAlias(Float8E4M3B11FNUZ, 1)
2063+
Float8E4M3B11FNUZx2 = VectorAlias(Float8E4M3B11FNUZ, 2)
2064+
Float8E4M3B11FNUZx4 = VectorAlias(Float8E4M3B11FNUZ, 4)
2065+
Float8E4M3B11FNUZx8 = VectorAlias(Float8E4M3B11FNUZ, 8)
2066+
Float8E4M3B11FNUZx16 = VectorAlias(Float8E4M3B11FNUZ, 16)
2067+
2068+
Float8E4M3FNx1 = VectorAlias(Float8E4M3FN, 1)
2069+
Float8E4M3FNx2 = VectorAlias(Float8E4M3FN, 2)
2070+
Float8E4M3FNx4 = VectorAlias(Float8E4M3FN, 4)
2071+
Float8E4M3FNx8 = VectorAlias(Float8E4M3FN, 8)
2072+
Float8E4M3FNx16 = VectorAlias(Float8E4M3FN, 16)
2073+
2074+
Float8E4M3FNUZx1 = VectorAlias(Float8E4M3FNUZ, 1)
2075+
Float8E4M3FNUZx2 = VectorAlias(Float8E4M3FNUZ, 2)
2076+
Float8E4M3FNUZx4 = VectorAlias(Float8E4M3FNUZ, 4)
2077+
Float8E4M3FNUZx8 = VectorAlias(Float8E4M3FNUZ, 8)
2078+
Float8E4M3FNUZx16 = VectorAlias(Float8E4M3FNUZ, 16)
2079+
2080+
Float8E5M2x1 = VectorAlias(Float8E5M2, 1)
2081+
Float8E5M2x2 = VectorAlias(Float8E5M2, 2)
2082+
Float8E5M2x4 = VectorAlias(Float8E5M2, 4)
2083+
Float8E5M2x8 = VectorAlias(Float8E5M2, 8)
2084+
Float8E5M2x16 = VectorAlias(Float8E5M2, 16)
2085+
2086+
Float8E8M0FNUx1 = VectorAlias(Float8E8M0FNU, 1)
2087+
Float8E8M0FNUx2 = VectorAlias(Float8E8M0FNU, 2)
2088+
Float8E8M0FNUx4 = VectorAlias(Float8E8M0FNU, 4)
2089+
Float8E8M0FNUx8 = VectorAlias(Float8E8M0FNU, 8)
2090+
Float8E8M0FNUx16 = VectorAlias(Float8E8M0FNU, 16)
2091+
2092+
BFloat16x1 = VectorAlias(BFloat16, 1)
2093+
BFloat16x2 = VectorAlias(BFloat16, 2)
2094+
BFloat16x4 = VectorAlias(BFloat16, 4)
2095+
BFloat16x8 = VectorAlias(BFloat16, 8)
2096+
BFloat16x16 = VectorAlias(BFloat16, 16)
2097+
2098+
Float16x1 = VectorAlias(Float16, 1)
2099+
Float16x2 = VectorAlias(Float16, 2)
2100+
Float16x4 = VectorAlias(Float16, 4)
2101+
Float16x8 = VectorAlias(Float16, 8)
2102+
Float16x16 = VectorAlias(Float16, 16)
2103+
2104+
Float32x1 = VectorAlias(Float32, 1)
2105+
Float32x2 = VectorAlias(Float32, 2)
2106+
Float32x4 = VectorAlias(Float32, 4)
2107+
Float32x8 = VectorAlias(Float32, 8)
2108+
Float64x1 = VectorAlias(Float64, 1)
2109+
Float64x2 = VectorAlias(Float64, 2)
2110+
Float64x4 = VectorAlias(Float64, 4)
2111+
2112+
Int4x2 = VectorAlias(Int4, 2)
2113+
Int4x4 = VectorAlias(Int4, 4)
2114+
Int4x8 = VectorAlias(Int4, 8)
2115+
Int4x16 = VectorAlias(Int4, 16)
2116+
Int4x32 = VectorAlias(Int4, 32)
2117+
Int8x1 = VectorAlias(Int8, 1)
2118+
Int8x2 = VectorAlias(Int8, 2)
2119+
Int8x4 = VectorAlias(Int8, 4)
2120+
Int8x8 = VectorAlias(Int8, 8)
2121+
Int8x16 = VectorAlias(Int8, 16)
2122+
Int16x1 = VectorAlias(Int16, 1)
2123+
Int16x2 = VectorAlias(Int16, 2)
2124+
Int16x4 = VectorAlias(Int16, 4)
2125+
Int16x8 = VectorAlias(Int16, 8)
2126+
Int16x16 = VectorAlias(Int16, 16)
2127+
2128+
Int32x1 = VectorAlias(Int32, 1)
2129+
Int32x2 = VectorAlias(Int32, 2)
2130+
Int32x4 = VectorAlias(Int32, 4)
2131+
Int32x8 = VectorAlias(Int32, 8)
2132+
Int64x1 = VectorAlias(Int64, 1)
2133+
Int64x2 = VectorAlias(Int64, 2)
2134+
Int64x4 = VectorAlias(Int64, 4)
2135+
Int128x1 = VectorAlias(Int128, 1)
2136+
2137+
Uint8x1 = VectorAlias(Uint8, 1)
2138+
Uint8x2 = VectorAlias(Uint8, 2)
2139+
Uint8x4 = VectorAlias(Uint8, 4)
2140+
Uint8x8 = VectorAlias(Uint8, 8)
2141+
Uint8x16 = VectorAlias(Uint8, 16)
2142+
Uint16x1 = VectorAlias(Uint16, 1)
2143+
Uint16x2 = VectorAlias(Uint16, 2)
2144+
Uint16x4 = VectorAlias(Uint16, 4)
2145+
Uint16x8 = VectorAlias(Uint16, 8)
2146+
Uint16x16 = VectorAlias(Uint16, 16)
2147+
Uint32x1 = VectorAlias(Uint32, 1)
2148+
Uint32x2 = VectorAlias(Uint32, 2)
2149+
Uint32x4 = VectorAlias(Uint32, 4)
2150+
Uint32x8 = VectorAlias(Uint32, 8)
2151+
Uint64x1 = VectorAlias(Uint64, 1)
2152+
Uint64x2 = VectorAlias(Uint64, 2)
2153+
Uint64x4 = VectorAlias(Uint64, 4)
2154+
Uint128x1 = VectorAlias(Uint128, 1)
2155+
2156+
__all__ += [
2157+
"VectorAlias",
2158+
"BFloat16x1",
2159+
"BFloat16x2",
2160+
"BFloat16x4",
2161+
"BFloat16x8",
2162+
"BFloat16x16",
2163+
"Float4E2M1FNx2",
2164+
"Float4E2M1FNx4",
2165+
"Float4E2M1FNx8",
2166+
"Float4E2M1FNx16",
2167+
"Float4E2M1FNx32",
2168+
"Float8E4M3x1",
2169+
"Float8E4M3x2",
2170+
"Float8E4M3x4",
2171+
"Float8E4M3x8",
2172+
"Float8E4M3x16",
2173+
"Float8E4M3B11FNUZx1",
2174+
"Float8E4M3B11FNUZx2",
2175+
"Float8E4M3B11FNUZx4",
2176+
"Float8E4M3B11FNUZx8",
2177+
"Float8E4M3B11FNUZx16",
2178+
"Float8E4M3FNx1",
2179+
"Float8E4M3FNx2",
2180+
"Float8E4M3FNx4",
2181+
"Float8E4M3FNx8",
2182+
"Float8E4M3FNx16",
2183+
"Float8E4M3FNUZx1",
2184+
"Float8E4M3FNUZx2",
2185+
"Float8E4M3FNUZx4",
2186+
"Float8E4M3FNUZx8",
2187+
"Float8E4M3FNUZx16",
2188+
"Float8E5M2x1",
2189+
"Float8E5M2x2",
2190+
"Float8E5M2x4",
2191+
"Float8E5M2x8",
2192+
"Float8E5M2x16",
2193+
"Float8E8M0FNUx1",
2194+
"Float8E8M0FNUx2",
2195+
"Float8E8M0FNUx4",
2196+
"Float8E8M0FNUx8",
2197+
"Float8E8M0FNUx16",
2198+
"Float16x1",
2199+
"Float16x2",
2200+
"Float16x4",
2201+
"Float16x8",
2202+
"Float16x16",
2203+
"Float32x1",
2204+
"Float32x2",
2205+
"Float32x4",
2206+
"Float32x8",
2207+
"Float64x1",
2208+
"Float64x2",
2209+
"Float64x4",
2210+
"Int4x2",
2211+
"Int4x4",
2212+
"Int4x8",
2213+
"Int4x16",
2214+
"Int4x32",
2215+
"Int8x1",
2216+
"Int8x2",
2217+
"Int8x4",
2218+
"Int8x8",
2219+
"Int8x16",
2220+
"Int16x1",
2221+
"Int16x2",
2222+
"Int16x4",
2223+
"Int16x8",
2224+
"Int16x16",
2225+
"Int32x1",
2226+
"Int32x2",
2227+
"Int32x4",
2228+
"Int32x8",
2229+
"Int64x1",
2230+
"Int64x2",
2231+
"Int64x4",
2232+
"Int128x1",
2233+
"Uint8x1",
2234+
"Uint8x2",
2235+
"Uint8x4",
2236+
"Uint8x8",
2237+
"Uint8x16",
2238+
"Uint16x1",
2239+
"Uint16x2",
2240+
"Uint16x4",
2241+
"Uint16x8",
2242+
"Uint16x16",
2243+
"Uint32x1",
2244+
"Uint32x2",
2245+
"Uint32x4",
2246+
"Uint32x8",
2247+
"Uint64x1",
2248+
"Uint64x2",
2249+
"Uint64x4",
2250+
"Uint128x1",
2251+
]
Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,44 @@
11
# SPDX-License-Identifier: Apache-2.0
2-
# Copyright (c) 2025 FlyDSL Project Contributors
2+
# Copyright (c) 2026 FlyDSL Project Contributors
3+
4+
from typing import Any, Callable
35

46
from .print_typst import print_typst
57

68
__all__ = [
79
"print_typst",
10+
"lazy_classattr",
811
]
12+
13+
14+
class lazy_classattr:
15+
"""A class-level attribute computed lazily by a zero-arg function.
16+
17+
Reading the attribute on the class (``Owner.attr``) or on an instance calls
18+
``fn()`` and returns its result; nothing is cached, so each access re-runs
19+
``fn``.
20+
21+
Two reasons it is a descriptor rather than a ``@property`` on a metaclass:
22+
23+
* **Deferral is required, caching is wrong.** It exists for values that can
24+
only be built inside a transient context (e.g. an MLIR type, valid only
25+
under the active ``ir.Context``). Caching the first result would leak it
26+
into later contexts, so ``__get__`` recomputes every time.
27+
* **The metaclass route is unavailable.** It is meant for classes whose
28+
metaclass cannot be subclassed (such as ``ir.Value``), which rules out
29+
hosting a metaclass property; a plain descriptor in the class dict still
30+
fires on class access.
31+
"""
32+
33+
def __init__(self, fn: Callable[[], Any]):
34+
self._fn = fn
35+
self._name = "<unnamed>"
36+
37+
def __set_name__(self, owner, name):
38+
self._name = name
39+
40+
def __get__(self, obj, owner=None):
41+
return self._fn()
42+
43+
def __repr__(self):
44+
return f"<{type(self).__name__} {self._name!r}>"

0 commit comments

Comments
 (0)