GCC Code Coverage Report


Directory: src/
File: src/apis/DLB_interface_talp.c
Date: 2026-09-15 07:37:49
Exec Total Coverage
Lines: 105 109 96.3%
Functions: 16 16 100.0%
Branches: 38 48 79.2%

Line Branch Exec Source
1 /*********************************************************************************/
2 /* Copyright 2009-2026 Barcelona Supercomputing Center */
3 /* */
4 /* This file is part of the DLB library. */
5 /* */
6 /* DLB is free software: you can redistribute it and/or modify */
7 /* it under the terms of the GNU Lesser General Public License as published by */
8 /* the Free Software Foundation, either version 3 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* DLB is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU Lesser General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU Lesser General Public License */
17 /* along with DLB. If not, see <https://www.gnu.org/licenses/>. */
18 /*********************************************************************************/
19
20 /* Tracking Application Live Performance */
21
22 #include "apis/dlb_talp.h"
23
24 #include "apis/dlb_errors.h"
25 #include "LB_core/spd.h"
26 #include "LB_core/thread_ctx.h"
27 #include "LB_core/DLB_kernel.h"
28 #include "LB_comm/shmem_cpuinfo.h"
29 #include "LB_comm/shmem_procinfo.h"
30 #include "LB_comm/shmem_talp.h"
31 #include "support/dlb_common.h"
32 #include "support/mask_utils.h"
33 #include "support/mytime.h"
34 #include "talp/regions.h"
35 #include "talp/sample.h"
36 #include "talp/talp.h"
37
38
39 /*********************************************************************************/
40 /* TALP */
41 /*********************************************************************************/
42
43 DLB_EXPORT_SYMBOL
44 9 int DLB_TALP_Attach(void) {
45 int lewi_color;
46 char shm_key[MAX_OPTION_LENGTH];
47 char *shm_key_ptr;
48 int shm_size_multiplier;
49 9 spd_enter_dlb(thread_spd);
50
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 if (!thread_spd->dlb_initialized) {
51 6 thread_ctx_set_observer(true);
52 6 options_parse_entry("--lewi-color", &lewi_color);
53 6 options_parse_entry("--shm-key", shm_key);
54 6 options_parse_entry("--shm-size-multiplier", &shm_size_multiplier);
55 6 shm_key_ptr = shm_key;
56 } else {
57 3 lewi_color = thread_spd->options.lewi_color;
58 3 shm_key_ptr = thread_spd->options.shm_key;
59 3 shm_size_multiplier = thread_spd->options.shm_size_multiplier;
60 }
61 9 shmem_cpuinfo_ext__init(shm_key_ptr, lewi_color);
62 9 shmem_procinfo_ext__init(shm_key_ptr, shm_size_multiplier);
63 9 shmem_talp_ext__init(shm_key_ptr, shm_size_multiplier);
64 9 return DLB_SUCCESS;
65 }
66
67 DLB_EXPORT_SYMBOL
68 9 int DLB_TALP_Detach(void) {
69 9 int error = shmem_cpuinfo_ext__finalize();
70
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 error = error ? error : shmem_procinfo_ext__finalize();
71
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 error = error ? error : shmem_talp_ext__finalize();
72 9 return error;
73 }
74
75 DLB_EXPORT_SYMBOL
76 1 int DLB_TALP_GetNumCPUs(int *ncpus) {
77 1 *ncpus = mu_get_system_count();
78 1 return DLB_SUCCESS;
79 }
80
81 DLB_EXPORT_SYMBOL
82 5 int DLB_TALP_GetPidList(int *pidlist, int *nelems, int max_len) {
83 5 return shmem_procinfo__getpidlist(pidlist, nelems, max_len);
84 }
85
86 DLB_EXPORT_SYMBOL
87 5 int DLB_TALP_GetTimes(int pid, double *mpi_time, double *useful_time) {
88
89 int error;
90
91
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
7 if (pid == 0 || (thread_spd && thread_spd->id == pid)) {
92 /* Same process */
93 2 const dlb_monitor_t *monitor = region_get_global(thread_spd);
94
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (monitor != NULL) {
95 1 *mpi_time = nsecs_to_secs(monitor->mpi_time);
96 1 *useful_time = nsecs_to_secs(monitor->useful_time);
97 1 error = DLB_SUCCESS;
98 } else {
99 1 error = DLB_ERR_NOTALP;
100 }
101 } else {
102 /* Different process, fetch from shared memory */
103 talp_region_list_t region;
104 3 error = shmem_talp__get_region(&region, pid, region_get_global_name());
105
106
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (error == DLB_SUCCESS) {
107 2 *mpi_time = nsecs_to_secs(region.mpi_time);
108 2 *useful_time = nsecs_to_secs(region.useful_time);
109 }
110 }
111
112 5 return error;
113 }
114
115 DLB_EXPORT_SYMBOL
116 4 int DLB_TALP_GetNodeTimes(const char *name, dlb_node_times_t *node_times_list,
117 int *nelems, int max_len) {
118
119 int error;
120
121
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
4 if (shmem_talp__initialized()) {
122 /* Only if a worker process started with --talp-external-profiler */
123 3 int shmem_max_regions = shmem_talp__get_max_regions();
124
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (max_len > shmem_max_regions) {
125 1 max_len = shmem_max_regions;
126 }
127
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (name == DLB_GLOBAL_REGION) {
128 3 name = region_get_global_name();
129 }
130 3 talp_region_list_t *region_list = malloc(sizeof(talp_region_list_t)*max_len);
131 3 error = shmem_talp__get_regionlist(region_list, nelems, max_len, name);
132
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (error == DLB_SUCCESS) {
133
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
8 for (int i=0; i<*nelems; ++i) {
134 5 node_times_list[i] = (const dlb_node_times_t) {
135 5 .pid = region_list[i].pid,
136 5 .mpi_time = region_list[i].mpi_time,
137 5 .useful_time = region_list[i].useful_time,
138 };
139 }
140 }
141 3 free(region_list);
142 } else {
143 /* shmem does not exist */
144 1 error = DLB_ERR_NOSHMEM;
145 }
146
147 4 return error;
148 }
149
150 DLB_EXPORT_SYMBOL
151 2 int DLB_TALP_QueryPOPNodeMetrics(const char *name, dlb_node_metrics_t *node_metrics) {
152
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (shmem_talp__initialized()) {
153 /* Only if a worker process started with --talp-external-profiler */
154 1 return talp_query_pop_node_metrics(name, node_metrics);
155 } else {
156 1 return DLB_ERR_NOSHMEM;
157 }
158 }
159
160
161 /*********************************************************************************/
162 /* TALP Monitoring Regions */
163 /*********************************************************************************/
164
165 DLB_EXPORT_SYMBOL
166 4 dlb_monitor_t* DLB_MonitoringRegionGetGlobal(void) {
167 4 spd_enter_dlb(thread_spd);
168
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (unlikely(!thread_spd->talp_info)) {
169 1 return NULL;
170 }
171 3 return region_get_global(thread_spd);
172 }
173
174 DLB_EXPORT_SYMBOL
175 DLB_ALIAS(dlb_monitor_t*, DLB_MonitoringRegionGetImplicit, (void), (), \
176 DLB_MonitoringRegionGetGlobal)
177
178 DLB_EXPORT_SYMBOL
179 DLB_ALIAS(const dlb_monitor_t*, DLB_MonitoringRegionGetMPIRegion, (void), (), \
180 DLB_MonitoringRegionGetGlobal)
181
182 DLB_EXPORT_SYMBOL
183 12 dlb_monitor_t* DLB_MonitoringRegionRegister(const char *name){
184 12 spd_enter_dlb(thread_spd);
185
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10 times.
12 if (unlikely(!thread_spd->talp_info)) {
186 2 return NULL;
187 }
188 10 return region_register(thread_spd, name);
189 }
190
191 DLB_EXPORT_SYMBOL
192 3 int DLB_MonitoringRegionReset(dlb_monitor_t *handle){
193 3 spd_enter_dlb(thread_spd);
194
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (unlikely(!thread_spd->talp_info)) {
195 2 return DLB_ERR_NOTALP;
196 }
197 1 return region_reset(thread_spd, handle);
198 }
199
200 DLB_EXPORT_SYMBOL
201 312 int DLB_MonitoringRegionStart(dlb_monitor_t *handle){
202 312 spd_enter_dlb(thread_spd);
203
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 310 times.
312 if (unlikely(!thread_spd->talp_info)) {
204 2 return DLB_ERR_NOTALP;
205 }
206 310 return region_start(thread_spd, handle);
207 }
208
209 DLB_EXPORT_SYMBOL
210 412 int DLB_MonitoringRegionStop(dlb_monitor_t *handle){
211 412 spd_enter_dlb(thread_spd);
212
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 410 times.
412 if (unlikely(!thread_spd->talp_info)) {
213 2 return DLB_ERR_NOTALP;
214 }
215 410 return region_stop(thread_spd, handle);
216 }
217
218 DLB_EXPORT_SYMBOL
219 6 int DLB_MonitoringRegionReport(const dlb_monitor_t *handle){
220 6 spd_enter_dlb(thread_spd);
221
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (unlikely(!thread_spd->talp_info)) {
222 2 return DLB_ERR_NOTALP;
223 }
224 4 return region_report(thread_spd, handle);
225 }
226
227 DLB_EXPORT_SYMBOL
228 4 int DLB_MonitoringRegionsUpdate(void) {
229 4 spd_enter_dlb(thread_spd);
230
231 4 void *talp_info = thread_spd->talp_info;
232
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (unlikely(!talp_info)) {
233 1 return DLB_ERR_NOTALP;
234 }
235
236 3 talp_sample_update(talp_info);
237 3 return talp_aggregate_samples_to_regions(talp_info);
238 }
239
240 DLB_EXPORT_SYMBOL
241 1 int DLB_TALP_CollectPOPMetrics(dlb_monitor_t *monitor, dlb_pop_metrics_t *pop_metrics) {
242 1 spd_enter_dlb(thread_spd);
243
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (unlikely(!thread_spd->talp_info)) {
244 1 return DLB_ERR_NOTALP;
245 }
246 return talp_collect_pop_metrics(thread_spd, monitor, pop_metrics);
247 }
248
249 DLB_EXPORT_SYMBOL
250 1 int DLB_TALP_CollectPOPNodeMetrics(dlb_monitor_t *monitor, dlb_node_metrics_t *node_metrics) {
251 1 spd_enter_dlb(thread_spd);
252
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (unlikely(!thread_spd->talp_info)) {
253 1 return DLB_ERR_NOTALP;
254 }
255 if (unlikely(!thread_spd->options.barrier)) {
256 return DLB_ERR_NOCOMP;
257 }
258 return talp_collect_pop_node_metrics(thread_spd, monitor, node_metrics);
259 }
260
261 DLB_EXPORT_SYMBOL
262 DLB_ALIAS(int, DLB_TALP_CollectNodeMetrics, \
263 (dlb_monitor_t *monitor, dlb_node_metrics_t *node_metrics), \
264 (monitor, node_metrics), \
265 DLB_TALP_CollectPOPNodeMetrics)
266