5#define NS_LOG_APPEND_CONTEXT \
8 std::clog << " [ CellId " << GetCellId() << ", bwpId " << GetBwpId() << "] "; \
11#include "nr-mac-scheduler-tdma.h"
22NS_LOG_COMPONENT_DEFINE(
"NrMacSchedulerTdma");
23NS_OBJECT_ENSURE_REGISTERED(NrMacSchedulerTdma);
28 static TypeId tid = TypeId(
"ns3::NrMacSchedulerTdma").SetParent<
NrMacSchedulerNs3>();
40std::vector<NrMacSchedulerNs3::UePtrAndBufferReq>
43 std::vector<UePtrAndBufferReq> ueVector;
44 for (
const auto& el : activeUes)
46 uint64_t size = ueVector.size();
48 for (
const auto& ue : GetUeVector(el))
50 ueVector.emplace_back(ue);
52 NS_ASSERT(size + GetUeVector(el).size() == ueVector.size());
104NrMacSchedulerTdma::AssignRBGTDMA(uint32_t symAvail,
105 const ActiveUeMap& activeUe,
106 const std::string& type,
107 const BeforeSchedFn& BeforeSchedFn,
108 const GetCompareUeFn& GetCompareFn,
109 const GetTBSFn& GetTBSFn,
110 const GetRBGFn& GetRBGFn,
111 const GetSymFn& GetSymFn,
112 const AfterSuccessfulAssignmentFn& SuccessfulAssignmentFn,
113 const AfterUnsuccessfulAssignmentFn& UnSuccessfulAssignmentFn,
114 const CallNotifyFn& callNotifyFn)
const
116 NS_LOG_FUNCTION(
this);
117 NS_LOG_DEBUG(
"Assigning RBG in " << type <<
", # beams active flows: " << activeUe.size()
118 <<
", # sym: " << symAvail);
121 std::vector<UePtrAndBufferReq> ueVector = GetUeVectorFromActiveUeMap(activeUe);
124 uint32_t resources = symAvail;
127 const std::vector<bool> notchedRBGsMask =
129 int zeroes = std::count(notchedRBGsMask.begin(), notchedRBGsMask.end(), 0);
131 NS_ASSERT(numOfAssignableRbgs > 0);
133 for (
auto& ue : ueVector)
135 BeforeSchedFn(ue,
FTResources(numOfAssignableRbgs, 1));
138 while (resources > 0)
142 callNotifyFn(ueVector);
146 auto schedInfoIt = ueVector.begin();
148 std::stable_sort(ueVector.begin(), ueVector.end(), GetCompareFn());
151 while (schedInfoIt != ueVector.end())
153 uint32_t bufQueueSize = schedInfoIt->second;
155 if (GetTBSFn(GetUe(*schedInfoIt)) >= std::max(bufQueueSize, 10U))
157 NS_LOG_INFO(
"UE " << GetUe(*schedInfoIt)->m_rnti <<
" TBS "
158 << GetTBSFn(GetUe(*schedInfoIt)) <<
" queue " << bufQueueSize
170 if (schedInfoIt == ueVector.end())
172 NS_LOG_INFO(
"All the UE already have their resources allocated. Skipping the beam");
178 auto& assignedRbgs = GetRBGFn(GetUe(*schedInfoIt));
179 auto existingRbgs = assignedRbgs.size();
180 assignedRbgs.resize(assignedRbgs.size() + numOfAssignableRbgs);
181 std::iota(assignedRbgs.begin() + existingRbgs, assignedRbgs.end(), 0);
182 assigned.m_rbg += numOfAssignableRbgs;
184 auto& assignedSymbols = GetSymFn(GetUe(*schedInfoIt));
185 auto existingSymbols = assignedSymbols.size();
186 assignedSymbols.resize(assignedSymbols.size() + numOfAssignableRbgs);
187 std::fill(assignedSymbols.begin() + existingSymbols, assignedSymbols.end(), resources);
194 NS_LOG_DEBUG(
"Assigned " << numOfAssignableRbgs <<
" " << type <<
" RBG (= 1 SYM) to UE "
195 << GetUe(*schedInfoIt)->m_rnti <<
" total assigned up to now: "
196 << GetRBGFn(GetUe(*schedInfoIt)).size() <<
" that corresponds to "
198 SuccessfulAssignmentFn(*schedInfoIt,
FTResources(numOfAssignableRbgs, 1), assigned);
201 for (
auto& ue : ueVector)
203 if (GetUe(ue)->m_rnti != GetUe(*schedInfoIt)->m_rnti)
205 UnSuccessfulAssignmentFn(ue,
FTResources(numOfAssignableRbgs, 1), assigned);
212 for (
const auto& el : activeUe)
214 uint32_t symOfBeam = 0;
215 for (
const auto& ue : el.second)
217 symOfBeam += GetRBGFn(ue.first).size() / numOfAssignableRbgs;
219 ret.insert(std::make_pair(el.first, symOfBeam));
236 NS_LOG_FUNCTION(
this);
240 std::placeholders::_1,
241 std::placeholders::_2);
244 std::placeholders::_1,
245 std::placeholders::_2,
246 std::placeholders::_3);
249 std::placeholders::_1,
250 std::placeholders::_2,
251 std::placeholders::_3);
258 CallNotifyFn callNotifyFn =
261 return AssignRBGTDMA(symAvail,
286 NS_LOG_FUNCTION(
this);
289 std::placeholders::_1,
290 std::placeholders::_2);
293 std::placeholders::_1,
294 std::placeholders::_2,
295 std::placeholders::_3);
299 std::placeholders::_1,
300 std::placeholders::_2,
301 std::placeholders::_3);
306 CallNotifyFn callNotifyFn =
309 return AssignRBGTDMA(symAvail,
332std::shared_ptr<DciInfoElementTdma>
334 const std::shared_ptr<NrMacSchedulerUeInfo>& ueInfo,
335 [[maybe_unused]] uint32_t maxSym)
const
337 NS_LOG_FUNCTION(
this);
338 uint32_t tbs =
m_dlAmc->CalculateTbSize(ueInfo->GetDlMcs(),
345 NS_LOG_DEBUG(
"While creating DL DCI for UE " << ueInfo->m_rnti <<
" assigned "
346 << ueInfo->m_dlRBG.size()
347 <<
" DL RBG, but TBS < 10");
348 ueInfo->m_dlTbSize = 0;
353 int zeroes = std::count(notchedRBGsMask.begin(), notchedRBGsMask.end(), 0);
356 uint8_t numSym =
static_cast<uint8_t
>(ueInfo->m_dlRBG.size() / numOfAssignableRbgs);
358 auto dci = CreateDci(spoint,
364 ueInfo->m_dlPrecMats,
365 std::max(numSym,
static_cast<uint8_t
>(1)));
369 spoint->
m_sym += numSym;
385std::shared_ptr<DciInfoElementTdma>
387 const std::shared_ptr<NrMacSchedulerUeInfo>& ueInfo,
388 uint32_t maxSym)
const
390 NS_LOG_FUNCTION(
this);
391 uint32_t tbs =
m_ulAmc->CalculateTbSize(ueInfo->m_ulMcs,
399 NS_LOG_DEBUG(
"While creating UL DCI for UE " << ueInfo->m_rnti <<
" assigned "
400 << ueInfo->m_ulRBG.size()
401 <<
" UL RBG, but TBS " << tbs <<
" < 12");
406 int zeroes = std::count(notchedRBGsMask.begin(), notchedRBGsMask.end(), 0);
410 static_cast<uint8_t
>(std::max<size_t>(ueInfo->m_ulRBG.size() / numOfAssignableRbgs, 1));
411 numSym = std::min(numSym,
static_cast<uint8_t
>(maxSym));
413 NS_ASSERT(spoint->
m_sym >= numSym);
416 spoint->
m_sym -= numSym;
418 auto dci = CreateDci(spoint,
424 ueInfo->m_ulPrecMats,
436 NS_LOG_FUNCTION(
this);
454std::shared_ptr<DciInfoElementTdma>
456 const std::shared_ptr<NrMacSchedulerUeInfo>& ueInfo,
461 Ptr<const ComplexMatrixArray> precMats,
462 uint8_t numSym)
const
464 NS_LOG_FUNCTION(
this);
466 NS_ASSERT(numSym > 0);
468 std::shared_ptr<DciInfoElementTdma> dci =
469 std::make_shared<DciInfoElementTdma>(ueInfo->m_rnti,
483 std::vector<bool> rbgAssigned =
486 if (rbgAssigned.empty())
493 dci->m_rbgBitmask = std::move(rbgAssigned);
495 std::ostringstream oss;
496 for (
auto x : dci->m_rbgBitmask)
498 oss << std::to_string(x) <<
" ";
501 NS_LOG_INFO(
"UE " << ueInfo->m_rnti <<
" assigned RBG from " << spoint->
m_rbg <<
" with mask "
502 << oss.str() <<
" for " <<
static_cast<uint32_t
>(numSym) <<
" SYM ");
504 NS_ASSERT(std::count(dci->m_rbgBitmask.begin(), dci->m_rbgBitmask.end(), 0) !=
A general scheduler for nr in NS3.
Ptr< NrAmc > m_ulAmc
AMC pointer.
Ptr< NrAmc > m_dlAmc
AMC pointer.
bool m_activeUlAi
Flag for activating AI for uplink.
std::vector< bool > GetUlNotchedRbgMask() const
Get the notched (blank) RBGs Mask for the UL.
std::unordered_map< BeamId, uint32_t, BeamIdHash > BeamSymbolMap
Map between a BeamId and the symbol assigned to that beam.
uint16_t GetBwpId() const
Get the bwp id of this MAC.
bool m_activeDlAi
Flag for activating AI for downlink.
std::unordered_map< BeamId, std::vector< UePtrAndBufferReq >, BeamIdHash > ActiveUeMap
Map between a BeamId and a vector of UE (the UE are in that beam)
std::vector< bool > GetDlNotchedRbgMask() const
Get the notched (blank) RBGs Mask for the DL.
uint16_t GetBandwidthInRbg() const
uint64_t GetNumRbPerRbg() const
Private function that is used to get the number of resource blocks per resource block group and also ...
PointInFTPlane FTResources
Represent an amount of RBG/symbols that can be, or is, assigned.
virtual std::function< bool(const NrMacSchedulerNs3::UePtrAndBufferReq &lhs, const NrMacSchedulerNs3::UePtrAndBufferReq &rhs)> GetUeCompareUlFn() const =0
Provide the comparison function to order the UE when scheduling UL.
std::shared_ptr< DciInfoElementTdma > CreateDlDci(PointInFTPlane *spoint, const std::shared_ptr< NrMacSchedulerUeInfo > &ueInfo, uint32_t maxSym) const override
Create a DL DCI starting from spoint and spanning maxSym symbols.
NrMacSchedulerTdma()
NrMacSchedulerTdma constructor.
virtual void AssignedUlResources(const UePtrAndBufferReq &ue, const FTResources &assigned, const FTResources &totalAssigned) const =0
Update the UE representation after a symbol (DL) has been assigned to it.
virtual std::function< bool(const NrMacSchedulerNs3::UePtrAndBufferReq &lhs, const NrMacSchedulerNs3::UePtrAndBufferReq &rhs)> GetUeCompareDlFn() const =0
Provide the comparison function to order the UE when scheduling DL.
BeamSymbolMap AssignDLRBG(uint32_t symAvail, const ActiveUeMap &activeDl) const override
Assign the available DL RBG to the UEs.
static TypeId GetTypeId()
GetTypeId.
virtual void NotAssignedUlResources(const UePtrAndBufferReq &ue, const FTResources ¬Assigned, const FTResources &totalAssigned) const =0
Update the UE representation after a symbol (UL) has been assigned to other UE.
virtual void NotAssignedDlResources(const UePtrAndBufferReq &ue, const FTResources ¬Assigned, const FTResources &totalAssigned) const =0
Update the UE representation after a symbol (DL) has been assigned to other UE.
virtual void AssignedDlResources(const UePtrAndBufferReq &ue, const FTResources &assigned, const FTResources &totalAssigned) const =0
Update the UE representation after a symbol (DL) has been assigned to it.
BeamSymbolMap AssignULRBG(uint32_t symAvail, const ActiveUeMap &activeUl) const override
Assign the available UL RBG to the UEs.
virtual void BeforeUlSched(const UePtrAndBufferReq &ue, const FTResources &assignableInIteration) const =0
Prepare UE for the UL scheduling.
~NrMacSchedulerTdma() override
NrMacSchedulerTdma deconstructor.
uint8_t GetTpc() const override
Returns TPC command.
virtual void CallNotifyDlFn(const std::vector< UePtrAndBufferReq > &ueVector) const
Call the notify callback function in the OpenGymEnv class in the ns3-gym module for downlink.
virtual void CallNotifyUlFn(const std::vector< UePtrAndBufferReq > &ueVector) const
Call the notify callback function in the OpenGymEnv class in the ns3-gym module for uplink.
virtual void BeforeDlSched(const UePtrAndBufferReq &ue, const FTResources &assignableInIteration) const =0
Prepare UE for the DL scheduling.
std::shared_ptr< DciInfoElementTdma > CreateUlDci(PointInFTPlane *spoint, const std::shared_ptr< NrMacSchedulerUeInfo > &ueInfo, uint32_t maxSym) const override
Create a UL DCI starting from spoint and spanning maxSym symbols.
static uint32_t & GetUlTBS(const UePtr &ue)
GetUlTBS.
static std::vector< uint8_t > & GetUlSym(const UePtr &ue)
GetUlSym.
static std::vector< uint16_t > & GetUlRBG(const UePtr &ue)
GetUlRBG.
static std::vector< uint16_t > & GetDlRBG(const UePtr &ue)
GetDlRBG.
static std::vector< uint8_t > & GetDlSym(const UePtr &ue)
GetDlSym.
static uint32_t & GetDlTBS(const UePtr &ue)
GetDlTBS.
@ DATA
Used for DL/UL DATA.
DciFormat
Format of the DCI.
Point in the Frequency/Time plane.
uint32_t m_rbg
Represent the starting RBG.
uint8_t m_sym
Represent the starting symbol.