SST 16.0.0
Structural Simulation Toolkit
coreTest_SubComponent.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_SUBCOMPONENT_H
13#define SST_CORE_CORETEST_SUBCOMPONENT_H
14
15#include "sst/core/component.h"
16#include "sst/core/link.h"
17#include "sst/core/subcomponent.h"
18
19#include <cstdint>
20#include <vector>
21
22namespace SST::CoreTestSubComponent {
23
24/*
25
26 CoreTestSubComponent will test the various ways to use SubComponents.
27 The SubComponents will be loadable as both named and unnamed
28 SubComponets. When an unname SubComponent is used, it inherits the
29 port interface from the BaseComponent that created it. A named
30 SubComponent owns it's own ports and will mask the ports from any
31 BaseComponent higher in the call tree.
32
33 Each BaseComponent will have a port(s) that may or may not be used
34 depending on the configuration.
35 */
36
37class SubCompEvent : public SST::Event
38{
39public:
40 SubCompEvent(bool last) :
41 Event(),
42 last(last)
43 {}
44
45 SubCompEvent() = default; // For serialization
46
47 bool last = false;
48
49 void serialize_order(SST::Core::Serialization::serializer& ser) override
50 {
51 Event::serialize_order(ser);
52 SST_SER(last);
53 }
54
55 ImplementSerializable(SubCompEvent);
56};
57
58class SubCompInterface : public SST::SubComponent
59{
60public:
61 SST_ELI_REGISTER_SUBCOMPONENT_API(SST::CoreTestSubComponent::SubCompInterface)
62
63 explicit SubCompInterface(ComponentId_t id) :
64 SubComponent(id)
65 {}
66 SubCompInterface(ComponentId_t id, Params& UNUSED(params)) :
67 SubComponent(id)
68 {}
69 SubCompInterface() :
70 SubComponent()
71 {}
72 virtual ~SubCompInterface() {}
73 virtual void clock(SST::Cycle_t) {}
74
75 void serialize_order(SST::Core::Serialization::serializer& ser) override
76 {
77 SST::SubComponent::serialize_order(ser);
78 }
80};
81
82class SubCompSlotInterface : public SubCompInterface
83{
84public:
85 SST_ELI_REGISTER_SUBCOMPONENT_DERIVED_API(SST::CoreTestSubComponent::SubCompSlotInterface,
87
88 SST_ELI_DOCUMENT_PARAMS(
89 {"num_subcomps","Number of anonymous SubComponents to load. Ignored if using name SubComponents.","1"}
90 )
91
92 SST_ELI_DOCUMENT_PORTS(
93 {"test", "Just a test port", { "coreTestMessageGeneratorComponent.coreTestMessage", "" } },
94 )
95
96 SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
97 )
98
99 explicit SubCompSlotInterface(ComponentId_t id) :
100 SubCompInterface(id)
101 {}
102 SubCompSlotInterface(ComponentId_t id, Params& UNUSED(params)) :
103 SubCompInterface(id)
104 {}
105 virtual ~SubCompSlotInterface() {}
106
107 SubCompSlotInterface() {}
108 void serialize_order(SST::Core::Serialization::serializer& ser) override { SubCompInterface::serialize_order(ser); }
110};
111
112/* Our trivial component */
113class SubComponentLoader : public Component
114{
115public:
116 // REGISTER THIS COMPONENT INTO THE ELEMENT LIBRARY
117 SST_ELI_REGISTER_COMPONENT(
118 SubComponentLoader,
119 "coreTestElement",
120 "SubComponentLoader",
121 SST_ELI_ELEMENT_VERSION(1,0,0),
122 "Demonstrates subcomponents",
123 COMPONENT_CATEGORY_UNCATEGORIZED
124 )
125
126 SST_ELI_DOCUMENT_PARAMS(
127 {"clock", "Clock Rate", "1GHz"},
128 {"unnamed_subcomponent", "Unnamed SubComponent to load. If empty, then a named subcomponent is loaded", ""},
129 {"num_subcomps","Number of anonymous SubComponents to load. Ignored if using name SubComponents.","1"},
130 {"verbose", "Verbosity level", "0"},
131 )
132
133 SST_ELI_DOCUMENT_STATISTICS(
134 {"totalSent", "# of total messages sent", "", 1},
135 )
136
137 // This ports will be used only by unnamed SubComponents
138 SST_ELI_DOCUMENT_PORTS(
139 {"port%d", "Sending or Receiving Port(s)", { "coreTestMessageGeneratorComponent.coreTestMessage", "" } },
140 )
141
142 SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
143 {"mySubComp", "Test slot", "SST::CoreTestSubComponent::SubCompInterface" }
144 )
145
146 SST_ELI_IS_CHECKPOINTABLE()
147
148 SubComponentLoader(ComponentId_t id, SST::Params& params);
149
150 SubComponentLoader() {}
151 void serialize_order(SST::Core::Serialization::serializer& ser) override
152 {
153 SST::Component::serialize_order(ser);
154 SST_SER(count);
155 SST_SER(subComps);
156 }
158
159private:
160 uint32_t count = 0;
161 bool tick(SST::Cycle_t);
162 std::vector<SubCompInterface*> subComps;
163};
164
165/* Our example subcomponents */
166class SubCompSlot : public SubCompSlotInterface
167{
168public:
169 SST_ELI_REGISTER_SUBCOMPONENT(
170 SubCompSlot,
171 "coreTestElement",
172 "SubCompSlot",
173 SST_ELI_ELEMENT_VERSION(1,0,0),
174 "Subcomponent which is just a wrapper for the actual SubComponent to be used",
176 )
177
178 SST_ELI_DOCUMENT_PARAMS(
179 {"unnamed_subcomponent", "Unnamed SubComponent to load. If empty, then a named subcomponent is loaded", ""},
180 {"verbose", "Verbosity level", "0"},
181 )
182
183 // Only used when loading unnamed SubComponents
184 SST_ELI_DOCUMENT_PORTS(
185 {"slot_port%d", "Port(s) to send or receive on", { "coreTestMessageGeneratorComponent.coreTestMessage", "" } },
186 )
187
188 SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
189 {"mySubCompSlot", "Test slot", "SST::CoreTestSubComponent::SubCompInterface" }
190 )
191
192 SST_ELI_IS_CHECKPOINTABLE()
193
194 SubCompSlot() {}
195 void serialize_order(SST::Core::Serialization::serializer& ser) override
196 {
197 SubCompSlotInterface::serialize_order(ser);
198 SST_SER(subComps);
199 }
200 ImplementSerializable(SST::CoreTestSubComponent::SubCompSlot)
201
202private:
203 std::vector<SubCompInterface*> subComps;
204
205public:
206 SubCompSlot(ComponentId_t id, Params& params);
207 // Direct load
208 SubCompSlot(ComponentId_t id, std::string unnamed_sub);
209
210 ~SubCompSlot() {}
211 void clock(Cycle_t) override;
212};
213
214// Add in some extra levels of ELI hierarchy for testing
215class SubCompSendRecvInterface : public SubCompInterface
216{
217public:
218 SST_ELI_REGISTER_SUBCOMPONENT_DERIVED_API(SST::CoreTestSubComponent::SubCompSendRecvInterface,
220
221 // REGISTER THIS SUB-COMPONENT INTO THE ELEMENT LIBRARY
222 SST_ELI_REGISTER_SUBCOMPONENT(
223 SubCompSendRecvInterface,
224 "coreTestElement",
225 "SubCompSendRecv",
226 SST_ELI_ELEMENT_VERSION(1,0,0),
227 "Default Subcomponent for ELI testing only",
229 )
230
231 SST_ELI_DOCUMENT_PARAMS(
232 {"port_name", "Name of port to connect to", ""},
233 {"sendCount", "Number of Messages to Send", "10"},
234 {"verbose", "Verbosity level", "0"}
235 )
236
237 SST_ELI_DOCUMENT_PORTS(
238 {"sendPort", "Sending Port", { "coreTestMessageGeneratorComponent.coreTestMessage", "" } },
239 // The following port is a test to make sure that when loaded
240 // anonymously, a port that's named the same as one of its
241 // parent's ports doesn't conflict.
242 {"slot_port%d", "This is just a test port that duplicates a port from the SubComponent that will instance it", { "", "" } },
243 )
244
245 SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
246 )
247
248 SST_ELI_DOCUMENT_STATISTICS(
249 {"numRecv", "# of msgs recv", "", 1},
250 )
251
252 SST_ELI_IS_CHECKPOINTABLE()
253
254 explicit SubCompSendRecvInterface(ComponentId_t id) :
255 SubCompInterface(id)
256 {}
257 SubCompSendRecvInterface(ComponentId_t id, Params& UNUSED(params)) :
258 SubCompInterface(id)
259 {}
260 virtual ~SubCompSendRecvInterface() {}
261
262 SubCompSendRecvInterface() {}
263 void serialize_order(SST::Core::Serialization::serializer& ser) override { SubCompInterface::serialize_order(ser); }
265};
266
267class SubCompSender : public SubCompSendRecvInterface
268{
269public:
270 // REGISTER THIS SUB-COMPONENT INTO THE ELEMENT LIBRARY
271 SST_ELI_REGISTER_SUBCOMPONENT(
272 SubCompSender,
273 "coreTestElement",
274 "SubCompSender",
275 SST_ELI_ELEMENT_VERSION(1,0,0),
276 "Sending Subcomponent",
278 )
279
280 SST_ELI_REGISTER_ALIAS("SubCompSender_alias")
281
282 SST_ELI_DOCUMENT_PARAMS(
283 )
284
285 SST_ELI_DOCUMENT_STATISTICS(
286 SST_ELI_DELETE_STAT("numRecv"),
287 {"numSent", "# of msgs sent", "", 1},
288 )
289
290 SST_ELI_DOCUMENT_PORTS(
291 {"sendPort", "Sending Port", { "coreTestMessageGeneratorComponent.coreTestMessage", "" } },
292 )
293
294 SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
295 {"test_slot", "Test slot", "" }
296 )
297
298 SST_ELI_IS_CHECKPOINTABLE()
299
300 SubCompSender() {}
301 void serialize_order(SST::Core::Serialization::serializer& ser) override
302 {
303 SubCompSendRecvInterface::serialize_order(ser);
304 SST_SER(link);
305 SST_SER(nToSend);
306 SST_SER(nMsgSent);
307 SST_SER(totalMsgSent);
308 SST_SER(out);
309 }
310 ImplementSerializable(SST::CoreTestSubComponent::SubCompSender)
311
312private:
313 Statistic<uint32_t>* nMsgSent;
314 Statistic<uint32_t>* totalMsgSent;
315 uint32_t nToSend;
316 SST::Link* link;
317 SST::Output* out;
318
319public:
320 SubCompSender(ComponentId_t id, Params& params);
321 // Direct API
322 SubCompSender(ComponentId_t id, uint32_t nToSend, const std::string& port_name);
323 ~SubCompSender() {}
324 void clock(Cycle_t) override;
325};
326
327class SubCompReceiver : public SubCompSendRecvInterface
328{
329
330public:
331 // REGISTER THIS SUB-COMPONENT INTO THE ELEMENT LIBRARY
332 SST_ELI_REGISTER_SUBCOMPONENT(
333 SubCompReceiver,
334 "coreTestElement",
335 "SubCompReceiver",
336 SST_ELI_ELEMENT_VERSION(1,0,0),
337 "Receiving Subcomponent",
339 )
340
341 SST_ELI_DOCUMENT_PARAMS(
342 SST_ELI_DELETE_PARAM("sendCount")
343 )
344
345 SST_ELI_DOCUMENT_STATISTICS(
346 )
347
348 SST_ELI_DOCUMENT_PORTS(
349 SST_ELI_DELETE_PORT("sendPort"),
350 {"recvPort", "Receiving Port", { "coreTestMessageGeneratorComponent.coreTestMessage", "" } },
351 )
352
353 SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS(
354 SST_ELI_DELETE_SUBCOMPONENT_SLOT("test_slot")
355 )
356
357 SST_ELI_IS_CHECKPOINTABLE()
358
359 SubCompReceiver() {}
360 void serialize_order(SST::Core::Serialization::serializer& ser) override
361 {
362 SubCompSendRecvInterface::serialize_order(ser);
363 SST_SER(link);
364 SST_SER(nMsgReceived);
365 SST_SER(out);
366 SST_SER(numRecv);
367 }
368 ImplementSerializable(SST::CoreTestSubComponent::SubCompReceiver)
369
370private:
371 Statistic<uint32_t>* nMsgReceived;
372 SST::Link* link;
373 SST::Output* out;
374 uint32_t numRecv = 0;
375
376 void handleEvent(SST::Event* ev);
377
378public:
379 SubCompReceiver(ComponentId_t id, Params& params);
380 SubCompReceiver(ComponentId_t id, std::string port);
381 ~SubCompReceiver() {}
382 void clock(Cycle_t) override;
383};
384
385} // namespace SST::CoreTestSubComponent
386
387#endif // SST_CORE_CORETEST_SUBCOMPONENT_H
Definition coreTest_SubComponent.h:59
Definition coreTest_SubComponent.h:328
Definition coreTest_SubComponent.h:216
Definition coreTest_SubComponent.h:268
Definition coreTest_SubComponent.h:83
Definition coreTest_SubComponent.h:167
Definition coreTest_SubComponent.h:114
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
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
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