-
Notifications
You must be signed in to change notification settings - Fork 9
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
NNI Evaluation Engine #377
Conversation
249b84d
to
03182a2
Compare
8e8a2ce
to
1bda563
Compare
TEST_CASE("NNI Engine: Add NNI Test")
|
327dd44
to
5604219
Compare
* Grafted DAG: This allows modifying the SubsplitDAG with the quick adding and removing of proposed NNIs to DAG. * NNI Engine: This is an engine for using Nearest Neighbor Interchanges to perform a systematic search on a DAG. * Finds all NNIs adjacent to DAG. * Adds all NNIs to DAG via Graft. * Evaluates likelihood of NNI. (Unfinished - left to Issue #405 and #404) * Filter NNIs to accept or reject. (Unfinished - left to Issue #405) * Add accepted NNIs to DAG. * Remove adjacent NNIs from Graft and Add back NNIs adjacent to new Accepted NNIs. Return to Step c). Closes #372
5604219
to
228d091
Compare
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.
Some nitpicks here, but mostly tomorrow I'd like to discuss the overall design-- who owns what and who has a pointer or reference to what. Could you come with a little diagram describing that (just a photo of a hand-scribble would be great).
Also, it feels like there is a lot of code duplication with things like IterateOverLeafwardEdges
. I wonder if this could be reduced. We'll chat!
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 for this, @davidrich27 ! Some things I'm looking forward to discussing today.
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 have to move to something else, but will come back soon to look at the cpp files.
Have we picked a naming convention with regards to left and leftside, etc? I'm sure you have something but clarifying it for me would help.
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.
A few more comments.
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.
A factoring point... "pushing" before meeting.
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.
partway through graft_dag
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.
Finishing my pass.
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.
Typo fix needed.
I think you'd notice these things if you looked at the diff after pushing.
* Grafted DAG: This allows modifying the SubsplitDAG with the quick adding and removing of proposed NNIs to DAG. * NNI Engine: This is an engine for using Nearest Neighbor Interchanges to perform a systematic search on a DAG. * Finds all NNIs adjacent to DAG. * Adds all NNIs to DAG via Graft. * Evaluates likelihood of NNI. (Unfinished - left to Issue #405 and #404) * Filter NNIs to accept or reject. (Unfinished - left to Issue #405) * Add accepted NNIs to DAG. * Remove adjacent NNIs from Graft and Add back NNIs adjacent to new Accepted NNIs. Return to Step c). Closes #372
3ca51c5
to
e149f9f
Compare
* Grafted DAG: This allows modifying the SubsplitDAG with the quick adding and removing of proposed NNIs to DAG. * NNI Engine: This is an engine for using Nearest Neighbor Interchanges to perform a systematic search on a DAG. * Finds all NNIs adjacent to DAG. * Adds all NNIs to DAG via Graft. * Evaluates likelihood of NNI. (Unfinished - left to Issue #405 and #404) * Filter NNIs to accept or reject. (Unfinished - left to Issue #405) * Add accepted NNIs to DAG. * Remove adjacent NNIs from Graft and Add back NNIs adjacent to new Accepted NNIs. Return to Step c). Closes #372
9ebb58c
to
5b5e8a0
Compare
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.
Really nice work. Some nitpicking as usual, but trying to form habits here.
Do I understand correctly that the complexity of adding every NNI as a graft and then removing it is O(N^2), because we have to traverse the DAG, and then we also have a linear time addition process needing to search for parents and children?
This may be kind of big for dags with 100K nodes. Down the road we may want to consider keeping more information in the NNIs so that we can just reconnect their edges without needing a linear search.
src/graft_dag.hpp
Outdated
|
||
#pragma once | ||
|
||
class GPDAG; |
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.
Is this forward declaration necessary?
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 was needed before the PLVHandler. I'll remove it.
src/graft_dag.hpp
Outdated
// Get the GPCSP/edge index by its parent/child pair. | ||
size_t GetEdgeIdx(const Bitset &parent_subsplit, const Bitset &child_subsplit) const; | ||
size_t GetEdgeIdx(const size_t parent_id, const size_t child_id) const; | ||
// Get a sorted vector of all node subsplit's bitset representation. Optionally only |
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.
// Get a sorted vector of all node subsplit's bitset representation. Optionally only | |
// Get a sorted vector of all node subsplit bitset representations. Optionally only |
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.
Fixed.
src/graft_dag.hpp
Outdated
// Get a sorted vector of all node subsplit's bitset representation. Optionally only | ||
// graft nodes, or graft and host nodes. | ||
BitsetVector GetSortedVectorOfNodeBitsets(bool include_host = true) const; | ||
// Get a sorted vector of all edge PCSP's bitset representation. Optionally only graft |
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.
// Get a sorted vector of all edge PCSP's bitset representation. Optionally only graft | |
// Get a sorted vector of all edge PCSP bitset representations. Optionally only graft |
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.
Fixed.
src/graft_dag.hpp
Outdated
// DAG that the graft is proposed to be connected to. | ||
SubsplitDAG &host_dag_; | ||
// Nodes and edges in the graft. | ||
SubsplitDAGStorage storage_; |
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 have a slight preference for calling this graft_storage_
so it's obvious that it only stores the grafts.
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.
Changed name.
src/graft_dag.hpp
Outdated
// Nodes and edges in the graft. | ||
SubsplitDAGStorage storage_; | ||
// Duplicate nodes from host for edge bridging across graft. | ||
// std::vector<std::unique_ptr<SubsplitDAGNode>> bridge_nodes_; |
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.
Is this cruft?
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.
Yes. Removed.
src/nni_engine.hpp
Outdated
// Get Map of Adjacent NNIs with their score. | ||
const std::map<NNIOperation, double> &GetScoredNNIs() { return scored_nnis_; }; | ||
// Get number of runs of NNI engine. | ||
size_t GetRunCount() { return run_count_; }; |
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.
const
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.
Fixed.
src/nni_engine.hpp
Outdated
// Get Number of Accepted NNIs. | ||
size_t GetAcceptedNNICount() const { return accepted_nnis_.size(); }; | ||
// Get Map of Adjacent NNIs with their score. | ||
const std::map<NNIOperation, double> &GetScoredNNIs() { return scored_nnis_; }; |
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.
const method
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.
Fixed.
src/subsplit_dag.cpp
Outdated
return has_invalid_node; | ||
size_t correct_id = 0; | ||
for (auto node : storage_.GetVertices()) { | ||
if (correct_id++ != node.Id()) return false; |
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.
current style guideline says the body of any conditional gets wrapped in braces. We can change that if you feel strongly!
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.
This was from some rebasing by Ognian. I am happy with or without braces. We could ask Ognian if he has an opinion tomorrow.
src/subsplit_dag_node.hpp
Outdated
@@ -27,6 +27,14 @@ template <typename T> | |||
auto& GetStorage(const T& node) { | |||
return node.node_; | |||
} | |||
static inline void RemapNeighbors(NeighborsView neighbors, | |||
const SizeVector& node_reindexer) { | |||
std::map<VertexId, LineId> remaped; |
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.
std::map<VertexId, LineId> remaped; | |
std::map<VertexId, LineId> remapped; |
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.
Fixed.
src/subsplit_dag_storage.hpp
Outdated
@@ -222,6 +204,8 @@ class GenericNeighborsView { | |||
return result; | |||
} | |||
|
|||
void Remap(const T& neighbors) { neighbors_ = neighbors; } |
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.
Is this the clearest name for this method? It seems more like a SetNeighbors
.
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.
Good idea. Name changed.
I believe it should be O(N) per NNI. But since the number of NNIs is O(N), I think the whole process is roughly O(N^2). That's what you're saying? But yes, currently it is a linear search to find the parents/children. I think I may have proposed this to you earlier, but we could make this constant time operation by using a clade map. Essentially, we could store each subsplit's left and right clade in a map, and the unions of their clades into a map, paired with a vector of node ids. A subsplit's parents have a single clade equal to your union clade, and a subplit's children have a union clade equal to one of your single clades. So each would just require a single lookup. |
* Grafted DAG: This allows modifying the SubsplitDAG with the quick adding and removing of proposed NNIs to DAG. * NNI Engine: This is an engine for using Nearest Neighbor Interchanges to perform a systematic search on a DAG. * Finds all NNIs adjacent to DAG. * Adds all NNIs to DAG via Graft. * Evaluates likelihood of NNI. (Unfinished - left to Issue #405 and #404) * Filter NNIs to accept or reject. (Unfinished - left to Issue #405) * Add accepted NNIs to DAG. * Remove adjacent NNIs from Graft and Add back NNIs adjacent to new Accepted NNIs. Return to Step c). Closes #372
e777cdf
to
58579dc
Compare
Description
NNI Engine and Grafted DAG
Grafted DAG: This allows modifying the SubsplitDAG with the quick adding and removing of proposed NNIs to DAG.
NNI Engine: This is an engine for using Nearest Neighbor Interchanges to perform a systematic search on a DAG.
Closes #372
Tests
Checklist:
clang-format
has been run