SST 16.0.0
Structural Simulation Toolkit
portModule.h
1// Copyright 2009-2026 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-2026, 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_PORTMODULE_H
13#define SST_CORE_PORTMODULE_H
14
15#include "sst/core/eli/elementinfo.h"
16#include "sst/core/event.h"
17#include "sst/core/link.h"
18#include "sst/core/statapi/statbase.h"
19#include "sst/core/statapi/statengine.h"
20
21#include <cstdarg>
22#include <cstdint>
23#include <string>
24#include <utility>
25
26using namespace SST::Statistics;
27
28namespace SST {
29
30class BaseComponent;
31
32/**
33 PortModules are modules that can be attached to the send and/or
34 receive side of ports. Each PortModule is attached to one port and
35 uses the Event::HandlerBase::InterceptPoint for intercepting
36 incoming events and the Link::AttachPoint to intercept outgoing
37 events. The intercepted events can be inspected, modified and/or
38 canceled. For canceled events, the PortModule is required to delete
39 the event.
40
41 NOTE: Not Final API - PortModules will continue to be supported in
42 the future, but the API will not be finalized until the SST 15
43 release, so there may be slight changes to the base class.
44
45 NOTE: Attaching to a port on the send-side has known performance
46 issues, so it is recommended to attach to the input port whenever
47 possible.
48
49 */
51 public Event::HandlerBase::InterceptPoint,
52 public Link::AttachPoint,
54{
55
56public:
57 SST_ELI_DECLARE_BASE(PortModule)
58 // declare extern to limit compile times
59 SST_ELI_DECLARE_CTOR_EXTERN(SST::Params&)
60 // These categories will print in sst-info in the order they are
61 // listed here
62 SST_ELI_DECLARE_INFO_EXTERN(
66
67 PortModule();
68 virtual ~PortModule() {};
69
70 /******* Functions inherited from Link::AttachPoint *******/
71 /**
72 Function that will be called when a PortModule is registered on
73 sends (i.e. installOnSend() returns true). The uintptr_t
74 returned from this function will be passed into the eventSent()
75 function.
76
77 The default implementation will just return 0 and only needs to
78 be overwritten if the module needs any of the metadata and/or
79 needs to return a unique key.
80
81 @param mdata Metadata to be passed into the tool. NOTE: The
82 metadata will be of type EventHandlerMetaData (see
83 sst/core/event.h)
84
85 @return Opaque key that will be passed back into eventSent() to
86 identify the source of the call
87 */
88 virtual uintptr_t registerLinkAttachTool(const AttachPointMetaData& mdata) override;
89
90 /**
91 Function that will be called when an event is sent on a
92 link with registered PortModules. If ev is set to
93 nullptr, then the event will not be delivered and the function
94 should delete the original event.
95
96 NOTE: It is possible to delete the incoming event and replace
97 it with a new event, if this is done, the new event MUST call
98 copyAllDeliveryInfo(ev) or the event will not be properly
99 processed.
100
101 @param key Opaque key returned from registerLinkAttachTool()
102
103 @param ev Event to intercept
104 */
105 virtual void eventSent(uintptr_t key, Event*& ev) override = 0;
106
107
108 /**
109 Function that will be called to handle the key returned from
110 registerLinkAttachTool, if the AttachPoint tool is
111 serializable. This is needed because the key is opaque to the
112 Link, so it doesn't know how to handle it during serialization.
113 During SIZE and PACK phases of serialization, the tool needs to
114 store out any information that will be needed to recreate data
115 that is reliant on the key. On UNPACK, the function needs to
116 recreate the any state and reinitialize the passed in key
117 reference to the proper state to continue to make valid calls
118 to eventSent().
119
120 The default implemenation will just set key to 0 on UNPACK and
121 only needs to be overwritten if the module needs to return a
122 unique key from registerLinkAttachTool().
123
124 @param ser Serializer to use for serialization
125
126 @param key Key that would be passed into the eventSent() function.
127 */
128 virtual void serializeEventAttachPointKey(SST::Core::Serialization::serializer& ser, uintptr_t& key) override;
129
130
131 /******* Functions inherited from Event::HandlerBase::InterceptPoint *******/
132 /**
133 Function that will be called when a handler is registered with
134 recieves (i.e. installOnReceive() returns true). The uintptr_t
135 returned from this function will be passed into the intercept()
136 function.
137
138 The default implemenation will just return 0 and only needs to
139 be overwritten if the module needs any of the metadata and/or
140 needs to return a unique key.
141
142 @param mdata Metadata to be passed into the tool. NOTE: The
143 metadata will be of type EventHandlerMetaData (see
144 sst/core/event.h)
145
146 @return Opaque key that will be passed back into the
147 interceptHandler() calls
148 */
149 virtual uintptr_t registerHandlerIntercept(const AttachPointMetaData& mdata) override;
150
151
152 /**
153 Function that will be called before the event handler to let
154 the attach point intercept the data. The data can be modified,
155 and if cancel is set to true, the handler will not be executed.
156 If cancel is set to true, then the function should also delete
157 the event and set data to nullptr.
158
159 NOTE: It is possible to delete the incoming event and replace
160 the it with a new event, if this is done, the new event MUST
161 call copyAllDeliveryInfo(ev) or the event will not be properly
162 processed.
163
164 @param key Key returned from registerHandlerIntercept()
165 function
166
167 @param data Event that is to be passed to the handler
168
169 @param[out] cancel Set to true if the handler delivery should
170 be cancelled. If set to true, function must also delete the
171 event
172 */
173 virtual void interceptHandler(uintptr_t key, Event*& data, bool& cancel) override = 0;
174
175 /**
176 Function that will be called to handle the key returned from
177 registerHandlerIntercept, if the AttachPoint tool is
178 serializable. This is needed because the key is opaque to the
179 Link, so it doesn't know how to handle it during serialization.
180 During SIZE and PACK phases of serialization, the tool needs to
181 store out any information that will be needed to recreate data
182 that is reliant on the key. On UNPACK, the function needs to
183 recreate any state and reinitialize the passed in key reference
184 to the proper state to continue to make valid calls to
185 interceptHandler().
186
187 The default implemenation will just set key to 0 on UNPACK and
188 only needs to be overwritten if the module needs to return a
189 unique key from registerHandlerIntercept().
190
191 @param ser Serializer to use for serialization
192
193 @param key Key that would be passed into the interceptHandler() function.
194 */
195 virtual void serializeHandlerInterceptPointKey(SST::Core::Serialization::serializer& ser, uintptr_t& key) override;
196
197 /*** Functions that control whether module is install on send and/or receive ***/
198 /**
199 Called to determine if the PortModule should be installed on
200 receives
201
202 @return true if PortModule should be installed on receives
203 */
204 virtual bool installOnReceive() { return false; }
205
206 /**
207 Called to determine if the PortModule should be installed on
208 sends. NOTE: Installing PortModules on sends will have a
209 noticeable impact on performance, consider architecting things
210 so that you can intercept on receives.
211
212 @return true if PortModule should be installed on sends
213 */
214 virtual bool installOnSend() { return false; }
215
216 const std::string& getName() const;
217
218protected:
219 void serialize_order(SST::Core::Serialization::serializer& ser) override;
220
221 /*** Core API functions available to PortModules ***/
222
223 /** Get the core timebase */
225
226 /** Return the current simulation time as a cycle count*/
227 SimTime_t getCurrentSimCycle() const;
228
229 /** Return the current priority */
230 int getCurrentPriority() const;
231
232 /** Return the elapsed simulation time as a time */
234
235 /** Return the base simulation Output class instance */
237
238 /**
239 Return the simulated time since the simulation began in units
240 specified by the parameter.
241
242 @param tc TimeConverter specifying the units
243 */
244 [[deprecated("Use of shared TimeConverter objects is deprecated. Use 'getCurrentSimTime(TimeConverter& timebase)' "
245 "(i.e., no pointer) instead.")]]
246 SimTime_t getCurrentSimTime(TimeConverter* tc) const;
247 SimTime_t getCurrentSimTime(TimeConverter& tc) const;
248
249 /**
250 Return the simulated time since the simulation began in
251 timebase specified
252
253 @param base Timebase frequency in SI Units
254 */
255 SimTime_t getCurrentSimTime(const std::string& base) const;
256
257 /**
258 Utility function to return the time since the simulation began
259 in nanoseconds
260 */
261 SimTime_t getCurrentSimTimeNano() const;
262
263 /**
264 Utility function to return the time since the simulation began
265 in microseconds
266 */
267 SimTime_t getCurrentSimTimeMicro() const;
268
269 /**
270 Utility function to return the time since the simulation began
271 in milliseconds
272 */
273 SimTime_t getCurrentSimTimeMilli() const;
274
275 /** Convenience function for reporting fatal conditions. The
276 function will create a new Output object and call fatal()
277 using the supplied parameters. Before calling
278 Output::fatal(), the function will also print other
279 information about the (sub)component that called fatal and
280 about the simulation state.
281
282 From Output::fatal: Message will be sent to the output
283 location and to stderr. The output will be prepended with the
284 expanded prefix set in the object.
285 NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation.
286
287 @param line Line number of calling function (use CALL_INFO macro)
288 @param file File name calling function (use CALL_INFO macro)
289 @param func Function name calling function (use CALL_INFO macro)
290 @param exit_code The exit code used for termination of simulation.
291 will be passed to MPI_Abort()
292 @param format Format string. All valid formats for printf are available.
293 @param ... Arguments for format.
294 */
295 [[noreturn]]
296 void fatal(uint32_t line, const char* file, const char* func, int exit_code, const char* format, ...) const
297 __attribute__((format(printf, 6, 7)));
298
299 /** Convenience function for testing for and reporting fatal
300 conditions. If the condition holds, fatal() will be called,
301 otherwise, the function will return. The function will create
302 a new Output object and call fatal() using the supplied
303 parameters. Before calling Output::fatal(), the function will
304 also print other information about the (sub)component that
305 called fatal and about the simulation state.
306
307 From Output::fatal: Message will be sent to the output
308 location and to stderr. The output will be prepended with the
309 expanded prefix set in the object.
310 NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation.
311
312 @param condition on which to call fatal(); fatal() is called
313 if the bool is false.
314 @param line Line number of calling function (use CALL_INFO macro)
315 @param file File name calling function (use CALL_INFO macro)
316 @param func Function name calling function (use CALL_INFO macro)
317 @param exit_code The exit code used for termination of simulation.
318 will be passed to MPI_Abort()
319 @param format Format string. All valid formats for printf are available.
320 @param ... Arguments for format.
321 */
322 void sst_assert(bool condition, uint32_t line, const char* file, const char* func, int exit_code,
323 const char* format, ...) const __attribute__((format(printf, 7, 8)));
324
325 /** Registers a statistic.
326 If Statistic is allowed to exist (controlled by Python runtime parameters),
327 then a statistic will be created and returned. If not allowed to exist,
328 then a NullStatistic will be returned. The type of Statistic is set by Python
329 runtime parameters.
330 @param params Additional parameter set to be passed to the statistic constructor.
331 @param stat_name Primary name of the statistic. This name must match the
332 defined ElementInfoStatistic in the component, and must also
333 be enabled in the Python input file.
334 @param stat_sub_id An additional sub name for the statistic
335 @return Either a created statistic or a NullStatistic depending upon runtime settings.
336 */
337 template <typename T>
339 SST::Params& params, const std::string& stat_name, const std::string& stat_sub_id = "")
340 {
341 return registerStatistic_impl<T>(params, stat_name, stat_sub_id);
342 }
343
344 template <typename T>
345 Statistics::Statistic<T>* registerStatistic(const std::string& stat_name, const std::string& stat_sub_id = "")
346 {
347 SST::Params empty {};
348 return registerStatistic_impl<T>(empty, stat_name, stat_sub_id);
349 }
350
351 virtual std::string getEliType() const { return ""; }
352
353private:
354 friend class BaseComponent;
355
356 /**
357 Component that owns this PortModule
358 */
359 BaseComponent* component_ = nullptr;
360
361 PortModuleId_t id_; // Together with component_, uniquely identifies a port module
362
363 std::string name_;
364
365 // Utility function used by fatal and sst_assert
366 [[noreturn]]
367 void vfatal(uint32_t line, const char* file, const char* func, int exit_code, const char* format, va_list arg) const
368 __attribute__((format(printf, 6, 0)));
369
370 /**
371 Internal function to manage statistic registration
372 */
373 template <typename T>
374 Statistics::Statistic<T>* registerStatistic_impl(
375 SST::Params& params, const std::string& stat_name, const std::string& stat_sub_id)
376 {
377 // Lookup statistic enable level in ELI; if not present, returns 255
378 uint8_t level = getStatisticValidityAndLevel(stat_name);
379 if ( level == 255 ) {
380 fatal(__LINE__, __FILE__, "registerStatistic", 1,
381 "attempting to register a statistic '%s' that is not found in ELI", stat_name.c_str());
382 }
383
384 Params cfg_params;
385 bool enabled;
386 std::tie(enabled, cfg_params) = isStatisticEnabled(stat_name, level);
387
388 if ( enabled ) {
389 cfg_params.insert(params);
390 auto stat = getStatEngine()->createStatistic<T>(component_, stat_name, stat_sub_id, cfg_params);
391 stat->setPortModName(id_.first, id_.second);
392 return stat;
393 }
394 else {
395 return getStatEngine()->createDisabledStatistic<T>();
396 }
397 }
398
399 /** Helper functions for statistic enablement */
400 /**
401 Returns the local stat engine instance
402 */
403 Statistics::StatisticProcessingEngine* getStatEngine() const;
404
405 /**
406 Returns the required statistic level if stat exists in ELI, else returns 255
407 */
408 uint8_t getStatisticValidityAndLevel(const std::string& statistic_name) const;
409
410 /**
411 Returns a pair containing a bool indicating whether the statistic was enabled and a params object with any params
412 the statistic has been given.
413 */
414 std::pair<bool, Params> isStatisticEnabled(const std::string& statistic_name, const uint8_t min_level);
415};
416
417} // namespace SST
418
419// Macro used to register PortModules in the ELI database
420#define SST_ELI_REGISTER_PORTMODULE(cls, lib, name, version, desc) \
421 SST_ELI_REGISTER_DERIVED(SST::PortModule,cls,lib,name,ELI_FORWARD_AS_ONE(version),desc) \
422 std::string getEliType() const override \
423 { \
424 std::string ret(lib); \
425 return ret + "." + name; \
426 }
427
428#endif // SST_CORE_PORTMODULE_H
Main component object for the simulation.
Definition baseComponent.h:67
Definition serializable.h:25
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition serializer.h:43
Definition attributeInfo.h:42
Definition paramsInfo.h:41
Definition statsInfo.h:41
Base class for Events - Items sent across links to communicate between components.
Definition event.h:41
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file.
Definition output.h:58
Parameter store.
Definition params.h:65
void insert(const std::string &key, const std::string &value, bool overwrite=true)
Add a key/value pair into the param object.
Definition params.cc:171
PortModules are modules that can be attached to the send and/or receive side of ports.
Definition portModule.h:54
virtual uintptr_t registerHandlerIntercept(const AttachPointMetaData &mdata) override
Function that will be called when a handler is registered with recieves (i.e.
Definition portModule.cc:55
virtual bool installOnReceive()
Called to determine if the PortModule should be installed on receives.
Definition portModule.h:204
void sst_assert(bool condition, uint32_t line, const char *file, const char *func, int exit_code, const char *format,...) const
Convenience function for testing for and reporting fatal conditions.
Definition portModule.cc:203
virtual bool installOnSend()
Called to determine if the PortModule should be installed on sends.
Definition portModule.h:214
virtual void serializeHandlerInterceptPointKey(SST::Core::Serialization::serializer &ser, uintptr_t &key) override
Function that will be called to handle the key returned from registerHandlerIntercept,...
Definition portModule.cc:61
virtual void interceptHandler(uintptr_t key, Event *&data, bool &cancel) override=0
Function that will be called before the event handler to let the attach point intercept the data.
SimTime_t getCurrentSimTimeMicro() const
Utility function to return the time since the simulation began in microseconds.
Definition portModule.cc:136
virtual uintptr_t registerLinkAttachTool(const AttachPointMetaData &mdata) override
Function that will be called when a PortModule is registered on sends (i.e.
Definition portModule.cc:41
UnitAlgebra getCoreTimeBase() const
Get the core timebase.
Definition portModule.cc:82
SimTime_t getCurrentSimTimeMilli() const
Utility function to return the time since the simulation began in milliseconds.
Definition portModule.cc:142
UnitAlgebra getElapsedSimTime() const
Return the elapsed simulation time as a time.
Definition portModule.cc:100
virtual void serializeEventAttachPointKey(SST::Core::Serialization::serializer &ser, uintptr_t &key) override
Function that will be called to handle the key returned from registerLinkAttachTool,...
Definition portModule.cc:47
SimTime_t getCurrentSimCycle() const
Return the current simulation time as a cycle count.
Definition portModule.cc:88
SimTime_t getCurrentSimTimeNano() const
Utility function to return the time since the simulation began in nanoseconds.
Definition portModule.cc:130
int getCurrentPriority() const
Return the current priority.
Definition portModule.cc:94
Output & getSimulationOutput() const
Return the base simulation Output class instance.
Definition portModule.cc:106
virtual void eventSent(uintptr_t key, Event *&ev) override=0
Function that will be called when an event is sent on a link with registered PortModules.
void fatal(uint32_t line, const char *file, const char *func, int exit_code, const char *format,...) const
Convenience function for reporting fatal conditions.
Definition portModule.cc:194
Statistics::Statistic< T > * registerStatistic(SST::Params &params, const std::string &stat_name, const std::string &stat_sub_id="")
Registers a statistic.
Definition portModule.h:338
SimTime_t getCurrentSimTime(TimeConverter *tc) const
Return the simulated time since the simulation began in units specified by the parameter.
Definition portModule.cc:118
Forms the template defined base class for statistics gathering within SST.
Definition statbase.h:369
A class to convert between a component's view of time and the core's view of time.
Definition timeConverter.h:31
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:201