From ab2641dc32418b92d4bf916b5a680a1435ca11ad Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Fri, 5 Dec 2025 10:10:33 +0200 Subject: [PATCH 01/12] feat(typing): mark expr as positional-only in more mappers --- loopy/symbolic.py | 222 +++++++++++++++++++++++----------------------- 1 file changed, 113 insertions(+), 109 deletions(-) diff --git a/loopy/symbolic.py b/loopy/symbolic.py index ba6d71a80..b69505112 100644 --- a/loopy/symbolic.py +++ b/loopy/symbolic.py @@ -289,21 +289,21 @@ class UncachedIdentityMapper(UncachedIdentityMapperBase[P], class PartialEvaluationMapper( EvaluationMapperBase[Expression], IdentityMapperMixin[[]]): @override - def map_variable(self, expr: p.Variable) -> Expression: + def map_variable(self, expr: p.Variable, /) -> Expression: return expr @override def map_common_subexpression_uncached( - self, expr: p.CommonSubexpression) -> Expression: + self, expr: p.CommonSubexpression, /) -> Expression: return type(expr)(self.rec(expr.child), expr.prefix, expr.scope) class WalkMapperMixin(WalkMapperBase[P]): - def map_literal(self, expr: Literal, + def map_literal(self, expr: Literal, /, *args: P.args, **kwargs: P.kwargs) -> None: self.visit(expr, *args, **kwargs) - def map_array_literal(self, expr: ArrayLiteral, + def map_array_literal(self, expr: ArrayLiteral, /, *args: P.args, **kwargs: P.kwargs) -> None: if not self.visit(expr, *args, **kwargs): return @@ -311,22 +311,22 @@ def map_array_literal(self, expr: ArrayLiteral, for ch in expr.children: self.rec(ch, *args, **kwargs) - def map_group_hw_index(self, expr: GroupHardwareAxisIndex | RuleArgument, + def map_group_hw_index(self, expr: GroupHardwareAxisIndex | RuleArgument, /, *args: P.args, **kwargs: P.kwargs) -> None: self.visit(expr, *args, **kwargs) - def map_local_hw_index(self, expr: LocalHardwareAxisIndex, + def map_local_hw_index(self, expr: LocalHardwareAxisIndex, /, *args: P.args, **kwargs: P.kwargs) -> None: self.visit(expr, *args, **kwargs) - def map_reduction(self, expr: Reduction, + def map_reduction(self, expr: Reduction, /, *args: P.args, **kwargs: P.kwargs) -> None: if not self.visit(expr, *args, **kwargs): return self.rec(expr.expr, *args, **kwargs) - def map_type_cast(self, expr: TypeCast, + def map_type_cast(self, expr: TypeCast, /, *args: P.args, **kwargs: P.kwargs) -> None: if not self.visit(expr, *args, **kwargs): return @@ -335,11 +335,11 @@ def map_type_cast(self, expr: TypeCast, map_tagged_variable: Callable[Concatenate[Self, TaggedVariable, P], None] = WalkMapperBase.map_variable - def map_loopy_function_identifier(self, expr: FunctionIdentifier, + def map_loopy_function_identifier(self, expr: FunctionIdentifier, /, *args: P.args, **kwargs: P.kwargs) -> None: self.visit(expr, *args, **kwargs) - def map_linear_subscript(self, expr: LinearSubscript, + def map_linear_subscript(self, expr: LinearSubscript, /, *args: P.args, **kwargs: P.kwargs) -> None: if not self.visit(expr, *args, **kwargs): return @@ -352,7 +352,7 @@ def map_linear_subscript(self, expr: LinearSubscript, map_rule_argument: Callable[Concatenate[Self, RuleArgument, P], None] = map_group_hw_index - def map_sub_array_ref(self, expr: SubArrayRef, + def map_sub_array_ref(self, expr: SubArrayRef, /, *args: P.args, **kwargs: P.kwargs): if not self.visit(expr, *args, **kwargs): return @@ -360,7 +360,7 @@ def map_sub_array_ref(self, expr: SubArrayRef, self.rec(expr.swept_inames, *args, **kwargs) self.rec(expr.subscript, *args, **kwargs) - def map_resolved_function(self, expr: ResolvedFunction, + def map_resolved_function(self, expr: ResolvedFunction, /, *args: P.args, **kwargs: P.kwargs): if not self.visit(expr, *args, **kwargs): return @@ -388,7 +388,7 @@ class CallbackMapper(IdentityMapperMixin[P], class CombineMapper(CombineMapperBase[ResultT, P]): - def map_reduction(self, expr: Reduction, + def map_reduction(self, expr: Reduction, /, *args: P.args, **kwargs: P.kwargs) -> ResultT: return self.rec(expr.expr, *args, **kwargs) @@ -396,7 +396,7 @@ def map_type_cast(self, expr: TypeCast, /, *args: P.args, **kwargs: P.kwargs) -> ResultT: return self.rec(expr.child, *args, **kwargs) - def map_sub_array_ref(self, expr: SubArrayRef, + def map_sub_array_ref(self, expr: SubArrayRef, /, *args: P.args, **kwargs: P.kwargs) -> ResultT: return self.combine(( self.rec(expr.subscript, *args, **kwargs), @@ -404,13 +404,13 @@ def map_sub_array_ref(self, expr: SubArrayRef, self.rec(idx, *args, **kwargs) for idx in expr.swept_inames)))) - def map_linear_subscript(self, expr: LinearSubscript, + def map_linear_subscript(self, expr: LinearSubscript, /, *args: P.args, **kwargs: P.kwargs) -> ResultT: return self.combine( [self.rec(expr.aggregate, *args, **kwargs), self.rec(expr.index, *args, **kwargs)]) - def map_fortran_division(self, expr: FortranDivision, + def map_fortran_division(self, expr: FortranDivision, /, *args: P.args, **kwargs: P.kwargs) -> ResultT: return self.combine(( self.rec(expr.numerator, *args, **kwargs), @@ -420,7 +420,7 @@ def map_fortran_division(self, expr: FortranDivision, class SubstitutionMapper( SubstitutionMapperBase, IdentityMapperMixin[[]]): def map_common_subexpression_uncached( - self, expr: p.CommonSubexpression) -> Expression: + self, expr: p.CommonSubexpression, /) -> Expression: return type(expr)(self.rec(expr.child), expr.prefix, expr.scope) @@ -429,24 +429,24 @@ class ConstantFoldingMapper(ConstantFoldingMapperBase, IdentityMapperMixin[[]]): class StringifyMapper(StringifyMapperBase[[]]): - def map_literal(self, expr: Literal, enclosing_prec: int) -> str: + def map_literal(self, expr: Literal, /, enclosing_prec: int) -> str: return expr.s - def map_array_literal(self, expr: ArrayLiteral, enclosing_prec: int) -> str: + def map_array_literal(self, expr: ArrayLiteral, /, enclosing_prec: int) -> str: from pymbolic.mapper.stringifier import PREC_NONE children = ", ".join(self.rec(ch, PREC_NONE) for ch in expr.children) return f"{{{children}}}" - def map_group_hw_index(self, expr: GroupHardwareAxisIndex, + def map_group_hw_index(self, expr: GroupHardwareAxisIndex, /, enclosing_prec: int) -> str: return f"grp.{expr.axis}" - def map_local_hw_index(self, expr: LocalHardwareAxisIndex, + def map_local_hw_index(self, expr: LocalHardwareAxisIndex, /, enclosing_prec: int) -> str: return f"loc.{expr.axis}" - def map_reduction(self, expr: Reduction, enclosing_prec: int) -> str: + def map_reduction(self, expr: Reduction, /, enclosing_prec: int) -> str: from pymbolic.mapper.stringifier import PREC_NONE simul = "simul_" if expr.allow_simultaneous else "" @@ -454,10 +454,11 @@ def map_reduction(self, expr: Reduction, enclosing_prec: int) -> str: child = self.rec(expr.expr, PREC_NONE) return f"{simul}reduce({expr.operation}, [{inames}], {child})" - def map_tagged_variable(self, expr: TaggedVariable, enclosing_prec: int) -> str: + def map_tagged_variable(self, expr: TaggedVariable, /, enclosing_prec: int) -> str: return f"{expr.name}${{{', '.join(str(t) for t in expr.tags)}}}" - def map_linear_subscript(self, expr: LinearSubscript, enclosing_prec: int) -> str: + def map_linear_subscript(self, expr: LinearSubscript, /, + enclosing_prec: int) -> str: from pymbolic.mapper.stringifier import PREC_CALL, PREC_NONE return self.parenthesize_if_needed( @@ -467,32 +468,34 @@ def map_linear_subscript(self, expr: LinearSubscript, enclosing_prec: int) -> st enclosing_prec, PREC_CALL) def map_loopy_function_identifier( - self, expr: FunctionIdentifier, enclosing_prec: int) -> str: + self, expr: FunctionIdentifier, /, enclosing_prec: int) -> str: from dataclasses import fields initargs = ", ".join(f"{getattr(expr, fld.name)}" for fld in fields(expr)) return f"{type(expr).__name__}<{initargs}>" - def map_rule_argument(self, expr: RuleArgument, enclosing_prec: int) -> str: + def map_rule_argument(self, expr: RuleArgument, /, enclosing_prec: int) -> str: return f"" - def map_type_cast(self, expr: TypeCast, enclosing_prec: int) -> str: + def map_type_cast(self, expr: TypeCast, /, enclosing_prec: int) -> str: from pymbolic.mapper.stringifier import PREC_NONE child = self.rec(expr.child, PREC_NONE) return f"cast({expr.type!r}, {child})" - def map_resolved_function(self, expr: ResolvedFunction, enclosing_prec: int) -> str: + def map_resolved_function(self, expr: ResolvedFunction, /, + enclosing_prec: int) -> str: # underlining a resolved call return "\u0332".join(str(expr.function)) - def map_sub_array_ref(self, expr: SubArrayRef, enclosing_prec: int) -> str: + def map_sub_array_ref(self, expr: SubArrayRef, /, enclosing_prec: int) -> str: inames = ",".join(self.rec(iname, enclosing_prec) for iname in expr.swept_inames) subscr = self.rec(expr.subscript, enclosing_prec) return f"[{inames}]: {subscr}" - def map_fortran_division(self, expr: FortranDivision, enclosing_prec: int) -> str: + def map_fortran_division(self, expr: FortranDivision, /, + enclosing_prec: int) -> str: from pymbolic.mapper.stringifier import PREC_NONE result = self.map_quotient(expr, PREC_NONE) # pyright: ignore[reportArgumentType] return f"[FORTRANDIV]({result})" @@ -501,7 +504,7 @@ def map_fortran_division(self, expr: FortranDivision, enclosing_prec: int) -> st class UnidirectionalUnifier(UnidirectionalUnifierBase): def map_reduction( self, - expr: Reduction, + expr: Reduction, /, other: Expression, urecs: Sequence[UnificationRecord]) -> Sequence[UnificationRecord]: if not isinstance(other, type(expr)): @@ -515,7 +518,7 @@ def map_reduction( def map_tagged_variable( self, - expr: TaggedVariable, + expr: TaggedVariable, /, other: Expression, urecs: Sequence[UnificationRecord]) -> Sequence[UnificationRecord]: new_uni_record = self.unification_record_from_equation(expr, other) @@ -536,36 +539,36 @@ def map_tagged_variable( class DependencyMapper(DependencyMapperBase[P]): - def map_group_hw_index(self, expr: GroupHardwareAxisIndex, + def map_group_hw_index(self, expr: GroupHardwareAxisIndex, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: return set() - def map_local_hw_index(self, expr: LocalHardwareAxisIndex, + def map_local_hw_index(self, expr: LocalHardwareAxisIndex, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: return set() @override - def map_call(self, expr: p.Call, + def map_call(self, expr: p.Call, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: # Loopy does not have first-class functions. Do not descend # into 'function' attribute of Call. return self.rec(expr.parameters, *args, **kwargs) - def map_reduction(self, expr: Reduction, + def map_reduction(self, expr: Reduction, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: deps = self.rec(expr.expr, *args, **kwargs) return deps - {p.Variable(iname) for iname in expr.inames} - def map_tagged_variable(self, expr: TaggedVariable, + def map_tagged_variable(self, expr: TaggedVariable, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: return {expr} def map_loopy_function_identifier( - self, expr: FunctionIdentifier, + self, expr: FunctionIdentifier, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: return set() - def map_sub_array_ref(self, expr: SubArrayRef, + def map_sub_array_ref(self, expr: SubArrayRef, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: deps = self.rec(expr.subscript, *args, **kwargs) return deps - set(expr.swept_inames) @@ -573,20 +576,20 @@ def map_sub_array_ref(self, expr: SubArrayRef, map_linear_subscript: Callable[Concatenate[Self, LinearSubscript, P], Dependencies] = DependencyMapperBase.map_subscript - def map_type_cast(self, expr: TypeCast, + def map_type_cast(self, expr: TypeCast, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: return self.rec(expr.child, *args, **kwargs) - def map_resolved_function(self, expr: ResolvedFunction, + def map_resolved_function(self, expr: ResolvedFunction, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: return self.rec(expr.function, *args, **kwargs) - def map_literal(self, expr: Literal, + def map_literal(self, expr: Literal, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: return set() @override - def map_call_with_kwargs(self, expr: p.CallWithKwargs, + def map_call_with_kwargs(self, expr: p.CallWithKwargs, /, *args: P.args, **kwargs: P.kwargs) -> Dependencies: # See https://github.com/inducer/loopy/pull/323 raise NotImplementedError @@ -609,14 +612,14 @@ def __call__(self, expr: Expression) -> Expression: return super().__call__(expr) @override - def map_variable(self, expr: p.Variable) -> Expression: + def map_variable(self, expr: p.Variable, /) -> Expression: if expr.name in self.rules: return self.map_subst_rule(expr.name, self.rules[expr.name], ()) else: return super().map_variable(expr) @override - def map_call(self, expr: p.Call) -> Expression: + def map_call(self, expr: p.Call, /) -> Expression: assert isinstance(expr.function, p.Variable | ResolvedFunction) if expr.function.name in self.rules: assert isinstance(expr.function.name, str) @@ -629,7 +632,7 @@ def map_call(self, expr: p.Call) -> Expression: def map_subst_rule(self, name: str, - rule: SubstitutionRule, + rule: SubstitutionRule, /, arguments: Sequence[Expression], ) -> Expression: if len(rule.arguments) != len(arguments): @@ -1006,7 +1009,7 @@ class EvaluatorWithDeficientContext(PartialEvaluationMapper): """ @override - def map_variable(self, expr: p.Variable) -> Expression: + def map_variable(self, expr: p.Variable, /) -> Expression: if expr.name in self.context: return self.context[expr.name] else: @@ -1027,11 +1030,11 @@ def combine(self, values: Iterable[bool]) -> bool: return any(values) @override - def map_variable(self, expr: p.Variable) -> bool: + def map_variable(self, expr: p.Variable, /) -> bool: return expr in self.variables_to_search @override - def map_constant(self, expr: object) -> bool: + def map_constant(self, expr: object, /) -> bool: return False @@ -1041,7 +1044,7 @@ class SweptInameStrideCollector(CoefficientCollectorBase): """ @override - def map_algebraic_leaf(self, expr: p.AlgebraicLeaf) -> CoeffsT: + def map_algebraic_leaf(self, expr: p.AlgebraicLeaf, /) -> CoeffsT: # subscripts that are not involved in :attr:`target_names` are treated # as constants. if isinstance(expr, p.Subscript) and ( @@ -1159,7 +1162,7 @@ def __init__( @override def map_reduction( self, - expr: Reduction, *args: P.args, **kwargs: P.kwargs + expr: Reduction, /, *args: P.args, **kwargs: P.kwargs ) -> Dependencies: self.reduction_inames.update(expr.inames) return super().map_reduction(expr, *args, **kwargs) @@ -1195,23 +1198,23 @@ def combine(self, values: Iterable[Set[str]]) -> Set[str]: return frozenset(result) @override - def map_sub_array_ref(self, expr: SubArrayRef) -> Set[str]: + def map_sub_array_ref(self, expr: SubArrayRef, /) -> Set[str]: return frozenset({iname.name for iname in expr.swept_inames}) - @override - def map_constant( + def _map_no_swept_inames( self, expr: ( object | p.Variable | p.FunctionSymbol | p.NaN - | TaggedVariable | TypeCast | ResolvedFunction)) -> Set[str]: + | TaggedVariable | TypeCast | ResolvedFunction), /) -> Set[str]: return frozenset() - map_variable: Callable[[Self, p.Variable], Set[str]] = map_constant - map_function_symbol: Callable[[Self, p.FunctionSymbol], Set[str]] = map_constant - map_nan: Callable[[Self, p.NaN], Set[str]] = map_constant - map_tagged_variable: Callable[[Self, TaggedVariable], Set[str]] = map_constant - map_type_cast: Callable[[Self, TypeCast], Set[str]] = map_constant - map_resolved_function: Callable[[Self, ResolvedFunction], Set[str]] = map_constant + map_constant: Callable[[Self, object], Set[str]] = _map_no_swept_inames + map_variable: Callable[[Self, p.Variable], Set[str]] = _map_no_swept_inames + map_function_symbol: Callable[[Self, p.FunctionSymbol], Set[str]] = _map_no_swept_inames # noqa: E501 + map_nan: Callable[[Self, p.NaN], Set[str]] = _map_no_swept_inames + map_tagged_variable: Callable[[Self, TaggedVariable], Set[str]] = _map_no_swept_inames # noqa: E501 + map_type_cast: Callable[[Self, TypeCast], Set[str]] = _map_no_swept_inames + map_resolved_function: Callable[[Self, ResolvedFunction], Set[str]] = _map_no_swept_inames # noqa: E501 def get_sub_array_ref_swept_inames(expr: SubArrayRef) -> Set[str]: @@ -1283,7 +1286,7 @@ def __init__(self, renames: dict[str, str]) -> None: super().__init__() @override - def map_call(self, expr: p.Call) -> Expression: + def map_call(self, expr: p.Call, /) -> Expression: if not isinstance(expr.function, p.Variable): return super().map_call(expr) @@ -1301,7 +1304,7 @@ def map_call(self, expr: p.Call) -> Expression: return type(expr)(sym, tuple(self.rec(child) for child in expr.parameters)) @override - def map_variable(self, expr: p.Variable) -> Expression: + def map_variable(self, expr: p.Variable, /) -> Expression: name, tags = parse_tagged_name(expr) new_name = self.renames.get(name) @@ -1472,7 +1475,7 @@ def __init__(self, rule_mapping_context: SubstitutionRuleMappingContext) -> None @override def map_variable( - self, expr: p.Variable, expn_state: ExpansionState, + self, expr: p.Variable, /, expn_state: ExpansionState, *args: P.args, **kwargs: P.kwargs ) -> Expression: name, tags = parse_tagged_name(expr) @@ -1483,7 +1486,7 @@ def map_variable( @override def map_call( - self, expr: p.Call, expn_state: ExpansionState, + self, expr: p.Call, /, expn_state: ExpansionState, *args: P.args, **kwargs: P.kwargs ) -> Expression: if not isinstance(expr.function, p.Variable): @@ -1677,7 +1680,8 @@ def within(self, return self._within(kernel, instruction, stack) @override - def map_variable(self, expr: p.Variable, expn_state: ExpansionState) -> Expression: + def map_variable(self, expr: p.Variable, /, + expn_state: ExpansionState) -> Expression: if (expr.name in expn_state.arg_context or not self.within( expn_state.kernel, expn_state.instruction, expn_state.stack)): @@ -1748,7 +1752,7 @@ def map_subst_rule( class VarToTaggedVarMapper(IdentityMapper[[]]): @override - def map_variable(self, expr: p.Variable) -> Expression: + def map_variable(self, expr: p.Variable, /) -> Expression: dollar_idx = expr.name.find("$") if dollar_idx == -1: return expr @@ -1796,7 +1800,7 @@ def _parse_reduction(self, allow_simultaneous=allow_simultaneous) @override - def map_call(self, expr: p.Call) -> Expression: + def map_call(self, expr: p.Call, /) -> Expression: from loopy.library.reduction import parse_reduction_op if not isinstance(expr.function, p.Variable): @@ -1998,7 +2002,7 @@ class CoefficientCollector(CoefficientCollectorBase): CoeffsT] = CoefficientCollectorBase.map_variable @override - def map_subscript(self, expr: p.Subscript) -> CoeffsT: + def map_subscript(self, expr: p.Subscript, /) -> CoeffsT: from loopy.diagnostic import ExpressionNotAffineError raise ExpressionNotAffineError( "cannot gather coefficients -- indirect addressing in use") @@ -2021,15 +2025,15 @@ def combine(self, values: Iterable[Set[p.Subscript]]) -> Set[p.Subscript]: return set(flatten(values)) @override - def map_constant(self, expr: object) -> Set[p.Subscript]: + def map_constant(self, expr: object, /) -> Set[p.Subscript]: return set() @override - def map_algebraic_leaf(self, expr: p.AlgebraicLeaf) -> Set[p.Subscript]: + def map_algebraic_leaf(self, expr: p.AlgebraicLeaf, /) -> Set[p.Subscript]: return set() @override - def map_subscript(self, expr: p.Subscript) -> Set[p.Subscript]: + def map_subscript(self, expr: p.Subscript, /) -> Set[p.Subscript]: assert isinstance(expr.aggregate, p.Variable) if ( @@ -2139,38 +2143,38 @@ def __init__(self, super().__init__(context) @override - def map_constant(self, expr: object) -> isl.PwAff: + def map_constant(self, expr: object, /) -> isl.PwAff: iexpr = int(cast("int", expr)) return self.pw_zero + iexpr @override - def map_min(self, expr: p.Min) -> isl.PwAff: + def map_min(self, expr: p.Min, /) -> isl.PwAff: from functools import reduce return reduce( lambda a, b: a.min(b), (self.rec(ch) for ch in expr.children)) @override - def map_max(self, expr: p.Max) -> isl.PwAff: + def map_max(self, expr: p.Max, /) -> isl.PwAff: from functools import reduce return reduce( lambda a, b: a.max(b), (self.rec(ch) for ch in expr.children)) @override - def map_quotient(self, expr: p.Quotient) -> isl.PwAff: + def map_quotient(self, expr: p.Quotient, /) -> isl.PwAff: raise TypeError( f"true division in '{expr}' not supported for as-pwaff evaluation") @override - def map_floor_div(self, expr: p.FloorDiv) -> isl.PwAff: + def map_floor_div(self, expr: p.FloorDiv, /) -> isl.PwAff: num = self.rec(expr.numerator) denom = self.rec(expr.denominator) return num.div(denom).floor() @override - def map_remainder(self, expr: p.Remainder) -> isl.PwAff: + def map_remainder(self, expr: p.Remainder, /) -> isl.PwAff: num = self.rec(expr.numerator) denom = self.rec(expr.denominator) if not denom.is_cst(): @@ -2183,15 +2187,15 @@ def map_remainder(self, expr: p.Remainder) -> isl.PwAff: return num.mod_val(denom) - def map_literal(self, expr: Literal) -> isl.PwAff: + def map_literal(self, expr: Literal, /) -> isl.PwAff: raise TypeError(f"literal '{expr}' not supported for as-pwaff evaluation") - def map_reduction(self, expr: Reduction) -> isl.PwAff: + def map_reduction(self, expr: Reduction, /) -> isl.PwAff: raise TypeError( f"reduction in '{expr}' not supported for as-pwaff evaluation") @override - def map_call(self, expr: p.Call) -> isl.PwAff: + def map_call(self, expr: p.Call, /) -> isl.PwAff: # FIXME: There are some things here that we could handle, e.g. "abs". raise TypeError(f"call in '{expr}' not supported " "for as-pwaff evaluation") @@ -2310,19 +2314,19 @@ def __init__(self, super().__init__(context) @override - def map_constant(self, expr: object) -> isl.PwQPolynomial: + def map_constant(self, expr: object, /) -> isl.PwQPolynomial: iexpr = int(cast("int", expr)) return self.pw_zero + iexpr @override - def map_quotient(self, expr: p.Quotient) -> isl.PwQPolynomial: + def map_quotient(self, expr: p.Quotient, /) -> isl.PwQPolynomial: raise TypeError( f"true division in '{expr}' not supported " "for as-pwqpoly evaluation") @override - def map_power(self, expr: p.Power) -> isl.PwQPolynomial: + def map_power(self, expr: p.Power, /) -> isl.PwQPolynomial: from numbers import Integral if not isinstance(expr.exponent, Integral): raise TypeError("Only integral powers allowed in pwqpolynomials.") @@ -2520,7 +2524,7 @@ class ConditionExpressionToBooleanOpsExpression(IdentityMapper[[]]): """ @override - def map_comparison(self, expr: p.Comparison) -> Expression: + def map_comparison(self, expr: p.Comparison, /) -> Expression: return expr def _get_expr_neq_0(self, expr: ( @@ -2529,35 +2533,35 @@ def _get_expr_neq_0(self, expr: ( return p.Comparison(expr, "!=", 0) @override - def map_constant(self, expr: object) -> Expression: + def map_constant(self, expr: object, /) -> Expression: return p.Comparison(expr, "!=", 0) @override - def map_variable(self, expr: p.Variable) -> Expression: + def map_variable(self, expr: p.Variable, /) -> Expression: return self._get_expr_neq_0(expr) @override - def map_subscript(self, expr: p.Subscript) -> Expression: + def map_subscript(self, expr: p.Subscript, /) -> Expression: return self._get_expr_neq_0(expr) @override - def map_sum(self, expr: p.Sum) -> Expression: + def map_sum(self, expr: p.Sum, /) -> Expression: return self._get_expr_neq_0(expr) @override - def map_product(self, expr: p.Product) -> Expression: + def map_product(self, expr: p.Product, /) -> Expression: return self._get_expr_neq_0(expr) @override - def map_call(self, expr: p.Call) -> Expression: + def map_call(self, expr: p.Call, /) -> Expression: return self._get_expr_neq_0(expr) @override - def map_power(self, expr: p.Power) -> Expression: + def map_power(self, expr: p.Power, /) -> Expression: return self._get_expr_neq_0(expr) @override - def map_reduction(self, expr: Reduction) -> Expression: + def map_reduction(self, expr: Reduction, /) -> Expression: raise ExpressionToAffineConversionError("cannot (yet) convert reduction " "to affine") @@ -2572,7 +2576,7 @@ class AffineConditionToISLSetMapper(Mapper[isl.Set, []]): space: isl.Space @override - def map_comparison(self, expr: p.Comparison) -> isl.Set: + def map_comparison(self, expr: p.Comparison, /) -> isl.Set: if expr.operator == "!=": return self.rec(p.LogicalNot(p.Comparison(expr.left, "==", expr.right))) @@ -2604,17 +2608,17 @@ def _map_logical_reduce(self, return reduce(f, sets) @override - def map_logical_or(self, expr: p.LogicalOr) -> isl.Set: + def map_logical_or(self, expr: p.LogicalOr, /) -> isl.Set: import operator return self._map_logical_reduce(expr, operator.or_) @override - def map_logical_and(self, expr: p.LogicalAnd) -> isl.Set: + def map_logical_and(self, expr: p.LogicalAnd, /) -> isl.Set: import operator return self._map_logical_reduce(expr, operator.and_) @override - def map_logical_not(self, expr: p.LogicalNot) -> isl.Set: + def map_logical_not(self, expr: p.LogicalNot, /) -> isl.Set: set_ = self.rec(expr.child) return set_.complement() @@ -2702,7 +2706,7 @@ def __init__(self, callback: CallbackType[P]) -> None: super().__init__() @override - def map_reduction(self, expr: Reduction, + def map_reduction(self, expr: Reduction, /, *args: P.args, **kwargs: P.kwargs) -> Expression: result = self.callback(expr, self.rec, *args, **kwargs) if result is None: @@ -2730,15 +2734,15 @@ def combine(self, values: Iterable[Set[str]]) -> Set[str]: return result @override - def map_constant(self, expr: object) -> Set[str]: + def map_constant(self, expr: object, /) -> Set[str]: return set() @override - def map_algebraic_leaf(self, expr: p.AlgebraicLeaf) -> Set[str]: + def map_algebraic_leaf(self, expr: p.AlgebraicLeaf, /) -> Set[str]: return set() @override - def map_subscript(self, expr: p.Subscript) -> Set[str]: + def map_subscript(self, expr: p.Subscript, /) -> Set[str]: idx_vars = DependencyMapper()(expr.index) result: set[str] = set() @@ -2751,7 +2755,7 @@ def map_subscript(self, expr: p.Subscript) -> Set[str]: return result @override - def map_reduction(self, expr: Reduction) -> Set[str]: + def map_reduction(self, expr: Reduction, /) -> Set[str]: result = self.rec(expr.expr) if not (expr.inames_set & result): @@ -2777,7 +2781,7 @@ def __init__(self, unique_var_name_factory: Callable[[], str]) -> None: super().__init__() @override - def map_wildcard(self, expr: p.Wildcard) -> Expression: + def map_wildcard(self, expr: p.Wildcard, /) -> Expression: from pymbolic import var return var(self.unique_var_name_factory()) @@ -2794,7 +2798,7 @@ def __init__(self, which_vars: Collection[str]) -> None: super().__init__() @override - def map_variable(self, expr: p.Variable) -> Expression: + def map_variable(self, expr: p.Variable, /) -> Expression: from pymbolic import var if expr.name in self.which_vars: return var(f"{expr.name}'") @@ -2802,7 +2806,7 @@ def map_variable(self, expr: p.Variable) -> Expression: return expr @override - def map_tagged_variable(self, expr: TaggedVariable) -> Expression: + def map_tagged_variable(self, expr: TaggedVariable, /) -> Expression: if expr.name in self.which_vars: return TaggedVariable(f"{expr.name}'", expr.tags) else: @@ -2960,7 +2964,7 @@ def get_access_range(self, var_name: str) -> isl.Set | None: (not_none(val).range() for val in loops_to_amaps.values())) @override - def map_subscript(self, expr: p.Subscript, inames: Set[str]) -> None: + def map_subscript(self, expr: p.Subscript, /, inames: Set[str]) -> None: domain = self.kernel.get_inames_domain(inames) super().map_subscript(expr, inames) @@ -3010,7 +3014,7 @@ def map_subscript(self, expr: p.Subscript, inames: Set[str]) -> None: @override def map_linear_subscript( self, - expr: LinearSubscript, inames: Set[str] + expr: LinearSubscript, /, inames: Set[str] ) -> None: self.rec(expr.index, inames) @@ -3019,11 +3023,11 @@ def map_linear_subscript( self.bad_subscripts[expr.aggregate.name].append(expr) @override - def map_reduction(self, expr: Reduction, inames: Set[str]) -> None: + def map_reduction(self, expr: Reduction, /, inames: Set[str]) -> None: return WalkMapper.map_reduction(self, expr, inames | set(expr.inames)) @override - def map_sub_array_ref(self, expr: SubArrayRef, inames: Set[str]) -> None: + def map_sub_array_ref(self, expr: SubArrayRef, /, inames: Set[str]) -> None: assert isinstance(expr.subscript.aggregate, p.Variable) arg_name = expr.subscript.aggregate.name if arg_name not in self._var_names: From a22bce739521e85e4b226512ca122e1217fa2ed8 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Fri, 12 Dec 2025 21:36:04 +0200 Subject: [PATCH 02/12] feat(typing): add types to isl_helpers.make_slab --- loopy/isl_helpers.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/loopy/isl_helpers.py b/loopy/isl_helpers.py index 6665ec153..ddcc52334 100644 --- a/loopy/isl_helpers.py +++ b/loopy/isl_helpers.py @@ -1,4 +1,5 @@ """isl helpers""" + from __future__ import annotations @@ -50,13 +51,14 @@ def pw_aff_to_aff(pw_aff: isl.Aff | isl.PwAff) -> isl.Aff: if len(pieces) == 0: raise RuntimeError("PwAff does not have any pieces") + if len(pieces) > 1: _, first_aff = pieces[0] for _, other_aff in pieces[1:]: if not first_aff.plain_is_equal(other_aff): raise NotImplementedError("only single-valued piecewise affine " "expressions are supported here--encountered " - "multi-valued expression '%s'" % pw_aff) + f"multi-valued expression '{pw_aff}'") return first_aff @@ -65,7 +67,11 @@ def pw_aff_to_aff(pw_aff: isl.Aff | isl.PwAff) -> isl.Aff: # {{{ make_slab -def make_slab(space, iname, start, stop, iname_multiplier=1): +def make_slab(space: isl.Space, + iname: str | tuple[dim_type, int], + start: isl.Aff | isl.PwAff | ArithmeticExpression, + stop: isl.Aff | isl.PwAff | ArithmeticExpression, + iname_multiplier: int = 1) -> isl.BasicSet: """ Returns an instance of :class:`islpy._isl.BasicSet`, which satisfies the constraint ``start <= iname_multiplier*iname < stop``. @@ -245,8 +251,8 @@ def static_extremum_of_pw_aff( if len(pieces) == 1: (_, result), = pieces if constants_only and not result.is_cst(): - raise StaticValueFindingError("a numeric %s was not found for PwAff '%s'" - % (what, pw_aff)) + raise StaticValueFindingError( + f"a numeric {what} was not found for PwAff '{pw_aff}'") return result from pytools import flatten, memoize From 26ebbcdb2ac7c01214ec63ff272da2a20366edcd Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Fri, 12 Dec 2025 21:36:27 +0200 Subject: [PATCH 03/12] docs: update docstring formatting for isl_helpers.make_slab --- loopy/isl_helpers.py | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/loopy/isl_helpers.py b/loopy/isl_helpers.py index ddcc52334..ec49e2c3f 100644 --- a/loopy/isl_helpers.py +++ b/loopy/isl_helpers.py @@ -77,28 +77,14 @@ def make_slab(space: isl.Space, constraint ``start <= iname_multiplier*iname < stop``. :arg space: An instance of :class:`islpy._isl.Space`. - - :arg iname: - - Either an instance of :class:`str` as a name of the ``iname`` or a + :arg iname: Either an instance of :class:`str` as a name of the ``iname`` or a tuple of ``(iname_dt, iname_dx)`` indicating the *iname* in the space. - - :arg start: - - An instance of :class:`int` or an instance of - :class:`islpy._isl.Aff` indicating the lower bound of - ``iname_multiplier*iname``(inclusive). - - :arg stop: - - An instance of :class:`int` or an instance of - :class:`islpy._isl.Aff` indicating the upper bound of - ``iname_multiplier*iname``. - - :arg iname_multiplier: - - A strictly positive :class:`int` denoting *iname*'s coefficient in the - above inequality expression. + :arg start: An instance of :class:`int` or an instance of :class:`islpy._isl.Aff` + indicating the lower bound of ``iname_multiplier*iname``(inclusive). + :arg stop: An instance of :class:`int` or an instance of :class:`islpy._isl.Aff` + indicating the upper bound of ``iname_multiplier*iname``. + :arg iname_multiplier: A strictly positive :class:`int` denoting *iname*'s + coefficient in the above inequality expression. """ zero = isl.Aff.zero_on_domain(space) From c954d17dafbe083ec492d22dd095e3e8fac5a9e3 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Fri, 12 Dec 2025 21:36:55 +0200 Subject: [PATCH 04/12] feat: use fstrings in kernel.data.parse_tag --- loopy/kernel/data.py | 4 ++-- loopy/match.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/loopy/kernel/data.py b/loopy/kernel/data.py index f7896a00f..52bf0b286 100644 --- a/loopy/kernel/data.py +++ b/loopy/kernel/data.py @@ -314,7 +314,7 @@ def parse_tag(tag: ToInameTagConvertible) -> Tag | None: return tag if not isinstance(tag, str): - raise ValueError("cannot parse tag: %s" % tag) + raise ValueError(f"cannot parse tag: {tag!r}") if tag == "for": return None @@ -342,7 +342,7 @@ def parse_tag(tag: ToInameTagConvertible) -> Tag | None: else: return LocalInameTag(int(axis)) else: - raise ValueError("cannot parse tag: %s" % tag) + raise ValueError(f"cannot parse tag: {tag!r}") # }}} diff --git a/loopy/match.py b/loopy/match.py index dd986c037..febf588cf 100644 --- a/loopy/match.py +++ b/loopy/match.py @@ -618,6 +618,7 @@ def parse_stack_match(smatch: ToStackMatchConvertible) -> ConcreteStackMatch: if isinstance(smatch, ConcreteStackMatch): return smatch + if isinstance(smatch, MatchExpressionBase): return ConcreteStackMatch( StackItemMatchComponent( From cad0ee702982dc6d897cb3a535103245cc373da3 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Fri, 12 Dec 2025 21:37:37 +0200 Subject: [PATCH 05/12] feat(typing): improve some types in symbolic --- loopy/symbolic.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/loopy/symbolic.py b/loopy/symbolic.py index b69505112..3b35b63c8 100644 --- a/loopy/symbolic.py +++ b/loopy/symbolic.py @@ -41,6 +41,7 @@ TypeAlias, TypeVar, cast, + overload, ) from warnings import warn @@ -1697,12 +1698,12 @@ def map_variable(self, expr: p.Variable, /, class RuleAwareSubstitutionRuleExpander(RuleAwareIdentityMapper[[]]): - rules: dict[str, SubstitutionRule] + rules: Mapping[str, SubstitutionRule] within: StackMatch def __init__(self, rule_mapping_context: SubstitutionRuleMappingContext, - rules: dict[str, SubstitutionRule], + rules: Mapping[str, SubstitutionRule], within: StackMatch) -> None: super().__init__(rule_mapping_context) @@ -2070,6 +2071,14 @@ def aff_to_expr(aff: isl.Aff) -> ArithmeticExpression: return flatten(result // denom) +@overload +def pw_aff_to_expr(pw_aff: int, int_ok: bool = False) -> int: ... + +@overload +def pw_aff_to_expr(pw_aff: isl.PwAff | isl.Aff, + int_ok: bool = False) -> ArithmeticExpression: ... + + def pw_aff_to_expr( pw_aff: int | isl.PwAff | isl.Aff, int_ok: bool = False From 584c3e534ad3a96d294bf07266fea740691be2be Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Fri, 12 Dec 2025 21:38:15 +0200 Subject: [PATCH 06/12] feat(typing): add ToInameStrSetConvertible type alias --- doc/conf.py | 1 + loopy/typing.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index de5e3cd2d..661dccf09 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -62,6 +62,7 @@ # loopy "InameStr": "obj:loopy.typing.InameStr", "InameStrSet": "obj:loopy.typing.InameStrSet", + "ToInameStrSetConvertible": "obj:loopy.typing.ToInameStrSetConvertible", "KernelIname": "obj:loopy.kernel.data.Iname", "LoopNestTree": "obj:loopy.schedule.tools.LoopNestTree", "LoopTree": "obj:loopy.schedule.tools.LoopTree", diff --git a/loopy/typing.py b/loopy/typing.py index cf3b54356..bb3b00284 100644 --- a/loopy/typing.py +++ b/loopy/typing.py @@ -3,6 +3,7 @@ .. autoclass:: ShapeType .. autodata:: InameStr .. autodata:: InameStrSet +.. autodata:: ToInameStrSetConvertible .. autodata:: SymbolMangler :noindex: @@ -60,7 +61,7 @@ if TYPE_CHECKING: - from collections.abc import Callable, Iterator + from collections.abc import Callable, Iterable, Iterator from loopy.codegen import PreambleInfo from loopy.kernel import LoopKernel @@ -75,6 +76,7 @@ InameStr: TypeAlias = str InameStrSet: TypeAlias = frozenset[InameStr] +ToInameStrSetConvertible: TypeAlias = "Iterable[InameStr] | InameStr" InsnId: TypeAlias = str From 18a3ca310ccc6f5da6a2892701fa89a2c841dd0d Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Fri, 12 Dec 2025 21:38:53 +0200 Subject: [PATCH 07/12] feat(typing): add types to transform.subst.expand_subst --- loopy/transform/subst.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/loopy/transform/subst.py b/loopy/transform/subst.py index 4d196de61..3d2ee0f21 100644 --- a/loopy/transform/subst.py +++ b/loopy/transform/subst.py @@ -39,7 +39,7 @@ if TYPE_CHECKING: from loopy.kernel import LoopKernel from loopy.kernel.instruction import InstructionBase - from loopy.match import RuleStack, ToMatchConvertible + from loopy.match import RuleStack, ToMatchConvertible, ToStackMatchConvertible logger = logging.getLogger(__name__) @@ -526,7 +526,8 @@ def _accesses_lhs( # {{{ expand_subst @for_each_kernel -def expand_subst(kernel, within=None): +def expand_subst(kernel: LoopKernel, + within: ToStackMatchConvertible | None = None) -> LoopKernel: """ Returns an instance of :class:`loopy.LoopKernel` with the substitutions referenced in instructions of *kernel* matched by *within* expanded. @@ -542,6 +543,7 @@ def expand_subst(kernel, within=None): from loopy.match import parse_stack_match from loopy.symbolic import RuleAwareSubstitutionRuleExpander + rule_mapping_context = SubstitutionRuleMappingContext( kernel.substitutions, kernel.get_var_name_generator()) submap = RuleAwareSubstitutionRuleExpander( From 033e66ccff573d02b39e1e4e167234259ebc659d Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Fri, 12 Dec 2025 21:54:51 +0200 Subject: [PATCH 08/12] feat(typing): add more types to transform.iname --- doc/ref_kernel.rst | 8 +- loopy/transform/iname.py | 675 +++++++++++++++++++++------------------ 2 files changed, 372 insertions(+), 311 deletions(-) diff --git a/doc/ref_kernel.rst b/doc/ref_kernel.rst index 7e8b89c59..3036b3183 100644 --- a/doc/ref_kernel.rst +++ b/doc/ref_kernel.rst @@ -192,9 +192,9 @@ Values of domain parameters arise from Iname Implementation Tags ^^^^^^^^^^^^^^^^^^^^^^^^^ -=============================== ==================================================== +=============================== ====================================================== Tag Meaning -=============================== ==================================================== +=============================== ====================================================== ``None`` | ``"for"`` Sequential loop ``"ord"`` Forced-order sequential loop ``"l.N"`` Local (intra-group) axis N ("local") @@ -205,8 +205,8 @@ Tag Meaning ``"ilp"`` | ``"ilp.unr"`` Unroll using instruction-level parallelism ``"ilp.seq"`` Realize parallel iname as innermost loop ``"like.INAME"`` Can be used when tagging inames to tag like another -``"unused.g"`` | ``"unused.l"`` Can be to tag as the next unused group/local axis -=============================== ==================================================== +``"unused.g"`` | ``"unused.l"`` Can be used to tag as the next unused group/local axis +=============================== ====================================================== (Throughout this table, `N` must be replaced by an actual, zero-based number.) diff --git a/loopy/transform/iname.py b/loopy/transform/iname.py index 22dae4bd1..4342e5385 100644 --- a/loopy/transform/iname.py +++ b/loopy/transform/iname.py @@ -23,16 +23,25 @@ THE SOFTWARE. """ -from collections.abc import Callable, Collection, Iterable, Mapping, Sequence, Set -from typing import TYPE_CHECKING, Any, Literal, TypeAlias, final +from collections.abc import ( + Callable, + Collection, + Hashable, + Iterable, + Iterator, + Mapping, + Sequence, + Set, +) +from typing import TYPE_CHECKING, Any, Concatenate, Literal, TypeAlias, final from warnings import warn from constantdict import constantdict from typing_extensions import deprecated, override import islpy as isl +import pymbolic.primitives as prim from islpy import dim_type -from pymbolic.primitives import AlgebraicLeaf, is_arithmetic_expression from pytools.tag import Tag from loopy.diagnostic import LoopyError @@ -44,6 +53,8 @@ RuleAwareIdentityMapper, RuleAwareSubstitutionMapper, SubstitutionRuleMappingContext, + aff_from_expr, + get_dependencies, pw_aff_to_expr, ) from loopy.translation_unit import TranslationUnit, for_each_kernel @@ -51,19 +62,19 @@ if TYPE_CHECKING: - from pymbolic import ArithmeticExpression, Variable - from pymbolic.typing import Expression + from pymbolic.typing import ArithmeticExpression, Expression + from pytools import P from loopy.kernel.data import GroupInameTag, LocalInameTag, ToInameTagConvertible from loopy.kernel.instruction import InstructionBase from loopy.match import ( - ConcreteStackMatch, MatchExpressionBase, RuleStack, + StackMatch, ToMatchConvertible, ToStackMatchConvertible, ) - from loopy.typing import InameStr + from loopy.typing import InameStr, InameStrSet, InsnId, ToInameStrSetConvertible __doc__ = """ @@ -115,12 +126,19 @@ """ +def _to_inames_tuple(inames: ToInameStrSetConvertible) -> tuple[InameStr, ...]: + if isinstance(inames, str): + inames = [p for s in inames.split(",") if (p := s.strip())] + + return tuple(inames) + + # {{{ set loop priority @for_each_kernel def prioritize_loops( kernel: LoopKernel, - loop_priority: str | Sequence[InameStr]): + loop_priority: ToInameStrSetConvertible) -> LoopKernel: """Indicates the textual order in which loops should be entered in the kernel code. Note that this priority has an advisory role only. If the kernel logically requires a different nesting, priority is ignored. @@ -136,11 +154,8 @@ def prioritize_loops( """ assert isinstance(kernel, LoopKernel) - if isinstance(loop_priority, str): - loop_priority = tuple(s.strip() - for s in loop_priority.split(",") if s.strip()) - loop_priority = tuple(loop_priority) + loop_priority = _to_inames_tuple(loop_priority) return kernel.copy(loop_priority=kernel.loop_priority.union([loop_priority])) # }}} @@ -152,13 +167,19 @@ def prioritize_loops( @final class _InameSplitter(RuleAwareIdentityMapper[[]]): + within: MatchExpressionBase + iname_to_split: InameStr + outer_iname: InameStr + inner_iname: InameStr + replacement_index: ArithmeticExpression + def __init__(self, rule_mapping_context: SubstitutionRuleMappingContext, within: MatchExpressionBase, iname_to_split: InameStr, outer_iname: InameStr, inner_iname: InameStr, - replacement_index: ArithmeticExpression): + replacement_index: ArithmeticExpression) -> None: super().__init__(rule_mapping_context) self.within = within @@ -170,7 +191,8 @@ def __init__(self, self.replacement_index = replacement_index @override - def map_reduction(self, expr: Reduction, expn_state: ExpansionState): + def map_reduction(self, expr: Reduction, /, + expn_state: ExpansionState) -> Expression: if (self.iname_to_split in expr.inames and self.iname_to_split not in expn_state.arg_context and self.within( @@ -180,7 +202,6 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): new_inames.remove(self.iname_to_split) new_inames.extend([self.outer_iname, self.inner_iname]) - from loopy.symbolic import Reduction return Reduction(expr.operation, tuple(new_inames), self.rec(expr.expr, expn_state), expr.allow_simultaneous) @@ -188,7 +209,8 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): return super().map_reduction(expr, expn_state) @override - def map_variable(self, expr: Variable, expn_state: ExpansionState): + def map_variable(self, expr: prim.Variable, /, + expn_state: ExpansionState) -> Expression: if (expr.name == self.iname_to_split and self.iname_to_split not in expn_state.arg_context and self.within( @@ -201,12 +223,12 @@ def map_variable(self, expr: Variable, expn_state: ExpansionState): def _split_iname_in_set( s: isl.BasicSet, - iname_to_split: str, - inner_iname: str, - outer_iname: str, + iname_to_split: InameStr, + inner_iname: InameStr, + outer_iname: InameStr, fixed_length: int, fixed_length_is_inner: bool - ): + ) -> isl.BasicSet: var_dict = s.get_var_dict() if iname_to_split not in var_dict: @@ -222,6 +244,9 @@ def _split_iname_in_set( for dup_iname_to_split in generate_unique_names(f"dup_{iname_to_split}"): if dup_iname_to_split not in var_dict: break + else: + # NOTE: this should never happen, but it's a way to let pyright know + raise ValueError(f"could not generate unique names for {iname_to_split}") from loopy.isl_helpers import duplicate_axes s = duplicate_axes(s, (iname_to_split,), (dup_iname_to_split,)) @@ -261,7 +286,8 @@ def _split_iname_backend( iname_to_split: InameStr, fixed_length: int, fixed_length_is_inner: bool, - make_new_loop_index: Callable[[Variable, Variable], ArithmeticExpression], + make_new_loop_index: Callable[[prim.Variable, prim.Variable], + ArithmeticExpression], outer_iname: InameStr | None = None, inner_iname: InameStr | None = None, outer_tag: ToInameTagConvertible = None, @@ -293,6 +319,7 @@ def _split_iname_backend( existing_tags = [tag for tag in kernel.iname_tags(iname_to_split) if isinstance(tag, InameImplementationTag)] + from loopy.kernel.data import ForceSequentialTag, filter_iname_tags_by_type if (do_tagged_check and existing_tags and not filter_iname_tags_by_type(existing_tags, ForceSequentialTag)): @@ -305,21 +332,20 @@ def _split_iname_backend( vng = kernel.get_var_name_generator() if outer_iname is None: - outer_iname = vng(iname_to_split+"_outer") + outer_iname = vng(f"{iname_to_split}_outer") if inner_iname is None: - inner_iname = vng(iname_to_split+"_inner") + inner_iname = vng(f"{iname_to_split}_inner") new_domains = [ _split_iname_in_set(dom, iname_to_split, inner_iname, outer_iname, fixed_length, fixed_length_is_inner) for dom in kernel.domains] - from pymbolic import var - inner = var(inner_iname) - outer = var(outer_iname) + inner = prim.Variable(inner_iname) + outer = prim.Variable(outer_iname) new_loop_index = make_new_loop_index(inner, outer) - subst_map = {var(iname_to_split): new_loop_index} + subst_map = {prim.Variable(iname_to_split): new_loop_index} # {{{ update within_inames @@ -328,11 +354,9 @@ def _split_iname_backend( if iname_to_split in insn.within_inames and ( within(kernel, insn)): new_within_inames = ( - (insn.within_inames.copy() - - frozenset([iname_to_split])) + (insn.within_inames - frozenset([iname_to_split])) | frozenset([outer_iname, inner_iname])) - insn = insn.copy( - within_inames=new_within_inames) + insn = insn.copy(within_inames=new_within_inames) new_insns.append(insn) @@ -340,7 +364,7 @@ def _split_iname_backend( iname_slab_increments = kernel.iname_slab_increments.set(outer_iname, slabs) - new_priorities = [] + new_priorities: list[tuple[InameStr, ...]] = [] for prio in kernel.loop_priority: new_prio = () for prio_iname in prio: @@ -364,7 +388,8 @@ def _split_iname_backend( from loopy.kernel.instruction import MultiAssignmentBase - def check_insn_has_iname(kernel: LoopKernel, insn: InstructionBase, *args): + def check_insn_has_iname(kernel: LoopKernel, + insn: InstructionBase, *args: Any) -> bool: return (not isinstance(insn, MultiAssignmentBase) or iname_to_split in insn.dependency_names() or iname_to_split in insn.reduction_inames()) @@ -423,7 +448,9 @@ def split_iname( """ assert isinstance(kernel, LoopKernel) - def make_new_loop_index(inner: Variable, outer: Variable): + def make_new_loop_index( + inner: prim.Variable, + outer: prim.Variable) -> ArithmeticExpression: return inner + outer*inner_length return _split_iname_backend(kernel, split_iname, @@ -470,30 +497,28 @@ def chunk_iname( chunk_diff = chunk_ceil - chunk_floor chunk_mod = size.mod_val(num_chunks) - from pymbolic.primitives import Min - - from loopy.symbolic import pw_aff_to_expr - - def make_new_loop_index(inner: Variable, outer: Variable): + def make_new_loop_index( + inner: prim.Variable, + outer: prim.Variable) -> ArithmeticExpression: # These two expressions are equivalent. Benchmarking between the # two was inconclusive, although one is shorter. if 0: - # Triggers isl issues in check pass. + # FIXME: Triggers isl issues in check pass. return ( inner + pw_aff_to_expr(chunk_floor) * outer + - pw_aff_to_expr(chunk_diff) * Min( + pw_aff_to_expr(chunk_diff) * prim.Min( (outer, pw_aff_to_expr(chunk_mod)))) else: return ( inner + - pw_aff_to_expr(chunk_ceil) * Min( + pw_aff_to_expr(chunk_ceil) * prim.Min( (outer, pw_aff_to_expr(chunk_mod))) + pw_aff_to_expr(chunk_floor) * ( - outer - Min((outer, pw_aff_to_expr(chunk_mod))))) + outer - prim.Min((outer, pw_aff_to_expr(chunk_mod))))) # {{{ check that iname is a box iname @@ -547,19 +572,23 @@ def make_new_loop_index(inner: Variable, outer: Variable): @final class _InameJoiner(RuleAwareSubstitutionMapper): + joined_inames: frozenset[InameStr] + new_iname: InameStr + def __init__(self, rule_mapping_context: SubstitutionRuleMappingContext, - within: ConcreteStackMatch, - subst_func: Callable[[AlgebraicLeaf], Expression | None], - joined_inames: Sequence[InameStr], - new_iname: InameStr): + within: StackMatch, + subst_func: Callable[[prim.AlgebraicLeaf], Expression | None], + joined_inames: ToInameStrSetConvertible, + new_iname: InameStr) -> None: super().__init__(rule_mapping_context, subst_func, within) - self.joined_inames = set(joined_inames) + self.joined_inames = frozenset(_to_inames_tuple(joined_inames)) self.new_iname = new_iname @override - def map_reduction(self, expr: Reduction, expn_state: ExpansionState): + def map_reduction(self, expr: Reduction, /, + expn_state: ExpansionState) -> Expression: expr_inames = set(expr.inames) overlap = (self.joined_inames & expr_inames - set(expn_state.arg_context)) @@ -579,8 +608,8 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): new_inames = expr_inames - self.joined_inames new_inames.add(self.new_iname) - from loopy.symbolic import Reduction - return Reduction(expr.operation, tuple(new_inames), + new_inames = (expr_inames - self.joined_inames) | {self.new_iname} + return Reduction(expr.operation, tuple(sorted(new_inames)), self.rec(expr.expr, expn_state), expr.allow_simultaneous) else: @@ -590,10 +619,10 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): @for_each_kernel def join_inames( kernel: LoopKernel, - inames: Sequence[InameStr] | str, + inames: ToInameStrSetConvertible, new_iname: InameStr | None = None, tag: Tag | None = None, - within: ToMatchConvertible = None, ): + within: ToMatchConvertible = None) -> LoopKernel: """In a sense, the inverse of :func:`split_iname`. Takes in inames, finds their bounds (all but the first have to be bounded), and combines them into a single loop via analogs of ``new_iname = i0 * LEN(i1) + i1``. @@ -616,6 +645,7 @@ def join_inames( # }}} # now fastest varying first + inames = _to_inames_tuple(inames) inames = inames[::-1] if new_iname is None: @@ -634,11 +664,9 @@ def join_inames( new_domain = new_domain.set_dim_name(dim_type.set, new_dim_idx, new_iname) joint_aff = zero = isl.Aff.zero_on_domain(new_domain.space) - subst_dict = {} + subst_dict: dict[InameStr, ArithmeticExpression] = {} base_divisor = 1 - from pymbolic import var - for i, iname in enumerate(inames): iname_dt, iname_idx = zero.get_space().get_var_dict()[iname] iname_aff = zero.add_coefficient_val(iname_dt, iname_idx, 1) @@ -648,7 +676,6 @@ def join_inames( bounds = kernel.get_iname_bounds(iname, constants_only=True) from loopy.isl_helpers import static_max_of_pw_aff, static_value_of_pw_aff - from loopy.symbolic import pw_aff_to_expr length = int(pw_aff_to_expr( static_max_of_pw_aff(bounds.size, constants_only=True))) @@ -660,7 +687,7 @@ def join_inames( except Exception as e: raise type(e)("while finding lower bound of '%s': " % iname) from e - my_val = var(new_iname) // base_divisor + my_val = prim.Variable(new_iname) // base_divisor if i+1 < len(inames): my_val %= length my_val += pw_aff_to_expr(lower_bound_aff) @@ -677,11 +704,8 @@ def join_inames( iname_to_dim = new_domain.get_space().get_var_dict() iname_dt, iname_idx = iname_to_dim[iname] - if within is None: - new_domain = new_domain.project_out(iname_dt, iname_idx, 1) - - def subst_within_inames(fid): - result = set() + def subst_within_inames(fid: InameStrSet) -> InameStrSet: + result: set[InameStr] = set() for iname in fid: if iname in inames: result.add(new_iname) @@ -691,16 +715,14 @@ def subst_within_inames(fid): return frozenset(result) new_insns = [ - insn.copy( - within_inames=subst_within_inames(insn.within_inames)) if - within(kernel, insn) else insn for insn in kernel.instructions] + insn.copy(within_inames=subst_within_inames(insn.within_inames)) + if within(kernel, insn) else insn + for insn in kernel.instructions] - kernel = (kernel - .copy( - instructions=new_insns, - domains=domch.get_domains_with(new_domain), - applied_iname_rewrites=(*kernel.applied_iname_rewrites, subst_dict) - )) + kernel = kernel.copy( + instructions=new_insns, + domains=domch.get_domains_with(new_domain), + applied_iname_rewrites=(*kernel.applied_iname_rewrites, subst_dict)) from loopy.match import parse_stack_match within_s = parse_stack_match(within) @@ -725,10 +747,11 @@ def subst_within_inames(fid): # {{{ untag inames +@for_each_kernel def untag_inames( kernel: LoopKernel, iname_to_untag: InameStr, - tag_type: type[Tag]): + tag_type: type[Tag]) -> LoopKernel: """ Remove tags on *iname_to_untag* which matches *tag_type*. @@ -752,16 +775,18 @@ def untag_inames( # {{{ tag inames -_Tags_ish: TypeAlias = Tag | Collection[Tag] | str | Collection[str] +_Tags_ish: TypeAlias = Tag | Collection[Tag] | str | Collection[str] | None @for_each_kernel def tag_inames( kernel: LoopKernel, - iname_to_tag: (Mapping[str, _Tags_ish] + iname_to_tag: ( + Mapping[str, _Tags_ish] | Sequence[tuple[str, _Tags_ish]] | str), - force: bool = False, + *, + force: bool | None = None, ignore_nonexistent: bool = False ) -> LoopKernel: """Tag an iname @@ -782,15 +807,21 @@ def tag_inames( Added iterable of tags """ + if force is not None: + from warnings import warn + + warn("Setting 'force' has no effect and the argument will be removed " + "in 2026.", DeprecationWarning, stacklevel=2) + if isinstance(iname_to_tag, str): - def parse_kv(s: str) -> tuple[str, str]: + def parse_kv(s: str) -> tuple[InameStr, str]: colon_index = s.find(":") if colon_index == -1: - raise ValueError("tag decl '%s' has no colon" % s) + raise ValueError(f"tag decl '{s}' has no colon") - return (s[:colon_index].strip(), s[colon_index+1:].strip()) + return s[:colon_index].strip(), s[colon_index+1:].strip() - iname_to_tags_seq: Sequence[tuple[str, _Tags_ish]] = [ + iname_to_tags_seq: Sequence[tuple[InameStr, _Tags_ish]] = [ parse_kv(s) for s in iname_to_tag.split(",") if s.strip()] elif isinstance(iname_to_tag, Mapping): @@ -803,7 +834,7 @@ def parse_kv(s: str) -> tuple[str, str]: # flatten iterables of tags for each iname - unpack_iname_to_tag: list[tuple[str, Tag | str]] = [] + unpack_iname_to_tag: list[tuple[InameStr, ToInameTagConvertible]] = [] for iname, tags in iname_to_tags_seq: if isinstance(tags, Iterable) and not isinstance(tags, str): for tag in tags: @@ -813,14 +844,14 @@ def parse_kv(s: str) -> tuple[str, str]: from loopy.kernel.data import parse_tag as inner_parse_tag - def parse_tag(tag: Tag | str) -> Iterable[Tag]: + def parse_tag(tag: ToInameTagConvertible) -> Iterable[Tag]: if isinstance(tag, str): if tag.startswith("like."): return kernel.iname_tags(tag[5:]) elif tag == "unused.g": - return find_unused_axis_tag(kernel, "g") + return [find_unused_axis_tag(kernel, "g")] elif tag == "unused.l": - return find_unused_axis_tag(kernel, "l") + return [find_unused_axis_tag(kernel, "l")] result = inner_parse_tag(tag) if result is None: @@ -840,22 +871,22 @@ def parse_tag(tag: Tag | str) -> Iterable[Tag]: from loopy.match import re_from_glob for iname, new_tag in iname_to_parsed_tag: + assert new_tag is not None + if "*" in iname or "?" in iname: match_re = re_from_glob(iname) - inames = [sub_iname for sub_iname in all_inames + inames = [ + sub_iname for sub_iname in all_inames if match_re.match(sub_iname)] else: if iname not in all_inames: if ignore_nonexistent: continue else: - raise LoopyError("iname '%s' does not exist" % iname) + raise LoopyError(f"iname '{iname}' does not exist") inames = [iname] - if new_tag is None: - continue - for sub_iname in inames: knl_inames[sub_iname] = knl_inames[sub_iname].tagged(new_tag) @@ -866,16 +897,25 @@ def parse_tag(tag: Tag | str) -> Iterable[Tag]: # {{{ duplicate inames -class _InameDuplicator(RuleAwareIdentityMapper): - def __init__(self, rule_mapping_context, - old_to_new, within): +@final +class _InameDuplicator(RuleAwareIdentityMapper[[]]): + old_to_new: Mapping[InameStr, InameStr] + old_inames_set: set[InameStr] + within: StackMatch + + def __init__(self, + rule_mapping_context: SubstitutionRuleMappingContext, + old_to_new: Mapping[InameStr, InameStr], + within: StackMatch) -> None: super().__init__(rule_mapping_context) self.old_to_new = old_to_new self.old_inames_set = set(old_to_new.keys()) self.within = within - def map_reduction(self, expr, expn_state): + @override + def map_reduction(self, expr: Reduction, /, + expn_state: ExpansionState) -> Expression: if (set(expr.inames) & self.old_inames_set and self.within( expn_state.kernel, @@ -887,14 +927,15 @@ def map_reduction(self, expr, expn_state): else iname for iname in expr.inames) - from loopy.symbolic import Reduction return Reduction(expr.operation, new_inames, self.rec(expr.expr, expn_state), expr.allow_simultaneous) else: return super().map_reduction(expr, expn_state) - def map_variable(self, expr, expn_state): + @override + def map_variable(self, expr: prim.Variable, /, + expn_state: ExpansionState) -> Expression: new_name = self.old_to_new.get(expr.name) if (new_name is None @@ -905,10 +946,12 @@ def map_variable(self, expr, expn_state): expn_state.stack)): return super().map_variable(expr, expn_state) else: - from pymbolic import var - return var(new_name) + return prim.Variable(new_name) - def map_instruction(self, kernel, insn): + @override + def map_instruction(self, + kernel: LoopKernel, + insn: InstructionBase) -> InstructionBase: if not self.within(kernel, insn, ()): return insn @@ -919,34 +962,37 @@ def map_instruction(self, kernel, insn): @for_each_kernel -def duplicate_inames(kernel, inames, within, new_inames=None, suffix=None, - tags=None): +def duplicate_inames(kernel: LoopKernel, + inames: ToInameStrSetConvertible, + within: ToStackMatchConvertible, + new_inames: InameStr | Sequence[InameStr | None] | None = None, + suffix: str | None = None, + tags: Mapping[str, Tag] | None = None) -> LoopKernel: """ - :arg within: a stack match as understood by - :func:`loopy.match.parse_stack_match`. + :arg within: a stack match as understood by :func:`loopy.match.parse_stack_match`. """ if tags is None: tags = {} # {{{ normalize arguments, find unique new_inames - if isinstance(inames, str): - inames = [iname.strip() for iname in inames.split(",")] - - if isinstance(new_inames, str): - new_inames = [iname.strip() for iname in new_inames.split(",")] - - from loopy.match import parse_stack_match - within = parse_stack_match(within) + inames = _to_inames_tuple(inames) if new_inames is None: new_inames = [None] * len(inames) + else: + new_inames = _to_inames_tuple(new_inames) if len(new_inames) != len(inames): - raise ValueError("new_inames must have the same number of entries as inames") + raise ValueError( + "'new_inames' must have the same number of entries as 'inames': " + f"got {len(new_inames)} (expected {len(inames)})") - name_gen = kernel.get_var_name_generator() + from loopy.match import parse_stack_match + stack = parse_stack_match(within) + name_gen = kernel.get_var_name_generator() + new_suffixed_inames: list[InameStr] = [] for i, iname in enumerate(inames): new_iname = new_inames[i] @@ -957,7 +1003,6 @@ def duplicate_inames(kernel, inames, within, new_inames=None, suffix=None, new_iname += suffix new_iname = name_gen(new_iname) - else: if name_gen.is_name_conflicting(new_iname): raise ValueError("new iname '%s' conflicts with existing names" @@ -965,20 +1010,20 @@ def duplicate_inames(kernel, inames, within, new_inames=None, suffix=None, name_gen.add_name(new_iname) - new_inames[i] = new_iname + new_suffixed_inames.append(new_iname) # }}} # {{{ duplicate the inames - for old_iname, new_iname in zip(inames, new_inames, strict=True): - from loopy.kernel.tools import DomainChanger + from loopy.isl_helpers import duplicate_axes + from loopy.kernel.tools import DomainChanger + + for old_iname, new_iname in zip(inames, new_suffixed_inames, strict=True): domch = DomainChanger(kernel, frozenset([old_iname])) - from loopy.isl_helpers import duplicate_axes - kernel = kernel.copy( - domains=domch.get_domains_with( - duplicate_axes(domch.domain, [old_iname], [not_none(new_iname)]))) + dup_iname = duplicate_axes(domch.domain, [old_iname], [new_iname]) + kernel = kernel.copy(domains=domch.get_domains_with(dup_iname)) # }}} @@ -987,8 +1032,8 @@ def duplicate_inames(kernel, inames, within, new_inames=None, suffix=None, rule_mapping_context = SubstitutionRuleMappingContext( kernel.substitutions, name_gen) indup = _InameDuplicator(rule_mapping_context, - old_to_new=dict(list(zip(inames, new_inames, strict=True))), - within=within) + old_to_new=dict(list(zip(inames, new_suffixed_inames, strict=True))), + within=stack) def _does_access_old_inames(kernel: LoopKernel, insn: InstructionBase, @@ -1006,10 +1051,10 @@ def _does_access_old_inames(kernel: LoopKernel, # {{{ realize tags - for old_iname, new_iname in zip(inames, new_inames, strict=True): + for old_iname, new_iname in zip(inames, new_suffixed_inames, strict=True): new_tag = tags.get(old_iname) if new_tag is not None: - kernel = tag_inames(kernel, {new_iname: new_tag}) + kernel = tag_inames(kernel, {not_none(new_iname): new_tag}) # }}} @@ -1020,10 +1065,17 @@ def _does_access_old_inames(kernel: LoopKernel, # {{{ iname duplication for schedulability -def _get_iname_duplication_options(insn_iname_sets, old_common_inames=frozenset([])): + +def _get_iname_duplication_options( + insn_iname_sets: frozenset[InameStrSet], + old_common_inames: InameStrSet | None = None, + ) -> Iterator[tuple[InameStr, tuple[InameStrSet, ...]]]: + if old_common_inames is None: + old_common_inames = frozenset() + # Remove common inames of the current insn_iname_sets, as they are not relevant # for splitting. - common = frozenset([]).union(*insn_iname_sets).intersection(*insn_iname_sets) + common = frozenset[str]().union(*insn_iname_sets).intersection(*insn_iname_sets) # If common inames were found, we reduce the problem and go into recursion if common: @@ -1031,7 +1083,7 @@ def _get_iname_duplication_options(insn_iname_sets, old_common_inames=frozenset( insn_iname_sets = ( frozenset(iname_set - common for iname_set in insn_iname_sets) - - frozenset([frozenset([])])) + frozenset([frozenset[str]()])) # Join the common inames with those previously found common = common.union(old_common_inames) @@ -1042,7 +1094,9 @@ def _get_iname_duplication_options(insn_iname_sets, old_common_inames=frozenset( # Try finding a partitioning of the remaining inames, such that all instructions # use only inames from one of the disjoint sets from the partitioning. - def join_sets_if_not_disjoint(sets): + def join_sets_if_not_disjoint( + sets: frozenset[InameStrSet] + ) -> tuple[frozenset[InameStrSet], bool]: for s1 in sets: for s2 in sets: if s1 != s2 and s1 & s2: @@ -1063,8 +1117,8 @@ def join_sets_if_not_disjoint(sets): if len(partitioning) > 1: for part in partitioning: working_set = frozenset(s for s in insn_iname_sets if s <= part) - yield from _get_iname_duplication_options(working_set, - old_common_inames) + yield from _get_iname_duplication_options(working_set, old_common_inames) + # If exactly one set was found, an iname duplication is necessary elif len(partitioning) == 1: inames, = partitioning @@ -1090,7 +1144,9 @@ def join_sets_if_not_disjoint(sets): # If partitioning was empty, we have recursed successfully and yield nothing -def get_iname_duplication_options(kernel): +def get_iname_duplication_options( + kernel: LoopKernel + ) -> Iterator[tuple[InameStr, MatchExpressionBase]]: """List options for duplication of inames, if necessary for schedulability :returns: a generator listing all options to duplicate inames, if duplication @@ -1121,8 +1177,8 @@ def get_iname_duplication_options(kernel): duplicated in a given kernel. """ if isinstance(kernel, TranslationUnit): - if len([clbl for clbl in kernel.callables_table.values() if - isinstance(clbl, CallableKernel)]) == 1: + if len([clbl for clbl in kernel.callables_table.values() + if isinstance(clbl, CallableKernel)]) == 1: kernel = kernel[next(iter(kernel.entrypoints))] assert isinstance(kernel, LoopKernel) @@ -1140,7 +1196,7 @@ def get_iname_duplication_options(kernel): insn.within_inames - concurrent_inames for insn in kernel.instructions) - - frozenset([frozenset([])])) + frozenset([frozenset[str]()])) # Get the duplication options as a tuple of iname and a set for iname, insns in _get_iname_duplication_options(insn_iname_sets): @@ -1160,15 +1216,16 @@ def get_iname_duplication_options(kernel): yield iname, within -def has_schedulable_iname_nesting(kernel): +def has_schedulable_iname_nesting(kernel: LoopKernel) -> bool: """ :returns: a :class:`bool` indicating whether this kernel needs an iname duplication in order to be schedulable. """ if isinstance(kernel, TranslationUnit): - if len([clbl for clbl in kernel.callables_table.values() if - isinstance(clbl, CallableKernel)]) == 1: + if len([clbl for clbl in kernel.callables_table.values() + if isinstance(clbl, CallableKernel)]) == 1: kernel = kernel[next(iter(kernel.entrypoints))] + return not bool(next(get_iname_duplication_options(kernel), False)) # }}} @@ -1176,22 +1233,26 @@ def has_schedulable_iname_nesting(kernel): # {{{ remove unused inames -def get_used_inames(kernel): +def get_used_inames(kernel: LoopKernel) -> InameStrSet: import loopy as lp + exp_kernel = lp.expand_subst(kernel) - used_inames = set() + used_inames: set[InameStr] = set() for insn in exp_kernel.instructions: used_inames.update( insn.within_inames | insn.reduction_inames() | insn.sub_array_ref_inames()) - return used_inames + return frozenset(used_inames) @for_each_kernel -def remove_unused_inames(kernel: LoopKernel, inames: Collection[str] | None = None): +def remove_unused_inames( + kernel: LoopKernel, + inames: ToInameStrSetConvertible | None = None + ) -> LoopKernel: """Delete those among *inames* that are unused, i.e. project them out of the domain. If these inames pose implicit restrictions on other inames, these restrictions will persist as existentially @@ -1202,16 +1263,16 @@ def remove_unused_inames(kernel: LoopKernel, inames: Collection[str] | None = No # {{{ normalize arguments - if inames is None: - inames = kernel.all_inames() - elif isinstance(inames, str): - inames = inames.split(",") + inames = ( + kernel.all_inames() + if inames is None + else frozenset(_to_inames_tuple(inames))) # }}} # {{{ check which inames are unused - unused_inames = set(inames) - get_used_inames(kernel) + unused_inames = inames - get_used_inames(kernel) # }}} @@ -1219,7 +1280,7 @@ def remove_unused_inames(kernel: LoopKernel, inames: Collection[str] | None = No domains = kernel.domains for iname in sorted(unused_inames): - new_domains = [] + new_domains: list[isl.BasicSet] = [] for dom in domains: try: @@ -1239,12 +1300,13 @@ def remove_unused_inames(kernel: LoopKernel, inames: Collection[str] | None = No return kernel -def remove_any_newly_unused_inames(transformation_func): +def remove_any_newly_unused_inames( + transformation_func: Callable[Concatenate[LoopKernel, P], LoopKernel] + ) -> Callable[Concatenate[LoopKernel, P], LoopKernel]: from functools import wraps @wraps(transformation_func) - def wrapper(kernel, *args, **kwargs): - + def wrapper(kernel: LoopKernel, *args: P.args, **kwargs: P.kwargs) -> LoopKernel: # check for remove_unused_inames argument, default: True remove_newly_unused_inames = kwargs.pop("remove_newly_unused_inames", True) @@ -1275,19 +1337,24 @@ def wrapper(kernel, *args, **kwargs): @final class _ReductionSplitter(RuleAwareIdentityMapper[[]]): + within: StackMatch + inames: InameStrSet + direction: Literal["in", "out"] + def __init__(self, rule_mapping_context: SubstitutionRuleMappingContext, - within: ConcreteStackMatch, - inames: Set[str], - direction: Literal["in", "out"]): - super().__init__( - rule_mapping_context) + within: StackMatch, + inames: InameStrSet, + direction: Literal["in", "out"]) -> None: + super().__init__(rule_mapping_context) self.within = within self.inames = inames self.direction = direction - def map_reduction(self, expr: Reduction, expn_state: ExpansionState): + @override + def map_reduction(self, expr: Reduction, /, + expn_state: ExpansionState) -> Expression: if set(expr.inames) & set(expn_state.arg_context): # FIXME raise NotImplementedError() @@ -1299,7 +1366,6 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): expn_state.stack)): leftover_inames = set(expr.inames) - self.inames - from loopy.symbolic import Reduction if self.direction == "in": return Reduction(expr.operation, tuple(leftover_inames), Reduction(expr.operation, tuple(self.inames), @@ -1320,19 +1386,16 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): def _split_reduction( kernel: LoopKernel, - inames: Collection[str] | str, + inames: ToInameStrSetConvertible, direction: Literal["in", "out"], within: ToStackMatchConvertible = None - ): + ) -> LoopKernel: if direction not in ["in", "out"]: - raise ValueError("invalid value for 'direction': %s" % direction) - - if isinstance(inames, str): - inames = inames.split(",") - inames = set(inames) + raise ValueError(f"invalid value for 'direction': {direction!r}") + inames = frozenset(_to_inames_tuple(inames)) if not (inames <= kernel.all_inames()): - raise LoopyError(f"Unknown inames: {inames - kernel.all_inames()}.") + raise LoopyError(f"unknown inames: {inames - kernel.all_inames()}.") from loopy.match import parse_stack_match within = parse_stack_match(within) @@ -1348,8 +1411,8 @@ def _split_reduction( @for_each_kernel def split_reduction_inward( kernel: LoopKernel, - inames: Collection[str] | str, - within: ToStackMatchConvertible = None): + inames: ToInameStrSetConvertible, + within: ToStackMatchConvertible = None) -> LoopKernel: """Takes a reduction of the form:: sum([i,j,k], ...) @@ -1361,7 +1424,7 @@ def split_reduction_inward( In this case, *inames* would have been ``"i"`` indicating that the iname ``i`` should be made the iname governing the inner reduction. - :arg inames: A list of inames, or a comma-separated string that can + :arg inames: a list of inames, or a comma-separated string that can be parsed into those """ @@ -1371,8 +1434,8 @@ def split_reduction_inward( @for_each_kernel def split_reduction_outward( kernel: LoopKernel, - inames: Collection[str] | str, - within: ToStackMatchConvertible = None): + inames: ToInameStrSetConvertible, + within: ToStackMatchConvertible = None) -> LoopKernel: """Takes a reduction of the form:: sum([i,j,k], ...) @@ -1399,11 +1462,11 @@ def split_reduction_outward( @for_each_kernel def affine_map_inames( kernel: LoopKernel, - old_inames: Collection[InameStr] | str, - new_inames: Collection[InameStr] | str, + old_inames: ToInameStrSetConvertible, + new_inames: ToInameStrSetConvertible, equations: Sequence[tuple[ArithmeticExpression, ArithmeticExpression] | str] - ): + ) -> LoopKernel: """Return a new *kernel* where the affine transform specified by *equations* has been applied to the inames. @@ -1426,19 +1489,17 @@ def affine_map_inames( # {{{ check and parse arguments - if isinstance(new_inames, str): - new_inames = new_inames.split(",") - new_inames = [iname.strip() for iname in new_inames] - if isinstance(old_inames, str): - old_inames = old_inames.split(",") - old_inames = [iname.strip() for iname in old_inames] + old_inames = _to_inames_tuple(old_inames) + new_inames = _to_inames_tuple(new_inames) if isinstance(equations, str): equations = [equations] import re eqn_re = re.compile(r"^([^=]+)=([^=]+)$") - def parse_equation(eqn: str | tuple[ArithmeticExpression, ArithmeticExpression]): + def parse_equation( + eqn: str | tuple[ArithmeticExpression, ArithmeticExpression] + ) -> tuple[ArithmeticExpression, ArithmeticExpression]: if isinstance(eqn, str): eqn_match = eqn_re.match(eqn) if not eqn_match: @@ -1447,18 +1508,19 @@ def parse_equation(eqn: str | tuple[ArithmeticExpression, ArithmeticExpression]) from loopy.symbolic import parse lhs = parse(eqn_match.group(1)) rhs = parse(eqn_match.group(2)) - assert is_arithmetic_expression(lhs) - assert is_arithmetic_expression(rhs) + assert prim.is_arithmetic_expression(lhs) + assert prim.is_arithmetic_expression(rhs) return (lhs, rhs) elif isinstance(eqn, tuple): if len(eqn) != 2: - raise ValueError("unexpected length of equation tuple, " - "got %d, should be 2" % len(eqn)) + raise ValueError( + "unexpected length of equation tuple, got {len(eqn)}, should be 2") + return eqn else: - raise ValueError("unexpected type of equation" - "got %d, should be string or tuple" - % type(eqn).__name__) + raise TypeError( + f"unexpected type of equation: got {type(eqn)}, " + "should be string or tuple") equations = [parse_equation(eqn) for eqn in equations] @@ -1479,7 +1541,7 @@ def parse_equation(eqn: str | tuple[ArithmeticExpression, ArithmeticExpression]) from pymbolic.algorithm import solve_affine_equations_for old_inames_to_expr = solve_affine_equations_for(old_inames, equations) - subst_dict = { + subst_dict: dict[str, ArithmeticExpression] = { v.name: expr for v, expr in old_inames_to_expr.items()} @@ -1494,12 +1556,9 @@ def parse_equation(eqn: str | tuple[ArithmeticExpression, ArithmeticExpression]) old_to_new = RuleAwareSubstitutionMapper(rule_mapping_context, make_subst_func(subst_dict), within=parse_stack_match(None)) - kernel = ( - rule_mapping_context.finish_kernel( - old_to_new.map_kernel(kernel)) - .copy( - applied_iname_rewrites=(*kernel.applied_iname_rewrites, subst_dict) - )) + kernel = rule_mapping_context.finish_kernel(old_to_new.map_kernel(kernel)) + kernel = kernel.copy( + applied_iname_rewrites=(*kernel.applied_iname_rewrites, subst_dict)) # }}} @@ -1508,7 +1567,7 @@ def parse_equation(eqn: str | tuple[ArithmeticExpression, ArithmeticExpression]) new_inames_set = frozenset(new_inames) old_inames_set = frozenset(old_inames) - new_domains = [] + new_domains: list[isl.BasicSet] = [] for idom, dom in enumerate(kernel.domains): dom_var_dict = dom.get_var_dict() old_iname_overlap = [ @@ -1520,14 +1579,13 @@ def parse_equation(eqn: str | tuple[ArithmeticExpression, ArithmeticExpression]) new_domains.append(dom) continue - from loopy.symbolic import get_dependencies - dom_new_inames = set() - dom_old_inames = set() + dom_new_inames: set[InameStr] = set() + dom_old_inames: set[InameStr] = set() # mapping for new inames to dim_types - new_iname_dim_types = {} + new_iname_dim_types: dict[str, isl.dim_type] = {} - dom_equations = [] + dom_equations: list[tuple[ArithmeticExpression, ArithmeticExpression]] = [] for iname in old_iname_overlap: for ieqn, (lhs, rhs) in enumerate(equations): eqn_deps = get_dependencies(lhs) | get_dependencies(rhs) @@ -1569,7 +1627,6 @@ def parse_equation(eqn: str | tuple[ArithmeticExpression, ArithmeticExpression]) % (idom, ", ".join(dom_old_inames - set(dom_var_dict)))) # add inames to domain with correct dim_types - dom_new_inames = list(dom_new_inames) for iname in dom_new_inames: dt = new_iname_dim_types[iname] iname_idx = dom.dim(dt) @@ -1577,7 +1634,6 @@ def parse_equation(eqn: str | tuple[ArithmeticExpression, ArithmeticExpression]) dom = dom.set_dim_name(dt, iname_idx, iname) # add equations - from loopy.symbolic import aff_from_expr for lhs, rhs in dom_equations: dom = dom.add_constraint( isl.Constraint.equality_from_aff( @@ -1594,7 +1650,7 @@ def parse_equation(eqn: str | tuple[ArithmeticExpression, ArithmeticExpression]) # {{{ switch iname refs in instructions - def fix_iname_set(insn_id, inames): + def fix_iname_set(insn_id: InsnId, inames: InameStrSet) -> InameStrSet: if old_inames_set <= inames: return (inames - old_inames_set) | new_inames_set elif old_inames_set & inames: @@ -1605,8 +1661,7 @@ def fix_iname_set(insn_id, inames): return inames new_instructions = [ - insn.copy(within_inames=fix_iname_set( - insn.id, insn.within_inames)) + insn.copy(within_inames=fix_iname_set(insn.id, insn.within_inames)) for insn in kernel.instructions] # }}} @@ -1620,7 +1675,7 @@ def fix_iname_set(insn_id, inames): def find_unused_axis_tag( kernel: LoopKernel, - kind: str | type[GroupInameTag | LocalInameTag], + kind: Literal["l", "g"] | type[GroupInameTag | LocalInameTag], insn_match: ToMatchConvertible = None, ) -> GroupInameTag | LocalInameTag: """For one of the hardware-parallel execution tags, find an unused @@ -1634,8 +1689,6 @@ def find_unused_axis_tag( :class:`loopy.kernel.data.LocalInameTag` that is not being used within the instructions matched by *insn_match*. """ - used_axes: set[int] = set() - from loopy.kernel.data import GroupInameTag, LocalInameTag kind_cls: type[GroupInameTag | LocalInameTag] @@ -1653,6 +1706,7 @@ def find_unused_axis_tag( match = parse_match(insn_match) insns = [insn for insn in kernel.instructions if match(kernel, insn)] + used_axes: set[int] = set() for insn in insns: for iname in insn.within_inames: if kernel.iname_tags_of_type(iname, kind_cls): @@ -1670,29 +1724,38 @@ def find_unused_axis_tag( # {{{ separate_loop_head_tail_slab # undocumented, because not super-useful -def separate_loop_head_tail_slab(kernel, iname, head_it_count, tail_it_count): +def separate_loop_head_tail_slab(kernel: LoopKernel, + iname: InameStr, + head_it_count: int, + tail_it_count: int) -> LoopKernel: """Mark *iname* so that the separate code is generated for the lower *head_it_count* and the upper *tail_it_count* iterations of the loop on *iname*. """ - iname_slab_increments = kernel.iname_slab_increments.copy() + iname_slab_increments = dict(kernel.iname_slab_increments) iname_slab_increments[iname] = (head_it_count, tail_it_count) - return kernel.copy(iname_slab_increments=iname_slab_increments) + return kernel.copy(iname_slab_increments=constantdict(iname_slab_increments)) # }}} # {{{ make_reduction_inames_unique +@final class _ReductionInameUniquifier(RuleAwareIdentityMapper[[]]): - inames: Sequence[InameStr] + inames: InameStrSet | None old_to_new: list[tuple[str, str]] + within: StackMatch + iname_to_red_count: dict[InameStr, int] iname_to_nonsimultaneous_red_count: dict[InameStr, int] - def __init__(self, rule_mapping_context, inames, within): + def __init__(self, + rule_mapping_context: SubstitutionRuleMappingContext, + inames: InameStrSet | None, + within: StackMatch) -> None: super().__init__(rule_mapping_context) self.inames = inames @@ -1702,14 +1765,16 @@ def __init__(self, rule_mapping_context, inames, within): self.iname_to_red_count = {} self.iname_to_nonsimultaneous_red_count = {} - def get_cache_key(self, expr, expn_state): + @override + def get_cache_key(self, expr: Expression, expn_state: ExpansionState) -> Hashable: return (super().get_cache_key(expr, expn_state), hash(frozenset(self.iname_to_red_count.items())), hash(frozenset(self.iname_to_nonsimultaneous_red_count.items())), ) @override - def map_reduction(self, expr: Reduction, expn_state: ExpansionState): + def map_reduction(self, expr: Reduction, /, + expn_state: ExpansionState) -> Expression: within = self.within( expn_state.kernel, expn_state.instruction, @@ -1723,9 +1788,7 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): self.iname_to_nonsimultaneous_red_count.get(iname, 0) + 1) if within and not expr.allow_simultaneous: - subst_dict = {} - - from pymbolic import var + subst_dict: dict[InameStr, prim.Variable] = {} new_inames: list[str] = [] for iname in expr.inames: @@ -1737,7 +1800,7 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): continue new_iname = self.rule_mapping_context.make_unique_var_name(iname) - subst_dict[iname] = var(new_iname) + subst_dict[iname] = prim.Variable(new_iname) self.old_to_new.append((iname, new_iname)) new_inames.append(new_iname) @@ -1746,8 +1809,7 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): from loopy.symbolic import SubstitutionMapper return Reduction(expr.operation, tuple(new_inames), self.rec( - SubstitutionMapper(make_subst_func(subst_dict))( - expr.expr), + SubstitutionMapper(make_subst_func(subst_dict))(expr.expr), expn_state), expr.allow_simultaneous) else: @@ -1755,9 +1817,12 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): @for_each_kernel -def make_reduction_inames_unique(kernel, inames=None, within=None): +def make_reduction_inames_unique( + kernel: LoopKernel, + inames: ToInameStrSetConvertible | None = None, + within: ToStackMatchConvertible | None = None) -> LoopKernel: """ - :arg inames: if not *None*, only apply to these inames + :arg inames: if not *None*, only apply to these inames. :arg within: a stack match as understood by :func:`loopy.match.parse_stack_match`. @@ -1773,21 +1838,23 @@ def make_reduction_inames_unique(kernel, inames=None, within=None): rule_mapping_context = SubstitutionRuleMappingContext( kernel.substitutions, name_gen) - r_uniq = _ReductionInameUniquifier(rule_mapping_context, - inames, within=within) + r_uniq = _ReductionInameUniquifier( + rule_mapping_context, + frozenset(_to_inames_tuple(inames)) if inames is not None else inames, + within=within) - kernel = rule_mapping_context.finish_kernel( - r_uniq.map_kernel(kernel)) + kernel = rule_mapping_context.finish_kernel(r_uniq.map_kernel(kernel)) # }}} # {{{ duplicate the inames + from loopy.isl_helpers import duplicate_axes + from loopy.kernel.tools import DomainChanger + for old_iname, new_iname in r_uniq.old_to_new: - from loopy.kernel.tools import DomainChanger domch = DomainChanger(kernel, frozenset([old_iname])) - from loopy.isl_helpers import duplicate_axes kernel = kernel.copy( domains=domch.get_domains_with( duplicate_axes(domch.domain, [old_iname], [new_iname]))) @@ -1796,7 +1863,7 @@ def make_reduction_inames_unique(kernel, inames=None, within=None): # {{{ copy metadata - inames = kernel.inames + inames = dict(kernel.inames) for old_iname, new_iname in r_uniq.old_to_new: inames[new_iname] = inames[old_iname].copy(name=new_iname) @@ -1813,7 +1880,9 @@ def make_reduction_inames_unique(kernel, inames=None, within=None): # {{{ add_inames_to_insn @for_each_kernel -def add_inames_to_insn(kernel, inames, insn_match): +def add_inames_to_insn(kernel: LoopKernel, + inames: ToInameStrSetConvertible, + insn_match: ToMatchConvertible) -> LoopKernel: """ :arg inames: a frozenset of inames that will be added to the instructions matched by *insn_match*, or a comma-separated @@ -1827,17 +1896,11 @@ def add_inames_to_insn(kernel, inames, insn_match): .. versionadded:: 2016.3 """ - if isinstance(inames, str): - inames = frozenset(s.strip() for s in inames.split(",")) - - if not isinstance(inames, frozenset): - raise TypeError("'inames' must be a frozenset") - from loopy.match import parse_match match = parse_match(insn_match) + inames = frozenset(_to_inames_tuple(inames)) - new_instructions = [] - + new_instructions: list[InstructionBase] = [] for insn in kernel.instructions: if match(kernel, insn): new_instructions.append( @@ -1853,8 +1916,10 @@ def add_inames_to_insn(kernel, inames, insn_match): # {{{ remove_inames_from_insn @for_each_kernel -def remove_inames_from_insn(kernel: LoopKernel, inames: frozenset[str], - insn_match) -> LoopKernel: +def remove_inames_from_insn( + kernel: LoopKernel, + inames: ToInameStrSetConvertible, + insn_match: ToMatchConvertible) -> LoopKernel: """ :arg inames: a frozenset of inames that will be added to the instructions matched by *insn_match*. @@ -1873,22 +1938,19 @@ def remove_inames_from_insn(kernel: LoopKernel, inames: frozenset[str], .. versionadded:: 2023.0 """ - if not isinstance(inames, frozenset): - raise TypeError("'inames' must be a frozenset") - from loopy.match import parse_match match = parse_match(insn_match) + inames = frozenset(_to_inames_tuple(inames)) - new_instructions = [] - + new_instructions: list[InstructionBase] = [] for insn in kernel.instructions: if match(kernel, insn): new_inames = insn.within_inames - inames if new_inames == insn.within_inames: - raise LoopyError(f"Inames {inames} not found in instruction " - f"{insn.id}") - new_instructions.append( - insn.copy(within_inames=new_inames)) + raise LoopyError( + f"inames {inames} not found in instruction {insn.id}") + + new_instructions.append(insn.copy(within_inames=new_inames)) else: new_instructions.append(insn) @@ -1896,7 +1958,10 @@ def remove_inames_from_insn(kernel: LoopKernel, inames: frozenset[str], @for_each_kernel -def remove_predicates_from_insn(kernel, predicates, insn_match): +def remove_predicates_from_insn( + kernel: LoopKernel, + predicates: frozenset[Expression], + insn_match: ToMatchConvertible) -> LoopKernel: """ :arg predicates: a frozenset of predicates that will be added to the instructions matched by *insn_match* @@ -1920,13 +1985,11 @@ def remove_predicates_from_insn(kernel, predicates, insn_match): from loopy.match import parse_match match = parse_match(insn_match) - new_instructions = [] - + new_instructions: list[InstructionBase] = [] for insn in kernel.instructions: if match(kernel, insn): new_predicates = insn.predicates - predicates - new_instructions.append( - insn.copy(predicates=frozenset(new_predicates))) + new_instructions.append(insn.copy(predicates=frozenset(new_predicates))) else: new_instructions.append(insn) @@ -1939,6 +2002,7 @@ def remove_predicates_from_insn(kernel, predicates, insn_match): # {{{ _MapDomainMapper +@final class _MapDomainMapper(RuleAwareIdentityMapper[[]]): old_inames: Set[InameStr] new_inames: Set[InameStr] @@ -1948,7 +2012,7 @@ def __init__(self, rule_mapping_context: SubstitutionRuleMappingContext, new_inames: Set[InameStr], substitutions: Mapping[str, ArithmeticExpression] - ): + ) -> None: super().__init__(rule_mapping_context) self.old_inames = frozenset(substitutions) @@ -1957,7 +2021,8 @@ def __init__(self, self.substitutions = substitutions @override - def map_reduction(self, expr: Reduction, expn_state: ExpansionState): + def map_reduction(self, expr: Reduction, /, + expn_state: ExpansionState) -> Expression: red_overlap = frozenset(expr.inames) & self.old_inames arg_ctx_overlap = frozenset(expn_state.arg_context) & self.old_inames if red_overlap: @@ -1984,7 +2049,6 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): new_inames.remove(old_iname) new_inames.extend(self.new_inames) - from loopy.symbolic import Reduction return Reduction(expr.operation, tuple(new_inames), self.rec(expr.expr, expn_state), expr.allow_simultaneous) @@ -1992,7 +2056,8 @@ def map_reduction(self, expr: Reduction, expn_state: ExpansionState): return super().map_reduction(expr, expn_state) @override - def map_variable(self, expr: Variable, expn_state: ExpansionState): + def map_variable(self, expr: prim.Variable, /, + expn_state: ExpansionState) -> Expression: if (expr.name in self.old_inames and expr.name not in expn_state.arg_context): return self.substitutions[expr.name] @@ -2042,14 +2107,11 @@ def _apply_identity_for_missing_map_dims( # {{{ Find any missing vars and add them to the input and output space - missing_dims = list( - set(desired_dims) - set(mapping.get_var_names(dim_type.in_))) - augmented_mapping = add_and_name_dims( - mapping, dim_type.in_, missing_dims) + missing_dims = list(set(desired_dims) - set(mapping.get_var_names(dim_type.in_))) + augmented_mapping = add_and_name_dims(mapping, dim_type.in_, missing_dims) - missing_dims_proxies = [d+"_'prox'_" for d in missing_dims] - assert not set(missing_dims_proxies) & set( - augmented_mapping.get_var_dict().keys()) + missing_dims_proxies = [f"{d}_'prox'_" for d in missing_dims] + assert not set(missing_dims_proxies) & set(augmented_mapping.get_var_dict().keys()) augmented_mapping = add_and_name_dims( augmented_mapping, dim_type.out, missing_dims_proxies) @@ -2074,7 +2136,7 @@ def _apply_identity_for_missing_map_dims( # {{{ map_domain @for_each_kernel -def map_domain(kernel: LoopKernel, transform_map: isl.BasicMap): +def map_domain(kernel: LoopKernel, transform_map: isl.BasicMap) -> LoopKernel: """Transform an iname domain by applying a mapping from existing inames to new inames. @@ -2110,18 +2172,17 @@ def map_domain(kernel: LoopKernel, transform_map: isl.BasicMap): # {{{ Solve for representation of old inames in terms of new - substitutions = {} - var_substitutions = {} + substitutions: dict[str, ArithmeticExpression] = {} + var_substitutions: dict[prim.Variable, ArithmeticExpression] = {} applied_iname_rewrites = kernel.applied_iname_rewrites - from pymbolic import var out_vars_in_terms_of_in_vars = transform_map.reverse().to_map().as_pw_multi_aff() for iname in transform_map_in_dims: subst_from_map = pw_aff_to_expr( out_vars_in_terms_of_in_vars.get_pw_aff(in_var_dict[iname][1])) substitutions[iname] = subst_from_map - var_substitutions[var(iname)] = subst_from_map + var_substitutions[prim.Variable(iname)] = subst_from_map applied_iname_rewrites = (*applied_iname_rewrites, var_substitutions) del var_substitutions @@ -2130,7 +2191,7 @@ def map_domain(kernel: LoopKernel, transform_map: isl.BasicMap): # {{{ Function to apply mapping to one set - def process_set(s: isl.BasicSet): + def process_set(s: isl.BasicSet) -> isl.BasicSet: """Return the transformed set. Assume that map is applicable to this set.""" @@ -2284,8 +2345,8 @@ def process_set(s: isl.BasicSet): rule_mapping_context = SubstitutionRuleMappingContext( kernel.substitutions, kernel.get_var_name_generator()) - ins = _MapDomainMapper(rule_mapping_context, - transform_map_out_dims, substitutions) + ins = _MapDomainMapper( + rule_mapping_context, transform_map_out_dims, substitutions) kernel = ins.map_kernel(kernel) kernel = rule_mapping_context.finish_kernel(kernel) @@ -2386,8 +2447,8 @@ def add_inames_for_unused_hw_axes(kernel: LoopKernel, for axis in missing_local_axes: iname = local_axes_to_inames[axis] if iname: - insn = insn.copy(within_inames=insn.within_inames | - frozenset([iname])) + insn = insn.copy( + within_inames=insn.within_inames | frozenset([iname])) else: raise LoopyError("Multiple inames tagged with l.%d while" " adding unused local hw axes to instruction '%s'." @@ -2396,8 +2457,8 @@ def add_inames_for_unused_hw_axes(kernel: LoopKernel, for axis in missing_group_axes: iname = group_axes_to_inames[axis] if iname is not None: - insn = insn.copy(within_inames=insn.within_inames | - frozenset([iname])) + insn = insn.copy( + within_inames=insn.within_inames | frozenset([iname])) else: raise LoopyError("Multiple inames tagged with g.%d while" " adding unused group hw axes to instruction '%s'." @@ -2414,8 +2475,8 @@ def add_inames_for_unused_hw_axes(kernel: LoopKernel, @remove_any_newly_unused_inames def rename_inames( kernel: LoopKernel, - old_inames: Collection[str], - new_iname: str, + old_inames: Collection[InameStr], + new_iname: InameStr, existing_ok: bool = False, within: ToStackMatchConvertible = None, raise_on_domain_mismatch: bool | None = None @@ -2429,10 +2490,11 @@ def rename_inames( :math:`\exists (i_1,i_2) \in \{\text{old\_inames}\}^2 | \mathcal{D}_{i_1} \neq \mathcal{D}_{i_2}`. """ - if (isinstance(old_inames, str) - or not isinstance(old_inames, Collection)): - raise LoopyError("'old_inames' must be a collection of strings, " - f"got '{type(old_inames)}'.") + + if isinstance(old_inames, str) or not isinstance(old_inames, Collection): + raise LoopyError("'old_inames' must be a collection of strings: " + f"{type(old_inames)}") + old_inames = frozenset(_to_inames_tuple(old_inames)) if new_iname in old_inames: raise LoopyError("new iname is part of inames being renamed") @@ -2449,16 +2511,16 @@ def rename_inames( if raise_on_domain_mismatch is None: raise_on_domain_mismatch = __debug__ - # sort to have deterministic implementation. - old_inames = sorted(old_inames) - var_name_gen = kernel.get_var_name_generator() - # FIXME: Distinguish existing iname vs. existing other variable + # sort to have deterministic implementation. + sorted_old_inames = sorted(old_inames) + + # FIXME: distinguish existing iname vs. existing other variable does_exist = new_iname in kernel.all_inames() - if not (frozenset(old_inames) <= kernel.all_inames()): - raise LoopyError(f"old inames {frozenset(old_inames) - kernel.all_inames()}" + if not (old_inames <= kernel.all_inames()): + raise LoopyError(f"old inames {old_inames - kernel.all_inames()}" " do not exist.") if does_exist and not existing_ok: @@ -2470,10 +2532,10 @@ def rename_inames( # so that the code below can focus on "merging" inames that already exist kernel = duplicate_inames( - kernel, old_inames[0], within=within, new_inames=[new_iname]) + kernel, sorted_old_inames[0], within=within, new_inames=[new_iname]) # old_iname[0] is already renamed to new_iname => do not rename again. - old_inames = old_inames[1:] + sorted_old_inames = sorted_old_inames[1:] # }}} @@ -2481,7 +2543,7 @@ def rename_inames( assert new_iname in kernel.all_inames() if raise_on_domain_mismatch: - for old_iname in old_inames: + for old_iname in sorted_old_inames: # {{{ check that the domains match up dom = kernel.get_inames_domain(frozenset((old_iname, new_iname))) @@ -2519,8 +2581,8 @@ def rename_inames( # }}} - from pymbolic import var - subst_dict = {old_iname: var(new_iname) for old_iname in old_inames} + subst_dict = {old_iname: prim.Variable(new_iname) + for old_iname in sorted_old_inames} from loopy.match import parse_stack_match within = parse_stack_match(within) @@ -2536,22 +2598,21 @@ def rename_inames( def does_insn_involve_iname( kernel: LoopKernel, insn: InstructionBase, - stack: RuleStack): + stack: RuleStack) -> bool: return bool(not isinstance(insn, MultiAssignmentBase) - or frozenset(old_inames) & insn.dependency_names() - or frozenset(old_inames) & insn.reduction_inames()) + or old_inames & insn.dependency_names() + or old_inames & insn.reduction_inames()) kernel = rule_mapping_context.finish_kernel( smap.map_kernel(kernel, within=does_insn_involve_iname, map_tvs=False, map_args=False)) - new_instructions = [insn.copy(within_inames=((insn.within_inames - - frozenset(old_inames)) - | frozenset([new_iname]))) - if ((len(frozenset(old_inames) & insn.within_inames) != 0) - and within(kernel, insn, ())) - else insn - for insn in kernel.instructions] + new_instructions = [ + insn.copy(within_inames=( + (insn.within_inames - old_inames) | frozenset([new_iname]))) + if ((len(old_inames & insn.within_inames) != 0) and within(kernel, insn, ())) + else insn + for insn in kernel.instructions] kernel = kernel.copy(instructions=new_instructions) @@ -2561,8 +2622,8 @@ def does_insn_involve_iname( @for_each_kernel def rename_iname( kernel: LoopKernel, - old_iname: str, - new_iname: str, + old_iname: InameStr, + new_iname: InameStr, existing_ok: bool = False, within: ToStackMatchConvertible = None, preserve_tags: bool = True, From 45847d0f51f897cfde0d00ef677218f8f6245fa0 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Fri, 12 Dec 2025 21:55:02 +0200 Subject: [PATCH 09/12] docs: improve docs in transform.iname --- loopy/transform/iname.py | 304 +++++++++++++++++++-------------------- 1 file changed, 146 insertions(+), 158 deletions(-) diff --git a/loopy/transform/iname.py b/loopy/transform/iname.py index 4342e5385..ea6d0ec52 100644 --- a/loopy/transform/iname.py +++ b/loopy/transform/iname.py @@ -140,19 +140,21 @@ def prioritize_loops( kernel: LoopKernel, loop_priority: ToInameStrSetConvertible) -> LoopKernel: """Indicates the textual order in which loops should be entered in the - kernel code. Note that this priority has an advisory role only. If the - kernel logically requires a different nesting, priority is ignored. - Priority is only considered if loop nesting is ambiguous. + kernel code. - prioritize_loops can be used multiple times. If you do so, each given - *loop_priority* specifies a scheduling constraint. The constraints from - all calls to prioritize_loops together establish a partial order on the - inames (see https://en.wikipedia.org/wiki/Partially_ordered_set). + Note that this priority has an advisory role only. If the kernel logically + requires a different nesting, the priority is ignored. Priority is only + considered if loop nesting is ambiguous. - :arg: an iterable of inames, or, for brevity, a comma-separated string of - inames - """ + :func:`prioritize_loops` can be used multiple times. If you do so, each + given *loop_priority* specifies a scheduling constraint. The constraints + from all calls to :func:`prioritize_loops` together establish a partial + order on the inames (see `partially ordered sets + `__). + :arg loop_priority: an iterable of inames, or, for brevity, a comma-separated + string of inames. + """ assert isinstance(kernel, LoopKernel) loop_priority = _to_inames_tuple(loop_priority) @@ -297,9 +299,8 @@ def _split_iname_backend( within: ToMatchConvertible = None ) -> LoopKernel: """ - :arg within: If not None, limit the action of the transformation to - matching contexts. See :func:`loopy.match.parse_stack_match` - for syntax. + :arg within: if not *None*, limit the action of the transformation to + matching contexts. See :func:`loopy.match.parse_match` for syntax. """ from loopy.match import parse_match @@ -377,7 +378,7 @@ def _split_iname_backend( kernel = kernel.copy( domains=new_domains, iname_slab_increments=iname_slab_increments, - instructions=new_insns, + instructions=tuple(new_insns), applied_iname_rewrites=(*kernel.applied_iname_rewrites, subst_map), loop_priority=frozenset(new_priorities)) @@ -424,27 +425,24 @@ def split_iname( do_tagged_check: bool = True, within: ToMatchConvertible = None ) -> LoopKernel: - """Split *split_iname* into two inames (an 'inner' one and an 'outer' one) + """Split *split_iname* into two inames (an *inner* one and an *outer* one) so that ``split_iname == inner + outer*inner_length`` and *inner* is of constant length *inner_length*. - :arg outer_iname: The new iname to use for the 'inner' (fixed-length) - loop. Defaults to a name derived from ``split_iname + "_outer"`` - :arg inner_iname: The new iname to use for the 'inner' (fixed-length) - loop. Defaults to a name derived from ``split_iname + "_inner"`` - :arg inner_length: a positive integer - :arg slabs: - A tuple ``(head_it_count, tail_it_count)`` indicating the + Split inames do not inherit tags from their parent inames. + + :arg inner_length: a positive integer. + :arg outer_iname: the new iname to use for the *inner* (fixed-length) + loop. Defaults to a name derived from ``"{split_iname}_outer"``. + :arg inner_iname: the new iname to use for the *inner* (fixed-length) + loop. Defaults to a name derived from ``"{split_iname}_inner"``. + :arg outer_tag: the iname tag (see :ref:`iname-tags`) to apply to *outer_iname*. + :arg inner_tag: the iname tag (see :ref:`iname-tags`) to apply to *inner_iname*. + :arg slabs: a tuple ``(head_it_count, tail_it_count)`` indicating the number of leading/trailing iterations of *outer_iname* for which separate code should be generated. - :arg outer_tag: The iname tag (see :ref:`iname-tags`) to apply to - *outer_iname*. - :arg inner_tag: The iname tag (see :ref:`iname-tags`) to apply to - *inner_iname*. - :arg within: a stack match as understood by - :func:`loopy.match.parse_match`. - - Split inames do not inherit tags from their 'parent' inames. + :arg do_tagged_check: if *True*, check if the iname was already split. + :arg within: a match, as understood by :func:`loopy.match.parse_match`. """ assert isinstance(kernel, LoopKernel) @@ -477,15 +475,14 @@ def chunk_iname( do_tagged_check: bool = True, within: ToMatchConvertible = None ) -> LoopKernel: - """ - Split *split_iname* into two inames (an 'inner' one and an 'outer' one) + """Split *split_iname* into two inames (an *inner* one and an *outer* one) so that ``split_iname == inner + outer*chunk_length`` and *outer* is of fixed length *num_chunks*. - :arg within: a stack match as understood by - :func:`loopy.match.parse_stack_match`. + Split inames do not inherit tags from their parent inames. See + :func:`split_iname` for a description of the arguments. - Split inames do not inherit tags from their 'parent' inames. + :arg within: a match, as understood by :func:`loopy.match.parse_match`. .. versionadded:: 2016.2 """ @@ -549,9 +546,9 @@ def make_new_loop_index( box_dom <= dom and dom <= box_dom): - raise LoopyError("domain '%s' is not box-shape about iname " - "'%s', cannot use chunk_iname()" - % (dom, split_iname)) + raise LoopyError( + f"domain '{dom}' is not box-shape about iname " + f"'{split_iname}', cannot use chunk_iname()") # }}} @@ -623,17 +620,20 @@ def join_inames( new_iname: InameStr | None = None, tag: Tag | None = None, within: ToMatchConvertible = None) -> LoopKernel: - """In a sense, the inverse of :func:`split_iname`. Takes in inames, - finds their bounds (all but the first have to be bounded), and combines - them into a single loop via analogs of ``new_iname = i0 * LEN(i1) + i1``. - The old inames are re-obtained via the appropriate division/modulo - operations. - - :arg inames: a sequence of inames, fastest varying last - :arg within: a stack match as understood by - :func:`loopy.match.parse_stack_match`. + """In a sense, the inverse of :func:`split_iname`. + + Takes in inames, finds their bounds (all but the first have to be bounded), + and combines them into a single loop via analogs of ``new_iname = i0 * + len(i1) + i1``. The old inames can be re-obtained via the appropriate + division/modulo operations. + + :arg inames: a sequence of inames, fastest varying last. + :arg within: a match, as understood by :func:`loopy.match.parse_match`. """ + if isinstance(inames, str): + inames = [inames] + from loopy.match import parse_match within = parse_match(within) @@ -752,12 +752,11 @@ def untag_inames( kernel: LoopKernel, iname_to_untag: InameStr, tag_type: type[Tag]) -> LoopKernel: - """ - Remove tags on *iname_to_untag* which matches *tag_type*. + """Remove tags on *iname_to_untag* which matches *tag_type*. :arg iname_to_untag: iname as string. - :arg tag_type: a subclass of :class:`pytools.tag.Tag`, for example a - subclass of :class:`loopy.kernel.data.InameImplementationTag`. + :arg tag_type: a subclass of :class:`~pytools.tag.Tag`, for example a + subclass of :class:`~loopy.kernel.data.InameImplementationTag`. .. versionadded:: 2018.1 """ @@ -789,14 +788,21 @@ def tag_inames( force: bool | None = None, ignore_nonexistent: bool = False ) -> LoopKernel: - """Tag an iname + """Tag an iname. + + The iname to tags mapping can be given in several forms: + + * A sequence of tuples ``(iname, new_tags)``, where *new_tags* is a collection + of instances of :class:`~pytools.tag.Tag` (for example, a subclass of + :class:`~loopy.kernel.data.InameImplementationTag`). + * A string of comma-separated ``iname:new_tag`` formatted entries. Note that + in this format, it is not possible to pass in multiple tags for an iname. + * (deprecated) a mapping of inames to collections of tags. + + *iname* may also be a wildcard using ``*`` or ``?``. - :arg iname_to_tag: a list of tuples ``(iname, new_tag)``. *new_tag* is given - as an instance of a subclass of :class:`pytools.tag.Tag`, for example a - subclass of :class:`loopy.kernel.data.InameImplementationTag`. - May also be iterable of which, or as a string as shown in - :ref:`iname-tags`. May also be a dictionary for backwards - compatibility. *iname* may also be a wildcard using ``*`` and ``?``. + :arg iname_to_tag: a mapping of inames to their corresponding tags in one of + the formats described above. .. versionchanged:: 2016.3 @@ -1005,8 +1011,8 @@ def duplicate_inames(kernel: LoopKernel, new_iname = name_gen(new_iname) else: if name_gen.is_name_conflicting(new_iname): - raise ValueError("new iname '%s' conflicts with existing names" - % new_iname) + raise ValueError( + f"new iname '{new_iname}' conflicts with existing names") name_gen.add_name(new_iname) @@ -1147,12 +1153,12 @@ def join_sets_if_not_disjoint( def get_iname_duplication_options( kernel: LoopKernel ) -> Iterator[tuple[InameStr, MatchExpressionBase]]: - """List options for duplication of inames, if necessary for schedulability + """List options for duplication of inames, if necessary for schedulability. :returns: a generator listing all options to duplicate inames, if duplication of an iname is necessary to ensure the schedulability of the kernel. Duplication options are returned as tuples (iname, within) as - understood by :func:`duplicate_inames`. There is no guarantee, that the + understood by :func:`duplicate_inames`. There is no guarantee that the transformed kernel will be schedulable, because multiple duplications of iname may be necessary. @@ -1253,10 +1259,10 @@ def remove_unused_inames( kernel: LoopKernel, inames: ToInameStrSetConvertible | None = None ) -> LoopKernel: - """Delete those among *inames* that are unused, i.e. project them - out of the domain. If these inames pose implicit restrictions on - other inames, these restrictions will persist as existentially - quantified variables. + """Delete those among *inames* that are unused, i.e. project them out of the domain. + + If these inames pose implicit restrictions on other inames, these + restrictions will persist as existentially quantified variables. :arg inames: may be an iterable of inames or a string of comma-separated inames. """ @@ -1415,17 +1421,17 @@ def split_reduction_inward( within: ToStackMatchConvertible = None) -> LoopKernel: """Takes a reduction of the form:: - sum([i,j,k], ...) + sum([i, j, k], ...) and splits it into two nested reductions:: - sum([j,k], sum([i], ...)) + sum([j, k], sum([i], ...)) In this case, *inames* would have been ``"i"`` indicating that the iname ``i`` should be made the iname governing the inner reduction. - :arg inames: a list of inames, or a comma-separated string that can - be parsed into those + :arg inames: an iterable of inames, or a comma-separated string that can + be parsed into those. """ return _split_reduction(kernel, inames, "in", within) @@ -1438,17 +1444,17 @@ def split_reduction_outward( within: ToStackMatchConvertible = None) -> LoopKernel: """Takes a reduction of the form:: - sum([i,j,k], ...) + sum([i, j, k], ...) and splits it into two nested reductions:: - sum([i], sum([j,k], ...)) + sum([i], sum([j, k], ...)) In this case, *inames* would have been ``"i"`` indicating that the iname ``i`` should be made the iname governing the outer reduction. - :arg inames: A list of inames, or a comma-separated string that can - be parsed into those + :arg inames: an iterable of inames, or a comma-separated string that can + be parsed into those. """ return _split_reduction(kernel, inames, "out", within) @@ -1467,19 +1473,16 @@ def affine_map_inames( equations: Sequence[tuple[ArithmeticExpression, ArithmeticExpression] | str] ) -> LoopKernel: - """Return a new *kernel* where the affine transform - specified by *equations* has been applied to the inames. + """Return a new *kernel* where the affine transform specified by *equations* + has been applied to the inames. - :arg old_inames: A list of inames to be replaced by affine transforms - of their values. - May also be a string of comma-separated inames. - - :arg new_inames: A list of new inames that are not yet used in *kernel*, + :arg old_inames: an iterable of inames to be replaced by affine transforms + of their values. May also be a string of comma-separated inames. + :arg new_inames: an iterable of new inames that are not yet used in *kernel*, but have their values established in terms of *old_inames* by - *equations*. - May also be a string of comma-separated inames. - :arg equations: A list of equations establishing a relationship - between *old_inames* and *new_inames*. Each equation may be + *equations*. May also be a string of comma-separated inames. + :arg equations: a sequence of equations establishing a relationship + between *old_inames* and *new_inames*. Each equation should be a tuple ``(lhs, rhs)`` of expressions or a string, with left and right hand side of the equation separated by ``=``. """ @@ -1678,15 +1681,13 @@ def find_unused_axis_tag( kind: Literal["l", "g"] | type[GroupInameTag | LocalInameTag], insn_match: ToMatchConvertible = None, ) -> GroupInameTag | LocalInameTag: - """For one of the hardware-parallel execution tags, find an unused - axis. + """For one of the hardware-parallel execution tags, find an unused axis. - :arg insn_match: An instruction match as understood by - :func:`loopy.match.parse_match`. - :arg kind: may be "l" or "g", or the corresponding tag class name + :arg insn_match: a match as understood by :func:`loopy.match.parse_match`. + :arg kind: may be "l" or "g", or the corresponding tag class name. - :returns: an :class:`loopy.kernel.data.GroupInameTag` or - :class:`loopy.kernel.data.LocalInameTag` that is not being used within + :returns: an :class:`~loopy.kernel.data.GroupInameTag` or + :class:`~loopy.kernel.data.LocalInameTag` that is not being used within the instructions matched by *insn_match*. """ from loopy.kernel.data import GroupInameTag, LocalInameTag @@ -1823,8 +1824,7 @@ def make_reduction_inames_unique( within: ToStackMatchConvertible | None = None) -> LoopKernel: """ :arg inames: if not *None*, only apply to these inames. - :arg within: a stack match as understood by - :func:`loopy.match.parse_stack_match`. + :arg within: a stack match as understood by :func:`loopy.match.parse_stack_match`. .. versionadded:: 2016.2 """ @@ -1884,11 +1884,10 @@ def add_inames_to_insn(kernel: LoopKernel, inames: ToInameStrSetConvertible, insn_match: ToMatchConvertible) -> LoopKernel: """ - :arg inames: a frozenset of inames that will be added to the + :arg inames: an iterable of inames that will be added to the instructions matched by *insn_match*, or a comma-separated - string that parses to such a tuple. - :arg insn_match: An instruction match as understood by - :func:`loopy.match.parse_match`. + string that parses to such an iterable. + :arg insn_match: a match as understood by :func:`loopy.match.parse_match`. :returns: a :class:`LoopKernel` with the *inames* added to the instructions matched by *insn_match*. @@ -1920,20 +1919,20 @@ def remove_inames_from_insn( kernel: LoopKernel, inames: ToInameStrSetConvertible, insn_match: ToMatchConvertible) -> LoopKernel: - """ - :arg inames: a frozenset of inames that will be added to the - instructions matched by *insn_match*. - :arg insn_match: An instruction match as understood by - :func:`loopy.match.parse_match`. - - :returns: a :class:`LoopKernel` with the *inames* removed from - the instructions matched by *insn_match*. + """Remove inames from kernel instructions. This transformation is useful when an iname is added to an instruction in a sub-kernel by an inlining call because the kernel invocation itself has the iname. When the instruction does not depend on the iname, this transformation can be used - for removing that iname. + to remove that iname. + + :arg inames: an iterable of inames that will be added to the + instructions matched by *insn_match*. + :arg insn_match: a match as understood by :func:`loopy.match.parse_match`. + + :returns: a :class:`LoopKernel` with the *inames* removed from + the instructions matched by *insn_match*. .. versionadded:: 2023.0 """ @@ -1962,14 +1961,7 @@ def remove_predicates_from_insn( kernel: LoopKernel, predicates: frozenset[Expression], insn_match: ToMatchConvertible) -> LoopKernel: - """ - :arg predicates: a frozenset of predicates that will be added to the - instructions matched by *insn_match* - :arg insn_match: An instruction match as understood by - :func:`loopy.match.parse_match`. - - :returns: a :class:`LoopKernel` with the *predicates* removed from - the instructions matched by *insn_match*. + """Remove predicates from kernel instructions. This transformation is useful when a predicate is added to an instruction in a sub-kernel by an inlining call because the @@ -1977,6 +1969,13 @@ def remove_predicates_from_insn( does not depend on the predicate, this transformation can be used for removing that predicate. + :arg predicates: a frozenset of predicates that will be added to the + instructions matched by *insn_match* + :arg insn_match: a match as understood by :func:`loopy.match.parse_match`. + + :returns: a :class:`LoopKernel` with the *predicates* removed from + the instructions matched by *insn_match*. + .. versionadded:: 2023.0 """ if not isinstance(predicates, frozenset): @@ -2071,21 +2070,19 @@ def map_variable(self, expr: prim.Variable, /, def _apply_identity_for_missing_map_dims( mapping: isl.BasicMap, - desired_dims: Sequence[str]): - """For every variable v in *desired_dims* that is not found in the - input space for *mapping*, add input dimension v, output dimension - v_'proxy'_, and constraint v = v_'proxy'_ to the mapping. Also return a - list of the (v, v_'proxy'_) pairs. - - :arg mapping: An :class:`islpy.Map`. - - :arg desired_dims: An iterable of :class:`str` specifying the names of the + desired_dims: Sequence[str], + ) -> tuple[isl.BasicMap, Sequence[tuple[str, str]]]: + """For every variable *v* in *desired_dims* that is not found in the + input space for *mapping*, add input dimension *v*, output dimension + ``v_'proxy'_``, and constraint ``v = v_'proxy'_`` to the mapping. + + :arg mapping: an :class:`islpy.BasicMap`. + :arg desired_dims: a sequence of :class:`str` specifying the names of the desired map input dimensions. - :returns: A two-tuple containing the mapping with the new dimensions and - constraints added, and a list of two-tuples of :class:`str` values - specifying the (v, v_'proxy'_) pairs. - + :returns: a pair containing the mapping with the new dimensions and + constraints added, and sequence of pairs of :class:`str` values + specifying the ``(v, v_'proxy'_)`` pairs. """ # If the transform map in map_domain (below) does not contain all the @@ -2140,11 +2137,10 @@ def map_domain(kernel: LoopKernel, transform_map: isl.BasicMap) -> LoopKernel: """Transform an iname domain by applying a mapping from existing inames to new inames. - :arg transform_map: A bijective :class:`islpy.Map` from existing inames to + :arg transform_map: a bijective :class:`islpy.BasicMap` from existing inames to new inames. To be applicable to a kernel domain, all input inames in the map must be found in the domain. The map must be applicable to exactly one domain found in *kernel.domains*. - """ # FIXME: Express _split_iname_backend in terms of this @@ -2273,18 +2269,14 @@ def process_set(s: isl.BasicSet) -> isl.BasicSet: "inames are a subset of the domain inames.") for old_domain in kernel.domains: - # Make sure transform map is applicable to this set. Then transform. - if not transform_map_in_dims <= frozenset(old_domain.get_var_dict()): - # Map not applicable to this set because map transforms at least # one iname that is not present in the set. Don't transform. new_domains.append(old_domain) continue elif map_applied_to_one_dom: - # Map is applicable to this domain, but this map was # already applied. Error. raise LoopyError( @@ -2292,7 +2284,6 @@ def process_set(s: isl.BasicSet) -> isl.BasicSet: % (transform_map, transform_map_rules)) else: - # Map is applicable to this domain, and this map has not yet # been applied. Transform. new_domains.append(process_set(old_domain)) @@ -2362,11 +2353,10 @@ def process_set(s: isl.BasicSet) -> isl.BasicSet: def add_inames_for_unused_hw_axes(kernel: LoopKernel, within: ToMatchConvertible = None) -> LoopKernel: """ - Returns a kernel with inames added to each instruction - corresponding to any hardware-parallel iname tags - (:class:`loopy.kernel.data.GroupInameTag`, - :class:`loopy.kernel.data.LocalInameTag`) unused - in the instruction but used elsewhere in the kernel. + Returns a kernel with inames added to each instruction corresponding to any + hardware-parallel iname tags (:class:`~loopy.kernel.data.GroupInameTag`, + :class:`~loopy.kernel.data.LocalInameTag`) unused in the instruction but + used elsewhere in the kernel. Current limitations: @@ -2374,8 +2364,7 @@ def add_inames_for_unused_hw_axes(kernel: LoopKernel, * Occurrence of an ``l.auto`` tag when an instruction is missing one of the local hw axes. - :arg within: An instruction match as understood by - :func:`loopy.match.parse_match`. + :arg within: a match, as understood by :func:`loopy.match.parse_match`. """ from loopy.kernel.data import AutoFitLocalInameTag, GroupInameTag, LocalInameTag @@ -2482,11 +2471,10 @@ def rename_inames( raise_on_domain_mismatch: bool | None = None ) -> LoopKernel: r""" - :arg old_inames: A collection of inames that must be renamed to **new_iname**. - :arg within: a stack match as understood by - :func:`loopy.match.parse_stack_match`. - :arg existing_ok: execute even if *new_iname* already exists - :arg raise_on_domain_mismatch: If *True*, raises an error if + :arg old_inames: a collection of inames that must be renamed to *new_iname*. + :arg within: a stack match, as understood by :func:`loopy.match.parse_stack_match`. + :arg existing_ok: execute even if *new_iname* already exists. + :arg raise_on_domain_mismatch: if *True*, raises an error if :math:`\exists (i_1,i_2) \in \{\text{old\_inames}\}^2 | \mathcal{D}_{i_1} \neq \mathcal{D}_{i_2}`. """ @@ -2497,16 +2485,15 @@ def rename_inames( old_inames = frozenset(_to_inames_tuple(old_inames)) if new_iname in old_inames: - raise LoopyError("new iname is part of inames being renamed") + raise LoopyError("'new_iname' is part of inames being renamed: " + f"'{new_iname}' in {old_inames}") - if new_iname in (kernel.all_variable_names() - kernel.all_inames()): - raise LoopyError(f"New iname '{new_iname}' is already a variable in the" - "kernel") + if new_iname in (kinames := (kernel.all_variable_names() - kernel.all_inames())): + raise LoopyError(f"new iname '{new_iname}' is already a variable in the" + f"kernel: {kinames}") - if any((len(insn.within_inames & frozenset(old_inames)) > 1) - for insn in kernel.instructions): - raise LoopyError("old_inames contains nested inames" - " -- renaming is illegal.") + if any((len(insn.within_inames & old_inames) > 1) for insn in kernel.instructions): + raise LoopyError("'old_inames' contains nested inames -- renaming is illegal") if raise_on_domain_mismatch is None: raise_on_domain_mismatch = __debug__ @@ -2631,12 +2618,13 @@ def rename_iname( ) -> LoopKernel: r""" Single iname version of :func:`loopy.rename_inames`. + :arg existing_ok: execute even if *new_iname* already exists. - :arg within: a stack match understood by :func:`loopy.match.parse_stack_match`. + :arg within: a stack match, as understood by :func:`loopy.match.parse_stack_match`. :arg preserve_tags: copy the tags on the old iname to the new iname. :arg raise_on_domain_mismatch: If *True*, raises an error if - :math:`\exists (i_1,i_2) \in \{\text{old\_inames}\}^2 | - \mathcal{D}_{i_1} \neq \mathcal{D}_{i_2}`. + :math:`\exists (i_1,i_2) \in \{\text{old\_inames}\}^2 | + \mathcal{D}_{i_1} \neq \mathcal{D}_{i_2}`. """ from itertools import product From a0358500dcb611b6fe3703ea0f87097e5d8040a1 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 14 Dec 2025 14:59:31 +0200 Subject: [PATCH 10/12] feat: use more f-strings in transform.iname --- loopy/transform/iname.py | 138 +++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 70 deletions(-) diff --git a/loopy/transform/iname.py b/loopy/transform/iname.py index ea6d0ec52..33095d782 100644 --- a/loopy/transform/iname.py +++ b/loopy/transform/iname.py @@ -133,6 +133,10 @@ def _to_inames_tuple(inames: ToInameStrSetConvertible) -> tuple[InameStr, ...]: return tuple(inames) +def _to_inames_str(inames: Collection[str]) -> str: + return ", ".join(inames) + + # {{{ set loop priority @for_each_kernel @@ -248,7 +252,7 @@ def _split_iname_in_set( break else: # NOTE: this should never happen, but it's a way to let pyright know - raise ValueError(f"could not generate unique names for {iname_to_split}") + raise ValueError(f"could not generate unique names for {iname_to_split!r}") from loopy.isl_helpers import duplicate_axes s = duplicate_axes(s, (iname_to_split,), (dup_iname_to_split,)) @@ -378,7 +382,7 @@ def _split_iname_backend( kernel = kernel.copy( domains=new_domains, iname_slab_increments=iname_slab_increments, - instructions=tuple(new_insns), + instructions=new_insns, applied_iname_rewrites=(*kernel.applied_iname_rewrites, subst_map), loop_priority=frozenset(new_priorities)) @@ -586,24 +590,18 @@ def __init__(self, @override def map_reduction(self, expr: Reduction, /, expn_state: ExpansionState) -> Expression: - expr_inames = set(expr.inames) - overlap = (self.joined_inames & expr_inames - - set(expn_state.arg_context)) + expr_inames = frozenset(expr.inames) + overlap = self.joined_inames & expr_inames - set(expn_state.arg_context) if overlap and self.within( expn_state.kernel, expn_state.instruction, expn_state.stack): if overlap != expr_inames: raise LoopyError( - "Cannot join inames '%s' if there is a reduction " - "that does not use all of the inames being joined. " - "(Found one with just '%s'.)" - % ( - ", ".join(self.joined_inames), - ", ".join(expr_inames))) - - new_inames = expr_inames - self.joined_inames - new_inames.add(self.new_iname) + f"Cannot join inames '{_to_inames_str(self.joined_inames)}' " + "if there is a reduction that does not use all of the " + "inames being joined. (Found one with just " + f"'{_to_inames_str(expr_inames)}'.)") new_inames = (expr_inames - self.joined_inames) | {self.new_iname} return Reduction(expr.operation, tuple(sorted(new_inames)), @@ -655,8 +653,8 @@ def join_inames( domch = DomainChanger(kernel, frozenset(inames)) for iname in inames: if kernel.get_home_domain_index(iname) != domch.leaf_domain_index: - raise LoopyError("iname '%s' is not 'at home' in the " - "join's leaf domain" % iname) + raise LoopyError( + f"iname '{iname}' is not 'at home' in the join's leaf domain") new_domain = domch.domain new_dim_idx = new_domain.dim(dim_type.set) @@ -685,7 +683,7 @@ def join_inames( bounds.lower_bound_pw_aff.coalesce(), constants_only=False) except Exception as e: - raise type(e)("while finding lower bound of '%s': " % iname) from e + raise type(e)(f"while finding lower bound of '{iname}': ") from e my_val = prim.Variable(new_iname) // base_divisor if i+1 < len(inames): @@ -1385,7 +1383,7 @@ def map_reduction(self, expr: Reduction, /, expr.allow_simultaneous), expr.allow_simultaneous) else: - raise AssertionError() + raise ValueError(f"unsupported direction: {self.direction!r}") else: return super().map_reduction(expr, expn_state) @@ -1506,7 +1504,7 @@ def parse_equation( if isinstance(eqn, str): eqn_match = eqn_re.match(eqn) if not eqn_match: - raise ValueError("invalid equation: %s" % eqn) + raise ValueError(f"invalid equation: {eqn}") from loopy.symbolic import parse lhs = parse(eqn_match.group(1)) @@ -1530,12 +1528,11 @@ def parse_equation( all_vars = kernel.all_variable_names() for iname in new_inames: if iname in all_vars: - raise LoopyError("new iname '%s' is already used in kernel" - % iname) + raise LoopyError(f"new iname '{iname}' is already used in kernel") for iname in old_inames: if iname not in kernel.all_inames(): - raise LoopyError("old iname '%s' not known" % iname) + raise LoopyError(f"old iname '{iname}' not known") # }}} @@ -1605,10 +1602,10 @@ def parse_equation( if this_eqn_old_iname_dim_types: if len(this_eqn_old_iname_dim_types) > 1: - raise ValueError("inames '%s' (from equation %d (0-based)) " - "in domain %d (0-based) are not " - "of a uniform dim_type" - % (", ".join(eqn_deps & old_inames_set), ieqn, idom)) + raise ValueError( + f"inames '{_to_inames_str(eqn_deps & old_inames_set)}' " + f"(from equation {ieqn} (0-based)) in domain {idom} " + "(0-based) are not of a uniform dim_type") this_eqn_new_iname_dim_type, = this_eqn_old_iname_dim_types @@ -1616,18 +1613,19 @@ def parse_equation( if new_iname in new_iname_dim_types: if (this_eqn_new_iname_dim_type != new_iname_dim_types[new_iname]): - raise ValueError("dim_type disagreement for " - "iname '%s' (from equation %d (0-based)) " - "in domain %d (0-based)" - % (new_iname, ieqn, idom)) + raise ValueError( + "dim_type disagreement for iname " + f"'{new_iname}' (from equation {ieqn} " + f"(0-based)) in domain {idom} (0-based)") else: new_iname_dim_types[new_iname] = \ this_eqn_new_iname_dim_type if not dom_old_inames <= set(dom_var_dict): - raise ValueError("domain %d (0-based) does not know about " - "all old inames (specifically '%s') needed to define new inames" - % (idom, ", ".join(dom_old_inames - set(dom_var_dict)))) + raise ValueError( + f"domain {idom} (0-based) does not know about all old inames " + f"(specifically {_to_inames_str(dom_old_inames-set(dom_var_dict))}" + ") needed to define new inames") # add inames to domain with correct dim_types for iname in dom_new_inames: @@ -1657,9 +1655,10 @@ def fix_iname_set(insn_id: InsnId, inames: InameStrSet) -> InameStrSet: if old_inames_set <= inames: return (inames - old_inames_set) | new_inames_set elif old_inames_set & inames: - raise LoopyError("instruction '%s' uses only a part (%s), not all, " - "of the old inames" - % (insn_id, ", ".join(old_inames_set & inames))) + raise LoopyError( + f"instruction '{insn_id}' uses only a part " + f"({_to_inames_str(old_inames_set & inames)}), not all, " + "of the old inames") else: return inames @@ -1699,7 +1698,7 @@ def find_unused_axis_tag( kind_cls = cls break else: - raise LoopyError("invalid tag kind: %s" % kind) + raise LoopyError(f"invalid tag kind: {kind!r}") else: kind_cls = kind @@ -1979,7 +1978,7 @@ def remove_predicates_from_insn( .. versionadded:: 2023.0 """ if not isinstance(predicates, frozenset): - raise TypeError("'predicates' must be a frozenset") + raise TypeError(f"'predicates' must be a frozenset: {type(predicates)}") from loopy.match import parse_match match = parse_match(insn_match) @@ -2026,10 +2025,10 @@ def map_reduction(self, expr: Reduction, /, arg_ctx_overlap = frozenset(expn_state.arg_context) & self.old_inames if red_overlap: if len(red_overlap) != len(self.old_inames): - raise LoopyError("Reduction '%s' involves a part " - "of the map domain inames. Reductions must " - "either involve all or none of the map domain " - "inames." % str(expr)) + raise LoopyError( + f"Reduction '{expr}' involves a part of the map domain " + "inames. Reductions must either involve all or none of " + "the map domain inames.") if arg_ctx_overlap: if arg_ctx_overlap == red_overlap: @@ -2037,11 +2036,10 @@ def map_reduction(self, expr: Reduction, /, return super().map_reduction( expr, expn_state) else: - raise LoopyError("Reduction '%s' has" - "some of the reduction variables affected " - "by the map_domain shadowed by context. " - "Either all or none must be shadowed." - % str(expr)) + raise LoopyError( + f"Reduction '{expr}' has some of the reduction " + "variables affected by the map_domain shadowed by context. " + "Either all or none must be shadowed.") new_inames = list(expr.inames) for old_iname in self.old_inames: @@ -2161,8 +2159,8 @@ def map_domain(kernel: LoopKernel, transform_map: isl.BasicMap) -> LoopKernel: for prio in kernel.loop_priority: if set(prio) & transform_map_in_dims: raise ValueError( - "Loop priority %s contains iname(s) transformed by " - "map %s in map_domain." % (prio, transform_map)) + f"Loop priority {prio!r} contains iname(s) transformed by " + f"map {transform_map} in map_domain.") # }}} @@ -2280,8 +2278,8 @@ def process_set(s: isl.BasicSet) -> isl.BasicSet: # Map is applicable to this domain, but this map was # already applied. Error. raise LoopyError( - "Transform map %s was applicable to more than one domain. %s" - % (transform_map, transform_map_rules)) + f"Transform map {transform_map} was applicable to more than " + f"one domain. {transform_map_rules}") else: # Map is applicable to this domain, and this map has not yet @@ -2293,8 +2291,8 @@ def process_set(s: isl.BasicSet) -> isl.BasicSet: # or the map could not be applied to any domain, which should produce an error. if not map_applied_to_one_dom: raise LoopyError( - "Transform map %s was not applicable to any domain. %s" - % (transform_map, transform_map_rules)) + f"Transform map {transform_map} was not applicable to any domain. " + f"{transform_map_rules}") # }}} @@ -2314,10 +2312,10 @@ def process_set(s: isl.BasicSet) -> isl.BasicSet: overlap = transform_map_in_dims & stmt.within_inames if overlap: if len(overlap) != len(transform_map_in_dims): - raise LoopyError("Statement '%s' is within only a part " - "of the mapped inames in transformation map %s. " - "Statements must be within all or none of the mapped " - "inames." % (stmt.id, transform_map)) + raise LoopyError( + f"Statement '{stmt.id}' is within only a part of the mapped " + f"inames in transformation map {transform_map}. Statements " + "must be within all or none of the mapped inames.") stmt = stmt.copy(within_inames=( stmt.within_inames - transform_map_in_dims) | transform_map_out_dims) @@ -2385,8 +2383,7 @@ def add_inames_for_unused_hw_axes(kernel: LoopKernel, for tag in iname.tags) if contains_auto_local_tag: - raise LoopyError("Kernels containing l.auto tags are invalid" - " arguments.") + raise LoopyError("kernels containing 'l.auto' tags are invalid arguments") # {{{ fill axes_to_inames @@ -2403,7 +2400,7 @@ def add_inames_for_unused_hw_axes(kernel: LoopKernel, for name, iname in kernel.inames.items() if ith_local_axes_tag in iname.tags] if not inames: - raise LoopyError(f"Unused local hw axes {i}.") + raise LoopyError(f"unused local hw axes: {i}") local_axes_to_inames.append(inames[0] if len(inames) == 1 else None) @@ -2413,7 +2410,7 @@ def add_inames_for_unused_hw_axes(kernel: LoopKernel, for name, iname in kernel.inames.items() if ith_group_axes_tag in iname.tags] if not inames: - raise LoopyError(f"Unused group hw axes {i}.") + raise LoopyError(f"unused group hw axes: {i}") group_axes_to_inames.append(inames[0] if len(inames) == 1 else None) @@ -2439,9 +2436,9 @@ def add_inames_for_unused_hw_axes(kernel: LoopKernel, insn = insn.copy( within_inames=insn.within_inames | frozenset([iname])) else: - raise LoopyError("Multiple inames tagged with l.%d while" - " adding unused local hw axes to instruction '%s'." - % (axis, insn.id)) + raise LoopyError( + f"multiple inames tagged with 'l.{axis}' while " + f"adding unused local hw axes to instruction '{insn.id}'") for axis in missing_group_axes: iname = group_axes_to_inames[axis] @@ -2449,9 +2446,9 @@ def add_inames_for_unused_hw_axes(kernel: LoopKernel, insn = insn.copy( within_inames=insn.within_inames | frozenset([iname])) else: - raise LoopyError("Multiple inames tagged with g.%d while" - " adding unused group hw axes to instruction '%s'." - % (axis, insn.id)) + raise LoopyError( + f"multiple inames tagged with 'g.{axis}' while " + f"adding unused group hw axes to instruction '{insn.id}'") new_insns.append(insn) @@ -2486,7 +2483,7 @@ def rename_inames( if new_iname in old_inames: raise LoopyError("'new_iname' is part of inames being renamed: " - f"'{new_iname}' in {old_inames}") + f"'{new_iname}' in {_to_inames_str(old_inames)}") if new_iname in (kinames := (kernel.all_variable_names() - kernel.all_inames())): raise LoopyError(f"new iname '{new_iname}' is already a variable in the" @@ -2507,8 +2504,9 @@ def rename_inames( does_exist = new_iname in kernel.all_inames() if not (old_inames <= kernel.all_inames()): - raise LoopyError(f"old inames {old_inames - kernel.all_inames()}" - " do not exist.") + raise LoopyError( + f"old inames {_to_inames_str(old_inames - kernel.all_inames())}" + " do not exist.") if does_exist and not existing_ok: raise LoopyError(f"iname '{new_iname}' conflicts with an existing identifier" From e832c01f88110acaed0d224582a92ea489d36073 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 14 Dec 2025 20:07:17 +0200 Subject: [PATCH 11/12] feat: assume only sequence for LoopKernel.domains --- loopy/transform/callable.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/loopy/transform/callable.py b/loopy/transform/callable.py index 77b8900b3..dfa10896e 100644 --- a/loopy/transform/callable.py +++ b/loopy/transform/callable.py @@ -298,8 +298,7 @@ def _inline_call_instruction(caller_knl, callee_knl, call_insn): # {{{ iname_to_tags # new_inames: caller's inames post inlining - new_inames = caller_knl.inames.copy() - + new_inames = dict(caller_knl.inames) for old_name, callee_iname in callee_knl.inames.items(): new_name = name_map[old_name] new_inames[new_name] = callee_iname.copy(name=new_name) @@ -337,7 +336,7 @@ def _inline_call_instruction(caller_knl, callee_knl, call_insn): # {{{ process domains/assumptions # rename inames - new_domains = callee_knl.domains.copy() + new_domains = list(callee_knl.domains) for old_iname in callee_knl.all_inames(): new_domains = [rename_iname(dom, old_iname, name_map[old_iname]) for dom in new_domains] @@ -481,7 +480,7 @@ def _inline_call_instruction(caller_knl, callee_knl, call_insn): return caller_knl.copy(instructions=new_insns, temporary_variables=new_temps, - domains=caller_knl.domains+new_domains, + domains=[*caller_knl.domains, *new_domains], assumptions=(old_assumptions.params() & new_assumptions.params()), inames=new_inames, From ae1f9de79f717a373987813388c9bf6cccd5ca91 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Tue, 16 Dec 2025 21:29:49 +0200 Subject: [PATCH 12/12] chore: update baseline --- .basedpyright/baseline.json | 2800 +---------------------------------- 1 file changed, 56 insertions(+), 2744 deletions(-) diff --git a/.basedpyright/baseline.json b/.basedpyright/baseline.json index 7a88c6fce..fa11e913d 100644 --- a/.basedpyright/baseline.json +++ b/.basedpyright/baseline.json @@ -6465,14 +6465,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 50, - "endColumn": 53, - "lineCount": 1 - } - }, { "code": "reportUnknownParameterType", "range": { @@ -19560,106 +19552,26 @@ ], "./loopy/isl_helpers.py": [ { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 14, - "endColumn": 19, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 14, - "endColumn": 19, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 21, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 21, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 28, - "endColumn": 33, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 28, - "endColumn": 33, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 35, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 35, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 41, - "endColumn": 57, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 34, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", + "code": "reportOperatorIssue", "range": { - "startColumn": 41, - "endColumn": 49, + "startColumn": 20, + "endColumn": 54, "lineCount": 1 } }, { "code": "reportUnknownArgumentType", "range": { - "startColumn": 51, - "endColumn": 60, + "startColumn": 20, + "endColumn": 54, "lineCount": 1 } }, { - "code": "reportUnknownArgumentType", + "code": "reportOperatorIssue", "range": { "startColumn": 20, - "endColumn": 54, + "endColumn": 55, "lineCount": 1 } }, @@ -57143,14 +57055,6 @@ "lineCount": 1 } }, - { - "code": "reportUnusedParameter", - "range": { - "startColumn": 41, - "endColumn": 55, - "lineCount": 1 - } - }, { "code": "reportUnusedParameter", "range": { @@ -67007,14 +66911,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 70, - "endColumn": 80, - "lineCount": 1 - } - }, { "code": "reportUnknownParameterType", "range": { @@ -79938,15 +79834,15 @@ { "code": "reportUnknownMemberType", "range": { - "startColumn": 17, - "endColumn": 34, + "startColumn": 22, + "endColumn": 39, "lineCount": 1 } }, { - "code": "reportUnknownMemberType", + "code": "reportUnknownArgumentType", "range": { - "startColumn": 17, + "startColumn": 22, "endColumn": 39, "lineCount": 1 } @@ -80066,15 +79962,15 @@ { "code": "reportUnknownMemberType", "range": { - "startColumn": 18, - "endColumn": 36, + "startColumn": 23, + "endColumn": 41, "lineCount": 1 } }, { - "code": "reportUnknownMemberType", + "code": "reportUnknownArgumentType", "range": { - "startColumn": 18, + "startColumn": 23, "endColumn": 41, "lineCount": 1 } @@ -80610,8 +80506,8 @@ { "code": "reportUnknownMemberType", "range": { - "startColumn": 35, - "endColumn": 53, + "startColumn": 37, + "endColumn": 55, "lineCount": 1 } }, @@ -81643,6 +81539,14 @@ "lineCount": 1 } }, + { + "code": "reportUnknownArgumentType", + "range": { + "startColumn": 40, + "endColumn": 61, + "lineCount": 1 + } + }, { "code": "reportUnknownParameterType", "range": { @@ -82099,14 +82003,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 17, - "endColumn": 32, - "lineCount": 1 - } - }, { "code": "reportUnknownArgumentType", "range": { @@ -85929,30 +85825,6 @@ } ], "./loopy/transform/iname.py": [ - { - "code": "reportPossiblyUnboundVariable", - "range": { - "startColumn": 46, - "endColumn": 64, - "lineCount": 1 - } - }, - { - "code": "reportPossiblyUnboundVariable", - "range": { - "startColumn": 20, - "endColumn": 38, - "lineCount": 1 - } - }, - { - "code": "reportPossiblyUnboundVariable", - "range": { - "startColumn": 60, - "endColumn": 78, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -85961,22 +85833,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 8, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 36, - "endColumn": 50, - "lineCount": 1 - } - }, { "code": "reportUnusedParameter", "range": { @@ -85986,34 +85842,10 @@ } }, { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 73, - "endColumn": 77, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 73, - "endColumn": 77, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 43, - "endColumn": 63, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", + "code": "reportAny", "range": { - "startColumn": 32, - "endColumn": 80, + "startColumn": 53, + "endColumn": 57, "lineCount": 1 } }, @@ -86033,62 +85865,6 @@ "lineCount": 2 } }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 8, - "endColumn": 27, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 28, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 28, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 16, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 16, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 27, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 25, - "endColumn": 31, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -86097,219 +85873,51 @@ "lineCount": 1 } }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 28, - "endColumn": 38, - "lineCount": 1 - } - }, - { - "code": "reportUnusedParameter", - "range": { - "startColumn": 12, - "endColumn": 17, - "lineCount": 1 - } - }, - { - "code": "reportReturnType", - "range": { - "startColumn": 23, - "endColumn": 56, - "lineCount": 1 - } - }, - { - "code": "reportReturnType", - "range": { - "startColumn": 23, - "endColumn": 56, - "lineCount": 1 - } - }, - { - "code": "reportUnnecessaryComparison", - "range": { - "startColumn": 11, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportMissingTypeArgument", - "range": { - "startColumn": 23, - "endColumn": 46, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 23, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 23, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 12, - "endColumn": 22, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 12, - "endColumn": 22, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 24, - "endColumn": 30, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 24, - "endColumn": 30, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 25, - "endColumn": 45, - "lineCount": 1 - } - }, - { - "code": "reportUnannotatedClassAttribute", - "range": { - "startColumn": 13, - "endColumn": 23, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 8, - "endColumn": 27, - "lineCount": 1 - } - }, - { - "code": "reportUnannotatedClassAttribute", - "range": { - "startColumn": 13, - "endColumn": 27, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { - "startColumn": 34, - "endColumn": 49, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 34, - "endColumn": 51, - "lineCount": 1 - } - }, - { - "code": "reportUnannotatedClassAttribute", - "range": { - "startColumn": 13, - "endColumn": 19, - "lineCount": 1 - } - }, - { - "code": "reportImplicitOverride", - "range": { - "startColumn": 8, - "endColumn": 21, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 28, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 28, - "endColumn": 32, + "startColumn": 15, + "endColumn": 24, "lineCount": 1 } }, { - "code": "reportUnknownParameterType", + "code": "reportArgumentType", "range": { - "startColumn": 34, - "endColumn": 44, + "startColumn": 38, + "endColumn": 48, "lineCount": 1 } }, { - "code": "reportMissingParameterType", + "code": "reportUnusedParameter", "range": { - "startColumn": 34, - "endColumn": 44, + "startColumn": 32, + "endColumn": 38, "lineCount": 1 } }, { - "code": "reportUnknownMemberType", + "code": "reportAny", "range": { - "startColumn": 16, - "endColumn": 27, + "startColumn": 33, + "endColumn": 37, "lineCount": 1 } }, { - "code": "reportUnknownArgumentType", + "code": "reportUnusedParameter", "range": { - "startColumn": 16, - "endColumn": 27, + "startColumn": 33, + "endColumn": 37, "lineCount": 1 } }, { "code": "reportUnknownMemberType", "range": { - "startColumn": 31, - "endColumn": 50, + "startColumn": 12, + "endColumn": 21, "lineCount": 1 } }, @@ -86317,2039 +85925,55 @@ "code": "reportUnknownMemberType", "range": { "startColumn": 20, - "endColumn": 37, + "endColumn": 29, "lineCount": 1 } }, { "code": "reportUnknownMemberType", "range": { - "startColumn": 20, - "endColumn": 42, + "startColumn": 36, + "endColumn": 45, "lineCount": 1 } }, { "code": "reportUnknownMemberType", "range": { - "startColumn": 20, - "endColumn": 36, + "startColumn": 36, + "endColumn": 45, "lineCount": 1 } }, { "code": "reportUnknownMemberType", "range": { - "startColumn": 20, - "endColumn": 39, + "startColumn": 19, + "endColumn": 28, "lineCount": 1 } }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 20, - "endColumn": 44, - "lineCount": 4 - } - }, { "code": "reportUnknownMemberType", "range": { - "startColumn": 36, - "endColumn": 58, + "startColumn": 27, + "endColumn": 36, "lineCount": 1 } }, { "code": "reportUnknownMemberType", "range": { - "startColumn": 33, - "endColumn": 44, + "startColumn": 27, + "endColumn": 36, "lineCount": 1 } }, { "code": "reportUnknownMemberType", - "range": { - "startColumn": 29, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 29, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 45, - "endColumn": 55, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 33, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 33, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 44, - "endColumn": 54, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 24, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 24, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 41, - "endColumn": 45, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 47, - "endColumn": 57, - "lineCount": 1 - } - }, - { - "code": "reportImplicitOverride", - "range": { - "startColumn": 8, - "endColumn": 20, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 27, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 27, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 33, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 33, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 19, - "endColumn": 38, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 39, - "endColumn": 48, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 19, - "endColumn": 28, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 32, - "endColumn": 54, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 40, - "endColumn": 44, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 46, - "endColumn": 56, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 23, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportImplicitOverride", - "range": { - "startColumn": 8, - "endColumn": 23, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 30, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 38, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 16, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 16, - "endColumn": 47, - "lineCount": 2 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 15, - "endColumn": 24, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 21, - "endColumn": 27, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 21, - "endColumn": 27, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 29, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 29, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 37, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 37, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 45, - "endColumn": 55, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 45, - "endColumn": 55, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 62, - "endColumn": 68, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 62, - "endColumn": 68, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 8, - "endColumn": 12, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 8, - "endColumn": 12, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 31, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 34, - "endColumn": 40, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 11, - "endColumn": 21, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 30, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 15, - "endColumn": 44, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 30, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 15, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 33, - "endColumn": 35, - "lineCount": 2 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportCallIssue", - "range": { - "startColumn": 8, - "endColumn": 21, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 8, - "endColumn": 21, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 36, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 44, - "endColumn": 54, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 30, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 17, - "endColumn": 28, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 12, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 34, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 37, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 45, - "endColumn": 55, - "lineCount": 1 - } - }, - { - "code": "reportUnusedParameter", - "range": { - "startColumn": 32, - "endColumn": 38, - "lineCount": 1 - } - }, - { - "code": "reportAny", - "range": { - "startColumn": 33, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportUnusedParameter", - "range": { - "startColumn": 33, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 30, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 29, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 36, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 44, - "endColumn": 54, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 18, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 40, - "endColumn": 60, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 4, - "endColumn": 34, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 35, - "endColumn": 50, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 35, - "endColumn": 50, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 52, - "endColumn": 69, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 52, - "endColumn": 69, - "lineCount": 1 - } - }, - { - "code": "reportCallInDefaultInitializer", - "range": { - "startColumn": 70, - "endColumn": 83, - "lineCount": 1 - } - }, - { - "code": "reportCallInDefaultInitializer", - "range": { - "startColumn": 80, - "endColumn": 82, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 34, - "endColumn": 49, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 65, - "endColumn": 80, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 22, - "endColumn": 73, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 22, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 33, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 30, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 8, - "endColumn": 33, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 34, - "endColumn": 38, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 34, - "endColumn": 38, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 42, - "endColumn": 50, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 36, - "endColumn": 45, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 55, - "endColumn": 67, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 11, - "endColumn": 23, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 36, - "endColumn": 75, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 13, - "endColumn": 25, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 20, - "endColumn": 49, - "lineCount": 3 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 33, - "endColumn": 40, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 20, - "endColumn": 55, - "lineCount": 2 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 36, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 42, - "endColumn": 53, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 26, - "endColumn": 75, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 4, - "endColumn": 33, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 34, - "endColumn": 40, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 34, - "endColumn": 40, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 18, - "endColumn": 33, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 29, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 37, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 34, - "endColumn": 40, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 34, - "endColumn": 40, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 20, - "endColumn": 70, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 25, - "endColumn": 62, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 4, - "endColumn": 19, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 20, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 20, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 17, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 33, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 16, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 8, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 16, - "endColumn": 34, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 16, - "endColumn": 45, - "lineCount": 3 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 18, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 18, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 26, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 22, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 30, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 4, - "endColumn": 34, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 35, - "endColumn": 54, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 35, - "endColumn": 54, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 11, - "endColumn": 30, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 8, - "endColumn": 15, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 16, - "endColumn": 22, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 16, - "endColumn": 22, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 25, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 25, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 33, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 33, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 37, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 36, - "endColumn": 53, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 74, - "endColumn": 80, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 16, - "endColumn": 34, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 16, - "endColumn": 45, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 16, - "endColumn": 69, - "lineCount": 1 - } - }, - { - "code": "reportImplicitOverride", - "range": { - "startColumn": 8, - "endColumn": 21, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 18, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 28, - "endColumn": 38, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 30, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 41, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 41, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 40, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 39, - "endColumn": 73, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 30, - "endColumn": 44, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 49, - "endColumn": 58, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 8, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 8, - "endColumn": 21, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 22, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 22, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 31, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 31, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 42, - "endColumn": 65, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 21, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 4, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 33, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 33, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 41, - "endColumn": 46, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 41, - "endColumn": 46, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 48, - "endColumn": 61, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 48, - "endColumn": 61, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 63, - "endColumn": 76, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 63, - "endColumn": 76, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 28, - "endColumn": 56, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 28, - "endColumn": 61, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 11, - "endColumn": 22, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 23, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 23, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 45, - "endColumn": 51, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 45, - "endColumn": 51, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 53, - "endColumn": 59, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 53, - "endColumn": 59, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 25, - "endColumn": 45, - "lineCount": 1 - } - }, - { - "code": "reportUnannotatedClassAttribute", - "range": { - "startColumn": 13, - "endColumn": 19, - "lineCount": 1 - } - }, - { - "code": "reportImplicitOverride", - "range": { - "startColumn": 8, - "endColumn": 21, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 28, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 28, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 34, - "endColumn": 44, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 34, - "endColumn": 44, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 38, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 44, - "endColumn": 54, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 59, - "endColumn": 69, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 33, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 33, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 41, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 41, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 54, - "endColumn": 60, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 54, - "endColumn": 60, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 15, - "endColumn": 44, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 31, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 12, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 34, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 12, - "endColumn": 18, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 30, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportIndexIssue", - "range": { - "startColumn": 8, - "endColumn": 14, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 4, - "endColumn": 22, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 23, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 23, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 31, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 31, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 39, - "endColumn": 49, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 39, - "endColumn": 49, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 24, - "endColumn": 34, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 16, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 25, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 20, - "endColumn": 72, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 44, - "endColumn": 62, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 36, - "endColumn": 40, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 11, - "endColumn": 22, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 8, - "endColumn": 18, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 8, - "endColumn": 18, - "lineCount": 1 - } - }, - { - "code": "reportUnreachable", "range": { "startColumn": 8, - "endColumn": 55, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 24, - "endColumn": 34, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 4, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 32, - "endColumn": 38, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 32, - "endColumn": 38, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 40, - "endColumn": 50, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 40, - "endColumn": 50, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 52, - "endColumn": 62, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 52, - "endColumn": 62, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 24, - "endColumn": 34, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 16, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 25, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 29, - "endColumn": 44, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 16, - "endColumn": 25, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 16, - "endColumn": 63, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 47, - "endColumn": 61, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 36, - "endColumn": 40, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 11, - "endColumn": 22, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 19, - "endColumn": 28, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 36, - "endColumn": 49, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 27, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 27, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 24, - "endColumn": 33, + "endColumn": 17, "lineCount": 1 } } @@ -101713,134 +99337,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 4, - "endColumn": 16, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 17, - "endColumn": 23, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 17, - "endColumn": 23, - "lineCount": 1 - } - }, - { - "code": "reportUnknownParameterType", - "range": { - "startColumn": 25, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportMissingParameterType", - "range": { - "startColumn": 25, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 11, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 17, - "endColumn": 49, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 38, - "endColumn": 49, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 12, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 34, - "endColumn": 63, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 34, - "endColumn": 65, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 12, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 12, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 30, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportUnknownArgumentType", - "range": { - "startColumn": 64, - "endColumn": 70, - "lineCount": 1 - } - }, { "code": "reportUnknownParameterType", "range": { @@ -105085,14 +102581,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 10, - "endColumn": 25, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -106637,14 +104125,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 11, - "endColumn": 32, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -106879,14 +104359,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 10, - "endColumn": 31, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -108419,14 +105891,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 14, - "endColumn": 35, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -108789,14 +106253,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 10, - "endColumn": 25, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -109517,14 +106973,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 10, - "endColumn": 29, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -109533,14 +106981,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 10, - "endColumn": 29, - "lineCount": 1 - } - }, { "code": "reportArgumentType", "range": { @@ -109693,62 +107133,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 15, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 52, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 25, - "endColumn": 57, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 15, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 15, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 20, - "endColumn": 52, - "lineCount": 1 - } - }, { "code": "reportUnusedParameter", "range": { @@ -110653,14 +108037,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 10, - "endColumn": 29, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -111217,22 +108593,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 14, - "endColumn": 29, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 14, - "endColumn": 29, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -111701,14 +109061,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 10, - "endColumn": 41, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -115385,14 +112737,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 13, - "endColumn": 28, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -115937,14 +113281,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 13, - "endColumn": 44, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -115977,22 +113313,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 13, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 13, - "endColumn": 43, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": { @@ -116017,14 +113337,6 @@ "lineCount": 1 } }, - { - "code": "reportUnknownMemberType", - "range": { - "startColumn": 13, - "endColumn": 32, - "lineCount": 1 - } - }, { "code": "reportUnknownMemberType", "range": {