SST  12.0.1
StructuralSimulationToolkit
simpleNetwork.h
1 // -*- mode: c++ -*-
2 // Copyright 2009-2022 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-2022, 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 "sst/core/params.h"
18 #include "sst/core/serialization/serializable.h"
19 #include "sst/core/sst_types.h"
20 #include "sst/core/ssthandler.h"
21 #include "sst/core/subcomponent.h"
22 #include "sst/core/warnmacros.h"
23 
24 #include <string>
25 #include <unordered_map>
26 
27 namespace SST {
28 
29 class Component;
30 class Event;
31 class Link;
32 
33 namespace Interfaces {
34 
35 /**
36  * Generic network interface
37  */
39 {
40 
41 public:
42  SST_ELI_REGISTER_SUBCOMPONENT_API(SST::Interfaces::SimpleNetwork,int)
43 
44  /** All Addresses can be 64-bit */
45  typedef int64_t nid_t;
46 
47  static const nid_t INIT_BROADCAST_ADDR;
48 
49  /**
50  * Represents both network sends and receives
51  */
52  class Request : public SST::Core::Serialization::serializable, SST::Core::Serialization::serializable_type<Request>
53  {
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  Sets the payload field for this request
70  @param payload_in Event to set as payload.
71  */
72  inline void givePayload(Event* event) { payload = event; }
73 
74  /**
75  Returns the payload for the request. This will also set
76  the payload to nullptr, so the call will only return valid
77  data one time after each givePayload call.
78  @return Event that was set as payload of the request.
79  */
80  inline Event* takePayload()
81  {
82  Event* ret = payload;
83  payload = nullptr;
84  return ret;
85  }
86 
87  /**
88  Returns the payload for the request for inspection. This
89  call does not set the payload to nullptr, so deleting the
90  request will also delete the payload. If the request is
91  going to be deleted, use takePayload instead.
92  @return Event that was set as payload of the request.
93  */
94  inline Event* inspectPayload() { return payload; }
95 
96  /**
97  * Trace types
98  */
99  typedef enum {
100  NONE, /*!< No tracing enabled */
101  ROUTE, /*!< Trace route information only */
102  FULL /*!< Trace all movements of packets through network */
103  } TraceType;
104 
105  /** Constructor */
107  dest(0),
108  src(0),
109  size_in_bits(0),
110  head(false),
111  tail(false),
112  allow_adaptive(true),
113  payload(nullptr),
114  trace(NONE),
115  traceID(0)
116  {}
117 
118  Request(nid_t dest, nid_t src, size_t size_in_bits, bool head, bool tail, Event* payload = nullptr) :
119  dest(dest),
120  src(src),
121  size_in_bits(size_in_bits),
122  head(head),
123  tail(tail),
124  allow_adaptive(true),
125  payload(payload),
126  trace(NONE),
127  traceID(0)
128  {}
129 
130  virtual ~Request()
131  {
132  if ( payload != nullptr ) delete payload;
133  }
134 
135  inline Request* clone()
136  {
137  Request* req = new Request(*this);
138  // Copy constructor only makes a shallow copy, need to
139  // clone the event.
140  if ( payload != nullptr ) req->payload = payload->clone();
141  return req;
142  }
143 
144  void setTraceID(int id) { traceID = id; }
145  void setTraceType(TraceType type) { trace = type; }
146  int getTraceID() { return traceID; }
147  TraceType getTraceType() { return trace; }
148 
149  void serialize_order(SST::Core::Serialization::serializer& ser) override
150  {
151  ser& dest;
152  ser& src;
153  ser& vn;
154  ser& size_in_bits;
155  ser& head;
156  ser& tail;
157  ser& payload;
158  ser& trace;
159  ser& traceID;
160  ser& allow_adaptive;
161  }
162 
163  protected:
164  TraceType trace;
165  int traceID;
166 
167  private:
168  ImplementSerializable(SST::Interfaces::SimpleNetwork::Request)
169  };
170  /**
171  Class used to inspect network requests going through the network.
172  */
174  {
175 
176  public:
177  SST_ELI_REGISTER_SUBCOMPONENT_API(SST::Interfaces::SimpleNetwork::NetworkInspector,std::string)
178 
179  NetworkInspector(ComponentId_t id) : SubComponent(id) {}
180 
181  virtual ~NetworkInspector() {}
182 
183  virtual void inspectNetworkData(Request* req) = 0;
184  };
185 
186  /**
187  Base handler for event delivery.
188  */
190 
191  /**
192  Used to create handlers to notify the endpoint when the
193  SimpleNetwork sends or recieves a packet.. The callback
194  function is expected to be in the form of:
195 
196  bool func(int vn)
197 
198  In which case, the class is created with:
199 
200  new SimpleNetwork::Handler<classname>(this, &classname::function_name)
201 
202  Or, to add static data, the callback function is:
203 
204  bool func(int vn, dataT data)
205 
206  and the class is created with:
207 
208  new SimpleNetwork::Handler<classname, dataT>(this, &classname::function_name, data)
209 
210  In both cases, the boolean that's returned indicates whether
211  the handler should be kept in the list or not. On return
212  of true, the handler will be kept. On return of false, the
213  handler will be removed from the clock list.
214  */
215  template <typename classT, typename dataT = void>
217 
218 
219 public:
220  /** Constructor, designed to be used via 'loadUserSubComponent or loadAnonymousSubComponent'. */
221  SimpleNetwork(SST::ComponentId_t id) : SubComponent(id) {}
222 
223  /**
224  * Sends a network request during the init() phase
225  */
226  virtual void sendInitData(Request* req) = 0;
227 
228  /**
229  * Receive any data during the init() phase.
230  * @see SST::Link::recvInitData()
231  */
232  virtual Request* recvInitData() = 0;
233 
234  /**
235  * Sends a network request during untimed phases (init() and
236  * complete()).
237  * @see SST::Link::sendUntimedData()
238  *
239  * For now, simply call sendInitData. Once that call is
240  * deprecated and removed, this will become a pure virtual
241  * function. This means that when classes implement
242  * SimpleNetwork, they will need to overload both sendUntimedData
243  * and sendInitData with identical functionality (or having the
244  * Init version call the Untimed version) until sendInitData is
245  * removed in SST 9.0.
246  */
247  virtual void sendUntimedData(Request* req) { sendInitData(req); }
248 
249  /**
250  * Receive any data during untimed phases (init() and complete()).
251  * @see SST::Link::recvUntimedData()
252  *
253  * For now, simply call recvInitData. Once that call is
254  * deprecated and removed, this will become a pure virtual
255  * function. This means that when classes implement
256  * SimpleNetwork, they will need to overload both recvUntimedData
257  * and recvInitData with identical functionality (or having the
258  * Init version call the Untimed version) until recvInitData is
259  * removed in SST 9.0.
260  */
261  virtual Request* recvUntimedData() { return recvInitData(); }
262 
263  // /**
264  // * Returns a handle to the underlying SST::Link
265  // */
266  // virtual Link* getLink(void) const = 0;
267 
268  /**
269  * Send a Request to the network.
270  */
271  virtual bool send(Request* req, int vn) = 0;
272 
273  /**
274  * Receive a Request from the network.
275  *
276  * Use this method for polling-based applications.
277  * Register a handler for push-based notification of responses.
278  *
279  * @param vn Virtual network to receive on
280  * @return nullptr if nothing is available.
281  * @return Pointer to a Request response (that should be deleted)
282  */
283  virtual Request* recv(int vn) = 0;
284 
285  virtual void setup() override {}
286  virtual void init(unsigned int UNUSED(phase)) override {}
287  virtual void complete(unsigned int UNUSED(phase)) override {}
288  virtual void finish() override {}
289 
290  /**
291  * Checks if there is sufficient space to send on the specified
292  * virtual network
293  * @param vn Virtual network to check
294  * @param num_bits Minimum size in bits required to have space
295  * to send
296  * @return true if there is space in the output, false otherwise
297  */
298  virtual bool spaceToSend(int vn, int num_bits) = 0;
299 
300  /**
301  * Checks if there is a waiting network request request pending in
302  * the specified virtual network.
303  * @param vn Virtual network to check
304  * @return true if a network request is pending in the specified
305  * virtual network, false otherwise
306  */
307  virtual bool requestToReceive(int vn) = 0;
308 
309  /**
310  * Registers a functor which will fire when a new request is
311  * received from the network. Note, the actual request that
312  * was received is not passed into the functor, it is only a
313  * notification that something is available.
314  * @param functor Functor to call when request is received
315  */
316  virtual void setNotifyOnReceive(HandlerBase* functor) = 0;
317  /**
318  * Registers a functor which will fire when a request is
319  * sent to the network. Note, this only tells you when data
320  * is sent, it does not guarantee any specified amount of
321  * available space.
322  * @param functor Functor to call when request is sent
323  */
324  virtual void setNotifyOnSend(HandlerBase* functor) = 0;
325 
326  /**
327  * Check to see if network is initialized. If network is not
328  * initialized, then no other functions other than init() can
329  * can be called on the interface.
330  * @return true if network is initialized, false otherwise
331  */
332  virtual bool isNetworkInitialized() const = 0;
333 
334  /**
335  * Returns the endpoint ID. Cannot be called until after the
336  * network is initialized.
337  * @return Endpoint ID
338  */
339  virtual nid_t getEndpointID() const = 0;
340 
341  /**
342  * Returns the final BW of the link managed by the simpleNetwork
343  * instance. Cannot be called until after the network is
344  * initialized.
345  * @return Link bandwidth of associated link
346  */
347  virtual const UnitAlgebra& getLinkBW() const = 0;
348 };
349 
350 } // namespace Interfaces
351 } // namespace SST
352 
353 #endif // SST_CORE_INTERFACES_SIMPLENETWORK_H
virtual bool isNetworkInitialized() const =0
Check to see if network is initialized.
Definition: simpleNetwork.h:101
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:34
Definition: ssthandler.h:100
Event * inspectPayload()
Returns the payload for the request for inspection.
Definition: simpleNetwork.h:94
bool allow_adaptive
Definition: simpleNetwork.h:62
void givePayload(Event *event)
Sets the payload field for this request.
Definition: simpleNetwork.h:72
virtual Request * recv(int vn)=0
Receive a Request from the network.
Event Handler class with user-data argument.
Definition: ssthandler.h:115
virtual void sendInitData(Request *req)=0
Sends a network request during the init() phase.
virtual Request * recvUntimedData()
Receive any data during untimed phases (init() and complete()).
Definition: simpleNetwork.h:261
virtual void sendUntimedData(Request *req)
Sends a network request during untimed phases (init() and complete()).
Definition: simpleNetwork.h:247
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:285
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:106
nid_t dest
Definition: simpleNetwork.h:56
virtual nid_t getEndpointID() const =0
Returns the endpoint ID.
Definition: serializable.h:118
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:286
SimpleNetwork(SST::ComponentId_t id)
Constructor, designed to be used via &#39;loadUserSubComponent or loadAnonymousSubComponent&#39;.
Definition: simpleNetwork.h:221
Definition: simpleNetwork.h:100
Represents both network sends and receives.
Definition: simpleNetwork.h:52
virtual void finish() override
Called after simulation completes, but before objects are destroyed.
Definition: simpleNetwork.h:288
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.
bool head
Definition: simpleNetwork.h:60
SSTHandlerBase< bool, int, false > HandlerBase
Base handler for event delivery.
Definition: simpleNetwork.h:189
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:80
int64_t nid_t
All Addresses can be 64-bit.
Definition: simpleNetwork.h:45
Generic network interface.
Definition: simpleNetwork.h:38
Base class for Events - Items sent across links to communicate between components.
Definition: event.h:34
Performs Unit math in full precision.
Definition: unitAlgebra.h:106
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:173
virtual void complete(unsigned int UNUSED(phase)) override
Used during the complete phase after the end of simulation.
Definition: simpleNetwork.h:287
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:28
virtual Event * clone()
Clones the event in for the case of a broadcast.
Definition: event.cc:89
int vn
Definition: simpleNetwork.h:58
Definition: serializable.h:138