SST  15.1.0
StructuralSimulationToolkit
coreTest_SubComponent.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_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 
22 namespace 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 
37 class SubCompEvent : public SST::Event
38 {
39 public:
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 
59 {
60 public:
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  {}
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  }
79  ImplementSerializable(SST::CoreTestSubComponent::SubCompInterface)
80 };
81 
83 {
84 public:
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 
108  void serialize_order(SST::Core::Serialization::serializer& ser) override { SubCompInterface::serialize_order(ser); }
110 };
111 
112 /* Our trivial component */
114 {
115 public:
116  // REGISTER THIS COMPONENT INTO THE ELEMENT LIBRARY
117  SST_ELI_REGISTER_COMPONENT(
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  }
157  ImplementSerializable(SST::CoreTestSubComponent::SubComponentLoader)
158 
159 private:
160  uint32_t count = 0;
161  bool tick(SST::Cycle_t);
162  std::vector<SubCompInterface*> subComps;
163 };
164 
165 /* Our example subcomponents */
167 {
168 public:
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 
202 private:
203  std::vector<SubCompInterface*> subComps;
204 
205 public:
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
216 {
217 public:
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(
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 
263  void serialize_order(SST::Core::Serialization::serializer& ser) override { SubCompInterface::serialize_order(ser); }
265 };
266 
268 {
269 public:
270  // REGISTER THIS SUB-COMPONENT INTO THE ELEMENT LIBRARY
271  SST_ELI_REGISTER_SUBCOMPONENT(
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 
312 private:
313  Statistic<uint32_t>* nMsgSent;
314  Statistic<uint32_t>* totalMsgSent;
315  uint32_t nToSend;
316  SST::Link* link;
317  SST::Output* out;
318 
319 public:
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 
328 {
329 
330 public:
331  // REGISTER THIS SUB-COMPONENT INTO THE ELEMENT LIBRARY
332  SST_ELI_REGISTER_SUBCOMPONENT(
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 
370 private:
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 
378 public:
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
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
Definition: coreTest_SubComponent.h:58
Definition: coreTest_SubComponent.h:37
Definition: coreTest_SubComponent.h:215
Main component object for the simulation.
Definition: component.h:30
Definition: coreTest_SubComponent.h:267
Definition: coreTest_SubComponent.h:82
Definition: coreTest_SubComponent.h:113
Definition: coreTest_SubComponent.h:22
Parameter store.
Definition: params.h:63
Definition: coreTest_SubComponent.h:166
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
Definition: coreTest_SubComponent.h:327