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