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