| 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(®ion, 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 |