From 4e48349576bb5da3070111b2f3ba3fe352eeaa41 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Wed, 6 Mar 2024 12:39:18 -0800 Subject: [PATCH] replace NodeId to string --- include/ion/node.h | 28 ++++++++++------------- include/ion/port.h | 50 ++++++++++++++++++++---------------------- include/ion/port_map.h | 2 +- include/ion/util.h | 10 ++++++++- src/lower.cc | 24 ++++++++++---------- src/node.cc | 14 ++++++------ src/port.cc | 12 +++++----- src/serializer.h | 7 +++--- 8 files changed, 74 insertions(+), 73 deletions(-) diff --git a/include/ion/node.h b/include/ion/node.h index 8443a26a..79352dc9 100644 --- a/include/ion/node.h +++ b/include/ion/node.h @@ -29,8 +29,8 @@ class Node { std::vector arginfos; Impl(): id(), name(), target(), params(), ports() {} - Impl(const std::string& id_, const std::string& name_, const Halide::Target& target_); - Impl(const std::string& id_, const std::string& name_, const Halide::Target& target_, const GraphID &graph_id_); + Impl(const NodeID& id_, const std::string& name_, const Halide::Target& target_); + Impl(const NodeID& id_, const std::string& name_, const Halide::Target& target_, const GraphID &graph_id_); }; public: @@ -77,7 +77,7 @@ class Node { */ template Node operator()(Args ...args) { - set_iport(std::vector{get_iport(args)...}); + set_iport(std::vector{make_iport(args)...}); return *this; } @@ -99,10 +99,6 @@ class Node { return impl_->id; } - const std::string& id_to_string() const { - return to_string(impl_->id); - } - const std::string& name() const { return impl_->name; } @@ -127,38 +123,38 @@ class Node { private: Node(const std::string& id, const std::string& name, const Halide::Target& target) - : impl_(new Impl{id, name, target}) + : impl_(new Impl{NodeID(id), name, target}) { } Node(const std::string& id, const std::string& name, const Halide::Target& target, const GraphID& graph_id) - : impl_(new Impl{id, name, target, graph_id}) + : impl_(new Impl{NodeID(id), name, target, graph_id}) { } - Port get_iport(Port arg) const { + Port make_iport(Port arg) const { return arg; } template - Port get_iport(T *vptr) const { - if (impl_->graph_id.value().empty()) + Port make_iport(T *vptr) const { + if (to_string(impl_->graph_id).empty()) return Port(vptr); else return Port(vptr, impl_->graph_id); } template - Port get_iport(Halide::Buffer& arg) const { - if (impl_->graph_id.value().empty()) + Port make_iport(Halide::Buffer& arg) const { + if (to_string(impl_->graph_id).empty()) return Port(arg); else return Port(arg, impl_->graph_id); } template - Port get_iport(std::vector>& arg) const { - if (impl_->graph_id.value().empty()) + Port make_iport(std::vector>& arg) const { + if (to_string(impl_->graph_id).empty()) return Port(arg); else return Port(arg, impl_->graph_id); diff --git a/include/ion/port.h b/include/ion/port.h index d534a45b..4588ef15 100644 --- a/include/ion/port.h +++ b/include/ion/port.h @@ -65,12 +65,12 @@ class Port { std::unordered_map instances; Impl(); - Impl(const std::string& pid, const std::string& pn, const Halide::Type& t, int32_t d, const GraphID &gid ); + Impl(const NodeID& nid, const std::string& pn, const Halide::Type& t, int32_t d, const GraphID &gid ); }; public: - Port() : impl_(new Impl("", "", Halide::Type(), 0, GraphID())), index_(-1) {} + Port() : impl_(new Impl(NodeID(""), "", Halide::Type(), 0, GraphID(""))), index_(-1) {} Port(const std::shared_ptr& impl, int32_t index) : impl_(impl), index_(index) {} @@ -79,7 +79,7 @@ class Port { * @arg k: The key of the port which should be matched with BuildingBlock Input/Output name. * @arg t: The type of the value. */ - Port(const std::string& n, Halide::Type t) : impl_(new Impl("", n, t, 0, GraphID(""))), index_(-1) {} + Port(const std::string& n, Halide::Type t) : impl_(new Impl(NodeID(""), n, t, 0, GraphID(""))), index_(-1) {} /** * Construct new port for vector value. @@ -87,14 +87,14 @@ class Port { * @arg t: The type of the element value. * @arg d: The dimension of the port. The range is 1 to 4. */ - Port(const std::string& n, Halide::Type t, int32_t d) : impl_(new Impl("", n, t, d, GraphID(""))), index_(-1) {} + Port(const std::string& n, Halide::Type t, int32_t d) : impl_(new Impl(NodeID(""), n, t, d, GraphID(""))), index_(-1) {} /** * Construct new port from scalar pointer */ template::value>::type* = nullptr> - Port(T *vptr) : impl_(new Impl("", Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, GraphID(""))), index_(-1) { + Port(T *vptr) : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, GraphID(""))), index_(-1) { this->bind(vptr); } @@ -103,7 +103,7 @@ class Port { */ template::value>::type* = nullptr> - Port(T *vptr, const GraphID & gid) : impl_(new Impl("", Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, gid)), index_(-1) { + Port(T *vptr, const GraphID & gid) : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, gid)), index_(-1) { this->bind(vptr); } @@ -112,7 +112,7 @@ class Port { * Construct new port from buffer */ template - Port(const Halide::Buffer& buf) : impl_(new Impl("", buf.name(), buf.type(), buf.dimensions(), GraphID(""))), index_(-1) { + Port(const Halide::Buffer& buf) : impl_(new Impl(NodeID(""), buf.name(), buf.type(), buf.dimensions(), GraphID(""))), index_(-1) { this->bind(buf); } @@ -120,7 +120,7 @@ class Port { * Construct new port from buffer and bind graph id to port */ template - Port(const Halide::Buffer& buf, const GraphID & gid) : impl_(new Impl("", buf.name(), buf.type(), buf.dimensions(), gid)), index_(-1) { + Port(const Halide::Buffer& buf, const GraphID & gid) : impl_(new Impl(NodeID(""), buf.name(), buf.type(), buf.dimensions(), gid)), index_(-1) { this->bind(buf); } @@ -128,7 +128,7 @@ class Port { * Construct new port from array of buffer */ template - Port(const std::vector>& bufs) : impl_(new Impl("", unify_name(bufs), Halide::type_of(), unify_dimension(bufs), GraphID(""))), index_(-1) { + Port(const std::vector>& bufs) : impl_(new Impl(NodeID(""), unify_name(bufs), Halide::type_of(), unify_dimension(bufs), GraphID(""))), index_(-1) { this->bind(bufs); } @@ -136,39 +136,37 @@ class Port { * Construct new port from array of buffer and bind graph id to port */ template - Port(const std::vector>& bufs, const GraphID & gid) : impl_(new Impl("", unify_name(bufs), Halide::type_of(), unify_dimension(bufs), gid)), index_(-1) { + Port(const std::vector>& bufs, const GraphID & gid) : impl_(new Impl(NodeID(""), unify_name(bufs), Halide::type_of(), unify_dimension(bufs), gid)), index_(-1) { this->bind(bufs); } // Getter const PortID id() const { return impl_->id; } - const std::string& id_to_string() const { return to_string(impl_->id); } const Channel& pred_chan() const { return impl_->pred_chan; } const NodeID& pred_id() const { return std::get<0>(impl_->pred_chan); } - const std::string& pred_id_to_string() const { return to_string(std::get<0>(impl_->pred_chan)); } const std::string& pred_name() const { return std::get<1>(impl_->pred_chan); } const std::set& succ_chans() const { return impl_->succ_chans; } const Halide::Type& type() const { return impl_->type; } int32_t dimensions() const { return impl_->dimensions; } int32_t size() const { return static_cast(impl_->params.size()); } int32_t index() const { return index_; } - const std::string& graph_id_to_string() const { return to_string(impl_->graph_id); } + const GraphID& graph_id() const { return impl_->graph_id; } // Setter void set_index(int index) { index_ = index; } // Util bool has_pred() const { return !std::get<0>(impl_->pred_chan).value().empty(); } - bool has_pred_by_nid(const std::string& nid) const { return !to_string(std::get<0>(impl_->pred_chan)).empty(); } + bool has_pred_by_nid(const NodeID & nid) const { return !to_string(std::get<0>(impl_->pred_chan)).empty(); } bool has_succ() const { return !impl_->succ_chans.empty(); } bool has_succ(const Channel& c) const { return impl_->succ_chans.count(c); } - bool has_succ_by_nid(const std::string& nid) const { + bool has_succ_by_nid(const NodeID& nid) const { return std::count_if(impl_->succ_chans.begin(), impl_->succ_chans.end(), [&](const Port::Channel& c) { return std::get<0>(c) == nid; }); } - void determine_succ(const std::string& nid, const std::string& old_pn, const std::string& new_pn); + void determine_succ(const NodeID& nid, const std::string& old_pn, const std::string& new_pn); /** * Overloaded operator to set the port index and return a reference to the current port. eg. port[0] @@ -183,9 +181,9 @@ class Port { void bind(T *v) { auto i = index_ == -1 ? 0 : index_; if (has_pred()) { - impl_->params[i] = Halide::Internal::Parameter{Halide::type_of(), false, 0, argument_name(pred_id(), pred_name(), i, graph_id_to_string())}; + impl_->params[i] = Halide::Internal::Parameter{Halide::type_of(), false, 0, argument_name(pred_id(), pred_name(), i, graph_id())}; } else { - impl_->params[i] = Halide::Internal::Parameter{type(), false, dimensions(), argument_name(pred_id(), pred_name(), i,graph_id_to_string())}; + impl_->params[i] = Halide::Internal::Parameter{type(), false, dimensions(), argument_name(pred_id(), pred_name(), i, graph_id())}; } impl_->instances[i] = v; @@ -196,9 +194,9 @@ class Port { void bind(const Halide::Buffer& buf) { auto i = index_ == -1 ? 0 : index_; if (has_pred()) { - impl_->params[i] = Halide::Internal::Parameter{buf.type(), true, buf.dimensions(), argument_name(pred_id(), pred_name(), i,graph_id_to_string())}; + impl_->params[i] = Halide::Internal::Parameter{buf.type(), true, buf.dimensions(), argument_name(pred_id(), pred_name(), i,graph_id())}; } else { - impl_->params[i] = Halide::Internal::Parameter{type(), true, dimensions(), argument_name(pred_id(), pred_name(), i,graph_id_to_string())}; + impl_->params[i] = Halide::Internal::Parameter{type(), true, dimensions(), argument_name(pred_id(), pred_name(), i,graph_id())}; } impl_->instances[i] = buf.raw_buffer(); @@ -208,9 +206,9 @@ class Port { void bind(const std::vector>& bufs) { for (int i=0; i(bufs.size()); ++i) { if (has_pred()) { - impl_->params[i] = Halide::Internal::Parameter{bufs[i].type(), true, bufs[i].dimensions(), argument_name(pred_id(), pred_name(), i, graph_id_to_string())}; + impl_->params[i] = Halide::Internal::Parameter{bufs[i].type(), true, bufs[i].dimensions(), argument_name(pred_id(), pred_name(), i, graph_id())}; } else { - impl_->params[i] = Halide::Internal::Parameter{type(), true, dimensions(), argument_name(pred_id(), pred_name(), i, graph_id_to_string())}; + impl_->params[i] = Halide::Internal::Parameter{type(), true, dimensions(), argument_name(pred_id(), pred_name(), i, graph_id())}; } impl_->instances[i] = bufs[i].raw_buffer(); @@ -229,7 +227,7 @@ class Port { if (es.size() <= i) { es.resize(i+1, Halide::Expr()); } - es[i] = Halide::Internal::Variable::make(type(), argument_name(pred_id(), pred_name(), i, graph_id_to_string()), param); + es[i] = Halide::Internal::Variable::make(type(), argument_name(pred_id(), pred_name(), i, graph_id()), param); } return es; } @@ -250,7 +248,7 @@ class Port { args.push_back(Halide::Var::implicit(i)); args_expr.push_back(Halide::Var::implicit(i)); } - Halide::Func f(param.type(), param.dimensions(), argument_name(pred_id(), pred_name(), i, graph_id_to_string()) + "_im"); + Halide::Func f(param.type(), param.dimensions(), argument_name(pred_id(), pred_name(), i, graph_id()) + "_im"); f(args) = Halide::Internal::Call::make(param, args_expr); fs[i] = f; } @@ -264,7 +262,7 @@ class Port { args.resize(i+1, Halide::Argument()); } auto kind = dimensions() == 0 ? Halide::Argument::InputScalar : Halide::Argument::InputBuffer; - args[i] = Halide::Argument(argument_name(pred_id(), pred_name(), i, graph_id_to_string()), kind, type(), dimensions(), Halide::ArgumentEstimates()); + args[i] = Halide::Argument(argument_name(pred_id(), pred_name(), i, graph_id()), kind, type(), dimensions(), Halide::ArgumentEstimates()); } return args; } @@ -287,7 +285,7 @@ class Port { * pid and pn is stored in both pred and succ, * then it will determined through pipeline build process. */ - Port(const std::string& pid, const std::string& pn) : impl_(new Impl(pid, pn, Halide::Type(), 0, GraphID(""))), index_(-1) {} + Port(const NodeID & nid, const std::string& pn) : impl_(new Impl(nid, pn, Halide::Type(), 0, GraphID(""))), index_(-1) {} std::shared_ptr impl_; diff --git a/include/ion/port_map.h b/include/ion/port_map.h index 68455edc..ee036910 100644 --- a/include/ion/port_map.h +++ b/include/ion/port_map.h @@ -16,7 +16,7 @@ class PortMap { template [[deprecated("Port::bind can be used instead of PortMap.")]] void set(Port port, T v) { - auto& buf(scalar_buffer_[argument_name(port.pred_id_to_string(), port.pred_name(), port.index(), port.graph_id_to_string())]); + auto& buf(scalar_buffer_[argument_name(port.pred_id(), port.pred_name(), port.index(), port.graph_id())]); buf.resize(sizeof(v)); std::memcpy(buf.data(), &v, sizeof(v)); port.bind(reinterpret_cast(buf.data())); diff --git a/include/ion/util.h b/include/ion/util.h index 7103ef09..eb4caf42 100644 --- a/include/ion/util.h +++ b/include/ion/util.h @@ -14,12 +14,20 @@ template struct StringID { using tag_type = Tag; - // needs to be default-constuctable because of use in map[] below + // needs to be default-constructable because of use in map[] below StringID(std::string s) : _value(std::move(s)) {} StringID() : _value() {} // provide access to the underlying string value const std::string &value() const { return _value; } + struct StringIDHash { + // Use hash of string as hash function. + size_t operator()(const StringID& id) const + { + return std::hash()(id.value()); + } + }; + private: std::string _value; diff --git a/src/lower.cc b/src/lower.cc index a281a957..07725941 100644 --- a/src/lower.cc +++ b/src/lower.cc @@ -124,7 +124,7 @@ void determine_and_validate(std::vector& nodes) { throw std::runtime_error(msg); } - port.determine_succ(n.id_to_string(), pn, arginfo.name); + port.determine_succ(n.id(), pn, arginfo.name); pn = arginfo.name; } @@ -218,27 +218,27 @@ Halide::Pipeline lower(Builder builder, std::vector& nodes, bool implicit_ topological_sort(nodes); // Constructing Generator object and setting static parameters - std::unordered_map bbs; + std::unordered_map bbs; for (auto n : nodes) { auto bb(Halide::Internal::GeneratorRegistry::create(n.name(), Halide::GeneratorContext(n.target()))); // Default parameter Halide::GeneratorParamsMap params; params["builder_impl_ptr"] = std::to_string(reinterpret_cast(builder.impl_ptr())); - params["bb_id"] = n.id_to_string(); + params["bb_id"] = to_string(n.id()); // User defined parameter for (const auto& p : n.params()) { params[p.key()] = p.val(); } bb->set_generatorparam_values(params); - bbs[n.id_to_string()] = std::move(bb); + bbs[n.id()] = std::move(bb); } // Assigning ports and build pipeline for (size_t i=0; iarginfos(); for (const auto& [pn, port] : n.iports()) { @@ -254,7 +254,7 @@ Halide::Pipeline lower(Builder builder, std::vector& nodes, bool implicit_ auto index = port.index(); if (port.has_pred()) { - const auto& pred_bb(bbs[port.pred_id_to_string()]); + const auto& pred_bb(bbs[port.pred_id()]); auto fs = pred_bb->output_func(port.pred_name()); if (arginfo.kind == Halide::Internal::ArgInfoKind::Scalar) { bb->bind_input(arginfo.name, fs); @@ -295,19 +295,19 @@ Halide::Pipeline lower(Builder builder, std::vector& nodes, bool implicit_ if (implicit_output) { // Collects all output which is never referenced. // This mode is used for AOT compilation - std::unordered_map> referenced; + std::unordered_map, NodeID::StringIDHash> referenced; for (const auto& n : nodes) { for (const auto& [pn, port] : n.iports()) { if (port.has_pred()) { - for (const auto &f : bbs[port.pred_id_to_string()]->output_func(port.pred_name())) { - referenced[port.pred_id_to_string()].emplace_back(f.name()); + for (const auto &f : bbs[port.pred_id()]->output_func(port.pred_name())) { + referenced[port.pred_id()].emplace_back(f.name()); } } } } for (const auto& node : nodes) { - auto node_id = node.id_to_string(); + auto node_id = node.id(); for (auto arginfo : bbs[node_id]->arginfos()) { if (arginfo.dir != Halide::Internal::ArgInfoDirection::Output) { continue; @@ -336,7 +336,7 @@ Halide::Pipeline lower(Builder builder, std::vector& nodes, bool implicit_ continue; } - const auto& pred_bb(bbs[port.pred_id_to_string()]); + const auto& pred_bb(bbs[port.pred_id()]); // Validate port exists const auto& port_(port); // This is workaround for Clang-14 (MacOS) @@ -349,7 +349,7 @@ Halide::Pipeline lower(Builder builder, std::vector& nodes, bool implicit_ } - auto fs(bbs[port.pred_id_to_string()]->output_func(port.pred_name())); + auto fs(bbs[port.pred_id()]->output_func(port.pred_name())); output_funcs.insert(output_funcs.end(), fs.begin(), fs.end()); } } diff --git a/src/node.cc b/src/node.cc index 1369c079..73257a0c 100644 --- a/src/node.cc +++ b/src/node.cc @@ -5,7 +5,7 @@ namespace ion { -Node::Impl::Impl(const std::string& id_, const std::string& name_, const Halide::Target& target_) +Node::Impl::Impl(const NodeID& id_, const std::string& name_, const Halide::Target& target_) : id(id_), name(name_), target(target_), params(), ports() { auto bb(Halide::Internal::GeneratorRegistry::create(name_, Halide::GeneratorContext(target_))); @@ -17,7 +17,7 @@ Node::Impl::Impl(const std::string& id_, const std::string& name_, const Halide: arginfos = bb->arginfos(); } -Node::Impl::Impl(const std::string& id_, const std::string& name_, const Halide::Target& target_, const GraphID& graph_id_) +Node::Impl::Impl(const NodeID& id_, const std::string& name_, const Halide::Target& target_, const GraphID& graph_id_) : id(id_), name(name_), target(target_), params(), ports(), graph_id(graph_id_) { auto bb(Halide::Internal::GeneratorRegistry::create(name_, Halide::GeneratorContext(target_))); @@ -32,7 +32,7 @@ Node::Impl::Impl(const std::string& id_, const std::string& name_, const Halide: void Node::set_iport(const std::vector& ports) { impl_->ports.erase(std::remove_if(impl_->ports.begin(), impl_->ports.end(), - [&](const Port &p) { return p.has_succ_by_nid(this->id_to_string()); }), + [&](const Port &p) { return p.has_succ_by_nid(this->id());}), impl_->ports.end()); size_t i = 0; @@ -49,7 +49,7 @@ void Node::set_iport(const std::vector& ports) { // } // NOTE: Is succ_chans name OK to be just leave as it is? - port.impl_->succ_chans.insert({id_to_string(), "_ion_iport_" + std::to_string(i)}); + port.impl_->succ_chans.insert({id(), "_ion_iport_" + std::to_string(i)}); port.impl_ ->graph_id = impl_->graph_id; impl_->ports.push_back(port); @@ -59,13 +59,13 @@ void Node::set_iport(const std::vector& ports) { void Node::set_iport(Port port) { port.impl_ ->graph_id = impl_->graph_id; - port.impl_->succ_chans.insert({id_to_string(), port.pred_name()}); + port.impl_->succ_chans.insert({id(), port.pred_name()}); impl_->ports.push_back(port); } void Node::set_iport(const std::string& name, Port port) { port.impl_ ->graph_id = impl_->graph_id; - port.impl_->succ_chans.insert({id_to_string(), name}); + port.impl_->succ_chans.insert({id(), name}); impl_->ports.push_back(port); } @@ -75,7 +75,7 @@ Port Node::operator[](const std::string& name) { if (it == impl_->ports.end()) { // This is output port which is never referenced. // Bind myself as a predecessor and register - Port port(id_to_string(), name); + Port port(id(), name); port.impl_ ->graph_id = impl_->graph_id; impl_->ports.push_back(port); return port; diff --git a/src/port.cc b/src/port.cc index 1298c22a..752a8d25 100644 --- a/src/port.cc +++ b/src/port.cc @@ -6,24 +6,24 @@ namespace ion { Port::Impl::Impl() - : id(sole::uuid4().str()), pred_chan{"", ""}, succ_chans{}, type(), dimensions(-1) + : id(PortID(sole::uuid4().str())), pred_chan{"", ""}, succ_chans{}, type(), dimensions(-1) { } -Port::Impl::Impl(const std::string& pid, const std::string& pn, const Halide::Type& t, int32_t d, const GraphID & gid) - : id(sole::uuid4().str()), pred_chan{pid, pn}, succ_chans{}, type(t), dimensions(d), graph_id(gid) +Port::Impl::Impl(const NodeID & nid, const std::string& pn, const Halide::Type& t, int32_t d, const GraphID & gid) + : id(PortID(sole::uuid4().str())), pred_chan{nid, pn}, succ_chans{}, type(t), dimensions(d), graph_id(gid) { - params[0] = Halide::Internal::Parameter(type, dimensions != 0, dimensions, argument_name(pid, pn, 0, gid.value())); + params[0] = Halide::Internal::Parameter(type, dimensions != 0, dimensions, argument_name(nid, pn, 0, gid)); } -void Port::determine_succ(const std::string& nid, const std::string& old_pn, const std::string& new_pn) { +void Port::determine_succ(const NodeID& nid, const std::string& old_pn, const std::string& new_pn) { auto it = std::find(impl_->succ_chans.begin(), impl_->succ_chans.end(), Channel{nid, old_pn}); if (it == impl_->succ_chans.end()) { log::error("fixme"); throw std::runtime_error("fixme"); } - log::debug("Determine free port {} as {} on Node {}", old_pn, new_pn, nid); + log::debug("Determine free port {} as {} on Node {}", old_pn, new_pn, nid.value()); impl_->succ_chans.erase(it); impl_->succ_chans.insert(Channel{nid, new_pn}); } diff --git a/src/serializer.h b/src/serializer.h index 0514ed3d..92ee377e 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -44,7 +44,7 @@ struct adl_serializer { static void to_json(json& j, const ion::Port& v) { j["id"] = to_string(v.id()); std::map stringMap; - j["pred_chan"] =std::make_tuple(to_string(std::get<0>(v.pred_chan())), std::get<1>(v.pred_chan())); + j["pred_chan"] = std::make_tuple(to_string(std::get<0>(v.pred_chan())), std::get<1>(v.pred_chan())); std::set> succ_chans; for (auto& c:v.succ_chans()){ succ_chans.insert(std::make_tuple(to_string(std::get<0>(c)), std::get<1>(c))); @@ -62,8 +62,7 @@ struct adl_serializer { impl->pred_chan = j["pred_chan"].get>(); std::set succ_chans; for (auto & p : j["succ_chans"]){ - auto t = p.get>(); - succ_chans.insert(std::make_tuple(std::get<0>(t),std::get<1>(t))); + succ_chans.insert(p.get>()); } impl->succ_chans = succ_chans; impl->type = j["type"].get(); @@ -80,7 +79,7 @@ struct adl_serializer { template <> struct adl_serializer { static void to_json(json& j, const ion::Node& v) { - j["id"] = v.id_to_string(); + j["id"] = to_string(v.id()); j["name"] = v.name(); j["target"] = v.target().to_string(); j["params"] = v.params();