-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature[next]: Add power unrolling functionality and respective unit tests. #1409
Conversation
if check_node(new_node): | ||
assert len(new_node.args) == 2 | ||
# Check if unroll should be performed or if exponent is too large | ||
if int(new_node.args[1].value) > self.max_unroll: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if int(new_node.args[1].value) > self.max_unroll: | |
base, exponent = new_node.args[0], int(new_node.args[1].value) | |
if exponent > self.max_unroll: |
and so on
def _is_power_call( | ||
node: ir.FunCall, | ||
) -> bool: | ||
return ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return ( | |
"""Matches expressions of the form `power(base, integral_literal)`.""" | |
return ( |
) | ||
|
||
|
||
def _compute_integer_power_of_two(exp): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def _compute_integer_power_of_two(exp): | |
def _compute_integer_power_of_two(exp: itir.Expr) -> int: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad:
def _compute_integer_power_of_two(exp): | |
def _compute_integer_power_of_two(exp: int) -> int: |
max_unroll: int | ||
|
||
@classmethod | ||
def apply(cls, node: ir.Node, max_unroll=5) -> ir.Node: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def apply(cls, node: ir.Node, max_unroll=5) -> ir.Node: | |
def apply(cls, node: ir.Node, max_unroll: int=5) -> ir.Node: |
|
||
ret = im.multiplies_(ret, f"power_{2 ** pow_cur}") | ||
|
||
# In case of FunCall: build nested expression to avoid multiple evaluations of base |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# In case of FunCall: build nested expression to avoid multiple evaluations of base | |
# nest target expression to avoid multiple redundant evaluations |
For clarification: It is not only that we don't want to reevaluate the base expression, but also the various power compontents themselves.
|
||
# Simplify expression in case of SymRef by resolving let statements | ||
if isinstance(base, ir.SymRef): | ||
return InlineLambdas.apply(ret) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return InlineLambdas.apply(ret) | |
return InlineLambdas.apply(ret, opcount_preserving=True) |
The proper way would be to somehow tell the inliner to not ignore anything of the base, but we don't have a mechanism for this and the alternatives are less readable. This should be fine.
|
||
|
||
def test_power_unrolling_zero(): | ||
pytest.xfail("Not implemented.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pytest.xfail("Not implemented.") | |
pytest.xfail("Not implemented as we don't have an easy way to determine the type of the one literal (type inference is to expensive).") |
PR Title: Add power unrolling functionality and respective unit tests.