Commit 471df044 authored by Noemi Giustini's avatar Noemi Giustini

Add CARR.PUSCHMCSDist metric

Implement CARR.PUSCHMCSDist (3GPP TS 28.552 §5.1.1.12.2): uplink
counterpart of CARR.PDSCHMCSDist; PRB-weighted 3D histogram over
(rank, MCS-table, MCS-index) for PUSCH transmissions.

PUSCH may use MCS tables 0 (64-QAM), 1 (256-QAM) and 3 (SC-FDMA), so the
MCS-table dimension is indexed directly by current_BWP->mcs_table and
sized to 4 (index 2 unused). Remapping the tables into fewer bins would
lose the 64-QAM/256-QAM distinction, so no remapping is applied.

- ran_func_kpm.c: register CARR.PUSCHMCSDist in the RAN Function
  Definition advertisement (kpm_node_meas_* lists).
- ran_func_kpm_subs.c: add fill_CARR_PUSCHMCSDist(); distBinX (rank) is
  1-based on the wire and converted to a 0-based index, while distBinY
  (MCS table, values 0/1/3) and distBinZ (MCS index) are 0-based and used
  directly, returning du_stats->pusch_mcs_dist[rank-1][table][mcs]; add
  dispatch entry to lst_measure[].
- nr_mac_gNB.h: the pusch_mcs_dist histogram was sized [8][2][32], too
  small for MCS table 3 (SC-FDMA) and thus overflowing at collection time;
  size the MCS-table dimension to 4 via NR_KPM_NB_MCS_TABLE_UL to hold
  tables 0, 1, 3.
- gNB_scheduler_ulsch.c: the UL collection into pusch_mcs_dist already
  exists; align its surrounding DevAsserts with the KPM dimension macros
  (NR_KPM_MAX_LAYERS, NR_KPM_NB_MCS).

Carried as E2SM-KPM Style 1 / Format 1 with distBinX/Y/Z labels.
Advertised by DU and monolithic gNB node types.
Signed-off-by: default avatarNoemi Giustini <giustini.n@northeastern.edu>
parent 23ef597c
...@@ -440,11 +440,13 @@ bool read_kpm_sm(void* data) ...@@ -440,11 +440,13 @@ bool read_kpm_sm(void* data)
static const char* kpm_node_meas_du[] = { static const char* kpm_node_meas_du[] = {
"CARR.PDSCHMCSDist", "CARR.PDSCHMCSDist",
"CARR.PUSCHMCSDist",
NULL, NULL,
}; };
static const char* kpm_node_meas_gnb[] = { static const char* kpm_node_meas_gnb[] = {
"CARR.PDSCHMCSDist", "CARR.PDSCHMCSDist",
"CARR.PUSCHMCSDist",
NULL, NULL,
}; };
......
...@@ -244,6 +244,39 @@ static meas_record_lst_t fill_CARR_PDSCHMCSDist(const label_info_lst_t label, ...@@ -244,6 +244,39 @@ static meas_record_lst_t fill_CARR_PDSCHMCSDist(const label_info_lst_t label,
meas_record.int_val = du_stats->pdsch_mcs_dist[bin_x - 1][bin_y - 1][bin_z]; meas_record.int_val = du_stats->pdsch_mcs_dist[bin_x - 1][bin_y - 1][bin_z];
return meas_record; return meas_record;
} }
/* CARR.PUSCHMCSDist — 3GPP TS 28.552 - section 5.1.1.12.2 */
static meas_record_lst_t fill_CARR_PUSCHMCSDist(const label_info_lst_t label,
__attribute__((unused)) uint32_t gran_period_ms,
__attribute__((unused)) cudu_ue_info_pair_t ue_info,
__attribute__((unused)) const size_t ue_idx,
__attribute__((unused))e2_node_level_stats_t* node_stats)
{
meas_record_lst_t meas_record = {0};
if (label.distBinX == NULL || label.distBinY == NULL || label.distBinZ == NULL) {
printf("[E2 AGENT][E2SM-KPM] CARR.PUSCHMCSDist requested without distBinX/Y/Z labels; "
"TS 28.552 5.1.1.12.2 defines no aggregate value, reporting NO_VALUE\n");
meas_record.value = NO_VALUE_MEAS_VALUE;
return meas_record;
}
const uint32_t bin_x = *label.distBinX;
const uint32_t bin_y = *label.distBinY;
const uint32_t bin_z = *label.distBinZ;
if (bin_x < 1 || bin_x > NR_KPM_MAX_LAYERS || bin_y > NR_KPM_NB_MCS_TABLE_UL - 1 || bin_z > NR_KPM_NB_MCS - 1) {
printf("[E2 AGENT][E2SM-KPM] CARR.PUSCHMCSDist: bin out of range (X=%u Y=%u Z=%u), reporting NO_VALUE\n",
bin_x, bin_y, bin_z);
meas_record.value = NO_VALUE_MEAS_VALUE;
return meas_record;
}
const NR_du_stats_t* du_stats = &RC.nrmac[0]->du_stats;
meas_record.value = INTEGER_MEAS_VALUE;
meas_record.int_val = du_stats->pusch_mcs_dist[bin_x - 1][bin_y][bin_z];
return meas_record;
}
#endif #endif
static kv_measure_t lst_measure[] = { static kv_measure_t lst_measure[] = {
...@@ -256,6 +289,7 @@ static kv_measure_t lst_measure[] = { ...@@ -256,6 +289,7 @@ static kv_measure_t lst_measure[] = {
{.key = "RRU.PrbTotDl", .value = fill_RRU_PrbTotDl }, {.key = "RRU.PrbTotDl", .value = fill_RRU_PrbTotDl },
{.key = "RRU.PrbTotUl", .value = fill_RRU_PrbTotUl }, {.key = "RRU.PrbTotUl", .value = fill_RRU_PrbTotUl },
{.key = "CARR.PDSCHMCSDist", .value = fill_CARR_PDSCHMCSDist }, {.key = "CARR.PDSCHMCSDist", .value = fill_CARR_PDSCHMCSDist },
{.key = "CARR.PUSCHMCSDist", .value = fill_CARR_PUSCHMCSDist },
#endif #endif
}; };
......
...@@ -102,6 +102,7 @@ From 3GPP TS 28.552, we support the following list: ...@@ -102,6 +102,7 @@ From 3GPP TS 28.552, we support the following list:
* `RRU.PrbTotDl` * `RRU.PrbTotDl`
* `RRU.PrbTotUl` * `RRU.PrbTotUl`
* `CARR.PDSCHMCSDist` * `CARR.PDSCHMCSDist`
* `CARR.PUSCHMCSDist`
From `O-RAN.WG3.E2SM-KPM-version` specification, we implemented: From `O-RAN.WG3.E2SM-KPM-version` specification, we implemented:
* REPORT Service Style 4 ("Common condition-based, UE-level" - section 7.4.5) - fetch above measurements per each UE based on the common S-NSSAI `(1, 0xffffff)` condition * REPORT Service Style 4 ("Common condition-based, UE-level" - section 7.4.5) - fetch above measurements per each UE based on the common S-NSSAI `(1, 0xffffff)` condition
......
...@@ -2201,9 +2201,9 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, ...@@ -2201,9 +2201,9 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac,
T(T_GNB_MAC_UL, T_INT(UE->rnti), T_INT(frame), T_INT(slot), T_INT(sched_pusch->mcs), T_INT(sched_pusch->tb_size)); T(T_GNB_MAC_UL, T_INT(UE->rnti), T_INT(frame), T_INT(slot), T_INT(sched_pusch->mcs), T_INT(sched_pusch->tb_size));
DevAssert(sched_pusch->nrOfLayers >= 1 && sched_pusch->nrOfLayers <= 8); DevAssert(sched_pusch->nrOfLayers >= 1 && sched_pusch->nrOfLayers <= NR_KPM_MAX_LAYERS);
DevAssert(current_BWP->mcs_table == 0 || current_BWP->mcs_table == 1 || current_BWP->mcs_table == 3); DevAssert(current_BWP->mcs_table == 0 || current_BWP->mcs_table == 1 || current_BWP->mcs_table == 3);
DevAssert(sched_pusch->mcs >= 0 && sched_pusch->mcs <= 31); DevAssert(sched_pusch->mcs < NR_KPM_NB_MCS);
NR_du_stats_t *stats = &nr_mac->du_stats; NR_du_stats_t *stats = &nr_mac->du_stats;
stats->pusch_mcs_dist[sched_pusch->nrOfLayers - 1][current_BWP->mcs_table][sched_pusch->mcs] += sched_pusch->rbSize; stats->pusch_mcs_dist[sched_pusch->nrOfLayers - 1][current_BWP->mcs_table][sched_pusch->mcs] += sched_pusch->rbSize;
......
...@@ -1142,6 +1142,7 @@ typedef struct { ...@@ -1142,6 +1142,7 @@ typedef struct {
/* Dimensions of the per-cell MCS distribution histograms (3GPP TS 28.552 §5.1.1.12). */ /* Dimensions of the per-cell MCS distribution histograms (3GPP TS 28.552 §5.1.1.12). */
#define NR_KPM_MAX_LAYERS 8 /* RI: 1..8 */ #define NR_KPM_MAX_LAYERS 8 /* RI: 1..8 */
#define NR_KPM_NB_MCS_TABLE_DL 3 /* PDSCH MCS tables: 1..3 */ #define NR_KPM_NB_MCS_TABLE_DL 3 /* PDSCH MCS tables: 1..3 */
#define NR_KPM_NB_MCS_TABLE_UL 4 /* PUSCH MCS tables: 0, 1, 3 */
#define NR_KPM_NB_MCS 32 /* MCS index: 0..31 */ #define NR_KPM_NB_MCS 32 /* MCS index: 0..31 */
typedef struct NR_du_stats { typedef struct NR_du_stats {
...@@ -1154,8 +1155,8 @@ typedef struct NR_du_stats { ...@@ -1154,8 +1155,8 @@ typedef struct NR_du_stats {
uint32_t pdsch_mcs_dist[NR_KPM_MAX_LAYERS][NR_KPM_NB_MCS_TABLE_DL][NR_KPM_NB_MCS]; uint32_t pdsch_mcs_dist[NR_KPM_MAX_LAYERS][NR_KPM_NB_MCS_TABLE_DL][NR_KPM_NB_MCS];
/// cell-wide MCS distribution in PUSCH, see 28.552 5.1.1.12.1 /// cell-wide MCS distribution in PUSCH, see 28.552 5.1.1.12.1
/// 1-8 RI, 1-2 MCS table, 0-31 MCS value /// 1-8 RI, MCS table (0, 1, 3), 0-31 MCS value
uint32_t pusch_mcs_dist[8][2][32]; uint32_t pusch_mcs_dist[NR_KPM_MAX_LAYERS][NR_KPM_NB_MCS_TABLE_UL][NR_KPM_NB_MCS];
} NR_du_stats_t; } NR_du_stats_t;
/*! \brief top level eNB MAC structure */ /*! \brief top level eNB MAC structure */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment