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
Use get_parfor_writes to detect illegal array access that prevents fusion. #7582
Conversation
…is created by prior parfor of the same length.
…e moved and enable more fusion.
…then make sure that the second parfor only accesses that array using the parfor index variable. Since fusion is predicated on the loop index variables being the same (size), this is a cheap test for there being no dependencies.
…esses by its index variable.
Can something like |
…ase of non-parfor index variable indexed arrays use after def by previous parfor.
…oks into tuples to see if they are constructed from the loop nests indices.
I did something similar now. Please have a look. |
Didn't go through the details but seems like this is on the right track. Thanks. |
numba/parfors/parfor.py
Outdated
overlap = p1_body_defs.intersection(p2_uses) | ||
# overlap are those variable defined in first parfor and used in the second | ||
if len(overlap) != 0: | ||
is_safe = True # Assume safe until proven otherwise. |
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.
Can it default to be unsafe instead for a more conservative behavior?
It seems it just need all overlap
variables to be of ArrayCompatible
and in p2arraynotindexed
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.
I can do the following:
unsafe_var = [not isinstance(typemap[x], types.ArrayCompatible) or x in p2arraynotindexed for x in overlap]
if any(unsafe_var):
That is simpler looking but this does have potential to be slower than what I wrote that gives up as soon as it finds the first problem. The new line above would potentially compute some useless stuff but the amount of work is trivial so I've checked in this change. See if you like it.
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.
Would a generator comprehension solve this problem? If you change the brackets to parentheses, then the body will be lazily evaluated by any()
: unsafe_var = (not isinstance(typemap[x], types.ArrayCompatible) or x in p2arraynotindexed for x in overlap)
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.
Thanks. Done.
I think you'll need to merge in |
Closing to open again in an attempt to re-trigger towncrier. It should "just work" on this PR. |
@DrTodd13 there is a bug in the filename for towncrier: |
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.
LGTM
(CI failed due to conda timeout. i've restarted failing builds) |
Resolves #7578
In parfor fusion, there is a check that something written in one parfor not be used in the second parfor. There was a case in issue #7578 that an array was written in the first parfor and analysis of that parfor said that the array was "used" but not written in that parfor. Therefore, the second parfor which also used the same array didn't see a conflict and did the fusion. If you just make the array written in the first parfor loop body as a "def" then the array isn't passed to the parfor gufunc and ends up undefined. So, what I am trying here is to make the array both def and use so that the parfors don't fuse but the array is passed as a parameter to the gufunc.
This is in-progress at the moment as I expect this to break legitimate instances of fusion because the real problem with this example is that indices outside of the parfor index are used in the second parfor which is the only thing that should prevent fusion in this case. I want to see what the tests say to see which tests fail due to this and if none do then to create one that should be allowed.