SST 15.0
Structural Simulation Toolkit
link.h
1// Copyright 2009-2025 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-2025, 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/rankInfo.h"
17#include "sst/core/serialization/serialize_impl_fwd.h"
18#include "sst/core/sst_types.h"
19#include "sst/core/timeConverter.h"
20
21#include <cstdint>
22#include <string>
23#include <vector>
24
25namespace SST {
26
27#define _LINK_DBG(fmt, args...) __DBG(DBG_LINK, Link, fmt, ##args)
28
29class ActivityQueue;
30class BaseComponent;
31class TimeConverter;
32class LinkPair;
33class Simulation_impl;
34
35class UnitAlgebra;
36
37namespace Profile {
39}
40
41class Link;
42
43template <>
45{
46 // Function implemented in link.cc
47 void operator()(Link*& s, SST::Core::Serialization::serializer& ser, ser_opt_t options);
48
49 SST_FRIEND_SERIALIZE();
50};
51
52
53/** Link between two components. Carries events */
54class alignas(64) Link
55{
56 enum Type_t : uint16_t { POLL, HANDLER, SYNC, UNINITIALIZED };
57 enum Mode_t : uint16_t { INIT, RUN, COMPLETE };
58
60
61public:
62 /**
63 Attach point for inspecting, modifying or dropping events
64 sent on the Link.
65
66 NOTE: Using the Link::AttachPoint will noticeably affect the
67 performance of sending events on Links and it is recommended
68 that, if possible, Event::HandlerBase::AttachPoint or
69 Event::HandlerBase::InterceptPoint be used instead.
70 */
72 {
73 public:
74 /**
75 Function that will be called when an attach point is
76 registered with the tool implementing the attach point.
77 The metadata passed in will be dependent on what type of
78 tool this is attached to. The uintptr_t returned from this
79 function will be passed into the eventSent() function.
80
81 @param mdata Metadata to be passed into the tool
82
83 @return Opaque key that will be passed back into
84 eventSent() to identify the source of the call
85 */
86 virtual uintptr_t registerLinkAttachTool(const AttachPointMetaData& mdata) = 0;
87
88 /**
89 Function that will be called when an event is sent on a
90 link with registered attach points. If ev is set to
91 nullptr, then the event will not be delivered and the tool
92 should delete the original event.
93
94 @param key Opaque key returned from registerLinkAttachTool()
95 */
96 virtual void eventSent(uintptr_t key, Event*& ev) = 0;
97
98 /**
99 Function that will be called to handle the key returned
100 from registerLinkAttachTool, if the AttachPoint tool is
101 serializable. This is needed because the key is opaque to
102 the Link, so it doesn't know how to handle it during
103 serialization. During SIZE and PACK phases of
104 serialization, the tool needs to store out any information
105 that will be needed to recreate data that is reliant on the
106 key. On UNPACK, the function needs to recreate any state
107 and reinitialize the passed in key reference to the proper
108 state to continue to make valid calls to eventSent().
109
110 Since not all tools will be serializable, there is a
111 default, empty implementation.
112
113 @param ser Serializer to use for serialization
114
115 @param key Key that would be passed into the eventSent() function.
116 */
118
119 virtual ~AttachPoint() = default;
120 };
121
122 friend class LinkPair;
123 friend class RankSync;
124 friend class ThreadSync;
125 friend class Simulation_impl;
126 friend class SyncManager;
127 friend class ComponentInfo;
128
129 ~Link();
130
131 /** Set additional Latency to be added to events being sent out of this link
132 * @param cycles Number of Cycles to be added
133 * @param timebase Base Units of cycles
134 */
135 void addSendLatency(int cycles, const std::string& timebase);
136
137 /** Set additional Latency to be added to events being sent out of this link
138 * @param cycles Number of Cycles to be added
139 * @param timebase Base Units of cycles
140 */
141 [[deprecated("Use of shared TimeConverter objects is deprecated. Use 'addSendLatency(SimTime_t cycles, "
142 "TimeConverter timebase)' (i.e., no pointer) instead.")]]
143 void addSendLatency(SimTime_t cycles, TimeConverter* timebase);
144 void addSendLatency(SimTime_t cycles, TimeConverter timebase);
145
146 /** Set additional Latency to be added on to events coming in on this link.
147 * @param cycles Number of Cycles to be added
148 * @param timebase Base Units of cycles
149 */
150 void addRecvLatency(int cycles, const std::string& timebase);
151
152 /** Set additional Latency to be added on to events coming in on this link.
153 * @param cycles Number of Cycles to be added
154 * @param timebase Base Units of cycles
155 */
156 [[deprecated("Use of shared TimeConverter objects is deprecated. Use 'addRecvLatency(SimTime_t cycles, "
157 "TimeConverter timebase)' (i.e., no pointer) instead.")]]
158 void addRecvLatency(SimTime_t cycles, TimeConverter* timebase);
159 void addRecvLatency(SimTime_t cycles, TimeConverter timebase);
160
161 /** Set the callback function to be called when a message is
162 * delivered. Not available for Polling links.
163 * @param functor Functor to call when message is delivered
164 */
165 void setFunctor(Event::HandlerBase* functor);
166
167 /** Replace the callback function to be called when a message is
168 * delivered. Any previous handler will be deleted.
169 * Not available for Polling links.
170 * @param functor Functor to call when message is delivered
171 */
172 void replaceFunctor(Event::HandlerBase* functor);
173
174 /** Get the callback function to be called when a message is
175 * delivered. Polling links will return nullptr.
176 */
178
179 /** Send an event over the link with additional delay. Sends an event
180 * over a link with an additional delay specified with a
181 * TimeConverter. I.e. the total delay is the link's delay + the
182 * additional specified delay.
183 * @param delay - additional delay
184 * @param tc - time converter to specify units for the additional delay
185 * @param event - the Event to send
186 */
187 [[deprecated(
188 "Use of shared TimeConverter objects is deprecated. Use 'send(SimTime_t delay, const TimeConverter& tc, "
189 "Event* event)' instead.")]]
190 inline void send(SimTime_t delay, TimeConverter* tc, Event* event)
191 {
192 send(delay, *tc, event);
193 }
194
195 /** Send an event over the link with additional delay. Sends an event
196 * over a link with an additional delay specified with a
197 * TimeConverter. I.e. the total delay is the link's delay + the
198 * additional specified delay.
199 * @param delay - additional delay
200 * @param tc - time converter to specify units for the additional delay
201 * @param event - the Event to send
202 */
203 inline void send(SimTime_t delay, TimeConverter tc, Event* event) { send_impl(tc.convertToCoreTime(delay), event); }
204
205
206 /** Send an event with additional delay. Sends an event over a link
207 * with additional delay specified by the Link's default
208 * timebase.
209 * @param delay The additional delay, in units of the default Link timebase
210 * @param event The event to send
211 */
212 inline void send(SimTime_t delay, Event* event) { send_impl(delay * defaultTimeBase, event); }
213
214 /** Send an event with the Link's default delay
215 * @param event The event to send
216 */
217 inline void send(Event* event) { send_impl(0, event); }
218
219
220 /** Retrieve a pending event from the Link. For links which do not
221 * have a set event handler, they can be polled with this function.
222 * Returns nullptr if there is no pending event.
223 * Not available for HANDLER-type links.
224 * @return Event if one is available
225 * @return nullptr if no Event is available
226 */
227 Event* recv();
228
229 /** Manually set the default defaultTimeBase
230 * @param tc TimeConverter object for the timebase
231 */
232 [[deprecated("Use of shared TimeConverter objects is deprecated. Use 'setDefaultTimeBase(TimeConverter tc)', "
233 "(i.e., no pointer) instead.")]]
235
236 /** Manually set the default defaultTimeBase
237 * @param tc TimeConverter object for the timebase
238 */
240
241 /** Return the default Time Base for this link
242 * @return the default Time Base for this link
243 */
245
246 /** Return the default Time Base for this link
247 * @return the default Time Base for this link
248 */
249 const TimeConverter* getDefaultTimeBase() const;
250
251 /** Return the ID of this link
252 * @return the unique ID for this link
253 */
254 LinkId_t getId() { return tag; }
255
256 /** Send data during the init() or complete() phase.
257 * @param data event to send
258 */
259 void sendUntimedData(Event* data);
260
261 /** Receive an event (if any) during the init() or complete() phase.
262 * @return Event if one is available
263 * @return nullptr if no Event is available
264 */
266
267 /** Return whether link has been configured
268 * @return whether link is configured
269 */
270 bool isConfigured() { return type != UNINITIALIZED; }
271
272#ifdef __SST_DEBUG_EVENT_TRACKING__
273 void setSendingComponentInfo(const std::string& comp_in, const std::string& type_in, const std::string& port_in)
274 {
275 comp = comp_in;
276 ctype = type_in;
277 port = port_in;
278 }
279
280 const std::string& getSendingComponentName() { return comp; }
281 const std::string& getSendingComponentType() { return ctype; }
282 const std::string& getSendingPort() { return port; }
283
284#endif
285
286protected:
287 Link();
288
289 void setAsSyncLink() { type = SYNC; }
290
291 /**
292 Set the delivery_info for the link
293 */
294 void setDeliveryInfo(uintptr_t info) { delivery_info = info; }
295
296 /** Send an event over the link with additional delay. Sends an event
297 * over a link with an additional delay specified with a
298 * TimeConverter. I.e. the total delay is the link's delay + the
299 * additional specified delay.
300 * @param delay - additional total delay to add
301 * @param event - the Event to send
302 */
303 void send_impl(SimTime_t delay, Event* event);
304
305 // Since Links are found in pairs, I will keep all the information
306 // needed for me to send and deliver an event to the other side of
307 // the link. That means, that I mostly keep my pair's
308 // information. The one consequence, is that polling links will
309 // have to pull the data from the pair, but since this is a less
310 // common case, that's okay (this decision makes the common case
311 // faster and the less common case slower).
312
313 /** Queue of events to be received by the owning component */
315
316 /** Holds the delivery information. This is stored as a
317 uintptr_t, but is actually a pointer converted using
318 reinterpret_cast. For links connected to a
319 Component/SubComponent, this holds a pointer to the delivery
320 functor. For links connected to a Sync object, this holds a
321 pointer to the remote link to send the event on after
322 synchronization.
323 */
324 uintptr_t delivery_info;
325
326 /** Timebase used if no other timebase is specified. Used to specify
327 the units for added delays when sending, such as in
328 Link::send(). Often set by the Component::registerClock()
329 function if the regAll argument is true.
330 */
332
333 /** Latency of the link. It is used by the partitioner as the
334 weight. This latency is added to the delay put on the event by
335 the component.
336 */
337 SimTime_t latency;
338
339 /** Pointer to the opposite side of this link */
341
342private:
343 friend class BaseComponent;
344
345 SimTime_t& current_time;
346 Type_t type;
347 Mode_t mode;
348 LinkId_t tag;
349
350 /** Create a new link with a given tag
351
352 The tag is used for two different things depending on where
353 this link sends data:
354
355 If it sends it to a Sync object, then it represents the
356 remote_tag used to lookup the correct link on the other side.
357
358 If it sends to a TimeVortex (or DirectLinkQueue), it is the
359 value used for enforce_link_order (if that feature is
360 enabled).
361 */
362 explicit Link(LinkId_t tag);
363
364 Link(const Link& l);
365
366 /** Specifies that this link has no callback, and is poll-based only */
367 void setPolling();
368
369 /** Causes an event to be delivered to the registered callback */
370 inline void deliverEvent(Event* event) const { (*reinterpret_cast<Event::HandlerBase*>(delivery_info))(event); }
371
372 /** Set minimum link latency */
373 void setLatency(Cycle_t lat);
374
375 void sendUntimedData_sync(Event* data);
376 void finalizeConfiguration();
377 void prepareForComplete();
378
379 std::string createUniqueGlobalLinkName(
380 RankInfo local_rank, uintptr_t local_ptr, RankInfo remote_rank, uintptr_t remote_ptr);
381
382
383 void attachTool(AttachPoint* tool, const AttachPointMetaData& mdata);
384 void detachTool(AttachPoint* tool);
385
386
387 using ToolList = std::vector<std::pair<AttachPoint*, uintptr_t>>;
388 ToolList* attached_tools;
389
390 /** Manually set the default time base
391 * @param factor SimTime_T defining the timebase factor
392 */
393 void setDefaultTimeBase(SimTime_t factor) { defaultTimeBase = factor; }
394
395 /** Set the default time base fo uninitialized */
396 void resetDefaultTimeBase() { defaultTimeBase = 0; }
397
398
399#ifdef __SST_DEBUG_EVENT_TRACKING__
400 std::string comp;
401 std::string ctype;
402 std::string port;
403#endif
404};
405
406/** Self Links are links from a component to itself */
407class SelfLink : public Link
408{
409public:
410 SelfLink() :
411 Link()
412 {
413 pair_link = this;
414 latency = 0;
415 }
416};
417
418
419} // namespace SST
420
421#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:62
Base serialize class.
Definition serialize.h:110
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition serializer.h:45
Base class for Events - Items sent across links to communicate between components.
Definition event.h:35
SSTHandlerBase< void, Event * > HandlerBase
Base handler for event delivery.
Definition event.h:40
Defines a pair of links (to define a connected link)
Definition linkPair.h:24
Definition eventHandlerProfileTool.h:30
Definition rankInfo.h:24
Main control class for a SST Simulation.
Definition simulation_impl.h:87
A class to convert between a component's view of time and the core's view of time.
Definition timeConverter.h:28
SimTime_t convertToCoreTime(SimTime_t time) const
Converts from the component's view to the core's view of time.
Definition timeConverter.h:62
Performs Unit math in full precision.
Definition unitAlgebra.h:107
Struct used as a base class for all AttachPoint metadata passed to registration functions.
Definition sst_types.h:73