Skip to content

transforms: lower polynomials to arithmetic operations#5951

Open
szerdick wants to merge 14 commits into
xdslproject:mainfrom
szerdick:szerdick/add-polynomial-eval-pass
Open

transforms: lower polynomials to arithmetic operations#5951
szerdick wants to merge 14 commits into
xdslproject:mainfrom
szerdick:szerdick/add-polynomial-eval-pass

Conversation

@szerdick

@szerdick szerdick commented Apr 27, 2026

Copy link
Copy Markdown
Collaborator

Based on the specified polynomial family, evaluation interval, and scheme lower the polynomial approximation to arithmetic operations. Only supports Clenshaw's recurrence evaluation so far.

@szerdick szerdick requested a review from superlopuh April 27, 2026 16:15
@codecov

codecov Bot commented Apr 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.42424% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.74%. Comparing base (88cc66f) to head (49cfbf0).
⚠️ Report is 73 commits behind head on main.

Files with missing lines Patch % Lines
xdsl/transforms/polynomial_eval_to_arith.py 92.06% 3 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5951      +/-   ##
==========================================
+ Coverage   86.73%   86.74%   +0.01%     
==========================================
  Files         425      426       +1     
  Lines       63539    63628      +89     
  Branches     7289     7293       +4     
==========================================
+ Hits        55108    55196      +88     
- Misses       6865     6866       +1     
  Partials     1566     1566              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@superlopuh superlopuh marked this pull request as draft April 27, 2026 16:43
@superlopuh

Copy link
Copy Markdown
Member

We can take a look at this once the polynomial dialect is merged

@szerdick szerdick force-pushed the szerdick/add-polynomial-eval-pass branch from 7dae066 to 58ae869 Compare May 6, 2026 14:09
@szerdick szerdick marked this pull request as ready for review May 8, 2026 14:32
@szerdick szerdick force-pushed the szerdick/add-polynomial-eval-pass branch from 2674c91 to e6f7a53 Compare May 13, 2026 12:11
Comment on lines +125 to +127
raise NotImplementedError(
f"polynomial.eval scheme {scheme.value!r} has no lowering"
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you please raise a PassFailedException instead and add a test for it so that we detect what to update when new cases are added?

upper = op.domain_upper.value.data if op.domain_upper is not None else None

scheme = op.eval_scheme
if scheme is polynomial.EvalScheme.CLENSHAW:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

feels like a good place to use a match statement instead

Comment thread xdsl/transforms/expand_polynomial_eval.py Outdated
Comment on lines +34 to +49
def _float_constant(
value: float,
tp: AnyFloat | VectorType[AnyFloat] | TensorType[AnyFloat],
rewriter: PatternRewriter,
) -> arith.ConstantOp:
"""Create and insert a float constant, handling scalar/vector/tensor types."""
if isa(tp, VectorType[AnyFloat]):
attr = DenseIntOrFPElementsAttr.from_list(tp, [value])
elif isa(tp, TensorType[AnyFloat]):
attr = DenseIntOrFPElementsAttr.from_list(tp, [value])
elif isa(tp, AnyFloat):
attr = FloatAttr(value, tp)
else:
raise TypeError(f"Unsupported type for float constant: {tp}")
return rewriter.insert(arith.ConstantOp(attr))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this feels familiar, do we have code like this in the framework already? I think there was something similar in your exp to polynomial pass, is that right? I think we might want a helper for this in builtin with dedicated tests.

@szerdick szerdick May 14, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Hm, what is kind of suboptimal is that the function returns an arithmetic.ConstantOp but the arithmetic dialect is lower than the builtin dialect in the dialect stack (arith imports builtin).

But I could make a function in builtin dialect that returns FloatAttr | DenseIntOrFPElementsAttr and then the function in each of the passes would just be this:

return rewriter.insert(arith.ConstantOp(float_constant_attr(value, tp)))

but it feels a bit awkward to define another function then in each pass

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah sorry that's what I meant

@superlopuh superlopuh Jun 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I still think we should do this first before merging this PR

@szerdick szerdick requested a review from superlopuh May 15, 2026 09:36

@alexarice alexarice left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I haven't checked the mathematics, but overall looks fine to me.

@@ -0,0 +1,111 @@
// RUN: xdsl-opt -p polynomial-eval-to-arith %s | filecheck %s

builtin.module {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit: There's no need to have the builtin.module op explicitly, and not having it means you don't have to indent the entire file.

offset = -(upper + lower) / (upper - lower)
scale_op = _float_constant(scale, tp, rewriter)
offset_op = _float_constant(offset, tp, rewriter)
scaled = rewriter.insert(arith.MulfOp(x, scale_op.result))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not essential, but I wonder if this would all be a lot cleaner with an implicit builder?

lower_affine.LowerAffinePass(),
convert_scf_to_riscv_scf.ConvertScfToRiscvPass(),
expand_math_to_polynomials.ExpandMathToPolynomialsPass(),
polynomial_eval_to_arith.PolynomialEvalToArithPass(),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This feels like it should be a separate change?

@alexarice alexarice added the transformations Passes, rewrites label Jun 1, 2026
Comment on lines +35 to +39
pytest.fail(
f"EvalScheme.{scheme.name} has no dispatch branch in "
f"polynomial-eval-to-arith. Add a case for it in "
f"PolynomialEvalToArith.match_and_rewrite. ({e})"
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

let's test this with lit/filecheck instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

transformations Passes, rewrites

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants