SST  10.0.0
StructuralSimulationToolkit
simpleNetwork.h
1 // -*- mode: c++ -*-
2 // Copyright 2009-2020 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-2020, 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 SST_CORE_INTERFACES_SIMPLENETWORK_H_
15 #define SST_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 nullptr, 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 = nullptr;
86  return ret;
87  }
88 
89  /**
90  Returns the payload for the request for inspection. This
91  call does not set the payload to nullptr, 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(nullptr), 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 = nullptr) :
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 != nullptr ) 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 != nullptr ) 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 
171  NetworkInspector(ComponentId_t id) :
172  SubComponent(id)
173  {}
174 
175  virtual ~NetworkInspector() {}
176 
177  virtual void inspectNetworkData(Request* req) = 0;
178 
179  };
180 
181  /** Functor classes for handling of callbacks */
182  class HandlerBase {
183  public:
184  virtual bool operator()(int) = 0;
185  virtual ~HandlerBase() {}
186  };
187 
188 
189  /** Event Handler class with user-data argument
190  * @tparam classT Type of the Object
191  * @tparam argT Type of the argument
192  */
193  template <typename classT, typename argT = void>
194  class Handler : public HandlerBase {
195  private:
196  typedef bool (classT::*PtrMember)(int, argT);
197  classT* object;
198  const PtrMember member;
199  argT data;
200 
201  public:
202  /** Constructor
203  * @param object - Pointer to Object upon which to call the handler
204  * @param member - Member function to call as the handler
205  * @param data - Additional argument to pass to handler
206  */
207  Handler( classT* const object, PtrMember member, argT data ) :
208  object(object),
209  member(member),
210  data(data)
211  {}
212 
213  bool operator()(int vn) {
214  return (object->*member)(vn,data);
215  }
216  };
217 
218  /** Event Handler class without user-data
219  * @tparam classT Type of the Object
220  */
221  template <typename classT>
222  class Handler<classT, void> : public HandlerBase {
223  private:
224  typedef bool (classT::*PtrMember)(int);
225  classT* object;
226  const PtrMember member;
227 
228  public:
229  /** Constructor
230  * @param object - Pointer to Object upon which to call the handler
231  * @param member - Member function to call as the handler
232  */
233  Handler( classT* const object, PtrMember member ) :
234  object(object),
235  member(member)
236  {}
237 
238  bool operator()(int vn) {
239  return (object->*member)(vn);
240  }
241  };
242 
243 public:
244 
245  /** Constructor, designed to be used via 'loadUserSubComponent or loadAnonymousSubComponent'. */
246  SimpleNetwork(SST::ComponentId_t id) :
247  SubComponent(id)
248  { }
249 
250  /**
251  * Sends a network request during the init() phase
252  */
253  virtual void sendInitData(Request *req) = 0;
254 
255  /**
256  * Receive any data during the init() phase.
257  * @see SST::Link::recvInitData()
258  */
259  virtual Request* recvInitData() = 0;
260 
261  /**
262  * Sends a network request during untimed phases (init() and
263  * complete()).
264  * @see SST::Link::sendUntimedData()
265  *
266  * For now, simply call sendInitData. Once that call is
267  * deprecated and removed, this will become a pure virtual
268  * function. This means that when classes implement
269  * SimpleNetwork, they will need to overload both sendUntimedData
270  * and sendInitData with identical functionality (or having the
271  * Init version call the Untimed version) until sendInitData is
272  * removed in SST 9.0.
273  */
274  virtual void sendUntimedData(Request *req) {
275  sendInitData(req);
276  }
277 
278  /**
279  * Receive any data during untimed phases (init() and complete()).
280  * @see SST::Link::recvUntimedData()
281  *
282  * For now, simply call recvInitData. Once that call is
283  * deprecated and removed, this will become a pure virtual
284  * function. This means that when classes implement
285  * SimpleNetwork, they will need to overload both recvUntimedData
286  * and recvInitData with identical functionality (or having the
287  * Init version call the Untimed version) until recvInitData is
288  * removed in SST 9.0.
289  */
290  virtual Request* recvUntimedData() {
291  return recvInitData();
292  }
293 
294  // /**
295  // * Returns a handle to the underlying SST::Link
296  // */
297  // virtual Link* getLink(void) const = 0;
298 
299  /**
300  * Send a Request to the network.
301  */
302  virtual bool send(Request *req, int vn) = 0;
303 
304  /**
305  * Receive a Request from the network.
306  *
307  * Use this method for polling-based applications.
308  * Register a handler for push-based notification of responses.
309  *
310  * @param vn Virtual network to receive on
311  * @return nullptr if nothing is available.
312  * @return Pointer to a Request response (that should be deleted)
313  */
314  virtual Request* recv(int vn) = 0;
315 
316  virtual void setup() override {}
317  virtual void init(unsigned int UNUSED(phase)) override {}
318  virtual void complete(unsigned int UNUSED(phase)) override {}
319  virtual void finish() override {}
320 
321  /**
322  * Checks if there is sufficient space to send on the specified
323  * virtual network
324  * @param vn Virtual network to check
325  * @param num_bits Minimum size in bits required to have space
326  * to send
327  * @return true if there is space in the output, false otherwise
328  */
329  virtual bool spaceToSend(int vn, int num_bits) = 0;
330 
331 
332  /**
333  * Checks if there is a waiting network request request pending in
334  * the specified virtual network.
335  * @param vn Virtual network to check
336  * @return true if a network request is pending in the specified
337  * virtual network, false otherwise
338  */
339  virtual bool requestToReceive( int vn ) = 0;
340 
341  /**
342  * Registers a functor which will fire when a new request is
343  * received from the network. Note, the actual request that
344  * was received is not passed into the functor, it is only a
345  * notification that something is available.
346  * @param functor Functor to call when request is received
347  */
348  virtual void setNotifyOnReceive(HandlerBase* functor) = 0;
349  /**
350  * Registers a functor which will fire when a request is
351  * sent to the network. Note, this only tells you when data
352  * is sent, it does not guarantee any specified amount of
353  * available space.
354  * @param functor Functor to call when request is sent
355  */
356  virtual void setNotifyOnSend(HandlerBase* functor) = 0;
357 
358  /**
359  * Check to see if network is initialized. If network is not
360  * initialized, then no other functions other than init() can
361  * can be called on the interface.
362  * @return true if network is initialized, false otherwise
363  */
364  virtual bool isNetworkInitialized() const = 0;
365 
366  /**
367  * Returns the endpoint ID. Cannot be called until after the
368  * network is initialized.
369  * @return Endpoint ID
370  */
371  virtual nid_t getEndpointID() const = 0;
372 
373  /**
374  * Returns the final BW of the link managed by the simpleNetwork
375  * instance. Cannot be called until after the network is
376  * initialized.
377  * @return Link bandwidth of associated link
378  */
379  virtual const UnitAlgebra& getLinkBW() const = 0;
380 
381 
382 };
383 
384 }
385 }
386 
387 #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 void sendInitData(Request *req)=0
Sends a network request during the init() phase.
Handler(classT *const object, PtrMember member, argT data)
Constructor.
Definition: simpleNetwork.h:207
virtual Request * recvUntimedData()
Receive any data during untimed phases (init() and complete()).
Definition: simpleNetwork.h:290
virtual void sendUntimedData(Request *req)
Sends a network request during untimed phases (init() and complete()).
Definition: simpleNetwork.h:274
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:316
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:182
Definition: serializable.h:109
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:317
Handler(classT *const object, PtrMember member)
Constructor.
Definition: simpleNetwork.h:233
SimpleNetwork(SST::ComponentId_t id)
Constructor, designed to be used via &#39;loadUserSubComponent or loadAnonymousSubComponent&#39;.
Definition: simpleNetwork.h:246
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:319
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:194
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
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:107
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:318
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:29
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:132