mirror of https://github.com/PentHertz/srsLTE.git
fix sched_dl_cqi method to compute cqi-optimal rbgmask
This commit is contained in:
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…
Reference in New Issue