sched,nr: redesign sched nr ue object creation during rach. Update of sched nr tests to reflect this change

master
Francisco 3 years ago committed by Francisco Paisana
parent 7f200ac7f7
commit 822a1f5d19

@ -42,7 +42,7 @@ public:
void ue_cfg(uint16_t rnti, const ue_cfg_t& cfg) override;
void ue_rem(uint16_t rnti) override;
int dl_rach_info(const rar_info_t& rar_info, const ue_cfg_t& uecfg);
int dl_rach_info(const rar_info_t& rar_info);
void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) override;
void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) override;

@ -109,13 +109,14 @@ public:
////// RA signalling //////
struct rar_info_t {
uint32_t preamble_idx; // is this the RAPID?
uint32_t msg3_size = 7;
uint32_t cc;
uint16_t temp_crnti;
slot_point prach_slot;
uint32_t ofdm_symbol_idx;
uint32_t freq_idx;
uint32_t preamble_idx;
uint32_t ta_cmd;
uint16_t temp_crnti;
uint32_t msg3_size = 7;
slot_point prach_slot;
};
struct msg3_grant_t {
rar_info_t data;

@ -119,7 +119,8 @@ private:
class ue
{
public:
ue(uint16_t rnti, const sched_nr_ue_cfg_t& cfg, const sched_params_t& sched_cfg_);
ue(uint16_t rnti, uint32_t cc, const sched_params_t& sched_cfg_);
ue(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, const sched_params_t& sched_cfg_);
void new_slot(slot_point pdcch_slot);

@ -347,12 +347,13 @@ void mac_nr::rach_detected(const rach_info_t& rach_info)
// Trigger scheduler RACH
srsenb::sched_nr_interface::rar_info_t rar_info = {};
rar_info.cc = enb_cc_idx;
rar_info.preamble_idx = rach_info.preamble;
rar_info.temp_crnti = rnti;
rar_info.ta_cmd = rach_info.time_adv;
rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index};
// TODO: fill remaining fields as required
sched->dl_rach_info(rar_info, uecfg);
sched->dl_rach_info(rar_info);
rrc->add_user(rnti, uecfg);
logger.info("RACH: slot=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x",

@ -342,7 +342,7 @@ int sched_nr::add_ue_impl(uint16_t rnti, std::unique_ptr<sched_nr_impl::ue> u)
int sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg)
{
if (not ue_db.contains(rnti)) {
return add_ue_impl(rnti, std::unique_ptr<ue>(new ue{rnti, uecfg, cfg}));
return add_ue_impl(rnti, std::make_unique<ue>(rnti, uecfg, cfg));
}
ue_db[rnti]->set_cfg(uecfg);
return SRSRAN_SUCCESS;
@ -413,25 +413,24 @@ void sched_nr::get_metrics(mac_metrics_t& metrics)
metrics_handler->get_metrics(metrics);
}
int sched_nr::dl_rach_info(const rar_info_t& rar_info, const ue_cfg_t& uecfg)
int sched_nr::dl_rach_info(const rar_info_t& rar_info)
{
// enqueue UE creation event + RACH handling
auto add_ue = [this, uecfg, rar_info](event_manager::logger& ev_logger) {
// create user
// Note: UEs being created in sched main thread, which has higher priority
std::unique_ptr<ue> u{new ue{rar_info.temp_crnti, uecfg, cfg}};
// create user object outside of sched main thread
std::unique_ptr<ue> u = std::make_unique<ue>(rar_info.temp_crnti, rar_info.cc, cfg);
// enqueue UE creation event + RACH handling
auto add_ue = [this, rar_info, u = std::move(u)](event_manager::logger& ev_logger) mutable {
uint16_t rnti = rar_info.temp_crnti;
if (add_ue_impl(rnti, std::move(u)) == SRSRAN_SUCCESS) {
ev_logger.push("dl_rach_info(temp c-rnti=0x{:x})", rar_info.temp_crnti);
// RACH is handled only once the UE object is created and inserted in the ue_db
uint32_t cc = uecfg.carriers[0].cc;
uint32_t cc = rar_info.cc;
cc_workers[cc]->dl_rach_info(rar_info);
} else {
logger->warning("Failed to create UE object with rnti=0x%x", rar_info.temp_crnti);
}
};
pending_events->enqueue_event("dl_rach_info", add_ue);
pending_events->enqueue_event("dl_rach_info", std::move(add_ue));
return SRSRAN_SUCCESS;
}

@ -129,13 +129,27 @@ int ue_carrier::ul_crc_info(uint32_t pid, bool crc)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ue::ue(uint16_t rnti_, const sched_nr_ue_cfg_t& cfg, const sched_params_t& sched_cfg_) :
sched_nr_ue_cfg_t get_rach_ue_cfg(uint32_t cc, const sched_params_t& sched_params)
{
sched_nr_ue_cfg_t uecfg = {};
uecfg.carriers.resize(1);
uecfg.carriers[0].active = true;
uecfg.carriers[0].cc = cc;
uecfg.phy_cfg = sched_params.cells[cc].default_ue_phy_cfg;
return uecfg;
}
ue::ue(uint16_t rnti_, uint32_t cc, const sched_params_t& sched_cfg_) :
ue(rnti_, get_rach_ue_cfg(cc, sched_cfg_), sched_cfg_)
{}
ue::ue(uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg, const sched_params_t& sched_cfg_) :
rnti(rnti_),
sched_cfg(sched_cfg_),
buffers(rnti_, srslog::fetch_basic_logger(sched_cfg_.sched_cfg.logger_name)),
ue_cfg(0)
ue_cfg(uecfg.carriers[0].cc)
{
set_cfg(cfg);
set_cfg(uecfg);
}
void ue::set_cfg(const sched_nr_ue_cfg_t& cfg)
@ -144,11 +158,11 @@ void ue::set_cfg(const sched_nr_ue_cfg_t& cfg)
for (auto& ue_cc_cfg : cfg.carriers) {
if (ue_cc_cfg.active) {
if (carriers[ue_cc_cfg.cc] == nullptr) {
carriers[ue_cc_cfg.cc].reset(new ue_carrier(rnti,
ue_cfg,
sched_cfg.cells[ue_cc_cfg.cc],
common_ctxt,
ue_buffer_manager::pdu_builder{ue_cc_cfg.cc, buffers}));
carriers[ue_cc_cfg.cc] = std::make_unique<ue_carrier>(rnti,
ue_cfg,
sched_cfg.cells[ue_cc_cfg.cc],
common_ctxt,
ue_buffer_manager::pdu_builder{ue_cc_cfg.cc, buffers});
} else {
carriers[ue_cc_cfg.cc]->set_cfg(ue_cfg);
}

@ -89,14 +89,15 @@ void run_sched_nr_test(uint32_t nof_workers)
uecfg.lc_ch_to_add.emplace_back();
uecfg.lc_ch_to_add.back().lcid = 1;
uecfg.lc_ch_to_add.back().cfg.direction = mac_lc_ch_cfg_t::BOTH;
tester.add_user(rnti, uecfg, slot_rx, 0);
tester.user_cfg(rnti, uecfg);
}
tester.run_slot(slot_tx);
}
tester.stop();
tester.print_results();
// TESTASSERT(tasks.pdsch_count == (int)(max_nof_ttis * nof_sectors * 0.6));
TESTASSERT(tester.pdsch_count > 0);
// TESTASSERT(tester.pdsch_count == (int)(max_nof_ttis * nof_sectors * 0.6));
double final_avg_usec = tester.tot_latency_sched_ns;
final_avg_usec = final_avg_usec / 1000.0 / max_nof_ttis;

@ -18,16 +18,12 @@
namespace srsenb {
sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_,
const sched_nr_ue_cfg_t& ue_cfg_,
slot_point prach_slot_rx,
uint32_t preamble_idx) :
sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_, const sched_nr_ue_cfg_t& ue_cfg_) :
logger(srslog::fetch_basic_logger("MAC"))
{
ctxt.rnti = rnti_;
ctxt.prach_slot_rx = prach_slot_rx;
ctxt.preamble_idx = preamble_idx;
ctxt.rnti = rnti_;
ctxt.ue_cfg.apply_config_request(ue_cfg_);
ctxt.preamble_idx = -1;
ctxt.cc_list.resize(ue_cfg_.carriers.size());
for (auto& cc : ctxt.cc_list) {
@ -38,6 +34,16 @@ sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_,
}
}
sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_,
const sched_nr_ue_cfg_t& ue_cfg_,
slot_point prach_slot_rx,
uint32_t preamble_idx) :
sched_nr_ue_sim(rnti_, ue_cfg_)
{
ctxt.prach_slot_rx = prach_slot_rx;
ctxt.preamble_idx = preamble_idx;
}
int sched_nr_ue_sim::update(const sched_nr_cc_result_view& cc_out)
{
update_dl_harqs(cc_out);
@ -202,35 +208,51 @@ void sched_nr_base_test_bench::stop()
}
}
int sched_nr_base_test_bench::add_user(uint16_t rnti,
const sched_nr_interface::ue_cfg_t& ue_cfg_,
slot_point tti_rx,
uint32_t preamble_idx)
srsran::const_span<sched_nr_base_test_bench::cc_result_t> sched_nr_base_test_bench::get_slot_results() const
{
sem_wait(&slot_sem);
auto ret = cc_results;
sem_post(&slot_sem);
return ret;
}
TESTASSERT(ue_db.count(rnti) == 0);
int sched_nr_base_test_bench::rach_ind(uint16_t rnti, uint32_t cc, slot_point tti_rx, uint32_t preamble_idx)
{
sem_wait(&slot_sem);
ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, ue_cfg_, current_slot_tx, preamble_idx)));
TESTASSERT(ue_db.count(rnti) == 0);
sched_nr_interface::rar_info_t rach_info{};
rach_info.cc = cc;
rach_info.temp_crnti = rnti;
rach_info.prach_slot = tti_rx;
rach_info.preamble_idx = preamble_idx;
rach_info.msg3_size = 7;
sched_ptr->dl_rach_info(rach_info, ue_cfg_);
sched_ptr->dl_rach_info(rach_info);
sem_post(&slot_sem);
sched_nr_ue_cfg_t uecfg;
uecfg.carriers.resize(1);
uecfg.carriers[0].active = true;
uecfg.carriers[0].cc = cc;
uecfg.phy_cfg = cell_params[cc].default_ue_phy_cfg;
ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, uecfg, current_slot_tx, preamble_idx)));
sem_post(&slot_sem);
return SRSRAN_SUCCESS;
}
void sched_nr_base_test_bench::user_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_)
{
TESTASSERT(ue_db.count(rnti) > 0);
sem_wait(&slot_sem);
ue_db.at(rnti).get_ctxt().ue_cfg.apply_config_request(ue_cfg_);
if (ue_db.count(rnti) == 0) {
ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, ue_cfg_)));
} else {
ue_db.at(rnti).get_ctxt().ue_cfg.apply_config_request(ue_cfg_);
}
sched_ptr->ue_cfg(rnti, ue_cfg_);
sem_post(&slot_sem);
}
void sched_nr_base_test_bench::add_rlc_dl_bytes(uint16_t rnti, uint32_t lcid, uint32_t pdu_size_bytes)

@ -89,6 +89,7 @@ struct sim_nr_enb_ctxt_t {
class sched_nr_ue_sim
{
public:
sched_nr_ue_sim(uint16_t rnti_, const sched_nr_ue_cfg_t& ue_cfg_);
sched_nr_ue_sim(uint16_t rnti_, const sched_nr_ue_cfg_t& ue_cfg_, slot_point prach_slot_rx, uint32_t preamble_idx);
int update(const sched_nr_cc_result_view& cc_out);
@ -123,13 +124,16 @@ public:
slot_point get_slot_tx() const { return current_slot_tx; }
int add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_, slot_point tti_rx, uint32_t preamble_idx);
/// may block waiting for scheduler to finish generating slot result
srsran::const_span<cc_result_t> get_slot_results() const;
int rach_ind(uint16_t rnti, uint32_t cc, slot_point tti_rx, uint32_t preamble_idx);
void user_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_);
void add_rlc_dl_bytes(uint16_t rnti, uint32_t lcid, uint32_t pdu_size_bytes);
srsran::const_span<sched_nr_impl::cell_params_t> get_cell_params() { return cell_params; }
srsran::const_span<sched_nr_impl::cell_params_t> get_cell_params() const { return cell_params; }
/**
* @brief Specify external events that will be forwarded to the scheduler (CQI, ACKs, etc.) in the given slot

@ -14,15 +14,20 @@
#include "sched_nr_sim_ue.h"
#include "srsran/common/phy_cfg_nr_default.h"
#include "srsran/common/test_common.h"
#include "srsran/support/emergency_handlers.h"
#include <boost/program_options.hpp>
#include <fstream>
#include <random>
// shorten boost program options namespace
namespace bpo = boost::program_options;
namespace srsenb {
std::default_random_engine rand_gen;
struct sim_args_t {
uint32_t rand_seed;
uint32_t fixed_cqi;
std::string mac_log_level;
std::string test_log_level;
@ -98,7 +103,7 @@ struct sched_event_t {
sched_event_t add_user(uint32_t slot_count, uint16_t rnti, uint32_t preamble_idx)
{
auto task = [rnti, preamble_idx](sched_nr_base_test_bench& tester) {
tester.add_user(rnti, get_rach_ue_cfg(0), tester.get_slot_tx() - TX_ENB_DELAY, preamble_idx);
tester.rach_ind(rnti, 0, tester.get_slot_tx() - TX_ENB_DELAY, preamble_idx);
};
return sched_event_t{slot_count, task};
}
@ -160,9 +165,10 @@ void test_sched_nr_no_data(sim_args_t args)
void test_sched_nr_data(sim_args_t args)
{
uint32_t max_nof_ttis = 1000, nof_sectors = 1;
uint16_t rnti = 0x4601;
uint32_t nof_dl_bytes_to_tx = 2e6;
uint32_t max_nof_ttis = 100000, nof_sectors = 1;
uint16_t rnti = 0x4601;
uint32_t nof_dl_bytes_to_tx =
std::uniform_int_distribution<int>{0, 9}(rand_gen)*pow(10, std::uniform_int_distribution<int>{1, 7}(rand_gen));
sched_nr_interface::sched_args_t cfg;
cfg.auto_refill_buffer = false;
@ -179,7 +185,10 @@ void test_sched_nr_data(sim_args_t args)
events.push_back(add_rlc_dl_bytes(50, rnti, 0, nof_dl_bytes_to_tx));
/* Run Test */
for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) {
auto finish_condition = [max_nof_ttis, rnti, nof_dl_bytes_to_tx, &tester](uint32_t nof_slots) {
return nof_slots >= max_nof_ttis or tester.ue_metrics[rnti].nof_dl_bytes > nof_dl_bytes_to_tx;
};
for (uint32_t nof_slots = 0; not finish_condition(nof_slots); ++nof_slots) {
slot_point slot_rx(0, nof_slots % 10240);
slot_point slot_tx = slot_rx + TX_ENB_DELAY;
@ -192,7 +201,17 @@ void test_sched_nr_data(sim_args_t args)
// call sched
tester.run_slot(slot_tx);
}
// Run a few extra slots to ensure the scheduler does not allocate more DL bytes than necessary
for (uint32_t nof_slots_extra = 0; nof_slots_extra < 40; ++nof_slots_extra) {
tester.run_slot(tester.get_slot_tx() + 1);
auto results = tester.get_slot_results();
TESTASSERT(results[0].res.dl->phy.pdcch_dl.empty());
TESTASSERT(results[0].res.dl->phy.pdcch_ul.empty());
}
srslog::flush();
fmt::print("== Results ==\n");
fmt::print("Enqueued RLC DL bytes: {}\n", nof_dl_bytes_to_tx);
tester.print_results();
TESTASSERT(tester.ue_metrics[rnti].nof_dl_txs > 1);
@ -212,6 +231,7 @@ sim_args_t handle_args(int argc, char** argv)
// clang-format off
options_sim.add_options()
("seed", bpo::value<uint32_t>(&args.rand_seed)->default_value(std::chrono::system_clock::now().time_since_epoch().count()), "Simulation Random Seed")
("cqi", bpo::value<uint32_t>(&args.fixed_cqi)->default_value(15), "UE DL CQI")
("log.mac_level", bpo::value<std::string>(&args.mac_log_level)->default_value("info"), "MAC log level")
("log.test_level", bpo::value<std::string>(&args.test_log_level)->default_value("info"), "TEST log level")
@ -268,8 +288,13 @@ sim_args_t handle_args(int argc, char** argv)
int main(int argc, char** argv)
{
// Start the log backend.
srslog::init();
// Parse args
srsenb::sim_args_t args = srsenb::handle_args(argc, argv);
// Initialize Loggers
auto& test_logger = srslog::fetch_basic_logger("TEST");
test_logger.set_level(srslog::str_to_basic_level(args.test_log_level));
auto& mac_nr_logger = srslog::fetch_basic_logger("MAC-NR");
@ -277,9 +302,18 @@ int main(int argc, char** argv)
auto& pool_logger = srslog::fetch_basic_logger("POOL");
pool_logger.set_level(srslog::basic_levels::debug);
// Start the log backend.
srslog::init();
// Setup Random Generator
srsenb::rand_gen = std::default_random_engine(args.rand_seed);
fmt::print("TEST: Random Seed is {}", args.rand_seed);
add_emergency_cleanup_handler(
[](void* args_void) {
auto* args = (srsenb::sim_args_t*)args_void;
fmt::print("TEST: Random Seed was {}", args->rand_seed);
},
(void*)&args);
srsenb::test_sched_nr_no_data(args);
srsenb::test_sched_nr_data(args);
fmt::print("TEST: Random Seed was {}", args.rand_seed);
}

Loading…
Cancel
Save