5G-LENA nr-v3.3-49-g235218b1
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-pm-search.cc
1// Copyright (c) 2024 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "nr-pm-search.h"
6
7#include "ns3/enum.h"
8
9namespace ns3
10{
11
12NS_LOG_COMPONENT_DEFINE("NrPmSearch");
13NS_OBJECT_ENSURE_REGISTERED(NrPmSearch);
14
15TypeId
17{
18 static TypeId tid =
19 TypeId("ns3::NrPmSearch")
20 .SetParent<Object>()
21 .AddAttribute("RankLimit",
22 "Max MIMO rank is minimum of num UE ports, num gNB ports, and RankLimit",
23 UintegerValue(UINT8_MAX),
24 MakeUintegerAccessor(&NrPmSearch::m_rankLimit),
25 MakeUintegerChecker<uint8_t>(1, UINT8_MAX))
26 .AddAttribute("SubbandSize",
27 "Size of subband in PRBs for downsampling",
28 UintegerValue(1),
29 MakeUintegerAccessor(&NrPmSearch::m_subbandSize),
30 MakeUintegerChecker<uint8_t>(1, 32))
31 .AddAttribute(
32 "DownsamplingTechnique",
33 "Algorithm used to downsample PRBs into SBs",
35 MakeEnumAccessor<DownsamplingTechnique>(&NrPmSearch::m_downsamplingTechnique),
36 MakeEnumChecker(DownsamplingTechnique::FirstPRB,
37 "FirstPRB",
39 "RandomPRB",
41 "AveragePRB"));
42 return tid;
43}
44
46 : m_downsamplingUniRand(CreateObject<UniformRandomVariable>())
47{
48}
49
50void
51NrPmSearch::SetAmc(Ptr<const NrAmc> amc)
52{
53 m_amc = amc;
54}
55
56void
57NrPmSearch::SetGnbParams(bool isDualPol, size_t numHPorts, size_t numVPorts)
58{
59 m_nGnbPorts = isDualPol ? 2 * numHPorts * numVPorts : numHPorts * numVPorts;
60 m_isGnbDualPol = isDualPol;
61 m_nGnbHPorts = numHPorts;
62 m_nGnbVPorts = numVPorts;
63}
64
65void
66NrPmSearch::SetUeParams(size_t numTotalPorts)
67{
68 m_nRxPorts = numTotalPorts;
69}
70
71void
72NrPmSearch::SetSubbandSize(size_t subbandSize)
73{
74 m_subbandSize = subbandSize;
75}
76
77size_t
79{
80 return m_subbandSize;
81}
82
85{
86 size_t prbs = channelMatrix.GetNumPages();
87 // Check if subband size is allowed for bandwidth
88 // 3GPP TS 38.214 Table 5.2.1.4-2
89 if (prbs < 24)
90 {
91 NS_ASSERT_MSG(m_subbandSize == 1,
92 "Bandwidth parts with less than 24 PRBs should have subbands of size 1");
93 return channelMatrix;
94 }
95 else if (prbs >= 24 && prbs <= 72)
96 {
97 NS_ASSERT_MSG(m_subbandSize == 4 || m_subbandSize == 8,
98 "Bandwidth parts with 24<=x<=72 PRBs should have subbands of size 4 or 8");
99 }
100 else if (prbs >= 73 && prbs <= 144)
101 {
102 NS_ASSERT_MSG(m_subbandSize == 8 || m_subbandSize == 16,
103 "Bandwidth parts with 73<=x<=144 PRBs should have subbands of size 8 or 16");
104 }
105 else if (prbs >= 145 && prbs <= 275)
106 {
107 NS_ASSERT_MSG(
108 m_subbandSize == 16 || m_subbandSize == 32,
109 "Bandwidth parts with 145<=x<=275 PRBs should have subbands of size 16 or 32");
110 }
111 else
112 {
113 NS_ABORT_MSG("Unsupported subband size");
114 }
115
116 // Calculate number of subbands
117 size_t nSubbands = GetNumSubbands(channelMatrix);
118
119 // Preallocate resulting matrix
120 ComplexMatrixArray subbandChannelMatrix(channelMatrix.GetNumRows(),
121 channelMatrix.GetNumCols(),
122 nSubbands);
123
125 {
127 GetSubbandDownsampleFirstPrb(channelMatrix, subbandChannelMatrix);
128 break;
130 GetSubbandDownsampleRandomPrb(channelMatrix, subbandChannelMatrix);
131 break;
133 GetSubbandDownsampleAveragePrb(channelMatrix, subbandChannelMatrix);
134 break;
135 default:
136 NS_ABORT_MSG("Unknown downsampling algorithm");
137 }
138 return subbandChannelMatrix;
139}
140
141size_t
142NrPmSearch::GetNumSubbands(const NrIntfNormChanMat& chanMat) const
143{
144 size_t prbs = chanMat.GetNumPages();
145 size_t nSubbands = prbs / m_subbandSize;
146 int prbsLastSubband = prbs > m_subbandSize ? prbs % m_subbandSize : 0;
147 nSubbands += prbsLastSubband > 0;
148 return nSubbands;
149}
150
151void
152NrPmSearch::GetSubbandDownsampleFirstPrb(const NrIntfNormChanMat& chanMat,
153 ComplexMatrixArray& downsampledChanMat) const
154{
155 size_t matSize = chanMat.GetNumRows() * chanMat.GetNumCols();
156 size_t nSubbands = downsampledChanMat.GetNumPages();
157 for (size_t page = 0; page < nSubbands; page++)
158 {
159 auto sbPage = downsampledChanMat.GetPagePtr(page);
160 auto prbPage = chanMat.GetPagePtr(page * m_subbandSize);
161 for (size_t i = 0; i < matSize; i++)
162 {
163 sbPage[i] = prbPage[i];
164 }
165 }
166}
167
168void
169NrPmSearch::GetSubbandDownsampleRandomPrb(const NrIntfNormChanMat& chanMat,
170 ComplexMatrixArray& downsampledChanMat) const
171{
172 size_t matSize = chanMat.GetNumRows() * chanMat.GetNumCols();
173 size_t nSubbands = downsampledChanMat.GetNumPages();
174 size_t prbsLastSubband = chanMat.GetNumPages() % m_subbandSize;
175 for (size_t page = 0; page < nSubbands; page++)
176 {
177 auto sbPage = downsampledChanMat.GetPagePtr(page);
178 bool lastPageIsSmaller = prbsLastSubband && page == nSubbands - 1;
179 auto prbsInSubband = lastPageIsSmaller ? prbsLastSubband : m_subbandSize;
180 auto randomPrb = m_downsamplingUniRand->GetInteger(1, prbsInSubband - 1);
181 auto prbPage = chanMat.GetPagePtr(page * m_subbandSize + randomPrb);
182 for (size_t i = 0; i < matSize; i++)
183 {
184 sbPage[i] = prbPage[i];
185 }
186 }
187}
188
189void
190NrPmSearch::GetSubbandDownsampleAveragePrb(const NrIntfNormChanMat& chanMat,
191 ComplexMatrixArray& downsampledChanMat) const
192{
193 size_t matSize = chanMat.GetNumRows() * chanMat.GetNumCols();
194 size_t nSubbands = downsampledChanMat.GetNumPages();
195 size_t prbsLastSubband = chanMat.GetNumPages() % m_subbandSize;
196 auto bandSize = m_subbandSize;
197 for (size_t page = 0; page < nSubbands; page++)
198 {
199 // Use full subband size until we hit the last subband, which may be shorter
200 if (page == (nSubbands - 1) && prbsLastSubband)
201 {
202 bandSize = prbsLastSubband;
203 }
204 // Retrieve downsampled subband pointer
205 auto sbPage = downsampledChanMat.GetPagePtr(page);
206 for (size_t sbPrb = 0; sbPrb < bandSize; sbPrb++)
207 {
208 // For each original PRB, accumulate the values
209 auto prbPage = chanMat.GetPagePtr(page * m_subbandSize + sbPrb);
210 for (size_t i = 0; i < matSize; i++)
211 {
212 sbPage[i] += prbPage[i];
213 }
214 }
215 // Divide the accumulated values per the number of PRBs
216 for (size_t i = 0; i < matSize; i++)
217 {
218 sbPage[i] /= bandSize;
219 }
220 }
221}
222
223NrIntfNormChanMat
224NrPmSearch::SubbandUpsampling(const NrIntfNormChanMat& precMat, size_t numPrbs) const
225{
226 if (m_subbandSize == 1)
227 {
228 return precMat;
229 }
230 auto upsampledMatrix = ComplexMatrixArray(precMat.GetNumRows(), precMat.GetNumCols(), numPrbs);
231
232 for (size_t rb = 0; rb < numPrbs; rb++)
233 {
234 auto rbPage = upsampledMatrix.GetPagePtr(rb);
235 auto sbPage = precMat.GetPagePtr(floor(rb / m_subbandSize));
236
237 for (size_t i = 0; i < upsampledMatrix.GetNumRows() * upsampledMatrix.GetNumCols(); i++)
238 {
239 rbPage[i] = sbPage[i];
240 }
241 }
242 return upsampledMatrix;
243}
244
245int64_t
247{
248 m_downsamplingUniRand->SetStream(streamNum);
249 return 1;
250}
251
252} // namespace ns3
static TypeId GetTypeId()
Get TypeId.
int64_t AssignStreams(int64_t stream)
size_t GetSubbandSize() const
void SetSubbandSize(size_t subbandSize)
Set the subband size (in number of RBs)
Ptr< UniformRandomVariable > m_downsamplingUniRand
Uniform variable stream used to downsample PRBs.
NrPmSearch()
Default constructor.
void SetGnbParams(bool isDualPol, size_t numHPorts, size_t numVPorts)
Set the antenna parameters of the gNB antenna.
@ FirstPRB
Downsample m_subbandSize samples to bands based on the first PRB.
@ AveragePRB
Downsample m_subbandSize samples to bands based on the average of PRBs.
@ RandomPRB
Downsample m_subbandSize samples to bands based on a random PRB.
uint8_t m_rankLimit
Limit the UE's maximum supported rank.
enum DownsamplingTechnique m_downsamplingTechnique
Technique used to downsample PRBs.
void SetUeParams(size_t numTotalPorts)
Set the antenna parameters of the UE antenna.
size_t m_nRxPorts
Number of receive ports at this UE.
size_t m_nGnbHPorts
Number of horizontal ports in the gNB antenna array.
Ptr< const NrAmc > m_amc
The NrAmc to be used for computing TB size and MCS.
size_t m_nGnbPorts
Total number of ports in the gNB antenna array.
virtual NrIntfNormChanMat SubbandUpsampling(const NrIntfNormChanMat &precMat, size_t numPrbs) const
Upsample the input per-subband precoding matrix into a per-PRB precoding matrix.
bool m_isGnbDualPol
True when gNB has a dual-polarized antenna array.
virtual NrIntfNormChanMat SubbandDownsampling(const NrIntfNormChanMat &channelMatrix)
Downsample the input channel matrix into bins of at most m_subbandSize PRBs.
void SetAmc(Ptr< const NrAmc > amc)
Set the AMC object to be used for MCS and TB size calculation.
size_t m_subbandSize
Size of each subband (in number of RBs)
size_t m_nGnbVPorts
Number of vertical ports in the gNB antenna array.