Add optimization for replacing identities of binary operators.#817
Add optimization for replacing identities of binary operators.#817sbacchio wants to merge 3 commits intoserge-sans-paille:masterfrom sbacchio:feature/replace_identities
Conversation
|
Hi sabbachio and thanks for the on-going PR. First your proposal is a ntural extension of So you' be better register tour patterns here. Then considering the validity of the transformations : think of x == [1,2] or x == 'er'. but you could workaround that using remember pythran optimizations are type agnostic, as the generated program must keep polymorphism. |
|
Multiplication by 1 looks always foldable to me, and it does not interfere with type inference |
|
Ok, I missed PatternTransform. or try construct a more compact method as I did, but based on Placeholder? |
|
For clarity sake, the implementation I would like to carry out is an optimization of matrix products with a given sparse matrix (e.g transformation). For instance the code: Should be optimized in something like which then the compiler optimize easily. |
|
Yes for the palceholders! Your test case is very interesting :-) part of the job should feasible, you alreay have constant forlding, dead code elimination and loop unrolling. We don't have support for constant array shape (in the pythran export) but that's something I should be able to do. |
| # replacement is inserted in main ast | ||
| know_pattern_BinOp = { | ||
| ast.Mult.__name__ : [ | ||
| (Placeholder(0), ast.Num(1), lambda: Placeholder(0)), # X * 1 => X |
There was a problem hiding this comment.
Unfortunately, I relaized that even this simple transformation is not always correct:
x = [1,2]
y = x * 1
y[0] = 2
print(x, y)
There was a problem hiding this comment.
Arg, damn python.. I need to find a way to make it safe...
For my test case I need somehow the replacements
y += x * 0 => y += 0 => pass
| ast.Mult.__name__ : [ | ||
| (Placeholder(0), ast.Num(1), lambda: Placeholder(0)), # X * 1 => X | ||
| (ast.Num(1), Placeholder(0), lambda: Placeholder(0)), # 1 * X => X | ||
| (Placeholder(0), Placeholder(0), lambda: ast.BinOp(left=Placeholder(0), op=ast.Pow(), right=ast.Num(n=2))), # X * X => X ** 2 |
There was a problem hiding this comment.
This case is already handled by pythran.optimization.square
| ], | ||
| ast.Add.__name__ : [ | ||
| (Placeholder(0), ast.Num(0), lambda: Placeholder(0)), # X + 0 => X | ||
| (ast.Num(0), Placeholder(0), lambda: Placeholder(0)), # 0 + X => X |
There was a problem hiding this comment.
same copy issue as above, when one multiplies by one.
| ast.Add.__name__ : [ | ||
| (Placeholder(0), ast.Num(0), lambda: Placeholder(0)), # X + 0 => X | ||
| (ast.Num(0), Placeholder(0), lambda: Placeholder(0)), # 0 + X => X | ||
| ( # a + "..." + b => "...".join((a, b)) |
There was a problem hiding this comment.
This one looks correct :-)
| ], | ||
| ast.Sub.__name__ : [ | ||
| (Placeholder(0), ast.Num(0), lambda: Placeholder(0)), # X - 0 => X | ||
| (ast.Num(0), Placeholder(0), lambda: ast.UnaryOp(op=ast.USub(), operand=Placeholder(0))), # 0 - X => -X |
| """ | ||
| Special method for BinOp. | ||
| Try to replace if node match the given pattern. | ||
| """ |
There was a problem hiding this comment.
why do you need that specialization?
There was a problem hiding this comment.
I thought would be good for speeding-up the optimization.
As soon as I find a way to implement safely the patterns I have in mind, we may have order of 100 patterns to check for replacement.
Then, as it was, pattern transform would check for any node any given pattern careless of the structure.
In this way, instead, it goes trough BinOp just when needed and select from the dictionary the patterns relative to the used operator.
|
y += x * 0 => y += 0 => pass
I'll think about it but capturing the first pattern as a whole looks safe to me.
```
y += x * 0 => pass
```
|
|
ok, your identity is false for floating point numbers: evaluates to My guess is that you should give up with the pattern matching stuff and implement a new pattern in I don't know if I'm clear... |
|
Sure sure, it's clear. I will look at that. |
Hi,
I've casually find out pythran and it's a very interesting project. Thank you for all the effort you have put in it. I was experimenting a bit and trying to understand if it can be useful for the project I have in mind.
The structure is nice and easy to develop with it.
I've tried to implement an optimization which replace identities of the operators (BinOp at the moment). I tried to give a generic structure such that many identities can be implemented easily. Similarly in the optimization Square you have the function expand_pow which replace
x**0andx**1This can be moved here for instance.The pull request is not complete yet, but I wanted first to ask if it's something needed and the implementation is up-to-standard.
Cheers,
Simone