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