libadc-cxx 1.0.0
Structured logging for scientific computing
Loading...
Searching...
No Matches
mpiSimpleDemo.cpp
Go to the documentation of this file.
1/* Copyright 2025 NTESS. See the top-level LICENSE.txt file for details.
2 *
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5//
6// This demo shows how one might send messages from a parallel program.
7// Via ldms only.
8//
9#ifdef ADC_BOOST_JSON_PUBLIC
10#include "boost/json/src.hpp"
11#endif
12#include "adc/factory.hpp"
13#include <cerrno>
14#include <cstring>
15#include <sstream>
16#include <limits>
17#include <unistd.h>
18#ifdef ADC_HAVE_MPI
19#include <mpi.h>
20#endif
21
22#define DEBUG 1
23
24std::map<std::string, std::string> file_config =
25 {{ "DIRECTORY", "./test.outputs"},
26 { "FILE", "out.file.log" },
27 { "APPEND", "true" }
28 };
29
30std::map<std::string, std::string> null_config;
31
32std::map<std::string, std::string> ldmsd_stream_publish_config =
33 {
34 { "STREAM", "adc_publish_api" }
35 };
36
37
38int start_publisher(std::shared_ptr<adc::publisher_api> pi, std::map<std::string, std::string>& pconfig ) {
39 int e = 0;
40 int err = pi->config(pconfig);
41 if (err) {
42 std::cout << "config failed " <<
43 std::strerror(err) << std::endl;
44 e += 1;
45 err = 0;
46 }
47 err = pi->initialize();
48 if (err) {
49 std::cout << "initialize failed " <<
50 std::strerror(err) << std::endl;
51 e += 1;
52 err = 0;
53 }
54 return e;
55}
56
57void populate_start(std::shared_ptr<adc::builder_api> b, adc::factory & f) {
58
59 // define the 'application' tag
60 b->add_header_section("cxx_demo_1");
61
62 // report lots of hardware context information
63 b->add_host_section(ADC_HS_ALL);
64
65 // report host memory at start
66 b->add_memory_usage_section();
67
68 // create a customized section for application specific data
69 // in this case, mpi is reported.
70 std::shared_ptr< adc::builder_api > app_data = f.get_builder();
71 //
72 // include customized section in parent data object 'b'
73 app_data->add("foo","bar");
74 b->add_app_data_section(app_data);
75
76 // likewise, create a tailored 'version' section
77 // include mpi/ompi version details
78 std::shared_ptr< adc::builder_api > version = f.get_builder();
79 version->add("version", "1.1.3");
80 const char* tags[] = { "boca_raton", "saronida_2"};
81 version->add_array("tags", tags, 2);
82 version->add("mesh_version", "5.0.0");
83
84 std::vector<std::string> children = { "uuid1", "uuid2", "uuid3"};
85 b->add_workflow_section();
86 b->add_workflow_children(children);
87
88 void *commptr = NULL;
89#ifdef ADC_HAVE_MPI
90 MPI_Comm comm = MPI_COMM_WORLD;
91 commptr = &comm;
92#endif
93 // b->add_mpi_section("world", commptr, ADC_MPI_LOCAL); // use this version if only calling on rank 0
94 b->add_mpi_section("world", commptr, ADC_MPI_ALL); // use this version if calling on all ranks
95
96 // likewise create a section about model parameters.
97 // might including method, material names, mesh/particle domain names/sizes, etc
98 // in hierarchical object summaries
99 std::shared_ptr< adc::builder_api > model_data = f.get_builder();
100 model_data->add("nx", 3);
101 model_data->add("ny", 10);
102 model_data->add("step", 0);
103 b->add_model_data_section(model_data);
104
105}
106
107void populate_progress(std::shared_ptr<adc::builder_api> b, adc::factory & f) {
108
109 b->add_header_section("cxx_demo_1");
110 // include just the hostname for matching the start event
111 b->add_host_section(ADC_HS_BASE);
112
113 // add app_data with some misc data
114 std::shared_ptr< adc::builder_api > app_data = f.get_builder();
115
116 void *commptr = NULL;
117#ifdef ADC_HAVE_MPI
118 MPI_Comm comm = MPI_COMM_WORLD;
119 commptr = &comm;
120#endif
121 b->add_mpi_section("world", commptr, ADC_MPI_RANK);
122
123 float x[3] = { 3,2,1 };
124 app_data->add_array("direction", x, 3);
125 app_data->add("foo", 12);
126 app_data->add("bar", 2.5);
127 app_data->add_array("direction_set", x, 3, "set");
128 b->add_app_data_section(app_data);
129
130 // add the progress status
131 std::shared_ptr< adc::builder_api > progress_details = f.get_builder();
132 progress_details->add("step", 100);
133 b->add_model_data_section(progress_details);
134
135}
136
137void populate_end(std::shared_ptr<adc::builder_api> b, adc::factory & f) {
138
139 b->add_header_section("cxx_demo_1");
140 // include just the hostname for matching the start event
141 b->add_host_section(ADC_HS_BASE);
142 b->add_memory_usage_section();
143
144 // add app_data with the mpi rank for matching
145 std::shared_ptr< adc::builder_api > app_data = f.get_builder();
146 void *commptr = NULL;
147#ifdef ADC_HAVE_MPI
148 MPI_Comm comm = MPI_COMM_WORLD;
149 commptr = &comm;
150#endif
151 app_data->add_mpi_section("world", commptr, ADC_MPI_RANK | ADC_MPI_SIZE);
152 app_data->add_gitlab_ci_section();
153 b->add_app_data_section(app_data);
154
155 // add the exit status
156 std::shared_ptr< adc::builder_api > exit_details = f.get_builder();
157 exit_details->add("tmax", 15000.25);
158 exit_details->add("tmax_loc", 10325);
159 exit_details->add("step", 234);
160 b->add_exit_data_section(1, "we didn't succeed due to high temperatures", exit_details);
161
162}
163
164#ifdef ADC_HAVE_MPI
165int main(int argc, char **argv)
166{
167 MPI_Init(&argc, &argv);
168#else
169int main(int , char **)
170{
171#endif
172
173 // do something, probably parse input, load mesh, etc
174
175 adc::factory f;
176#if DEBUG
177 std::shared_ptr< adc::publisher_api > p = f.get_publisher("stdout");
178 int pub_err = start_publisher(p, null_config);
179#else
180 std::shared_ptr< adc::publisher_api > p = f.get_publisher("ldmsd_stream_publish");
182#endif
183
184 std::cout << "DUMP initial config of model, hardware, etc" << std::endl;
185 if (!pub_err) {
186 std::shared_ptr< adc::builder_api > b_init = f.get_builder();
187 populate_start(b_init, f);
188 int msg_err = p->publish(b_init);
189 if (msg_err) {
190 std::cout << "publish initial model info failed " <<
191 std::strerror(msg_err) << std::endl;
192 }
193 }
194
195 sleep(2);
196 // do something, probably a main loop
197 // ...
198 std::cout << "DUMP some progress" << std::endl;
199 // can at some frequency create and publish a progress report
200 // in machine readable form.
201 if (!pub_err) {
202 std::shared_ptr< adc::builder_api > b_progress = f.get_builder();
203 populate_progress(b_progress, f);
204 int msg_err = p->publish(b_progress);
205 if (msg_err) {
206 std::cout << "publish progress info failed " <<
207 std::strerror(msg_err) << std::endl;
208 }
209 }
210
211 sleep(2);
212 std::cout << "DUMP result" << std::endl;
213 // report final results
214 if (!pub_err) {
215 std::shared_ptr< adc::builder_api > b_final = f.get_builder();
216 populate_end(b_final, f);
217 int msg_err = p->publish(b_final);
218 if (msg_err) {
219 std::cout << "publish final status info failed " <<
220 std::strerror(msg_err) << std::endl;
221 }
222 }
223
224 p->finalize();
225
226#ifdef ADC_HAVE_MPI
227 MPI_Finalize();
228#endif
229 return 0;
230}
provides publishers and builders of application metadata.
Definition factory.hpp:34
std::shared_ptr< publisher_api > get_publisher(const std::string &name)
Definition factory.ipp:178
std::shared_ptr< builder_api > get_builder()
Definition factory.ipp:300
#define ADC_HS_BASE
ADC_HS_BASE collects just the hostname via gethostname()
Definition builder.hpp:51
#define ADC_HS_ALL
all ADC_HS_* optional data included
Definition builder.hpp:73
#define ADC_MPI_RANK
include "mpi_rank" field from mpi_comm_rank
Definition builder.hpp:93
#define ADC_MPI_ALL
include all mpi options. If this value is used, then the call to add_mpi must be collective.
Definition builder.hpp:121
#define ADC_MPI_SIZE
include "mpi_size" field from mpi_comm_size
Definition builder.hpp:96
void populate_start(std::shared_ptr< adc::builder_api > b, adc::factory &f)
int start_publisher(std::shared_ptr< adc::publisher_api > pi, std::map< std::string, std::string > &pconfig)
int main(int, char **)
void populate_progress(std::shared_ptr< adc::builder_api > b, adc::factory &f)
void populate_end(std::shared_ptr< adc::builder_api > b, adc::factory &f)
std::map< std::string, std::string > ldmsd_stream_publish_config
std::map< std::string, std::string > file_config
std::map< std::string, std::string > null_config