31#include "neml2/base/DependencyDefinition.h"
43template <
typename Node,
typename ItemType>
99 const std::vector<Node *> &
resolution()
const {
return _resolution; }
105 const std::map<Item, std::set<Item>> &
item_providers()
const {
return _item_provider_graph; }
111 const std::map<Item, std::set<Item>> &
item_consumers()
const {
return _item_consumer_graph; }
117 const std::map<Node *, std::set<Node *>> &
node_providers()
const {
return _node_provider_graph; }
123 const std::map<Node *, std::set<Node *>> &
node_consumers()
const {
return _node_consumer_graph; }
126 const std::set<Node *> &
end_nodes()
const {
return _end_nodes; }
132 const std::set<Node *> &
start_nodes()
const {
return _start_nodes; }
151 bool _unique_item_provider =
true;
154 bool _unique_item_consumer =
false;
157 std::set<Node *> _nodes;
160 std::set<Item> _consumed_items;
163 std::set<Item> _provided_items;
167 std::map<Item, std::set<Item>> _item_provider_graph;
171 std::map<Item, std::set<Item>> _item_consumer_graph;
175 std::map<Node *, std::set<Node *>> _node_provider_graph;
179 std::map<Node *, std::set<Node *>> _node_consumer_graph;
182 std::set<Node *> _end_nodes;
185 std::set<Node *> _start_nodes;
188 std::set<Item> _out_items;
191 std::set<Item> _in_items;
194 std::vector<Node *> _resolution;
197 std::map<Node *, int> _status;
200 std::map<Node *, size_t> _priority;
203template <
typename Node,
typename ItemType>
208 _nodes.emplace(
node);
210 for (
const auto &
item :
node->consumed_items())
211 _consumed_items.emplace(
node,
item);
213 for (
const auto &
item :
node->provided_items())
214 _provided_items.emplace(
node,
item);
217template <
typename Node,
typename ItemType>
221 _consumed_items.emplace(
nullptr,
item);
224template <
typename Node,
typename ItemType>
233template <
typename Node,
typename ItemType>
238 _item_provider_graph.clear();
239 _item_consumer_graph.clear();
240 _node_provider_graph.clear();
241 _node_consumer_graph.clear();
242 _start_nodes.clear();
248 for (
const auto &
itemi : _consumed_items)
252 for (
const auto &
itemj : _provided_items)
263 if (_priority[
itemi.parent] > _priority[
itemj.parent])
273 if (_unique_item_provider)
275 providers.size() == 1,
"Multiple providers have been found for item ",
itemi.value);
283 for (
const auto &
itemi : _provided_items)
287 for (
const auto &
itemj : _consumed_items)
302 if (_priority[
itemi.parent] < _priority[
itemj.parent])
312 if (_unique_item_consumer)
314 consumers.size() == 1,
"Multiple consumers have been found for item ",
itemi.value);
321 for (
const auto &
node : _nodes)
326 for (
const auto &
node : _nodes)
331 for (
const auto &
item : _consumed_items)
336 for (
const auto &
item : _provided_items)
341 for (
const auto &
item : _consumed_items)
345 "Unable to find provider of the additional outbound item ",
347 for (
const auto &
provider : _item_provider_graph[
item])
355template <
typename Node,
typename ItemType>
363 for (
const auto &
node : _end_nodes)
368 for (
const auto &
node : _nodes)
370 auto count = std::count(_resolution.begin(), _resolution.end(),
node);
372 "Each node must appear in the dependency resolution. Node ",
374 " is missing. This is an internal error -- consider filing a bug report.");
376 "Each node must appear in the dependency resolution once and only once. Node ",
380 " times. This indicates cyclic dependency.");
384template <
typename Node,
typename ItemType>
393 if (_node_provider_graph.count(
node))
394 for (
const auto &
dep : _node_provider_graph[
node])
399 "While resolving dependency, two nodes '",
403 "' have (possibly indirect) cyclic dependency. The cyclic dependency can be "
404 "resolved by explicitly setting the node priorities.");
412 _resolution.push_back(
node);
The wrapper (decorator) for cross-referencing unresolved values at parse time.
Definition CrossRef.h:54
The DependencyResolver identifies and resolves the dependencies among a set of objects derived from D...
Definition DependencyResolver.h:45
const std::map< Node *, std::set< Node * > > & node_consumers() const
Definition DependencyResolver.h:123
const std::map< Node *, std::set< Node * > > & node_providers() const
Definition DependencyResolver.h:117
const std::set< Item > & inbound_items() const
The items consumed by the overall dependency graph, i.e., the items that are not provided by any node...
Definition DependencyResolver.h:135
const std::map< Item, std::set< Item > > & item_consumers() const
Definition DependencyResolver.h:111
DependencyResolver()=default
void add_additional_outbound_item(const ItemType &item)
Add an additional outbound item that the dependency graph provides
Definition DependencyResolver.h:219
void set_priority(DependencyDefinition< ItemType > *, size_t)
Set a node's priority, useful for resolving cyclic dependency.
Definition DependencyResolver.h:226
bool & unique_item_provider()
Definition DependencyResolver.h:138
void resolve()
Resolve nodal dependency and find an evaluation order.
Definition DependencyResolver.h:357
const std::set< Node * > & end_nodes() const
End nodes which are not consumed by anyone else.
Definition DependencyResolver.h:126
const std::vector< Node * > & resolution() const
The resolved (nodal) evaluation order following which all consumed items of the current node.
Definition DependencyResolver.h:99
const std::set< Item > & outbound_items() const
The items provided by the overall dependency graph, i.e., the items that are not consumed by any node...
Definition DependencyResolver.h:129
void add_node(DependencyDefinition< ItemType > *)
Add a node (defining consumed/provided items) in the dependency graph.
Definition DependencyResolver.h:205
const std::set< Node * > & start_nodes() const
Start nodes which do not consume anyone else.
Definition DependencyResolver.h:132
const std::map< Item, std::set< Item > > & item_providers() const
Definition DependencyResolver.h:105
bool & unique_item_consumer()
Definition DependencyResolver.h:141
Definition CrossRef.cxx:31
void neml_assert(bool assertion, Args &&... args)
Definition error.h:64
Definition DependencyResolver.h:52
Node *const parent
Node which defines this item.
Definition DependencyResolver.h:60
bool operator<(const Item &other) const
An arbitrary comparator so that items can be sorted (for consistency)
Definition DependencyResolver.h:78
bool operator==(const Item &other) const
Test for equality between two items.
Definition DependencyResolver.h:66
bool operator!=(const Item &other) const
Test for inequality between two items.
Definition DependencyResolver.h:72
const ItemType value
The consumed/provided item.
Definition DependencyResolver.h:63
Item(Node *const node, ItemType item)
Definition DependencyResolver.h:53