Skip to content

Commit fddd247

Browse files
committed
phy,gnb: review metrics
phy: fix metric decorators phy: review metrics docs phy: review
1 parent a29a194 commit fddd247

18 files changed

+528
-96
lines changed

apps/units/flexible_o_du/split_helpers/metrics/flexible_o_du_metrics_consumers.cpp

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ void flexible_o_du_metrics_consumer_json::handle_metric(const app_services::metr
215215
const auto& metric_enc = odu_metrics.du.low.ldpc_metrics.encoder_metrics;
216216
double ldpc_enc_cpu_usage = 100.0 * metric_enc.cpu_usage_us / metric_period_us;
217217
ldpc_encoder.write<metric_average_cb_size>(metric_enc.avg_cb_size);
218-
ldpc_encoder.write<metric_average_latency>(metric_enc.avg_cb_latency);
218+
ldpc_encoder.write<metric_average_latency>(metric_enc.avg_cb_latency_us);
219219
ldpc_encoder.write<metric_min_latency>(metric_enc.min_cb_latency_us);
220220
ldpc_encoder.write<metric_max_latency>(metric_enc.max_cb_latency_us);
221221
ldpc_encoder.write<metric_avg_throughput_mbps>(metric_enc.encoding_rate_Mbps);
@@ -456,14 +456,22 @@ static void log_upper_phy_metrics_verbose(fmt::basic_memory_buffer<char, str_buf
456456
double pusch_wait_time_percent =
457457
validate_fp_value(100.0 * static_cast<double>(du_lo.pusch_metrics.pusch_proc_metrics.total_wait_time.count()) /
458458
static_cast<double>(du_lo.pusch_metrics.pusch_proc_metrics.total_proc_time.count()));
459+
fmt::format_to(std::back_inserter(buffer), "\n");
460+
461+
const auto& dl_processor = du_lo.dl_processor_metrics;
462+
fmt::format_to(std::back_inserter(buffer),
463+
"{:<25} max_latency={:.2f} us in slot={}\n",
464+
" DL processing:",
465+
validate_fp_value(dl_processor.max_latency_us.first),
466+
dl_processor.max_latency_us.second);
459467

460468
const auto& ldpc_encoder = du_lo.ldpc_metrics.encoder_metrics;
461469
fmt::format_to(std::back_inserter(buffer),
462470
"{:<25} avg_cb_size={:.2f} bits, avg_latency={:.2f} us, max_latency={:.2f} us, "
463471
"encode_rate={:.2f} Mbps\n",
464472
" LDPC Encoder:",
465473
validate_fp_value(ldpc_encoder.avg_cb_size),
466-
validate_fp_value(ldpc_encoder.avg_cb_latency),
474+
validate_fp_value(ldpc_encoder.avg_cb_latency_us),
467475
validate_fp_value(ldpc_encoder.max_cb_latency_us),
468476
validate_fp_value(ldpc_encoder.encoding_rate_Mbps));
469477

@@ -634,38 +642,6 @@ static void log_upper_phy_metrics_verbose(fmt::basic_memory_buffer<char, str_buf
634642
fmt::format_to(std::back_inserter(buffer), " |-> UL-SCH Demux: {:.2f} %\n", ulsch_demux_percent);
635643
fmt::format_to(
636644
std::back_inserter(buffer), " |------> Decoder: {:.2f} % (multi-threaded)\n", pusch_wait_time_percent);
637-
}
638-
639-
static void
640-
log_handle_du_low_metrics(srslog::log_channel& log_chan, const srs_du::o_du_low_metrics& du_lo, bool verbose)
641-
{
642-
if (du_lo.metrics_period == std::chrono::microseconds()) {
643-
return;
644-
}
645-
646-
fmt::basic_memory_buffer<char, str_buffer_size> buffer;
647-
fmt::format_to(std::back_inserter(buffer), "Upper PHY metrics:\n");
648-
649-
// Verbose logging.
650-
if (verbose) {
651-
log_upper_phy_metrics_verbose(buffer, du_lo);
652-
}
653-
654-
const auto& ldpc_encoder = du_lo.ldpc_metrics.encoder_metrics;
655-
const auto& ldpc_decoder = du_lo.ldpc_metrics.decoder_metrics;
656-
const auto& ldpc_rm = du_lo.ldpc_metrics.rate_match_metrics;
657-
const auto& ldpc_rdm = du_lo.ldpc_metrics.rate_dematch_metrics;
658-
const auto& crc_pdsch = du_lo.pdsch_metrics.crc_metrics;
659-
const auto& crc_pusch = du_lo.pusch_metrics.crc_metrics;
660-
const auto& prg_pdsch = du_lo.pdsch_metrics.scrambling_metrics;
661-
const auto& prg_pusch = du_lo.pusch_metrics.scrambling_metrics;
662-
const auto& pusch_demod_map = du_lo.pusch_metrics.demod_demapper_metrics;
663-
const auto& pdsch_mod = du_lo.pdsch_metrics.modulator_metrics;
664-
const auto& pdsch_dmrs = du_lo.pdsch_metrics.dmrs_metrics;
665-
const auto& p = du_lo.pdsch_metrics.precoding_metrics;
666-
const auto& xform = du_lo.pusch_metrics.xform_precoder_metrics;
667-
const auto& pdsch_proc = du_lo.pdsch_metrics.pdsch_proc_metrics;
668-
const auto& pusch_proc = du_lo.pusch_metrics.pusch_proc_metrics;
669645

670646
// CPU consumption.
671647
double metric_period_us = static_cast<double>(du_lo.metrics_period.count());
@@ -711,6 +687,41 @@ log_handle_du_low_metrics(srslog::log_channel& log_chan, const srs_du::o_du_low_
711687
validate_fp_value(descramble_cpu_usage),
712688
validate_fp_value(pusch_demod_map_cpu),
713689
validate_fp_value(pusch_precode_cpu_usage));
690+
}
691+
692+
static void
693+
log_handle_du_low_metrics(srslog::log_channel& log_chan, const srs_du::o_du_low_metrics& du_lo, bool verbose)
694+
{
695+
if (du_lo.metrics_period == std::chrono::microseconds()) {
696+
return;
697+
}
698+
699+
fmt::basic_memory_buffer<char, str_buffer_size> buffer;
700+
fmt::format_to(std::back_inserter(buffer),
701+
"PHY metrics: "
702+
"dl_processing_max_latency={:.1f}us "
703+
"dl_processing_max_slot={} "
704+
"ul_processing_max_latency={:.1f}us "
705+
"ul_processing_max_slot={} "
706+
"ldpc_encoder_avg_latency={:.1f}us "
707+
"ldpc_encoder_max_latency={:.1f}us "
708+
"ldpc_decoder_avg_latency={:.1f}us "
709+
"ldp_decoder_max_latency={:.1f}us "
710+
"ldpc_decoder_avg_nof_iter={}",
711+
validate_fp_value(du_lo.dl_processor_metrics.max_latency_us.first),
712+
du_lo.dl_processor_metrics.max_latency_us.second,
713+
validate_fp_value(du_lo.pusch_metrics.pusch_proc_metrics.max_data_latency_us.first),
714+
du_lo.pusch_metrics.pusch_proc_metrics.max_data_latency_us.second,
715+
du_lo.ldpc_metrics.encoder_metrics.avg_cb_latency_us,
716+
du_lo.ldpc_metrics.encoder_metrics.max_cb_latency_us,
717+
du_lo.ldpc_metrics.decoder_metrics.avg_cb_latency_us,
718+
du_lo.ldpc_metrics.decoder_metrics.max_cb_latency_us,
719+
du_lo.ldpc_metrics.decoder_metrics.avg_nof_iterations);
720+
721+
// Verbose logging.
722+
if (verbose) {
723+
log_upper_phy_metrics_verbose(buffer, du_lo);
724+
}
714725

715726
// Flush buffer to the logger.
716727
log_chan("{}", to_c_str(buffer));

apps/units/flexible_o_du/split_helpers/metrics/flexible_o_du_metrics_consumers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct ru_metrics;
2525
class flexible_o_du_metrics_consumer_log : public app_services::metrics_consumer
2626
{
2727
public:
28-
explicit flexible_o_du_metrics_consumer_log(srslog::log_channel& log_chan_) : log_chan(log_chan_), verbose(true)
28+
explicit flexible_o_du_metrics_consumer_log(srslog::log_channel& log_chan_) : log_chan(log_chan_), verbose(false)
2929
{
3030
srsran_assert(log_chan.enabled(), "Logger log channel is not enabled");
3131
}

include/srsran/du/du_low/o_du_low_metrics.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct o_du_low_ldpc_metrics {
4444
/// Average codeblock size in bits.
4545
double avg_cb_size;
4646
/// Average codeblock latency in microseconds.
47-
double avg_cb_latency;
47+
double avg_cb_latency_us;
4848
/// Minimum codeblock latency in microseconds.
4949
double min_cb_latency_us;
5050
/// Maximum codeblock latency in microseconds.
@@ -227,7 +227,7 @@ struct o_du_low_pusch_metrics {
227227
/// Minimum data processing latency in microseconds.
228228
double min_data_latency_us;
229229
/// Maximum data processing latency in microseconds.
230-
double max_data_latency_us;
230+
std::pair<double, slot_point> max_data_latency_us;
231231
/// Average UCI processing latency in microseconds.
232232
double avg_uci_latency_us;
233233
/// Minimum UCI processing latency in microseconds.
@@ -313,12 +313,20 @@ struct o_du_low_pdsch_metrics {
313313
pdsch_processing_metrics pdsch_proc_metrics;
314314
};
315315

316+
/// Aggregates downlink processor metrics.
317+
struct o_du_low_dl_processor_metrics {
318+
double min_latency_us;
319+
double avg_latency_us;
320+
std::pair<double, slot_point> max_latency_us;
321+
};
322+
316323
/// O-RAN DU low metrics.
317324
struct o_du_low_metrics {
318-
o_du_low_ldpc_metrics ldpc_metrics;
319-
o_du_low_pusch_metrics pusch_metrics;
320-
o_du_low_pdsch_metrics pdsch_metrics;
321-
std::chrono::microseconds metrics_period;
325+
o_du_low_ldpc_metrics ldpc_metrics;
326+
o_du_low_pusch_metrics pusch_metrics;
327+
o_du_low_pdsch_metrics pdsch_metrics;
328+
o_du_low_dl_processor_metrics dl_processor_metrics;
329+
std::chrono::microseconds metrics_period;
322330
};
323331

324332
} // namespace srs_du

include/srsran/phy/metrics/phy_metrics_factories.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "srsran/phy/upper/channel_processors/pdsch/factories.h"
1616
#include "srsran/phy/upper/channel_processors/pusch/factories.h"
1717
#include "srsran/phy/upper/signal_processors/signal_processor_factories.h"
18+
#include "srsran/phy/upper/upper_phy_factories.h"
1819

1920
namespace srsran {
2021

@@ -116,4 +117,9 @@ std::shared_ptr<dmrs_pdsch_processor_factory>
116117
create_dmrs_pdsch_generator_metric_decorator_factory(std::shared_ptr<dmrs_pdsch_processor_factory> base_factory,
117118
pdsch_dmrs_generator_metric_notifier& notifier);
118119

120+
/// Creates a downlink processor metric decorator factory.
121+
std::shared_ptr<downlink_processor_factory>
122+
create_downlink_processor_generator_metric_decorator_factory(std::shared_ptr<downlink_processor_factory> base_factory,
123+
downlink_processor_metric_notifier& notifier);
124+
119125
} // namespace srsran

include/srsran/phy/metrics/phy_metrics_notifiers.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ using port_channel_estimator_metric_notifier = detail::phy_metric_notifier<po
5454
using transform_precoder_metric_notifier = detail::phy_metric_notifier<transform_precoder_metrics>;
5555
using pdsch_processor_metric_notifier = detail::phy_metric_notifier<pdsch_processor_metrics>;
5656
using pdsch_dmrs_generator_metric_notifier = detail::phy_metric_notifier<pdsch_dmrs_generator_metrics>;
57+
using downlink_processor_metric_notifier = detail::phy_metric_notifier<downlink_processor_metrics>;
5758

5859
/// Groups upper physical layer metric notifiers.
5960
class upper_phy_metrics_notifiers
@@ -81,7 +82,8 @@ class upper_phy_metrics_notifiers
8182
virtual port_channel_estimator_metric_notifier& get_pusch_port_channel_estimator_notifier() = 0;
8283
virtual transform_precoder_metric_notifier& get_pusch_transform_precoder_notifier() = 0;
8384
virtual pdsch_processor_metric_notifier& get_pdsch_processor_notifier() = 0;
84-
virtual pdsch_dmrs_generator_metric_notifier& get_pdsch_dmrs_generator() = 0;
85+
virtual pdsch_dmrs_generator_metric_notifier& get_pdsch_dmrs_generator_notifier() = 0;
86+
virtual downlink_processor_metric_notifier& get_downlink_processor_notifier() = 0;
8587
};
8688

8789
} // namespace srsran

include/srsran/phy/metrics/phy_metrics_reports.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ struct pusch_channel_estimator_metrics {
7676

7777
/// Collects PUSCH processor metrics.
7878
struct pusch_processor_metrics {
79+
/// Slot context
80+
slot_point slot;
7981
/// Codeblock size.
8082
units::bytes tbs;
8183
/// Set to true if the CRC matches.
@@ -226,4 +228,19 @@ struct pdsch_dmrs_generator_metrics {
226228
resource_usage_utils::measurements measurements;
227229
};
228230

231+
/// Collects upper PHY downlink processor metrics.
232+
struct downlink_processor_metrics {
233+
/// Slot context
234+
slot_point slot;
235+
236+
/// Elapsed time that comprises the configuration of the resource grid and the completion of PDUs.
237+
std::chrono::nanoseconds elapsed_data;
238+
/// Elapsed time between the time point in which the resource grid is configured and the time point the resource grid
239+
/// is sent over the gateway.
240+
std::chrono::nanoseconds elapsed_configure;
241+
/// Elapsed time between the time point in the downlink processor PDU queueing is completed and the time point the
242+
/// resource grid is sent over the gateway.
243+
std::chrono::nanoseconds elapsed_finish;
244+
};
245+
229246
} // namespace srsran
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
*
3+
* Copyright 2021-2025 Software Radio Systems Limited
4+
*
5+
* By using this file, you agree to the terms and conditions set
6+
* forth in the LICENSE file which can be found at the top level of
7+
* the distribution.
8+
*
9+
*/
10+
11+
#pragma once
12+
13+
#include "aggregator_helpers.h"
14+
#include "srsran/phy/metrics/phy_metrics_notifiers.h"
15+
#include "srsran/phy/metrics/phy_metrics_reports.h"
16+
#include <atomic>
17+
#include <utility>
18+
19+
namespace srsran {
20+
21+
/// Downlink processor metrics aggregator.
22+
class downlink_processor_metrics_aggregator : public downlink_processor_metric_notifier
23+
{
24+
public:
25+
/// Gets the average transmission latency in microseconds.
26+
double get_avg_latency_us() const
27+
{
28+
return count.load(std::memory_order_relaxed)
29+
? static_cast<double>(sum_elapsed_finish_ns) / static_cast<double>(count) * 1e-3
30+
: 0;
31+
}
32+
33+
/// Gets the minimum transmission latency in microseconds.
34+
double get_min_latency_us() const
35+
{
36+
uint64_t min_latency_ns = unpack_duration(packed_min_latency_ns);
37+
return (min_latency_ns == unpack_duration(default_packed_min_latency_ns))
38+
? 0
39+
: static_cast<double>(min_latency_ns) / 1000.0;
40+
}
41+
42+
/// Gets the maximum transmission latency in microseconds and the slot point in which was detected.
43+
std::pair<double, slot_point> get_max_latency_us() const
44+
{
45+
uint64_t packed_max_latency = packed_max_latency_ns;
46+
uint64_t max_latency_ns = unpack_duration(packed_max_latency);
47+
slot_point slot = unpack_slot(packed_max_latency);
48+
return {static_cast<double>(max_latency_ns) / 1000.0, slot};
49+
}
50+
51+
/// Resets values of all internal counters.
52+
void reset()
53+
{
54+
count = 0;
55+
sum_elapsed_data_ns = 0;
56+
sum_elapsed_configure_ns = 0;
57+
sum_elapsed_finish_ns = 0;
58+
packed_min_latency_ns = default_packed_min_latency_ns;
59+
packed_max_latency_ns = default_packed_max_latency_ns;
60+
}
61+
62+
private:
63+
static constexpr uint64_t default_packed_min_latency_ns =
64+
pack_slot_and_duration({}, std::numeric_limits<uint32_t>::max());
65+
static constexpr uint64_t default_packed_max_latency_ns =
66+
pack_slot_and_duration({}, std::numeric_limits<uint32_t>::min());
67+
68+
// See interface for documentation.
69+
void on_new_metric(const downlink_processor_metrics& metrics) override
70+
{
71+
sum_elapsed_data_ns += metrics.elapsed_data.count();
72+
sum_elapsed_configure_ns += metrics.elapsed_configure.count();
73+
sum_elapsed_finish_ns += metrics.elapsed_finish.count();
74+
update_slotmin(metrics.slot, metrics.elapsed_finish.count(), packed_min_latency_ns);
75+
update_slotmax(metrics.slot, metrics.elapsed_finish.count(), packed_max_latency_ns);
76+
++count;
77+
}
78+
79+
std::atomic<uint64_t> sum_elapsed_data_ns = {};
80+
std::atomic<uint64_t> sum_elapsed_configure_ns = {};
81+
std::atomic<uint64_t> sum_elapsed_finish_ns = {};
82+
std::atomic<uint64_t> count = {};
83+
std::atomic<uint64_t> packed_min_latency_ns = default_packed_min_latency_ns;
84+
std::atomic<uint64_t> packed_max_latency_ns = default_packed_max_latency_ns;
85+
};
86+
87+
} // namespace srsran

0 commit comments

Comments
 (0)