SST  9.1.0
StructuralSimulationToolkit
simpleNetwork.h
1 // -*- mode: c++ -*-
2 // Copyright 2009-2019 NTESS. Under the terms
3 // of Contract DE-NA0003525 with NTESS, the U.S.
4 // Government retains certain rights in this software.
5 //
6 // Copyright (c) 2009-2019, NTESS
7 // All rights reserved.
8 //
9 // This file is part of the SST software package. For license
10 // information, see the LICENSE file in the top level directory of the
11 // distribution.
12 //
13 
14 #ifndef CORE_INTERFACES_SIMPLENETWORK_H_
15 #define CORE_INTERFACES_SIMPLENETWORK_H_
16 
17 #include <string>
18 #include <unordered_map>
19 
20 #include <sst/core/sst_types.h>
21 #include <sst/core/warnmacros.h>
22 #include <sst/core/subcomponent.h>
23 #include <sst/core/params.h>
24 
25 #include <sst/core/serialization/serializable.h>
26 
27 namespace SST {
28 
29 class Component;
30 class Event;
31 class Link;
32 
33 namespace Interfaces {
34 
35 
36 /**
37  * Generic network interface
38  */
39 class SimpleNetwork : public SubComponent {
40 
41 public:
42 
43  SST_ELI_REGISTER_SUBCOMPONENT_API(SST::Interfaces::SimpleNetwork,int)
44 
45  /** All Addresses can be 64-bit */
46  typedef int64_t nid_t;
47 
48  static const nid_t INIT_BROADCAST_ADDR;
49 
50  /**
51  * Represents both network sends and receives
52  */
53  class Request : public SST::Core::Serialization::serializable, SST::Core::Serialization::serializable_type<Request> {
54 
55  public:
56  nid_t dest; /*!< Node ID of destination */
57  nid_t src; /*!< Node ID of source */
58  int vn; /*!< Virtual network of packet */
59  size_t size_in_bits; /*!< Size of packet in bits */
60  bool head; /*!< True if this is the head of a stream */
61  bool tail; /*!< True if this is the tail of a steram */
62  bool allow_adaptive; /*!< Indicates whether adaptive routing is allowed or not. */
63 
64  private:
65  Event* payload; /*!< Payload of the request */
66 
67  public:
68 
69  /**
70  Sets the payload field for this request
71  @param payload_in Event to set as payload.
72  */
73  inline void givePayload(Event *event) {
74  payload = event;
75  }
76 
77  /**
78  Returns the payload for the request. This will also set
79  the payload to NULL, so the call will only return valid
80  data one time after each givePayload call.
81  @return Event that was set as payload of the request.
82  */
83  inline Event* takePayload() {
84  Event* ret = payload;
85  payload = NULL;
86  return ret;
87  }
88 
89  /**
90  Returns the payload for the request for inspection. This
91  call does not set the payload to NULL, so deleting the
92  request will also delete the payload. If the request is
93  going to be deleted, use takePayload instead.
94  @return Event that was set as payload of the request.
95  */
96  inline Event* inspectPayload() {
97  return payload;
98  }
99 
100  /**
101  * Trace types
102  */
103  typedef enum {
104  NONE, /*!< No tracing enabled */
105  ROUTE, /*!< Trace route information only */
106  FULL /*!< Trace all movements of packets through network */
107  } TraceType;
108 
109 
110  /** Constructor */
112  dest(0), src(0), size_in_bits(0), head(false), tail(false), allow_adaptive(true),
113  payload(NULL), trace(NONE), traceID(0)
114  {}
115 
116  Request(nid_t dest, nid_t src, size_t size_in_bits,
117  bool head, bool tail, Event* payload = NULL) :
118  dest(dest), src(src), size_in_bits(size_in_bits), head(head), tail(tail), allow_adaptive(true),
119  payload(payload), trace(NONE), traceID(0)
120  {
121  }
122 
123  virtual ~Request()
124  {
125  if ( payload != NULL ) delete payload;
126  }
127 
128  inline Request* clone() {
129  Request* req = new Request(*this);
130  // Copy constructor only makes a shallow copy, need to
131  // clone the event.
132  if ( payload != NULL ) req->payload = payload->clone();
133  return req;
134  }
135 
136  void setTraceID(int id) {traceID = id;}
137  void setTraceType(TraceType type) {trace = type;}
138  int getTraceID() {return traceID;}
139  TraceType getTraceType() {return trace;}
140 
141  void serialize_order(SST::Core::Serialization::serializer &ser) override {
142  ser & dest;
143  ser & src;
144  ser & vn;
145  ser & size_in_bits;
146  ser & head;
147  ser & tail;
148  ser & payload;
149  ser & trace;
150  ser & traceID;
151  ser & allow_adaptive;
152  }
153 
154  protected:
155  TraceType trace;
156  int traceID;
157 
158  private:
159 
160  ImplementSerializable(SST::Interfaces::SimpleNetwork::Request)
161  };
162  /**
163  Class used to inspect network requests going through the network.
164  */
166 
167  public:
168  SST_ELI_REGISTER_SUBCOMPONENT_API(SST::Interfaces::SimpleNetwork::NetworkInspector,std::string)
169 
170  NetworkInspector(Component* parent) :
171  SubComponent(parent)
172  {}
173 
174  NetworkInspector(ComponentId_t id) :
175  SubComponent(id)
176  {}
177 
178  virtual ~NetworkInspector() {}
179 
180  virtual void inspectNetworkData(Request* req) = 0;
181 
182  /**
183  * The ID uniquely identifies the component in which this
184  * subcomponent is instantiated. It does not uniquely define
185  * this particular NetworkInspector, and all NetworkInspectors
186  * instantiated in the same component will get the same ID. If
187  * registering statistics, the ID is intended to be used as the
188  * subfield of the statistic.
189  */
190  virtual void initialize(std::string id) = 0;
191  };
192 
193  /** Functor classes for handling of callbacks */
194  class HandlerBase {
195  public:
196  virtual bool operator()(int) = 0;
197  virtual ~HandlerBase() {}
198  };
199 
200 
201  /** Event Handler class with user-data argument
202  * @tparam classT Type of the Object
203  * @tparam argT Type of the argument
204  */
205  template <typename classT, typename argT = void>
206  class Handler : public HandlerBase {
207  private:
208  typedef bool (classT::*PtrMember)(int, argT);
209  classT* object;
210  const PtrMember member;
211  argT data;
212 
213  public:
214  /** Constructor
215  * @param object - Pointer to Object upon which to call the handler
216  * @param member - Member function to call as the handler
217  * @param data - Additional argument to pass to handler
218  */
219  Handler( classT* const object, PtrMember member, argT data ) :
220  object(object),
221  member(member),
222  data(data)
223  {}
224 
225  bool operator()(int vn) {
226  return (object->*member)(vn,data);
227  }
228  };
229 
230  /** Event Handler class without user-data
231  * @tparam classT Type of the Object
232  */
233  template <typename classT>
234  class Handler<classT, void> : public HandlerBase {
235  private:
236  typedef bool (classT::*PtrMember)(int);
237  classT* object;
238  const PtrMember member;
239 
240  public:
241  /** Constructor
242  * @param object - Pointer to Object upon which to call the handler
243  * @param member - Member function to call as the handler
244  */
245  Handler( classT* const object, PtrMember member ) :
246  object(object),
247  member(member)
248  {}
249 
250  bool operator()(int vn) {
251  return (object->*member)(vn);
252  }
253  };
254 
255 public:
256 
257  /** Constructor, designed to be used via 'loadSubComponent'. */
259  SubComponent(comp)
260  { }
261 
262  /** Constructor, designed to be used via 'loadUserSubComponent or loadAnonymousSubComponent'. */
263  SimpleNetwork(SST::ComponentId_t id) :
264  SubComponent(id)
265  { }
266 
267  /** Second half of building the interface.
268  Initialize network interface
269  @param portName - Name of port to connect to
270  @param link_bw - Bandwidth of the link
271  @param vns - Number of virtual networks to be provided
272  @param in_buf_size - Size of input buffers (from router)
273  @param out_buf_size - Size of output buffers (to router)
274  * @return true if the link was able to be configured.
275  */
276  virtual bool initialize(const std::string &portName, const UnitAlgebra& link_bw,
277  int vns, const UnitAlgebra& in_buf_size,
278  const UnitAlgebra& out_buf_size) = 0;
279 
280  /**
281  * Sends a network request during the init() phase
282  */
283  virtual void sendInitData(Request *req) = 0;
284 
285  /**
286  * Receive any data during the init() phase.
287  * @see SST::Link::recvInitData()
288  */
289  virtual Request* recvInitData() = 0;
290 
291  /**
292  * Sends a network request during untimed phases (init() and
293  * complete()).
294  * @see SST::Link::sendUntimedData()
295  *
296  * For now, simply call sendInitData. Once that call is
297  * deprecated and removed, this will become a pure virtual
298  * function. This means that when classes implement
299  * SimpleNetwork, they will need to overload both sendUntimedData
300  * and sendInitData with identical functionality (or having the
301  * Init version call the Untimed version) until sendInitData is
302  * removed in SST 9.0.
303  */
304  virtual void sendUntimedData(Request *req) {
305  sendInitData(req);
306  }
307 
308  /**
309  * Receive any data during untimed phases (init() and complete()).
310  * @see SST::Link::recvUntimedData()
311  *
312  * For now, simply call recvInitData. Once that call is
313  * deprecated and removed, this will become a pure virtual
314  * function. This means that when classes implement
315  * SimpleNetwork, they will need to overload both recvUntimedData
316  * and recvInitData with identical functionality (or having the
317  * Init version call the Untimed version) until recvInitData is
318  * removed in SST 9.0.
319  */
320  virtual Request* recvUntimedData() {
321  return recvInitData();
322  }
323 
324  // /**
325  // * Returns a handle to the underlying SST::Link
326  // */
327  // virtual Link* getLink(void) const = 0;
328 
329  /**
330  * Send a Request to the network.
331  */
332  virtual bool send(Request *req, int vn) = 0;
333 
334  /**
335  * Receive a Request from the network.
336  *
337  * Use this method for polling-based applications.
338  * Register a handler for push-based notification of responses.
339  *
340  * @param vn Virtual network to receive on
341  * @return NULL if nothing is available.
342  * @return Pointer to a Request response (that should be deleted)
343  */
344  virtual Request* recv(int vn) = 0;
345 
346  virtual void setup() override {}
347  virtual void init(unsigned int UNUSED(phase)) override {}
348  virtual void complete(unsigned int UNUSED(phase)) override {}
349  virtual void finish() override {}
350 
351  /**
352  * Checks if there is sufficient space to send on the specified
353  * virtual network
354  * @param vn Virtual network to check
355  * @param num_bits Minimum size in bits required to have space
356  * to send
357  * @return true if there is space in the output, false otherwise
358  */
359  virtual bool spaceToSend(int vn, int num_bits) = 0;
360 
361 
362  /**
363  * Checks if there is a waiting network request request pending in
364  * the specified virtual network.
365  * @param vn Virtual network to check
366  * @return true if a network request is pending in the specified
367  * virtual network, false otherwise
368  */
369  virtual bool requestToReceive( int vn ) = 0;
370 
371  /**
372  * Registers a functor which will fire when a new request is
373  * received from the network. Note, the actual request that
374  * was received is not passed into the functor, it is only a
375  * notification that something is available.
376  * @param functor Functor to call when request is received
377  */
378  virtual void setNotifyOnReceive(HandlerBase* functor) = 0;
379  /**
380  * Registers a functor which will fire when a request is
381  * sent to the network. Note, this only tells you when data
382  * is sent, it does not guarantee any specified amount of
383  * available space.
384  * @param functor Functor to call when request is sent
385  */
386  virtual void setNotifyOnSend(HandlerBase* functor) = 0;
387 
388  /**
389  * Check to see if network is initialized. If network is not
390  * initialized, then no other functions other than init() can
391  * can be called on the interface.
392  * @return true if network is initialized, false otherwise
393  */
394  virtual bool isNetworkInitialized() const = 0;
395 
396  /**
397  * Returns the endpoint ID. Cannot be called until after the
398  * network is initialized.
399  * @return Endpoint ID
400  */
401  virtual nid_t getEndpointID() const = 0;
402 
403  /**
404  * Returns the final BW of the link managed by the simpleNetwork
405  * instance. Cannot be called until after the network is
406  * initialized.
407  * @return Link bandwidth of associated link
408  */
409  virtual const UnitAlgebra& getLinkBW() const = 0;
410 
411 
412 };
413 
414 }
415 }
416 
417 #endif
virtual bool isNetworkInitialized() const =0
Check to see if network is initialized.
Definition: simpleNetwork.h:105
nid_t src
Definition: simpleNetwork.h:57
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:35
Event * inspectPayload()
Returns the payload for the request for inspection.
Definition: simpleNetwork.h:96
bool allow_adaptive
Definition: simpleNetwork.h:62
void givePayload(Event *event)
Sets the payload field for this request.
Definition: simpleNetwork.h:73
virtual Request * recv(int vn)=0
Receive a Request from the network.
virtual bool initialize(const std::string &portName, const UnitAlgebra &link_bw, int vns, const UnitAlgebra &in_buf_size, const UnitAlgebra &out_buf_size)=0
Second half of building the interface.
virtual void sendInitData(Request *req)=0
Sends a network request during the init() phase.
Main component object for the simulation.
Definition: component.h:32
Handler(classT *const object, PtrMember member, argT data)
Constructor.
Definition: simpleNetwork.h:219
virtual Request * recvUntimedData()
Receive any data during untimed phases (init() and complete()).
Definition: simpleNetwork.h:320
virtual void sendUntimedData(Request *req)
Sends a network request during untimed phases (init() and complete()).
Definition: simpleNetwork.h:304
bool tail
Definition: simpleNetwork.h:61
virtual void setup() override
Called after all components have been constructed and initialization has completed, but before simulation time has begun.
Definition: simpleNetwork.h:346
virtual void setNotifyOnReceive(HandlerBase *functor)=0
Registers a functor which will fire when a new request is received from the network.
Request()
Constructor.
Definition: simpleNetwork.h:111
nid_t dest
Definition: simpleNetwork.h:56
virtual nid_t getEndpointID() const =0
Returns the endpoint ID.
Functor classes for handling of callbacks.
Definition: simpleNetwork.h:194
Definition: serializable.h:110
virtual Request * recvInitData()=0
Receive any data during the init() phase.
virtual void init(unsigned int UNUSED(phase)) override
Used during the init phase.
Definition: simpleNetwork.h:347
SimpleNetwork(SST::Component *comp)
Constructor, designed to be used via &#39;loadSubComponent&#39;.
Definition: simpleNetwork.h:258
Handler(classT *const object, PtrMember member)
Constructor.
Definition: simpleNetwork.h:245
SimpleNetwork(SST::ComponentId_t id)
Constructor, designed to be used via &#39;loadUserSubComponent or loadAnonymousSubComponent&#39;.
Definition: simpleNetwork.h:263
Definition: simpleNetwork.h:104
Represents both network sends and receives.
Definition: simpleNetwork.h:53
virtual void finish() override
Called after simulation completes, but before objects are destroyed.
Definition: simpleNetwork.h:349
virtual bool send(Request *req, int vn)=0
Returns a handle to the underlying SST::Link.
virtual const UnitAlgebra & getLinkBW() const =0
Returns the final BW of the link managed by the simpleNetwork instance.
Event Handler class with user-data argument.
Definition: simpleNetwork.h:206
bool head
Definition: simpleNetwork.h:60
virtual bool requestToReceive(int vn)=0
Checks if there is a waiting network request request pending in the specified virtual network...
virtual bool spaceToSend(int vn, int num_bits)=0
Checks if there is sufficient space to send on the specified virtual network.
size_t size_in_bits
Definition: simpleNetwork.h:59
Event * takePayload()
Returns the payload for the request.
Definition: simpleNetwork.h:83
int64_t nid_t
All Addresses can be 64-bit.
Definition: simpleNetwork.h:46
virtual void initialize(std::string id)=0
The ID uniquely identifies the component in which this subcomponent is instantiated.
Generic network interface.
Definition: simpleNetwork.h:39
Base class for Events - Items sent across links to communicate between components.
Definition: event.h:31
Performs Unit math in full precision.
Definition: unitAlgebra.h:104
virtual void setNotifyOnSend(HandlerBase *functor)=0
Registers a functor which will fire when a request is sent to the network.
Class used to inspect network requests going through the network.
Definition: simpleNetwork.h:165
virtual void complete(unsigned int UNUSED(phase)) override
Used during the init phase.
Definition: simpleNetwork.h:348
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:30
virtual Event * clone()
Clones the event in for the case of a broadcast.
Definition: event.cc:33
int vn
Definition: simpleNetwork.h:58
Definition: serializable.h:133