FaninCat.h
Go to the documentation of this file.
1 #ifndef WIRECELLTBB_FANINCAT
2 #define WIRECELLTBB_FANINCAT
3 
6 #include "WireCellUtil/Testing.h"
8 
9 namespace WireCellTbb {
10 
11 
12  // Body for a TBB join node.
13  template<typename TupleType>
14  class FaninBody {
16  public:
19 
21  m_wcnode = std::dynamic_pointer_cast<WireCell::IFaninNodeBase>(wcnode);
22  Assert(m_wcnode);
23  }
24 
25  boost::any operator() (const TupleType &tup) const {
26  helper_type ih;
27  any_vector in = ih.as_any(tup);
28  boost::any ret;
29  // bool ok = (*m_wcnode)(in, ret);
30  (*m_wcnode)(in, ret); // fixme: don't ignore return code
31  return ret;
32  }
33 
34  };
35 
36  template<std::size_t N>
38  tbb::flow::graph_node*& joiner, tbb::flow::graph_node*& caller)
39  {
40  typedef typename WireCell::type_repeater<N, boost::any>::type TupleType;
41 
42  // this node is fully TBB and joins N receiver ports into a tuple
43  typedef tbb::flow::join_node< TupleType > tbb_join_node_type;
44  tbb_join_node_type* jn = new tbb_join_node_type(graph);
45  joiner = jn;
46 
47  // this node takes user WC body and runs it after converting input tuple to vector
48  typedef tbb::flow::function_node<TupleType,boost::any> joining_node;
49  joining_node* fn = new joining_node(graph, wcnode->concurrency(), FaninBody<TupleType>(wcnode));
50  caller = fn;
51 
52  tbb::flow::make_edge(*jn, *fn);
53 
54  //FaninNodeInputPorts<TupleType,N> ports;
55  //return ports(*jn);
56  return receiver_ports(*jn);
57  }
58 
59  // Wrap the TBB (compound) node
60  class FaninWrapper : public NodeWrapper {
61  tbb::flow::graph_node *m_joiner, *m_caller;
63 
64  public:
65 
67  : m_joiner(0), m_caller(0)
68  {
69  int nin = wcnode->input_types().size();
70  // an exhaustive switch to convert from run-time to compile-time types and enumerations.
71  Assert (nin > 0 && nin <= 3); // fixme: exception instead?
72  if (1 == nin) m_receiver_ports = build_faniner<1>(graph, wcnode, m_joiner, m_caller);
73  if (2 == nin) m_receiver_ports = build_faniner<2>(graph, wcnode, m_joiner, m_caller);
74  if (3 == nin) m_receiver_ports = build_faniner<3>(graph, wcnode, m_joiner, m_caller);
75  }
76 
78  return m_receiver_ports;
79  }
80 
82  auto ptr = dynamic_cast< sender_type* >(m_caller);
83  return sender_port_vector{ptr};
84  }
85 
86  };
87 
88 
89 }
90 
91 #endif
FaninBody(WireCell::INode::pointer wcnode)
Definition: FaninCat.h:20
receiver_port_vector m_receiver_ports
Definition: FaninCat.h:62
receiver_port_vector receiver_ports(tbb::flow::join_node< Tuple > &jn, std::index_sequence< Is... >)
Definition: NodeWrapper.h:56
WireCell::IFaninNodeBase::pointer m_wcnode
Definition: FaninCat.h:15
virtual sender_port_vector sender_ports()
Definition: FaninCat.h:81
def graph(desc, maker=maker)
Definition: apa.py:294
#define Assert
Definition: Testing.h:7
receiver_port_vector build_faniner(tbb::flow::graph &graph, WireCell::INode::pointer wcnode, tbb::flow::graph_node *&joiner, tbb::flow::graph_node *&caller)
Definition: FaninCat.h:37
QAsciiDict< Entry > fn
FaninWrapper(tbb::flow::graph &graph, WireCell::INode::pointer wcnode)
Definition: FaninCat.h:66
std::shared_ptr< Interface > pointer
Definition: Interface.h:16
WireCell::tuple_helper< TupleType > helper_type
Definition: FaninCat.h:18
std::vector< receiver_type * > receiver_port_vector
Definition: NodeWrapper.h:19
virtual receiver_port_vector receiver_ports()
Definition: FaninCat.h:77
WireCell::IFaninNodeBase::any_vector any_vector
Definition: FaninCat.h:17
tbb::flow::sender< boost::any > sender_type
Definition: NodeWrapper.h:15
std::vector< boost::any > any_vector
Definition: IFaninNode.h:22
const void * ptr(const T *p)
Definition: format.h:3138
boost::any operator()(const TupleType &tup) const
Definition: FaninCat.h:25
std::vector< sender_type * > sender_port_vector
Definition: NodeWrapper.h:18
tbb::flow::graph_node * m_joiner
Definition: FaninCat.h:61
std::shared_ptr< IFaninNodeBase > pointer
Definition: IFaninNode.h:18