SST  12.0.0
StructuralSimulationToolkit
link.h
1 // Copyright 2009-2022 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2022, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_LINK_H
13 #define SST_CORE_LINK_H
14 
15 #include "sst/core/event.h"
16 #include "sst/core/sst_types.h"
17 #include "sst/core/timeConverter.h"
18 
19 namespace SST {
20 
21 #define _LINK_DBG(fmt, args...) __DBG(DBG_LINK, Link, fmt, ##args)
22 
23 class ActivityQueue;
24 class BaseComponent;
25 class TimeConverter;
26 class LinkPair;
27 class Simulation_impl;
28 
29 class UnitAlgebra;
30 
31 /** Link between two components. Carries events */
32 class alignas(64) Link
33 {
34  enum Type_t : uint16_t { POLL, HANDLER, SYNC, UNINITIALIZED };
35  enum Mode_t : uint16_t { INIT, RUN, COMPLETE };
36 
37 public:
38  friend class LinkPair;
39  friend class RankSync;
40  friend class ThreadSync;
41  friend class Simulation_impl;
42  friend class SyncManager;
43  friend class ComponentInfo;
44 
45  virtual ~Link();
46 
47  /** Set additional Latency to be added to events being sent out of this link
48  * @param cycles Number of Cycles to be added
49  * @param timebase Base Units of cycles
50  */
51  void addSendLatency(int cycles, const std::string& timebase);
52 
53  /** Set additional Latency to be added to events being sent out of this link
54  * @param cycles Number of Cycles to be added
55  * @param timebase Base Units of cycles
56  */
57  void addSendLatency(SimTime_t cycles, TimeConverter* timebase);
58 
59  /** Set additional Latency to be added on to events coming in on this link.
60  * @param cycles Number of Cycles to be added
61  * @param timebase Base Units of cycles
62  */
63  void addRecvLatency(int cycles, const std::string& timebase);
64 
65  /** Set additional Latency to be added on to events coming in on this link.
66  * @param cycles Number of Cycles to be added
67  * @param timebase Base Units of cycles
68  */
69  void addRecvLatency(SimTime_t cycles, TimeConverter* timebase);
70 
71  /** Set the callback function to be called when a message is
72  * delivered. Not available for Polling links.
73  * @param functor Functor to call when message is delivered
74  */
75  void setFunctor(Event::HandlerBase* functor);
76 
77  /** Replace the callback function to be called when a message is
78  * delivered. Any previous handler will be deleted.
79  * Not available for Polling links.
80  * @param functor Functor to call when message is delivered
81  */
82  void replaceFunctor(Event::HandlerBase* functor);
83 
84  /** Send an event over the link with additional delay. Sends an event
85  * over a link with an additional delay specified with a
86  * TimeConverter. I.e. the total delay is the link's delay + the
87  * additional specified delay.
88  * @param delay - additional delay
89  * @param tc - time converter to specify units for the additional delay
90  * @param event - the Event to send
91  */
92  inline void send(SimTime_t delay, TimeConverter* tc, Event* event)
93  {
94  send_impl(tc->convertToCoreTime(delay), event);
95  }
96 
97  /** Send an event with additional delay. Sends an event over a link
98  * with additional delay specified by the Link's default
99  * timebase.
100  * @param delay The additional delay, in units of the default Link timebase
101  * @param event The event to send
102  */
103  inline void send(SimTime_t delay, Event* event) { send_impl(delay * defaultTimeBase, event); }
104 
105  /** Send an event with the Link's default delay
106  * @param event The event to send
107  */
108  inline void send(Event* event) { send_impl(0, event); }
109 
110 
111  /** Retrieve a pending event from the Link. For links which do not
112  * have a set event handler, they can be polled with this function.
113  * Returns nullptr if there is no pending event.
114  * Not available for HANDLER-type links.
115  * @return Event if one is available
116  * @return nullptr if no Event is available
117  */
118  Event* recv();
119 
120  /** Manually set the default detaulTimeBase
121  * @param tc TimeConverter object for the timebase
122  */
124 
125  /** Return the default Time Base for this link
126  * @return the default Time Base for this link
127  */
129 
130  /** Return the default Time Base for this link
131  * @return the default Time Base for this link
132  */
133  const TimeConverter* getDefaultTimeBase() const;
134 
135  /** Return the ID of this link
136  * @return the unique ID for this link
137  */
138  LinkId_t getId() { return tag; }
139 
140  /** Send data during the init() or complete() phase.
141  * @param data event to send
142  */
143  void sendUntimedData(Event* data);
144 
145  /** Receive an event (if any) during the init() or complete() phase.
146  * @return Event if one is available
147  * @return nullptr if no Event is available
148  */
150 
151  /** Send data during the init() or complete() phase.
152  * Same as sendUntimedData()
153  * @param init_data data to send
154  */
155  void sendInitData(Event* init_data) { sendUntimedData(init_data); }
156 
157  /** Receive an event (if any) during the init() or complete() phase.
158  * Same as recvUntimedData()
159  * @return Event if one is available
160  * @return nullptr if no Event is available
161  */
163 
164  /** Return whether link has been configured
165  * @return whether link is configured
166  */
167  bool isConfigured() { return type != UNINITIALIZED; }
168 
169 #ifdef __SST_DEBUG_EVENT_TRACKING__
170  void setSendingComponentInfo(const std::string& comp_in, const std::string& type_in, const std::string& port_in)
171  {
172  comp = comp_in;
173  ctype = type_in;
174  port = port_in;
175  }
176 
177  const std::string& getSendingComponentName() { return comp; }
178  const std::string& getSendingComponentType() { return ctype; }
179  const std::string& getSendingPort() { return port; }
180 
181 #endif
182 
183 protected:
184  Link();
185 
186  void setAsSyncLink() { type = SYNC; }
187 
188  /**
189  Set the delivery_info for the link
190  */
191  void setDeliveryInfo(uintptr_t info) { delivery_info = info; }
192 
193  /** Send an event over the link with additional delay. Sends an event
194  * over a link with an additional delay specified with a
195  * TimeConverter. I.e. the total delay is the link's delay + the
196  * additional specified delay.
197  * @param delay - additional total delay to add
198  * @param event - the Event to send
199  */
200  void send_impl(SimTime_t delay, Event* event);
201 
202  // Since Links are found in pairs, I will keep all the information
203  // needed for me to send and deliver an event to the other side of
204  // the link. That means, that I mostly keep my pair's
205  // information. The one consequence, is that polling links will
206  // have to pull the data from the pair, but since this is a less
207  // common case, that's okay (this decision makes the common case
208  // faster and the less common case slower).
209 
210  /** Queue of events to be received by the owning component */
212 
213  /** Holds the delivery information. This is stored as a
214  uintptr_t, but is actually a pointer converted using
215  reinterpret_cast. For links connected to a
216  Component/SubComponent, this holds a pointer to the delivery
217  functor. For links connected to a Sync object, this holds a
218  pointer to the remote link to send the event on after
219  synchronization.
220  */
221  uintptr_t delivery_info;
222 
223  /** Timebase used if no other timebase is specified. Used to specify
224  the units for added delays when sending, such as in
225  Link::send(). Often set by the Component::registerClock()
226  function if the regAll argument is true.
227  */
228  SimTime_t defaultTimeBase;
229 
230  /** Latency of the link. It is used by the partitioner as the
231  weight. This latency is added to the delay put on the event by
232  the component.
233  */
234  SimTime_t latency;
235 
236  /** Pointer to the opposite side of this link */
238 
239 private:
240  friend class BaseComponent;
241 
242  SimTime_t& current_time;
243  Type_t type;
244  Mode_t mode;
245  LinkId_t tag;
246 
247  /** Create a new link with a given tag
248 
249  The tag is used for two different things depending on where
250  this link sends data:
251 
252  If it sends it to a Sync object, then it represents the
253  remote_tag used to lookup the correct link on the other side.
254 
255  If it sends to a TimeVortex (or DirectLinkQueue), it is the
256  value used for enforce_link_order (if that feature is
257  enabled).
258  */
259  Link(LinkId_t tag);
260 
261  Link(const Link& l);
262 
263  /** Specifies that this link has no callback, and is poll-based only */
264  void setPolling();
265 
266  /** Causes an event to be delivered to the registered callback */
267  inline void deliverEvent(Event* event) const { (*reinterpret_cast<Event::HandlerBase*>(delivery_info))(event); }
268 
269  /** Set minimum link latency */
270  void setLatency(Cycle_t lat);
271 
272  void sendUntimedData_sync(Event* data);
273  void finalizeConfiguration();
274  void prepareForComplete();
275 
276 
277 #ifdef __SST_DEBUG_EVENT_TRACKING__
278  std::string comp;
279  std::string ctype;
280  std::string port;
281 #endif
282 };
283 
284 /** Self Links are links from a component to itself */
285 class SelfLink : public Link
286 {
287 public:
288  SelfLink() : Link()
289  {
290  pair_link = this;
291  latency = 0;
292  }
293 };
294 
295 
296 } // namespace SST
297 
298 #endif // SST_CORE_LINK_H
Definition: syncManager.h:114
Definition: ssthandler.h:100
A class to convert between a component&#39;s view of time and the core&#39;s view of time.
Definition: timeConverter.h:26
Definition: syncManager.h:32
SimTime_t convertToCoreTime(SimTime_t time) const
Converts from the component&#39;s view to the core&#39;s view of time.
Definition: timeConverter.h:36
Definition: syncManager.h:75
Main control class for a SST Simulation.
Definition: simulation_impl.h:75
Main component object for the simulation.
Definition: baseComponent.h:49
Defines a pair of links (to define a connected link)
Definition: linkPair.h:23
Definition: componentInfo.h:39
Base Class for a queue of Activities.
Definition: activityQueue.h:21
Base class for Events - Items sent across links to communicate between components.
Definition: event.h:34