fix sched_dl_cqi method to compute cqi-optimal rbgmask

master
Francisco 4 years ago committed by Francisco Paisana
parent 485c6ee129
commit 8564996eaf

@ -25,6 +25,7 @@ namespace srsenb {
constexpr float tti_duration_ms = 1;
constexpr uint32_t NOF_AGGR_LEVEL = 4;
constexpr uint32_t MAX_NOF_RBGS = 25;
/***********************
* Helper Types
@ -85,7 +86,7 @@ public:
using pdcch_mask_t = srsran::bounded_bitset<sched_interface::max_cce, true>;
//! Bitmask that stores the allocared DL RBGs
using rbgmask_t = srsran::bounded_bitset<25, true>;
using rbgmask_t = srsran::bounded_bitset<MAX_NOF_RBGS, true>;
//! Bitmask that stores the allocated UL PRBs
using prbmask_t = srsran::bounded_bitset<100, true>;

@ -88,6 +88,16 @@ public:
int get_avg_cqi() const { return get_grant_avg_cqi(rbg_interval(0, cell_nof_rbg)); }
/// Get CQI of RBG
int get_rbg_cqi(uint32_t rbg) const
{
if (not subband_cqi_enabled()) {
return static_cast<int>(wb_cqi_avg);
}
uint32_t sb_idx = rbg_to_sb_index(rbg);
return bp_list[get_bp_index(sb_idx)].last_feedback_tti.is_valid() ? subband_cqi[sb_idx] : wb_cqi_avg;
}
/// Get average CQI in given RBG interval
int get_grant_avg_cqi(rbg_interval interv) const
{
@ -126,21 +136,12 @@ public:
}
/// Get CQI-optimal RBG mask
rbgmask_t get_optim_rbg_mask(uint32_t req_rbgs) const
rbgmask_t get_optim_rbgmask(uint32_t req_rbgs) const
{
req_rbgs = std::min(req_rbgs, cell_nof_rbg);
rbgmask_t mask(cell_nof_rbg);
if (not subband_cqi_enabled()) {
mask.fill(0, req_rbgs);
return mask;
}
srsran::bounded_vector<float, max_nof_subbands> sorted_cqis = subband_cqi;
std::partial_sort(sorted_cqis.begin(), sorted_cqis.begin() + req_rbgs, sorted_cqis.end());
for (uint32_t i = 0; i < req_rbgs; ++i) {
mask.set(i);
}
return mask;
rbgmask_t rbgmask(cell_nof_rbg);
return get_optim_rbgmask(rbgmask, req_rbgs);
}
rbgmask_t get_optim_rbgmask(const rbgmask_t& dl_mask, uint32_t req_rbgs) const;
/// TS 36.321, 7.2.2 - Parameter N
uint32_t nof_subbands() const { return subband_cqi.size(); }

@ -43,7 +43,7 @@ rbg_interval find_empty_rbg_interval(uint32_t max_nof_rbgs, const rbgmask_t& cur
* @param current_mask bitmask of occupied RBGs, where to search for available RBGs
* @return bitmask of found RBGs. If a valid mask wasn't found, bitmask::size() == 0
*/
rbgmask_t compute_rbgmask_greedy(uint32_t max_nof_rbgs, bool is_contiguous, const rbgmask_t& current_mask);
rbgmask_t find_available_rbgmask(uint32_t max_nof_rbgs, bool is_contiguous, const rbgmask_t& current_mask);
/**
* Finds a range of L contiguous PRBs that are empty

@ -9,7 +9,7 @@
add_subdirectory(schedulers)
set(SOURCES mac.cc ue.cc sched.cc sched_carrier.cc sched_grid.cc sched_ue_ctrl/sched_harq.cc sched_ue.cc
sched_ue_ctrl/sched_lch.cc sched_ue_ctrl/sched_ue_cell.cc sched_phy_ch/sf_cch_allocator.cc sched_phy_ch/sched_dci.cc sched_helpers.cc)
sched_ue_ctrl/sched_lch.cc sched_ue_ctrl/sched_ue_cell.cc sched_ue_ctrl/sched_dl_cqi.cc sched_phy_ch/sf_cch_allocator.cc sched_phy_ch/sched_dci.cc sched_helpers.cc)
add_library(srsenb_mac STATIC ${SOURCES} $<TARGET_OBJECTS:mac_schedulers>)
set(SOURCES mac_nr.cc)

@ -0,0 +1,46 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "srsenb/hdr/stack/mac/sched_ue_ctrl/sched_dl_cqi.h"
#include "srsenb/hdr/stack/mac/schedulers/sched_base.h"
using namespace srsenb;
rbgmask_t sched_dl_cqi::get_optim_rbgmask(const rbgmask_t& dl_mask, uint32_t req_rbgs) const
{
req_rbgs = std::min(req_rbgs, cell_nof_rbg);
if (not subband_cqi_enabled()) {
// in case of wideband, just find any available RBGs
return find_available_rbgmask(req_rbgs, false, dl_mask);
}
rbgmask_t emptymask = ~dl_mask;
if (emptymask.none() or req_rbgs >= emptymask.size() or emptymask.count() <= req_rbgs) {
return emptymask;
}
srsran::bounded_vector<uint32_t, MAX_NOF_RBGS> sorted_cqi_pos;
srsran::bounded_vector<uint32_t, MAX_NOF_RBGS> sorted_cqis;
for (int pos = emptymask.find_lowest(0, emptymask.size(), true); pos >= 0;
pos = emptymask.find_lowest(pos + 1, emptymask.size(), true)) {
sorted_cqis.push_back(get_rbg_cqi(pos));
sorted_cqi_pos.push_back(pos);
}
std::stable_sort(sorted_cqi_pos.begin(), sorted_cqi_pos.end(), [&sorted_cqis](uint32_t lhs, uint32_t rhs) {
return sorted_cqis[lhs] > sorted_cqis[rhs];
});
for (size_t i = req_rbgs; i < sorted_cqi_pos.size(); ++i) {
emptymask.set(sorted_cqi_pos[i], false);
}
return emptymask;
}

@ -49,11 +49,16 @@ RBInterval find_contiguous_interval(const RBMask& in_mask, uint32_t max_size)
* DL Helper methods
***************************/
rbgmask_t find_available_rb_mask(const rbgmask_t& in_mask, uint32_t max_size)
rbgmask_t find_available_rbgmask(const rbgmask_t& in_mask, uint32_t max_size)
{
// 1's for free RBs
rbgmask_t localmask = ~(in_mask);
if (max_size >= localmask.size() or max_size >= localmask.count()) {
// shortcut in case rbg count < max_size
return localmask;
}
uint32_t i = 0, nof_alloc = 0;
for (; i < localmask.size() and nof_alloc < max_size; ++i) {
if (localmask.test(i)) {
@ -69,7 +74,7 @@ rbg_interval find_empty_rbg_interval(uint32_t max_nof_rbgs, const rbgmask_t& cur
return find_contiguous_interval(current_mask, max_nof_rbgs);
}
rbgmask_t compute_rbgmask_greedy(uint32_t max_nof_rbgs, bool is_contiguous, const rbgmask_t& current_mask)
rbgmask_t find_available_rbgmask(uint32_t max_nof_rbgs, bool is_contiguous, const rbgmask_t& current_mask)
{
// Allocate enough RBs that accommodate pending data
rbgmask_t newtx_mask(current_mask.size());
@ -77,7 +82,7 @@ rbgmask_t compute_rbgmask_greedy(uint32_t max_nof_rbgs, bool is_contiguous, cons
rbg_interval interv = find_contiguous_interval(current_mask, max_nof_rbgs);
newtx_mask.fill(interv.start(), interv.stop());
} else {
newtx_mask = find_available_rb_mask(current_mask, max_nof_rbgs);
newtx_mask = find_available_rbgmask(current_mask, max_nof_rbgs);
}
return newtx_mask;
}
@ -128,7 +133,7 @@ alloc_result try_dl_retx_alloc(sf_sched& tti_sched, sched_ue& ue, const dl_harq_
// If previous mask does not fit, find another with exact same number of rbgs
size_t nof_rbg = retx_mask.count();
bool is_contiguous_alloc = ue.get_dci_format() == SRSRAN_DCI_FORMAT1A;
retx_mask = compute_rbgmask_greedy(nof_rbg, is_contiguous_alloc, tti_sched.get_dl_mask());
retx_mask = find_available_rbgmask(nof_rbg, is_contiguous_alloc, tti_sched.get_dl_mask());
if (retx_mask.count() == nof_rbg) {
return tti_sched.alloc_dl_user(&ue, retx_mask, h.get_id());
}
@ -155,7 +160,7 @@ alloc_result try_dl_newtx_alloc_greedy(sf_sched& tti_sched, sched_ue& ue, const
// Find RBG mask that accommodates pending data
bool is_contiguous_alloc = ue.get_dci_format() == SRSRAN_DCI_FORMAT1A;
rbgmask_t newtxmask = compute_rbgmask_greedy(req_rbgs.stop(), is_contiguous_alloc, current_mask);
rbgmask_t newtxmask = find_available_rbgmask(req_rbgs.stop(), is_contiguous_alloc, current_mask);
if (newtxmask.none() or newtxmask.count() < req_rbgs.start()) {
return alloc_result::no_sch_space;
}

@ -45,7 +45,7 @@ void test_sched_cqi_one_subband_cqi()
TESTASSERT(ue_cqi.get_grant_avg_cqi(mask) > 0 and ue_cqi.get_grant_avg_cqi(mask) < 5);
// TEST: Get optimal RBG mask in terms of CQI
mask = ue_cqi.get_optim_rbg_mask(5);
mask = ue_cqi.get_optim_rbgmask(5);
TESTASSERT(mask.count() == 5);
for (uint32_t i = 0; i < 5; ++i) {
TESTASSERT(mask.test(i) > 0);
@ -73,7 +73,7 @@ void test_sched_cqi_wideband_cqi()
TESTASSERT(ue_cqi.get_grant_avg_cqi(mask) == 5);
// TEST: Get optimal RBG mask in terms of CQI
mask = ue_cqi.get_optim_rbg_mask(5);
mask = ue_cqi.get_optim_rbgmask(5);
TESTASSERT(mask.count() == 5);
for (uint32_t i = 0; i < 5; ++i) {
TESTASSERT(mask.test(i) > 0);

Loading…
Cancel
Save