Skip to content
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

(Towards #2704) 2704 access improvements #2734

Open
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

LonelyCat124
Copy link
Collaborator

WIP.
Forward_access implementation is done. I need to do backwards next.

@sergisiso How should we modify forward/backward_dependence from node? Do these need to only return 1 result or should we change them to return potentially multiple?

Copy link

codecov bot commented Oct 3, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.87%. Comparing base (33ff7e8) to head (5c29b70).
Report is 104 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff            @@
##           master    #2734    +/-   ##
========================================
  Coverage   99.86%   99.87%            
========================================
  Files         354      355     +1     
  Lines       48967    49229   +262     
========================================
+ Hits        48903    49165   +262     
  Misses         64       64            

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

@sergisiso
Copy link
Collaborator

Forward_access implementation is done. I need to do backwards next.

@sergisiso How should we modify forward/backward_dependence from node? Do these need to only return 1 result or should we change them to return potentially multiple?

I see this is already quite big, could separate them in different PRs, this one, next one for backwards and next one to replace forward/backward_dependence ? At this point we just need to know that there is a path/plan to replace forward/backward_dependence with the new functionality and we don't end up with multiple implementations of very similar things. What do you think?

@LonelyCat124
Copy link
Collaborator Author

Yeah that sounds fine! I'll fix coverage and then put this bit up for ready for review.

@LonelyCat124 LonelyCat124 marked this pull request as ready for review October 8, 2024 13:53
@LonelyCat124
Copy link
Collaborator Author

@sergisiso @arporter This is ready for a first look now. I'm editing it to towards 2704 now as its only the first piece (but as Sergi says, already big enough to be its own PR).

@LonelyCat124 LonelyCat124 changed the title (Closes #2704) 2704 access improvements (Towards #2704) 2704 access improvements Oct 8, 2024
@LonelyCat124
Copy link
Collaborator Author

LonelyCat124 commented Oct 9, 2024

So from some experimentation - in principle the functionality of forward_dependence wouldn't be difficult to implement, however the current DefinitionUseChains won't support it.

There are 23 failing tests with this implementation:

        # The scope is this node's parent's children.
        scope = self.parent.children[:]
        dependence = None
        for arg in self.args:
            chain = DefinitionUseChain(
                    arg,
                    scope
            )
            results = chain.find_forward_accesses()
            for res in results:
                if res.abs_position <= arg.abs_position:
                    continue
                node = res
                while node.depth > self.depth:
                    node = node.parent
                if self.sameParent(node) and node is not self:
                    # The remote node (or one of its ancestors) shares
                    # the same parent as me (but its not me)
                    if not dependence:
                        # this is the first dependence found so keep it
                        dependence = node
                    else:
                        if dependence.position > node.position:
                            # the new dependence is closer to me than
                            # the previous dependence so keep it
                            dependence = node
        return dependence

I think this code matches the previous code, however I can't yet check because DefinitionUseChains only support Reference inputs, but the forward_dependence passes DynKernelArguments instead of Reference objects. I'm not sure how hard it would be to adjust this/whether KernelArgument have any similarities to References - if not it might not help with reimplementing this.

Edit: Actually its more complex than this - at the moment this depends on some subclass implementations in psyGen.py which use _find_arguments and following, and this _depends_on routine. I think in principle this may all be replaced by the implementation above, but it does depend on Argument vs Reference.

@sergisiso
Copy link
Collaborator

There are 23 failing tests with this implementation:

Can you fix the code formatting, it didn't get the linebreaks.

but the forward_dependence passes DynKernelArguments instead of Reference objects

Ah I forgot about it, it won't be easy but I think I have a long term plan. We need the new backend (soon), moving the invoke.declaration that creates the symbol at the raising step (psyir construction), and let the argument know its symbol (they can subclass reference then). But that won't be ready anytime soon, so let's forget about replacing those methods for now.

@LonelyCat124
Copy link
Collaborator Author

Can you fix the code formatting, it didn't get the linebreaks.

Done, sorry my windows terminal just stops copying line breaks.

Copy link
Collaborator

@sergisiso sergisiso left a comment

Choose a reason for hiding this comment

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

@LonelyCat124 I made a first high-level review, I like the structure/interface, I just made minor comments about it. I have not gone too deep into the implementation details yet.

I noticed there are a few FIXMEs, TODOs in the code. Can some of this be resolved now?

Also it will be good to document in https://psyclone-dev.readthedocs.io/en/latest/dependency.html this new class, describe its functionality and how to use it, and how is it different from the others tools/methods mentioned in that same page.

src/psyclone/psyir/nodes/reference.py Outdated Show resolved Hide resolved
src/psyclone/psyir/nodes/reference.py Outdated Show resolved Hide resolved
src/psyclone/psyir/nodes/reference.py Outdated Show resolved Hide resolved
src/psyclone/psyir/nodes/reference.py Outdated Show resolved Hide resolved
Comment on lines 283 to 289
# The scope is as far as the Routine that contains this
# Reference.
routine = self.ancestor(Routine)
# Handle the case when this is a subtree without an ancestor
# Routine
if routine is None:
routine = self.root
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need this code and passing the [routine] argument? I think this is the same that the DefinitionUseChain does by default.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We don't need it - i kinda preferred being specific but I can remove it if you'd prefer.

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah, I think I prefer removing it in this case, as it also allows to remove one of the inlined imports which we are trying to reduce

Comment on lines 152 to 165
"""
:returns: the list of output nodes computed by this DefinitionUseChain.
:rtype: List[:py:class:`psyclone.psyir.nodes.Node`]
"""
return self._defsout

@property
def killed(self):
"""
:returns: the list of killed output nodes computed by this
DefinitionUseChain.
:rtype: List[:py:class:`psyclone.psyir.nodes.Node`]
"""
return self._killed
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you expand what defsout are, I don't quite understand what they are and how are they different than killed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I expanded on killed to make it hopefully clearer. Realistically these are not too common in this implementation, since we usually stop caring about things once we find a write, but they can appear when we have control flow.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok - so the implementation does need/use the killed accesses now, I need some more tests for behviour inside control flow for codeblocks/calls to ensure this is behaving as I expect.

src/psyclone/psyir/tools/definition_use_chains.py Outdated Show resolved Hide resolved
Comment on lines 476 to 478
# TODO For now the if statement doesn't kill the accesses,
# even though it will always be written to.
# FIXME Add issue to the previous comment
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes please, create and reference in the TODO the issue for this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

src/psyclone/psyir/tools/definition_use_chains.py Outdated Show resolved Hide resolved
Comment on lines +198 to +201
# FIXME If all defsout is in control flow we should add a None into
# the defsout array. @Reviewer not sure about this - should we make
# it clear somehow its not guaranteed to be written to or does it not
# matter?
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am not sure about this, maybe we need to discuss this again with some examples/use_cases of how this will be used?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We discussed this previously when I was on-site - and initially thought this might be a good idea, but I'm not actually sure.
It could be left up to the code that uses the result to check this, as I think some of use-cases will not care if the write is "guaranteed" or not.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think also until #2760 is implemented it doesn't make sense to fix this anyway.

@LonelyCat124
Copy link
Collaborator Author

I've added a small section to the documentation, it probably needs expanding but a bit unsure what to put in there for now.

TODO: Handle CYCLE, BREAK, GOTO etc.

@LonelyCat124
Copy link
Collaborator Author

ok - there is an issue with how i'm handling writes to the reference that I need to fix. I produce a defs_out (which is the final write to the symbol in a region) and a list of prior writes.

We don't actually realistically care about the last write for a single basic block, but realistically we care about the first write, so I need to check the code is following this correctly and doing the right thing.

@LonelyCat124
Copy link
Collaborator Author

ok - there is an issue with how i'm handling writes to the reference that I need to fix. I produce a defs_out (which is the final write to the symbol in a region) and a list of prior writes.

We don't actually realistically care about the last write for a single basic block, but realistically we care about the first write, so I need to check the code is following this correctly and doing the right thing.

This is fixed for general case with no control flow. I need to check this is fixed with control flow and calls/writes/codeblocks.

@LonelyCat124
Copy link
Collaborator Author

I've now handled CYCLE, BREAK and RETURN i think - let me know if you agree. Should be ready for another look if coverage is ok.

@LonelyCat124
Copy link
Collaborator Author

@sergisiso ready for another look I think.

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

Successfully merging this pull request may close these issues.

2 participants