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