-
Notifications
You must be signed in to change notification settings - Fork 790
[NFC][SYCL][Graph] Introduce nodes_range
utility
#19295
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
Conversation
N.registerSuccessor(Node); | ||
this->removeRoot(Node); | ||
} | ||
if (Node->MPredecessors.empty()) { |
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.
IMO, the "root" invariant should be handled completely automatically between node_impl
's ctor and add/removePredecessor
methods. I'm not familiar with the implementation though, so can't state for certain that it would work and even if so, that should be left to a separate patch.
However, I've changed graph_impl::add
overload to stop appending node_impl
s from std::set
to an std::vector
and am making to calls to addDepsToNode
instead, hence this particular change.
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.
That refactor of how root nodes gets recording makes, sense but agree that's for a separate patch.
It looks like lots of `std::vector<std::weak_ptr<node_impl>>` aren't actually used for lifetime management and aren't expected to ever have an "expired" `std::weak_ptr`. As such, it would make sense to transition many of them to raw pointers/references (e.g. `std::vector<node_impl *>`). This utility should help to make such transition a bit easier. However, I expect it to be useful even after the elimination of unnecessary `weak_ptr`s and that can be seen even as part of this PR already. * Scenario A: we need to process both `std::vector<node_impl *>` passed around as function parameters or created as a local variable on stack, and `std::vector<node>` or `std::vector<std::shared_ptr<node_impl>>` that *is* used for lifetime management (e.g. `handler`'s data member, or all the nodes in the graph). This utility would allow such an API to have a single overload to work with both scenarios. * Scenario B: no conversion between `std::set`->`std::vector<>` (already updated here) is necessary and no templates required to support them both via single overload.
e64923e
to
bc04d13
Compare
For extra context, follow-up changes would look like this: 05d00da (not sure if I'll be able to split in multiple PRs yet). |
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.
Your observation that the node weak-ptrs are expected to always be alive is correct. So the move to raw ptrs/reference is a good direction and this is a nice step to get there, thanks.
N.registerSuccessor(Node); | ||
this->removeRoot(Node); | ||
} | ||
if (Node->MPredecessors.empty()) { |
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.
That refactor of how root nodes gets recording makes, sense but agree that's for a separate patch.
Part of refactoring to get rid of most (all?) `std::weak_ptr<node_impl>` and some of `std::shared_ptr<node_impl>` started in intel#19295. Use `nodes_range` from that PR to implement `successors`/`predecessors` views and update read-only accesses to the successors/predecessors to go through them. I'm not changing the data members `MSuccessors`/`MPredecessors` yet because it would affect unittests. I'd prefer to refactor most of the code in future PRs before making that change and updating unittests in one go. I'm updating some APIs to accept `node_impl &` instead of `std::shared_ptr` where the change is mostly localized to the callers iterating over successors/predecessors and doesn't spoil into other code too much. For those that weren't updated here we (temporarily) use `shared_from_this()` but I expect to eliminate those unnecessary copies when those interfaces will be updated in the subsequent PRs.
Part of refactoring to get rid of most (all?) `std::weak_ptr<node_impl>` and some of `std::shared_ptr<node_impl>` started in intel#19295. Use `nodes_range` from that PR to implement `successors`/`predecessors` views and update read-only accesses to the successors/predecessors to go through them. I'm not changing the data members `MSuccessors`/`MPredecessors` yet because it would affect unittests. I'd prefer to refactor most of the code in future PRs before making that change and updating unittests in one go. I'm updating some APIs to accept `node_impl &` instead of `std::shared_ptr` where the change is mostly localized to the callers iterating over successors/predecessors and doesn't spoil into other code too much. For those that weren't updated here we (temporarily) use `shared_from_this()` but I expect to eliminate those unnecessary copies when those interfaces will be updated in the subsequent PRs.
Continuation of the refactoring in intel#19295 intel#19332
Part of refactoring to get rid of most (all?) `std::weak_ptr<node_impl>` and some of `std::shared_ptr<node_impl>` started in intel#19295. Use `nodes_range` from that PR to implement `successors`/`predecessors` views and update read-only accesses to the successors/predecessors to go through them. I'm not changing the data members `MSuccessors`/`MPredecessors` yet because it would affect unittests. I'd prefer to refactor most of the code in future PRs before making that change and updating unittests in one go. I'm updating some APIs to accept `node_impl &` instead of `std::shared_ptr` where the change is mostly localized to the callers iterating over successors/predecessors and doesn't spoil into other code too much. For those that weren't updated here we (temporarily) use `shared_from_this()` but I expect to eliminate those unnecessary copies when those interfaces will be updated in the subsequent PRs.
Continuation of the refactoring in intel#19295 intel#19332
Continuation of the refactoring in intel#19295 intel#19332
... and update the code surrounding their uses in the same spirit. Continuation of intel#19295 intel#19332 intel#19334
…19332) Part of refactoring to get rid of most (all?) `std::weak_ptr<node_impl>` and some of `std::shared_ptr<node_impl>` started in #19295. Use `nodes_range` from that PR to implement `successors`/`predecessors` views and update read-only accesses to the successors/predecessors to go through them. I'm not changing the data members `MSuccessors`/`MPredecessors` yet because it would affect unittests. I'd prefer to refactor most of the code in future PRs before making that change and updating unittests in one go. I'm updating some APIs to accept `node_impl &` instead of `std::shared_ptr` where the change is mostly localized to the callers iterating over successors/predecessors and doesn't spoil into other code too much. For those that weren't updated here we (temporarily) use `shared_from_this()` but I expect to eliminate those unnecessary copies when those interfaces will be updated in the subsequent PRs.
... and update the code surrounding their uses in the same spirit. Continuation of intel#19295 intel#19332 intel#19334
It looks like lots of
std::vector<std::weak_ptr<node_impl>>
aren't actually used for lifetime management and aren't expected to ever have an "expired"std::weak_ptr
. As such, it would make sense to transition many of them to raw pointers/references (e.g.std::vector<node_impl *>
). This utility should help to make such transition a bit easier.However, I expect it to be useful even after the elimination of unnecessary
weak_ptr
s and that can be seen even as part of this PR already.Scenario A: we need to process both
std::vector<node_impl *>
passed around as function parameters or created as a local variable on stack, andstd::vector<node>
orstd::vector<std::shared_ptr<node_impl>>
that is used for lifetime management (e.g.handler
's data member, or all the nodes in the graph). This utility would allow such an API to have a single overload to work with both scenarios.Scenario B: no conversion between
std::set
->std::vector<>
(already updated here) is necessary and no templates required to support them both via single overload.Another potentially useful application would be to provide "getters" like
nodes_range node_impl::successors()
to hide away implementation details of the underlying container.