[prototype] Approach 3: PartialTypeSpec lazy generic types (vs Stage-0)#66
[prototype] Approach 3: PartialTypeSpec lazy generic types (vs Stage-0)#66havogt wants to merge 1 commit into
Conversation
… types Experiment for design comparison vs Stage-0 (GridTools#2660). NOT for merge. Reverts FieldType.dtype to the concrete ScalarType | ListType and expresses all dtype genericity through a separate PartialTypeSpec wrapper (target type-tag + partial field values, some of which may be TypeVarType). Specialization substitutes the bound vars and materializes a real concrete FieldType, so the IR/backend never observes a TypeVarType and every Stage-0 narrowing assert/cast is removed. partial_type_info.py: bind / substitute / specialize / is_generic over PartialTypeSpec. _approach3_deduction_sketch.py: illustrative deduction-impact sketch only (not imported/wired).
|
Independent re-verification: |
|
|
||
| def is_generic(type_: Any) -> bool: | ||
| """A `PartialTypeSpec` (or a structure containing one / a bare `TypeVarType`) is generic.""" | ||
| return next(_walk_typevars(type_), None) is not None |
There was a problem hiding this comment.
| return next(_walk_typevars(type_), None) is not None | |
| return isinstance(type_, (ts.PartialTypeSpec, ts.TypeVarType)) |
| type_spec: ts.TypeSpec, new_scalar_kind: ts.ScalarKind | ||
| ) -> ts.ScalarType | ts.FieldType: | ||
| if isinstance(type_spec, ts.PartialTypeSpec) and type_spec.target is ts.FieldType: | ||
| fields = dict(type_spec.fields) |
There was a problem hiding this comment.
I think making ts.PartialTypeSpec a proxy for all concrete fields would be nice and I don't see any major down sides. Could even work for properties / member functions (if needed with an opt-in mechanism like def fun(self: Self | PartialTypeSpec[Self]): ...).
| @@ -0,0 +1,156 @@ | |||
| # GT4Py - GridTools Framework | |||
There was a problem hiding this comment.
The implementations here are terrible, I doubt they help in assessing the value of this approach in this area (The changes in [_approach3_deduction_sketch.py](https://github.com/havogt/gt4py/pull/66/changes#diff-0e89c4ea0389924f1639bc19be9d88d68abd8841c40f33c03e6640eb28f4a90a) are though). is_generic for example is completely off.
This branch is one of four explored alternatives to Stage-0's handling of dtype-generic
operators. It exists so the diff against the Stage-0 branch (
dtype-generics-2-type-system,base of GridTools#2660) is reviewable. Do not merge.
Problem being explored
Stage-0 widened
FieldType.dtypetoScalarType | ListType | TypeVarType. Becausetype_specifications.pyis shared between the frontend and the IR/backend, that wideningforces ~15-20 defensive
assert isinstance(dtype, (ScalarType, ListType))narrowings acrossiterator/+program_processors/(dace dominates). The invariant "noTypeVarTypereachesGTIR" is real (monomorphization) but unenforced by the type system.
What Approach 3 does
FieldType.dtypeto the concreteScalarType | ListType— the existingconcrete type system (and the entire IR/backend) is untouched, and every Stage-0 narrowing
assert/cast is removed (see the
dace/lowering/*andglobal_tmps.pyhunks).PartialTypeSpec(target, fields)wrapper: a type-tag (
target: type[TypeSpec]) plus partial field values, some of which maybe a
TypeVarType. The IR/backend never sees it.FieldType—so GTIR only ever observes concrete types. eve now runtime-rejects
FieldType(dtype=TypeVarType),turning the invariant into an enforced fact rather than a comment.
Files
type_specifications.pyFieldType.dtypeto concrete; addPartialTypeSpecpartial_type_info.py(new)bind/substitute/specialize/is_genericoverPartialTypeSpectype_info.pydace/lowering/*,global_tmps.py_approach3_deduction_sketch.py(new)The tradeoff (vs Stage-0 and the inverse-subclass alternative)
TypeVarTypereferences initerator/+program_processors/. Cache keys safe (PartialTypeSpec.content_hashis deterministic andcross-process-stable; serializes
targetby qualified class name).structurally still a
FieldType, so every deduction site inherits it for free). Approach 3distributes it: ~15-25 frontend type-deduction sites that match-and-reconstruct a field
each need a parallel
case ts.PartialTypeSpec(...)arm, plus a permanent second representationof "a field."
_approach3_deduction_sketch.pyillustrates that.dimsis justanother slot value, no new mechanism.
Validation
Reported by the prototype run:
uv run mypy src/clean (358 files); type_system unit + ffrontunit tests pass. Independent re-verification of
mypy src/is in progress; result will be addedas a comment.