From dbe35e98a826b06d8820dcfa80df5e8713b98032 Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Wed, 11 Oct 2023 15:03:05 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E4=B8=80?= =?UTF-8?q?=E7=A7=8D=E9=93=BE=E5=BC=8F=E7=9A=84=E5=9B=BE=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E4=B8=8E=E7=BA=BF=E6=80=A7=E7=9A=84=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E4=BA=92=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: YdrMaster --- .../include/graph_topo/builder.hpp | 7 - .../include/graph_topo/container.h | 11 +- .../include/graph_topo/graph_topo.h | 2 +- .../{modifier.h => inplace_modifier.h} | 12 +- .../include/graph_topo/linked_graph.h | 236 ++++++++++++++++++ .../src/{modifier.cc => inplace_modifier.cc} | 8 +- src/01graph_topo/test/test_linked.cpp | 13 + src/01graph_topo/test/test_modifier.cpp | 10 +- 8 files changed, 274 insertions(+), 25 deletions(-) rename src/01graph_topo/include/graph_topo/{modifier.h => inplace_modifier.h} (85%) create mode 100644 src/01graph_topo/include/graph_topo/linked_graph.h rename src/01graph_topo/src/{modifier.cc => inplace_modifier.cc} (93%) create mode 100644 src/01graph_topo/test/test_linked.cpp diff --git a/src/01graph_topo/include/graph_topo/builder.hpp b/src/01graph_topo/include/graph_topo/builder.hpp index 0a3bc00c..04188d9b 100644 --- a/src/01graph_topo/include/graph_topo/builder.hpp +++ b/src/01graph_topo/include/graph_topo/builder.hpp @@ -8,13 +8,6 @@ namespace refactor::graph_topo { - template - struct Graph { - GraphTopo topology; - std::vector nodes; - std::vector edges; - }; - template struct BuilderNode { std::vector inputs, outputs; diff --git a/src/01graph_topo/include/graph_topo/container.h b/src/01graph_topo/include/graph_topo/container.h index 5c468d27..26c214d6 100644 --- a/src/01graph_topo/include/graph_topo/container.h +++ b/src/01graph_topo/include/graph_topo/container.h @@ -8,11 +8,11 @@ namespace refactor::graph_topo { class Searcher; - class Modifier; + class InplaceModifier; class GraphTopo { friend class Searcher; - friend class Modifier; + friend class InplaceModifier; class __Implement; __Implement *_impl; @@ -69,6 +69,13 @@ namespace refactor::graph_topo { void __setGlobalOutputs(std::vector outputs) noexcept; }; + template + struct Graph { + GraphTopo topology; + std::vector nodes; + std::vector edges; + }; + }// namespace refactor::graph_topo #endif// GRAPH_TOPO_CONTAINER_H diff --git a/src/01graph_topo/include/graph_topo/graph_topo.h b/src/01graph_topo/include/graph_topo/graph_topo.h index be8ebfd7..43e5f91e 100644 --- a/src/01graph_topo/include/graph_topo/graph_topo.h +++ b/src/01graph_topo/include/graph_topo/graph_topo.h @@ -2,7 +2,7 @@ #define GRAPH_TOPO_GRAPH_TOPO_H #include "builder.hpp" -#include "modifier.h" +#include "inplace_modifier.h" #include "searcher.h" #endif// GRAPH_TOPO_GRAPH_TOPO_H diff --git a/src/01graph_topo/include/graph_topo/modifier.h b/src/01graph_topo/include/graph_topo/inplace_modifier.h similarity index 85% rename from src/01graph_topo/include/graph_topo/modifier.h rename to src/01graph_topo/include/graph_topo/inplace_modifier.h index e449901a..6300a04a 100644 --- a/src/01graph_topo/include/graph_topo/modifier.h +++ b/src/01graph_topo/include/graph_topo/inplace_modifier.h @@ -1,5 +1,5 @@ -#ifndef GRAPH_TOPO_MODIFIER_H -#define GRAPH_TOPO_MODIFIER_H +#ifndef GRAPH_TOPO_INPLACE_MODIFIER_H +#define GRAPH_TOPO_INPLACE_MODIFIER_H #include "container.h" @@ -37,14 +37,14 @@ namespace refactor::graph_topo { size_t node, edge; }; - class Modifier { + class InplaceModifier { GraphTopo _g; public: - Modifier() noexcept = default; + InplaceModifier() noexcept = default; /// @brief 把图拓扑存入修改器。 - explicit Modifier(GraphTopo) noexcept; + explicit InplaceModifier(GraphTopo) noexcept; /// @brief 将图拓扑从修改器中取出。 GraphTopo take() noexcept; @@ -57,4 +57,4 @@ namespace refactor::graph_topo { }// namespace refactor::graph_topo -#endif// GRAPH_TOPO_MODIFIER_H +#endif// GRAPH_TOPO_INPLACE_MODIFIER_H diff --git a/src/01graph_topo/include/graph_topo/linked_graph.h b/src/01graph_topo/include/graph_topo/linked_graph.h new file mode 100644 index 00000000..fd23e46d --- /dev/null +++ b/src/01graph_topo/include/graph_topo/linked_graph.h @@ -0,0 +1,236 @@ +#ifndef GRAPH_TOPO_LINKED_GRAPH_H +#define GRAPH_TOPO_LINKED_GRAPH_H + +#include "container.h" +#include +#include +#include + +namespace refactor::graph_topo { + + template + class LinkedGraph { + public: + class Node; + class Edge; + + private: + using NodeRc = std::shared_ptr; + using EdgeRc = std::shared_ptr; + + std::vector _nodes; + std::vector _inputs, _outputs; + + public: + LinkedGraph() = default; + explicit LinkedGraph(Graph); + + static auto shareEdge(TE) -> EdgeRc; + + Graph build() const; + std::vector const &inputs() const; + std::vector const &outputs() const; + void setInputs(std::vector); + void setOutputs(std::vector); + NodeRc addNode(TN, std::vector); + }; + + template + class LinkedGraph::Node : public std::enable_shared_from_this::Node> { + friend class LinkedGraph; + friend class Edge; + + TN _info; + std::vector _inputs, _outputs; + + Node(TN, std::vector); + static NodeRc share(TN, std::vector); + + public: + TN const &info() const; + std::vector const &inputs() const; + std::vector const &outputs() const; + void connect(size_t i, EdgeRc input); + void disconnect(size_t i); + }; + + template + class LinkedGraph::Edge : public std::enable_shared_from_this::Edge> { + friend class LinkedGraph; + friend class Edge; + + TE _info; + NodeRc _source; + std::unordered_map _targets; + + public: + explicit Edge(TE); + TE const &info() const; + }; + +#define LINKED_GRAPH_FN template auto LinkedGraph:: +#define LINKED_GRAPH_CONSTRUCTOR template LinkedGraph:: + + LINKED_GRAPH_FN shareEdge(TE info)->EdgeRc { + return std::make_shared(std::move(info)); + } + + LINKED_GRAPH_FN inputs() const->std::vector const & { + return _inputs; + } + + LINKED_GRAPH_FN outputs() const->std::vector const & { + return _outputs; + } + + LINKED_GRAPH_FN setInputs(std::vector inputs)->void { + _inputs = std::move(inputs); + } + + LINKED_GRAPH_FN setOutputs(std::vector outputs)->void { + _outputs = std::move(outputs); + } + + LINKED_GRAPH_FN addNode(TN info, std::vector outputs)->NodeRc { + auto ans = Node::share(std::move(info), std::move(outputs)); + _nodes.push_back(ans); + return ans; + } + + LINKED_GRAPH_FN Node::share(TN info, std::vector outputs)->NodeRc { + auto ans = std::shared_ptr(new Node(std::move(info), std::move(outputs))); + for (auto &edge : ans->_outputs) { + edge->_source = ans; + } + return ans; + } + + LINKED_GRAPH_FN Node::info() const->TN const & { + return _info; + } + + LINKED_GRAPH_FN Node::inputs() const->std::vector const & { + return _inputs; + } + + LINKED_GRAPH_FN Node::outputs() const->std::vector const & { + return _outputs; + } + + LINKED_GRAPH_FN Node::connect(size_t i, EdgeRc input)->void { + if (i < _inputs.size()) { + disconnect(i); + } else { + _inputs.resize(i + 1, nullptr); + } + if (input) { + ++input->_targets.try_emplace(this->shared_from_this(), 0).first->second; + _inputs.at(i) = std::move(input); + } + } + + LINKED_GRAPH_FN Node::disconnect(size_t i)->void { + auto edge = std::exchange(_inputs.at(i), nullptr); + if (edge) { + auto it = edge->_targets.find(this->shared_from_this()); + if (!--it->second) { + edge->_targets.erase(it); + } + } + while (!_inputs.back()) { + _inputs.pop_back(); + } + } + + LINKED_GRAPH_FN Edge::info() const->TE const & { + return _info; + } + + LINKED_GRAPH_CONSTRUCTOR Node::Node(TN info, std::vector outputs) + : _info(std::move(info)), + _inputs(), + _outputs(std::move(outputs)) {} + + LINKED_GRAPH_CONSTRUCTOR Edge::Edge(TE info) + : _info(std::move(info)) {} + + LINKED_GRAPH_CONSTRUCTOR LinkedGraph(Graph g) + : _inputs(g.topology.globalInputsCount()), + _outputs(), + _nodes(g.topology.nodeCount()) { + + std::vector edges(g.edges.size()); + std::transform(g.edges.begin(), g.edges.end(), edges.begin(), + [](auto &e) { return shareEdge(std::move(e)); }); + + auto it = g.topology.begin(), end_ = g.topology.end(); + while (it != end_) { + auto [nodeIdx, inputs, outputs] = *it++; + std::vector outputs_(outputs.size()); + std::transform(outputs.begin(), outputs.end(), outputs_.begin(), + [&edges](auto i) { return edges[i]; }); + auto &node = _nodes[nodeIdx] = Node::share(std::move(g.nodes[nodeIdx]), std::move(outputs_)); + for (auto i : inputs) { node->connect(i, edges[i]); } + } + + auto inputs = it.globalInputs(); + std::transform(inputs.begin(), inputs.end(), _inputs.begin(), + [&edges](auto i) { return edges[i]; }); + auto outputs = it.globalOutputs(); + _outputs.resize(outputs.size()); + std::transform(outputs.begin(), outputs.end(), _outputs.begin(), + [&edges](auto i) { return std::move(edges[i]); }); + } + + LINKED_GRAPH_FN build() const->Graph { + auto topology = GraphTopo::__withGlobalInputs(_inputs.size()); + std::vector nodes; + std::vector edges; + + nodes.reserve(_nodes.size()); + edges.reserve(_inputs.size()); + + std::unordered_map edgeIndices; + for (auto &e : _inputs) { + edgeIndices.insert({reinterpret_cast(e.get()), edges.size()}); + edges.push_back(std::move(e->_info)); + } + + for (auto &n : _nodes) { + nodes.push_back(std::move(n->_info)); + + std::vector newLocal, nodeInputs; + nodeInputs.reserve(n->_inputs.size()); + for (auto &e : n->_inputs) { + auto [it, ok] = edgeIndices.try_emplace(reinterpret_cast(e.get()), edges.size()); + if (ok) { + ASSERT(!e->_source, "Local edge should not have source node"); + newLocal.push_back(it->second); + edges.push_back(std::move(e->_info)); + } + nodeInputs.push_back(it->second); + } + + for (auto &e : n->_outputs) { + edgeIndices.insert({reinterpret_cast(e.get()), edges.size()}); + edges.push_back(std::move(e->_info)); + } + + topology.__addNode(newLocal.size(), std::move(nodeInputs), n->_outputs.size()); + } + + std::vector outputs(_outputs.size()); + std::transform(_outputs.begin(), _outputs.end(), outputs.begin(), + [&](auto &e) { return edgeIndices.at(reinterpret_cast(e.get())); }); + topology.__setGlobalOutputs(std::move(outputs)); + + return { + std::move(topology), + std::move(nodes), + std::move(edges), + }; + } + +}// namespace refactor::graph_topo + +#endif// GRAPH_TOPO_LINKED_GRAPH_H diff --git a/src/01graph_topo/src/modifier.cc b/src/01graph_topo/src/inplace_modifier.cc similarity index 93% rename from src/01graph_topo/src/modifier.cc rename to src/01graph_topo/src/inplace_modifier.cc index 57379454..e2d730a1 100644 --- a/src/01graph_topo/src/modifier.cc +++ b/src/01graph_topo/src/inplace_modifier.cc @@ -1,4 +1,4 @@ -#include "graph_topo/modifier.h" +#include "graph_topo/inplace_modifier.h" #include "common/error_handler.h" #include "common/range.h" #include "internal.h" @@ -18,14 +18,14 @@ namespace refactor::graph_topo { bool OnNode::isOutput() const noexcept { return (edge & 1) == 1; } size_t OnNode::index() const noexcept { return edge >> 1; } - Modifier::Modifier(GraphTopo g) noexcept + InplaceModifier::InplaceModifier(GraphTopo g) noexcept : _g(std::move(g)) {} - auto Modifier::take() noexcept -> GraphTopo { + auto InplaceModifier::take() noexcept -> GraphTopo { return std::move(_g); } - auto Modifier::insert(Bridge bridge) noexcept -> BridgePos { + auto InplaceModifier::insert(Bridge bridge) noexcept -> BridgePos { auto n = bridge.node; auto idx = bridge.edge.index(); auto &g = *_g._impl; diff --git a/src/01graph_topo/test/test_linked.cpp b/src/01graph_topo/test/test_linked.cpp new file mode 100644 index 00000000..5a52a028 --- /dev/null +++ b/src/01graph_topo/test/test_linked.cpp @@ -0,0 +1,13 @@ +#include "graph_topo/linked_graph.h" +#include "topo.h" +#include + +using namespace refactor::graph_topo; + +TEST(GraphTopo, LinkedGraph) { + auto g = testTopo().build(); + LinkedGraph g_(g); + // auto g__ = g_.build(); + // EXPECT_EQ(g__.nodes, g.nodes); + // EXPECT_EQ(g__.edges, g.edges); +} diff --git a/src/01graph_topo/test/test_modifier.cpp b/src/01graph_topo/test/test_modifier.cpp index bc5717c6..ca55be02 100644 --- a/src/01graph_topo/test/test_modifier.cpp +++ b/src/01graph_topo/test/test_modifier.cpp @@ -3,26 +3,26 @@ using namespace refactor::graph_topo; -TEST(GraphTopo, Modifier) { +TEST(GraphTopo, InplaceModifier) { auto [topology, nodes, edges] = testTopo().build(); fmt::println("{}", topology.toString()); { - auto modifier = Modifier(topology); + auto modifier = InplaceModifier(topology); modifier.insert(Bridge{0, OnNode::input(1)}); fmt::println("{}", modifier.take().toString()); } { - auto modifier = Modifier(topology); + auto modifier = InplaceModifier(topology); modifier.insert(Bridge{1, OnNode::input(0)}); fmt::println("{}", modifier.take().toString()); } { - auto modifier = Modifier(topology); + auto modifier = InplaceModifier(topology); modifier.insert(Bridge{0, OnNode::output(1)}); fmt::println("{}", modifier.take().toString()); } { - auto modifier = Modifier(topology); + auto modifier = InplaceModifier(topology); modifier.insert(Bridge{2, OnNode::output(0)}); fmt::println("{}", modifier.take().toString()); } From b33467e2fce240a8f47c7b5eaa9034c7eb4936c3 Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Wed, 11 Oct 2023 17:39:29 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E6=94=B9=E6=AD=A3=E5=B9=B6=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=93=BE=E5=BC=8F=E5=9B=BE=E6=96=B0=E5=BB=BA=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=92=8C=E8=BF=9E=E6=8E=A5=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: YdrMaster --- .../include/graph_topo/linked_graph.h | 130 ++++++++++++++++-- src/01graph_topo/src/container.cc | 24 +++- src/01graph_topo/test/test_linked.cpp | 25 +++- 3 files changed, 154 insertions(+), 25 deletions(-) diff --git a/src/01graph_topo/include/graph_topo/linked_graph.h b/src/01graph_topo/include/graph_topo/linked_graph.h index fd23e46d..7d844afe 100644 --- a/src/01graph_topo/include/graph_topo/linked_graph.h +++ b/src/01graph_topo/include/graph_topo/linked_graph.h @@ -1,12 +1,15 @@ #ifndef GRAPH_TOPO_LINKED_GRAPH_H #define GRAPH_TOPO_LINKED_GRAPH_H +#include "common/range.h" #include "container.h" #include #include +#include #include namespace refactor::graph_topo { + using namespace common; template class LinkedGraph { @@ -21,18 +24,25 @@ namespace refactor::graph_topo { std::vector _nodes; std::vector _inputs, _outputs; + Graph toGraph(bool) const; + public: LinkedGraph() = default; explicit LinkedGraph(Graph); static auto shareEdge(TE) -> EdgeRc; - Graph build() const; + std::string toString() const; + Graph toGraph() const; + Graph intoGraph() const; + std::vector const &nodes() const; std::vector const &inputs() const; std::vector const &outputs() const; void setInputs(std::vector); void setOutputs(std::vector); - NodeRc addNode(TN, std::vector); + NodeRc pushNode(TN, std::vector); + void eraseNode(size_t); + void eraseNode(NodeRc); }; template @@ -50,7 +60,7 @@ namespace refactor::graph_topo { TN const &info() const; std::vector const &inputs() const; std::vector const &outputs() const; - void connect(size_t i, EdgeRc input); + void connect(size_t i, EdgeRc); void disconnect(size_t i); }; @@ -75,6 +85,38 @@ namespace refactor::graph_topo { return std::make_shared(std::move(info)); } + LINKED_GRAPH_FN toString() const->std::string { + std::unordered_map indices; + std::stringstream ss; + auto f = [&indices, &ss](EdgeRc const &e) { + if (e) { + auto [it, ok] = indices.try_emplace(reinterpret_cast(e.get()), indices.size()); + ss << it->second << ' '; + } else { + ss << "? "; + } + }; + ss << "*. -> ( "; + for (auto const &e : _inputs) { f(e); } + ss << ')' << std::endl; + for (auto i : range0_(_nodes.size())) { + auto n = _nodes[i]; + ss << i << ". ( "; + for (auto const &e : n->_inputs) { f(e); } + ss << ") -> ( "; + for (auto const &e : n->_outputs) { f(e); } + ss << ')' << std::endl; + } + ss << "*. <- ( "; + for (auto const &e : _outputs) { f(e); } + ss << ')' << std::endl; + return ss.str(); + } + + LINKED_GRAPH_FN nodes() const->std::vector const & { + return _nodes; + } + LINKED_GRAPH_FN inputs() const->std::vector const & { return _inputs; } @@ -91,13 +133,47 @@ namespace refactor::graph_topo { _outputs = std::move(outputs); } - LINKED_GRAPH_FN addNode(TN info, std::vector outputs)->NodeRc { + LINKED_GRAPH_FN pushNode(TN info, std::vector outputs)->NodeRc { auto ans = Node::share(std::move(info), std::move(outputs)); _nodes.push_back(ans); return ans; } - LINKED_GRAPH_FN Node::share(TN info, std::vector outputs)->NodeRc { + LINKED_GRAPH_FN eraseNode(size_t i)->void { + auto &node = _nodes.at(i); + for (auto i : range0_(node->_inputs.size())) { + node->disconnect(i); + } + for (auto i : range0_(node->_outputs.size())) { + auto out = node->_outputs[i]; + while (!out->_targets.empty()) { + auto target = out->_targets.begin()->first; + for (auto j : range0_(target->_inputs.size())) { + if (target->_inputs[j] == out) { + target->disconnect(j); + break; + } + } + } + for (auto j : range0_(_outputs.size())) { + if (_outputs[j] == out) { + _outputs[j] = nullptr; + } + } + } + _nodes.erase(_nodes.begin() + i); + } + + LINKED_GRAPH_FN eraseNode(NodeRc node)->void { + for (auto i : range0_(_nodes.size())) { + if (_nodes[i] == node) { + eraseNode(i); + } + } + } + + LINKED_GRAPH_FN Node::share(TN info, std::vector outputs) + ->NodeRc { auto ans = std::shared_ptr(new Node(std::move(info), std::move(outputs))); for (auto &edge : ans->_outputs) { edge->_source = ans; @@ -130,14 +206,13 @@ namespace refactor::graph_topo { } LINKED_GRAPH_FN Node::disconnect(size_t i)->void { - auto edge = std::exchange(_inputs.at(i), nullptr); - if (edge) { + if (auto edge = std::exchange(_inputs.at(i), nullptr); edge) { auto it = edge->_targets.find(this->shared_from_this()); - if (!--it->second) { + if (0 == --it->second) { edge->_targets.erase(it); } } - while (!_inputs.back()) { + while (!_inputs.empty() && !_inputs.back()) { _inputs.pop_back(); } } @@ -170,7 +245,7 @@ namespace refactor::graph_topo { std::transform(outputs.begin(), outputs.end(), outputs_.begin(), [&edges](auto i) { return edges[i]; }); auto &node = _nodes[nodeIdx] = Node::share(std::move(g.nodes[nodeIdx]), std::move(outputs_)); - for (auto i : inputs) { node->connect(i, edges[i]); } + for (auto i : range0_(inputs.size())) { node->connect(i, edges[inputs[i]]); } } auto inputs = it.globalInputs(); @@ -182,7 +257,7 @@ namespace refactor::graph_topo { [&edges](auto i) { return std::move(edges[i]); }); } - LINKED_GRAPH_FN build() const->Graph { + LINKED_GRAPH_FN toGraph(bool copy) const->Graph { auto topology = GraphTopo::__withGlobalInputs(_inputs.size()); std::vector nodes; std::vector edges; @@ -193,27 +268,44 @@ namespace refactor::graph_topo { std::unordered_map edgeIndices; for (auto &e : _inputs) { edgeIndices.insert({reinterpret_cast(e.get()), edges.size()}); - edges.push_back(std::move(e->_info)); + if (copy) { + edges.push_back(e->_info); + } else { + edges.emplace_back(std::move(e->_info)); + } } for (auto &n : _nodes) { - nodes.push_back(std::move(n->_info)); + if (copy) { + nodes.push_back(n->_info); + } else { + nodes.emplace_back(std::move(n->_info)); + } std::vector newLocal, nodeInputs; nodeInputs.reserve(n->_inputs.size()); for (auto &e : n->_inputs) { + ASSERT(e, "Input edge is not connected"); auto [it, ok] = edgeIndices.try_emplace(reinterpret_cast(e.get()), edges.size()); if (ok) { ASSERT(!e->_source, "Local edge should not have source node"); newLocal.push_back(it->second); - edges.push_back(std::move(e->_info)); + if (copy) { + edges.push_back(e->_info); + } else { + edges.emplace_back(std::move(e->_info)); + } } nodeInputs.push_back(it->second); } for (auto &e : n->_outputs) { edgeIndices.insert({reinterpret_cast(e.get()), edges.size()}); - edges.push_back(std::move(e->_info)); + if (copy) { + edges.push_back(e->_info); + } else { + edges.emplace_back(std::move(e->_info)); + } } topology.__addNode(newLocal.size(), std::move(nodeInputs), n->_outputs.size()); @@ -231,6 +323,14 @@ namespace refactor::graph_topo { }; } + LINKED_GRAPH_FN toGraph() const->Graph { + return toGraph(true); + } + + LINKED_GRAPH_FN intoGraph() const->Graph { + return toGraph(false); + } + }// namespace refactor::graph_topo #endif// GRAPH_TOPO_LINKED_GRAPH_H diff --git a/src/01graph_topo/src/container.cc b/src/01graph_topo/src/container.cc index feb987b7..0acc41a1 100644 --- a/src/01graph_topo/src/container.cc +++ b/src/01graph_topo/src/container.cc @@ -115,21 +115,31 @@ namespace refactor::graph_topo { } std::string GraphTopo::toString() const { - std::stringstream ans; + std::stringstream ss; auto it = begin(), end_ = end(); + ss << "*. -> ( "; + for (auto i : it.globalInputs()) { + ss << i << ' '; + } + ss << ')' << std::endl; while (it != end_) { auto [nodeIdx, inputs, outputs] = *it++; - ans << nodeIdx << ". ( "; + ss << nodeIdx << ". ( "; for (auto i : inputs) { - ans << i << ' '; + ss << i << ' '; } - ans << ") -> ( "; + ss << ") -> ( "; for (auto i : outputs) { - ans << i << ' '; + ss << i << ' '; } - ans << ")" << std::endl; + ss << ')' << std::endl; + } + ss << "*. <- ( "; + for (auto i : it.globalOutputs()) { + ss << i << ' '; } - return ans.str(); + ss << ')' << std::endl; + return ss.str(); } GraphTopo GraphTopo::__withGlobalInputs( diff --git a/src/01graph_topo/test/test_linked.cpp b/src/01graph_topo/test/test_linked.cpp index 5a52a028..8b5dca7c 100644 --- a/src/01graph_topo/test/test_linked.cpp +++ b/src/01graph_topo/test/test_linked.cpp @@ -7,7 +7,26 @@ using namespace refactor::graph_topo; TEST(GraphTopo, LinkedGraph) { auto g = testTopo().build(); LinkedGraph g_(g); - // auto g__ = g_.build(); - // EXPECT_EQ(g__.nodes, g.nodes); - // EXPECT_EQ(g__.edges, g.edges); + fmt::println("{}", g_.toString()); + auto g__ = g_.toGraph(); + EXPECT_EQ(g__.nodes, g.nodes); + EXPECT_EQ(g__.edges, g.edges); + + auto n0 = g_.nodes()[0]; + auto n1 = g_.nodes()[1]; + auto n2 = g_.nodes()[2]; + + auto n3 = g_.pushNode("n4", {g_.shareEdge("e0"), g_.shareEdge("e1")}); + n3->connect(0, n2->outputs()[0]); + g_.setOutputs({n3->outputs()[1]}); + fmt::println("{}", g_.toString()); + + n2->disconnect(0); + fmt::println("{}", g_.toString()); + + n2->connect(0, g_.inputs()[0]); + fmt::println("{}", g_.toString()); + + g_.eraseNode(n2); + fmt::println("{}", g_.toString()); }