SST  15.1.0
StructuralSimulationToolkit
enclosingComponent.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_CORETEST_MESSAGEMESH_ENCLOSINGCOMPONENT_H
13 #define SST_CORE_CORETEST_MESSAGEMESH_ENCLOSINGCOMPONENT_H
14 
15 #include "sst/core/testElements/message_mesh/messageEvent.h"
16 
17 #include "sst/core/component.h"
18 #include "sst/core/event.h"
19 #include "sst/core/link.h"
20 #include "sst/core/rng/rng.h"
21 #include "sst/core/ssthandler.h"
22 #include "sst/core/subcomponent.h"
23 
24 #include <cstddef>
25 #include <cstdint>
26 #include <vector>
27 
29 
31 {
32 public:
33  SST_ELI_REGISTER_SUBCOMPONENT_API(SST::CoreTest::MessageMesh::PortInterface)
34 
35  explicit PortInterface(ComponentId_t id) :
36  SubComponent(id)
37  {}
38  PortInterface() {}
39  virtual ~PortInterface() {}
40 
41  /**
42  Base handler for event delivery.
43  */
45 
46  /**
47  Used to create handlers to notify the component when a message
48  has arrived. endpoint when the The callback function is
49  expected to be in the form of:
50 
51  void func(Event* ev)
52 
53  In which case, the class is created with:
54 
55  new PortInterface::Handler<classname>(this, &classname::function_name)
56 
57  Or, to add static data, the callback function is:
58 
59  void func(Event* ev, dataT data)
60 
61  and the class is created with:
62 
63  new PortInterface::Handler<classname, dataT>(this, &classname::function_name, data)
64  */
65  template <typename classT, typename dataT = void>
67 
68  /**
69  Used to create checkpointable handlers to notify the component
70  when a message has arrived. endpoint when the The callback
71  function is expected to be in the form of:
72 
73  void func(Event* ev)
74 
75  In which case, the class is created with:
76 
77  new PortInterface::Handler2<classname, &classname::function_name>(this)
78 
79  Or, to add static data, the callback function is:
80 
81  void func(Event* ev, dataT data)
82 
83  and the class is created with:
84 
85  new PortInterface::Handler2<classname, &classname::function_name, dataT>(this, data)
86  */
87  template <typename classT, auto funcT, typename dataT = void>
89 
90  virtual void setNotifyOnReceive(HandlerBase* functor) { functor_ = functor; }
91 
92  virtual void send(MessageEvent* ev, size_t index) = 0;
93 
94  virtual size_t getPortCount() = 0;
95 
96  void serialize_order(SST::Core::Serialization::serializer& ser) override
97  {
98  SubComponent::serialize_order(ser);
99  SST_SER(functor_);
100  }
101  ImplementVirtualSerializable(SST::CoreTest::MessageMesh::PortInterface);
102 
103 protected:
104  HandlerBase* functor_ = nullptr;
105 };
106 
108 {
109 public:
110  SST_ELI_REGISTER_SUBCOMPONENT_API(SST::CoreTest::MessageMesh::RouteInterface, std::vector<PortInterface*>&, int)
111 
112  explicit RouteInterface(ComponentId_t id) :
113  SubComponent(id)
114  {}
115  RouteInterface() {}
116  virtual ~RouteInterface() {}
117 
118  virtual void send(MessageEvent* ev, int incoming_port) = 0;
119 
120  virtual void sendInitialEvents(int mod) = 0;
121 
122  void serialize_order(SST::Core::Serialization::serializer& ser) override { SubComponent::serialize_order(ser); }
123  ImplementVirtualSerializable(SST::CoreTest::MessageMesh::RouteInterface);
124 };
125 
127 {
128 public:
129  // REGISTER THIS COMPONENT INTO THE ELEMENT LIBRARY
130  SST_ELI_REGISTER_COMPONENT(
132  "coreTestElement",
133  "message_mesh.enclosing_component",
134  SST_ELI_ELEMENT_VERSION(1,0,0),
135  "Base element that encloses the SubComponents that actually provide the functionality",
136  COMPONENT_CATEGORY_NETWORK
137  )
138 
139  SST_ELI_DOCUMENT_PARAMS(
140  {"id", "Id for this component", ""},
141  {"mod", "Port modulus to restrict number of initial events", "1"},
142  {"verbose", "Print message count at end of simulation", "True"},
143  {"stats", "Statistics per component", "0"}
144  )
145 
146  SST_ELI_DOCUMENT_STATISTICS(
147  {"stat", "Test statistic", "count", 1},
148  )
149 
150  SST_ELI_DOCUMENT_PORTS(
151  )
152 
153  SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
154  {"ports", "Slot that the ports objects go in", "SST::CoreTest::MessageMesh::PortInterface" },
155  {"route", "Slot that the route object goes in", "SST::CoreTest::MessageMesh::RouteInterface" }
156  )
157 
158  SST_ELI_IS_CHECKPOINTABLE()
159 
160  EnclosingComponent(ComponentId_t id, Params& params);
161  EnclosingComponent() {}
162  ~EnclosingComponent() {}
163 
164  void setup() override;
165  void finish() override;
166 
167  void serialize_order(SST::Core::Serialization::serializer& ser) override;
168  ImplementSerializable(SST::CoreTest::MessageMesh::EnclosingComponent);
169 
170 private:
171  void handleEvent(SST::Event* ev, int port);
172 
173  std::vector<PortInterface*> ports_;
174  RouteInterface* route_;
175 
176  // Measuring statistics per component
177  std::vector<Statistic<uint64_t>*> stats_;
178 
179  int my_id_;
180  int message_count_ = 0;
181  int mod_ = 1;
182  bool verbose_ = true;
183 };
184 
185 // SubComponents
186 
187 class PortSlot : public PortInterface
188 {
189 public:
190  // REGISTER THIS SUB-COMPONENT INTO THE ELEMENT LIBRARY
191  SST_ELI_REGISTER_SUBCOMPONENT(
192  PortSlot,
193  "coreTestElement",
194  "message_mesh.port_slot",
195  SST_ELI_ELEMENT_VERSION(1,0,0),
196  "SubComponent implementing PortInterface that simply defers to another loaded PortInterface",
198  )
199 
200  SST_ELI_DOCUMENT_PARAMS(
201  )
202 
203  SST_ELI_DOCUMENT_STATISTICS(
204  )
205 
206  SST_ELI_DOCUMENT_PORTS(
207  )
208 
209  SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
210  {"port", "Slot to load the real PortInterface object", "SST::CoreTest::MessageMesh::PortInterface" }
211  )
212 
213  SST_ELI_IS_CHECKPOINTABLE()
214 
215  PortSlot(ComponentId_t id, Params& params);
216  PortSlot() {}
217  ~PortSlot() {}
218 
219  void send(MessageEvent* ev, size_t index) override { port_->send(ev, index); }
220  void setNotifyOnReceive(HandlerBase* functor) override { port_->setNotifyOnReceive(functor); }
221  size_t getPortCount() override { return port_->getPortCount(); }
222 
223  void serialize_order(SST::Core::Serialization::serializer& ser) override;
224  ImplementSerializable(SST::CoreTest::MessageMesh::PortSlot);
225 
226 
227 private:
228  PortInterface* port_;
229 };
230 
231 
233 {
234 public:
235  // REGISTER THIS SUB-COMPONENT INTO THE ELEMENT LIBRARY
236  SST_ELI_REGISTER_SUBCOMPONENT(
237  MessagePort,
238  "coreTestElement",
239  "message_mesh.message_port",
240  SST_ELI_ELEMENT_VERSION(1,0,0),
241  "SubComponent implementing PortInterface for sending and receiving messages",
243  )
244 
245  SST_ELI_DOCUMENT_PARAMS(
246  )
247 
248  SST_ELI_DOCUMENT_STATISTICS(
249  )
250 
251  SST_ELI_DOCUMENT_PORTS(
252  {"port%d", "Port to send or receive on", { "" } },
253  )
254 
255  SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
256  )
257 
258  MessagePort(ComponentId_t id, Params& params);
259  MessagePort() {}
260  ~MessagePort() {}
261 
262  void send(MessageEvent* ev, size_t index) override;
263  void handleEvent(Event* ev);
264  size_t getPortCount() override { return links_.size(); }
265 
266  void serialize_order(SST::Core::Serialization::serializer& ser) override;
267  ImplementSerializable(SST::CoreTest::MessageMesh::MessagePort);
268 
269 private:
270  std::vector<Link*> links_;
271 };
272 
274 {
275 public:
276  // REGISTER THIS SUB-COMPONENT INTO THE ELEMENT LIBRARY
277  SST_ELI_REGISTER_SUBCOMPONENT(
278  RouteMessage,
279  "coreTestElement",
280  "message_mesh.route_message",
281  SST_ELI_ELEMENT_VERSION(1,0,0),
282  "SubComponent implementing message routing",
284  )
285 
286  SST_ELI_DOCUMENT_PARAMS(
287  )
288 
289  SST_ELI_DOCUMENT_STATISTICS(
290  {"msg_count", "Message counter", "count", 1},
291  )
292 
293  SST_ELI_DOCUMENT_PORTS(
294  )
295 
296  SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
297  )
298 
299  SST_ELI_IS_CHECKPOINTABLE()
300 
301  RouteMessage(ComponentId_t id, Params& params, std::vector<PortInterface*>& ports, int my_id);
302  RouteMessage() {}
303  ~RouteMessage() {}
304 
305  void send(MessageEvent* ev, int incoming_port) override;
306 
307  void sendInitialEvents(int mod) override;
308 
309  void serialize_order(SST::Core::Serialization::serializer& ser) override;
310  ImplementSerializable(SST::CoreTest::MessageMesh::RouteMessage);
311 
312 private:
313  std::vector<PortInterface*> ports_;
314  std::vector<size_t> counts_;
315  int my_id_;
316  SST::RNG::Random* rng_;
317 
318  Statistic<uint64_t>* mcnt_;
319 };
320 
321 } // namespace SST::CoreTest::MessageMesh
322 
323 #endif // SST_CORE_CORETEST_MESSAGEMESH_ENCLOSINGCOMPONENT_H
Implements the base class for random number generators for the SST core.
Definition: rng.h:29
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:42
Definition: enclosingComponent.h:28
Base template for handlers which take a class defined argument.
Definition: ssthandler.h:109
Definition: enclosingComponent.h:126
SSTHandlerBase< void, Event * > HandlerBase
Base handler for event delivery.
Definition: enclosingComponent.h:44
Base template for the class.
Definition: ssthandler.h:1273
Handler class with user-data argument.
Definition: ssthandler.h:1136
Main component object for the simulation.
Definition: component.h:30
Definition: messageEvent.h:19
Definition: enclosingComponent.h:232
Definition: enclosingComponent.h:30
void setup() override
Called after all components have been constructed and initialization has completed, but before simulation time has begun.
Definition: enclosingComponent.cc:72
Definition: enclosingComponent.h:187
Definition: enclosingComponent.h:273
Parameter store.
Definition: params.h:63
Base class for Events - Items sent across links to communicate between components.
Definition: event.h:40
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:28
void finish() override
Called after complete phase, but before objects are destroyed.
Definition: enclosingComponent.cc:84
Definition: enclosingComponent.h:107