SST  15.1.0
StructuralSimulationToolkit
event.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_EVENT_H
13 #define SST_CORE_EVENT_H
14 
15 #include "sst/core/activity.h"
16 #include "sst/core/sst_types.h"
17 #include "sst/core/ssthandler.h"
18 
19 #include <atomic>
20 #include <cinttypes>
21 #include <cstdint>
22 #include <string>
23 #include <utility>
24 
25 namespace SST {
26 
27 class Link;
28 class NullEvent;
29 class RankSync;
30 class ThreadSync;
31 
32 namespace pvt {
33 class DeliveryInfoCompEvent;
34 } // namespace pvt
35 
36 /**
37  * Base class for Events - Items sent across links to communicate between
38  * components.
39  */
40 class Event : public Activity
41 {
42  friend class pvt::DeliveryInfoCompEvent;
43 
44 public:
45  /**
46  Base handler for event delivery.
47  */
49 
50  /**
51  Used to create handlers for event delivery. The callback
52  function is expected to be in the form of:
53 
54  void func(Event* event)
55 
56  In which case, the class is created with:
57 
58  new Event::Handler<classname>(this, &classname::function_name)
59 
60  Or, to add static data, the callback function is:
61 
62  void func(Event* event, dataT data)
63 
64  and the class is created with:
65 
66  new Event::Handler<classname, dataT>(this, &classname::function_name, data)
67  */
68  template <typename classT, typename dataT = void>
69  using Handler
70  [[deprecated("Handler has been deprecated. Please use Handler2 instead as it supports checkpointing.")]] =
72 
73 
74  /**
75  New style (checkpointable) SSTHandler
76  */
77  template <typename classT, auto funcT, typename dataT = void>
79 
80  /**
81  Class used to sort events during checkpointing. This is used
82  to sort events by delivery_info so we can use std::lower_bound
83  to easily find events targeting a specific handler. For Events
84  targetting the same handler, it will sort according to
85  Activity::less. This will ensure that things get inserted back
86  in correct order, though the only important thing is that
87  insertion order is maintained, so two events to be delivered at
88  the same time maintain their send order.
89 
90  */
91  class less
92  {
93  public:
94  bool operator()(const Event* lhs, const Event* rhs) const
95  {
96  if ( lhs->delivery_info != rhs->delivery_info ) return lhs->delivery_info < rhs->delivery_info;
97  return Activity::less<true, true, true>()(lhs, rhs);
98  }
99  };
100 
101 
102  /** Type definition of unique identifiers */
103  using id_type = std::pair<uint64_t, int>;
104  /** Constant, default value for id_types */
105  static const id_type NO_ID;
106 
107  Event() :
108  Activity(),
109  delivery_info(0)
110  {
111  setPriority(EVENTPRIORITY);
112 #if __SST_DEBUG_EVENT_TRACKING__
113  first_comp = "";
114  last_comp = "";
115 #endif
116  }
117  ~Event() override = default;
118 
119  /** Clones the event in for the case of a broadcast */
120  virtual Event* clone();
121 
122 
123 #ifdef __SST_DEBUG_EVENT_TRACKING__
124 
125  virtual void printTrackingInfo(const std::string& header, Output& out) const override
126  {
127  out.output("%s Event first sent from: %s:%s (type: %s) and last received by %s:%s (type: %s)\n", header.c_str(),
128  first_comp.c_str(), first_port.c_str(), first_type.c_str(), last_comp.c_str(), last_port.c_str(),
129  last_type.c_str());
130  }
131 
132  const std::string& getFirstComponentName() { return first_comp; }
133  const std::string& getFirstComponentType() { return first_type; }
134  const std::string& getFirstPort() { return first_port; }
135  const std::string& getLastComponentName() { return last_comp; }
136  const std::string& getLastComponentType() { return last_type; }
137  const std::string& getLastPort() { return last_port; }
138 
139  void addSendComponent(const std::string& comp, const std::string& type, const std::string& port)
140  {
141  if ( first_comp == "" ) {
142  first_comp = comp;
143  first_type = type;
144  first_port = port;
145  }
146  }
147  void addRecvComponent(const std::string& comp, const std::string& type, const std::string& port)
148  {
149  last_comp = comp;
150  last_type = type;
151  last_port = port;
152  }
153 
154 #endif
155 
156  bool isEvent() const override final { return true; }
157  bool isAction() const override final { return false; }
158 
159  void copyAllDeliveryInfo(const Activity* act) override final
160  {
161  Activity::copyAllDeliveryInfo(act);
162  const Event* ev = static_cast<const Event*>(act);
163  delivery_info = ev->delivery_info;
164  }
165 
166 
167  void serialize_order(SST::Core::Serialization::serializer& ser) override
168  {
169  Activity::serialize_order(ser);
170  SST_SER(delivery_info);
171 #ifdef __SST_DEBUG_EVENT_TRACKING__
172  SST_SER(first_comp);
173  SST_SER(first_type);
174  SST_SER(first_port);
175  SST_SER(last_comp);
176  SST_SER(last_type);
177  SST_SER(last_port);
178 #endif
179  }
180 
181 protected:
182  /**
183  * Generates an ID that is unique across ranks, components and events.
184  */
186 
187 
188 private:
189  friend class Link;
190  friend class NullEvent;
191  friend class RankSync;
192  friend class ThreadSync;
193  friend class TimeVortex;
194  friend class Simulation_impl;
195 
196 
197  /** Cause this event to fire */
198  void execute() override;
199 
200  /**
201  This sets the information needed to get the event properly
202  delivered for the next step of transfer.
203 
204  The tag is used to deterministically sort the events and is
205  based off of the sorted link names. This field is unused for
206  events sent across link connected to sync objects.
207 
208  For links that are going to a sync, the delivery_info is used
209  on the remote side to send the event on the proper link. For
210  local links, delivery_info contains the delivery functor.
211  @return void
212  */
213  inline void setDeliveryInfo(LinkId_t tag, uintptr_t delivery_info)
214  {
215  setOrderTag(tag);
216  this->delivery_info = delivery_info;
217  }
218 
219  /**
220  Update the delivery_info during a restart. This will fixup the
221  handler pointer.
222 
223  @param dinfo New handler pointer cast as a uintptr_t
224  */
225  void updateDeliveryInfo(uintptr_t dinfo) { delivery_info = dinfo; }
226 
227 
228  /** Gets the link id used for delivery. For use by SST Core only */
229  inline Link* getDeliveryLink() { return reinterpret_cast<Link*>(delivery_info); }
230 
231  /** Gets the link id associated with this event. For use by SST Core only */
232  inline LinkId_t getTag() const { return getOrderTag(); }
233 
234 
235  /** Holds the delivery information. This is stored as a
236  uintptr_t, but is actually a pointer converted using
237  reinterpret_cast. For events send on links connected to a
238  Component/SubComponent, this holds a pointer to the delivery
239  functor. For events sent on links connected to a Sync object,
240  this holds a pointer to the remote link to send the event on
241  after synchronization.
242  */
243  uintptr_t delivery_info;
244 
245 private:
246  static std::atomic<uint64_t> id_counter;
247 
248 #ifdef __SST_DEBUG_EVENT_TRACKING__
249  std::string first_comp;
250  std::string first_type;
251  std::string first_port;
252  std::string last_comp;
253  std::string last_type;
254  std::string last_port;
255 #endif
256 
257  ImplementVirtualSerializable(SST::Event)
258 };
259 
260 /**
261  * Empty Event. Does nothing.
262  */
263 class EmptyEvent : public Event
264 {
265 public:
266  EmptyEvent() :
267  Event()
268  {}
269  ~EmptyEvent() {}
270 
271 private:
272  ImplementSerializable(SST::EmptyEvent)
273 };
274 
276 {
277 public:
278  const ComponentId_t comp_id;
279  const std::string comp_name;
280  const std::string comp_type;
281  const std::string port_name;
282 
284  ComponentId_t id, const std::string& cname, const std::string& ctype, const std::string& pname) :
285  comp_id(id),
286  comp_name(cname),
287  comp_type(ctype),
288  port_name(pname)
289  {}
290 
292 };
293 
294 namespace pvt {
295 
296 /**
297  Class used with std::lower_bound to find the start of events in a
298  sorted list with the specified delivery_info.
299  */
301 {
302 public:
303  static uintptr_t getDeliveryInfo(Event* ev) { return ev->delivery_info; }
304 
305  DeliveryInfoCompEvent(uintptr_t delivery_info) { setDeliveryInfo(0, delivery_info); }
306 };
307 
308 } // namespace pvt
309 
310 } // namespace SST
311 
312 #endif // SST_CORE_EVENT_H
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file...
Definition: output.h:57
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:42
Base template for handlers which take a class defined argument.
Definition: ssthandler.h:109
Definition: event.h:275
Base class for all Activities in the SST Event Queue.
Definition: activity.h:47
id_type generateUniqueId()
Generates an ID that is unique across ranks, components and events.
Definition: event.cc:43
Base template for the class.
Definition: ssthandler.h:1273
Handler class with user-data argument.
Definition: ssthandler.h:1136
void setOrderTag(uint32_t tag)
Sets the order tag.
Definition: activity.h:156
Class used with std::lower_bound to find the start of events in a sorted list with the specified deli...
Definition: event.h:300
void setPriority(uint64_t priority)
Set the priority of the Activity.
Definition: activity.h:200
Definition: action.cc:18
std::pair< uint64_t, int > id_type
Type definition of unique identifiers.
Definition: event.h:103
void output(uint32_t line, const char *file, const char *func, const char *format,...) const
Output the message with formatting as specified by the format parameter.
Definition: output.h:189
static const id_type NO_ID
Constant, default value for id_types.
Definition: event.h:105
Empty Event.
Definition: event.h:263
Class used to sort events during checkpointing.
Definition: event.h:91
virtual Event * clone()
Clones the event in for the case of a broadcast.
Definition: event.cc:34
Struct used as a base class for all AttachPoint metadata passed to registration functions.
Definition: sst_types.h:80
Class to use as the less than operator for STL functions or sorting algorithms.
Definition: activity.h:65
Base class for Events - Items sent across links to communicate between components.
Definition: event.h:40
uint32_t getOrderTag() const
Return the order tag associated with this activity.
Definition: activity.h:159