1 /******************************************************************************
3 * Copyright (c) 2020 Intel.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *******************************************************************************/
20 * @brief xRAN BFP compression/decompression U-plane implementation and interface functions
22 * @file xran_compression.cpp
23 * @ingroup group_source_xran
24 * @author Intel Corporation
27 #include "xran_compression.hpp"
28 #include "xran_compression.h"
29 #include "xran_mod_compression.h"
30 #include "xran_fh_o_du.h"
33 #include <immintrin.h>
37 using namespace BlockFloatCompander;
39 /** callback function type for Symbol packet */
40 typedef void (*xran_bfp_compress_fn)(const BlockFloatCompander::ExpandedData& dataIn,
41 BlockFloatCompander::CompressedData* dataOut);
43 /** callback function type for Symbol packet */
44 typedef void (*xran_bfp_decompress_fn)(const BlockFloatCompander::CompressedData& dataIn, BlockFloatCompander::ExpandedData* dataOut);
47 xranlib_compress(const struct xranlib_compress_request *request,
48 struct xranlib_compress_response *response)
50 if (request->compMethod == XRAN_COMPMETHOD_MODULATION)
52 struct xranlib_5gnr_mod_compression_request mod_request;
53 struct xranlib_5gnr_mod_compression_response mod_response;
54 mod_request.data_in = request->data_in;
55 mod_request.unit = request->ScaleFactor;
56 mod_request.modulation = (enum xran_modulation_order)(request->iqWidth * 2);
57 mod_request.num_symbols = request->numRBs * XRAN_NUM_OF_SC_PER_RB;
58 mod_request.re_mask = request->reMask;
59 mod_response.data_out = response->data_out;
60 response->len = (request->numRBs * XRAN_NUM_OF_SC_PER_RB * request->iqWidth * 2) >> 3;
62 return xranlib_5gnr_mod_compression(&mod_request, &mod_response);
65 if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52)) {
66 return xranlib_compress_avxsnc(request,response);
68 return xranlib_compress_avx512(request,response);
74 xranlib_decompress(const struct xranlib_decompress_request *request,
75 struct xranlib_decompress_response *response)
77 if (request->compMethod == XRAN_COMPMETHOD_MODULATION)
79 struct xranlib_5gnr_mod_decompression_request mod_request;
80 struct xranlib_5gnr_mod_decompression_response mod_response;
81 mod_request.data_in = request->data_in;
82 mod_request.unit = request->ScaleFactor;
83 mod_request.modulation = (enum xran_modulation_order)(request->iqWidth * 2);
84 mod_request.num_symbols = request->numRBs * XRAN_NUM_OF_SC_PER_RB;
85 mod_request.re_mask = request->reMask;
86 mod_response.data_out = response->data_out;
87 response->len = request->numRBs * XRAN_NUM_OF_SC_PER_RB * 4;
89 return xranlib_5gnr_mod_decompression(&mod_request, &mod_response);
92 if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52)) {
93 return xranlib_decompress_avxsnc(request,response);
95 return xranlib_decompress_avx512(request,response);
101 xranlib_compress_bfw(const struct xranlib_compress_request *request,
102 struct xranlib_compress_response *response)
104 if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52)) {
105 return xranlib_compress_avxsnc_bfw(request,response);
107 return xranlib_compress_avx512_bfw(request,response);
112 xranlib_decompress_bfw(const struct xranlib_decompress_request *request,
113 struct xranlib_decompress_response *response)
115 if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52)) {
116 return xranlib_decompress_avxsnc_bfw(request,response);
118 return xranlib_decompress_avx512_bfw(request,response);
123 xranlib_compress_avx512(const struct xranlib_compress_request *request,
124 struct xranlib_compress_response *response)
126 BlockFloatCompander::ExpandedData expandedDataInput;
127 BlockFloatCompander::CompressedData compressedDataOut;
128 xran_bfp_compress_fn com_fn = NULL;
129 uint16_t totalRBs = request->numRBs;
130 uint16_t remRBs = totalRBs;
132 int16_t block_idx_bytes = 0;
134 switch (request->iqWidth) {
139 com_fn = BlockFloatCompander::BFPCompressUserPlaneAvx512;
142 com_fn = BlockFloatCompander::BFPCompressRef;
146 expandedDataInput.iqWidth = request->iqWidth;
147 expandedDataInput.numDataElements = 24;
150 expandedDataInput.dataExpanded = &request->data_in[block_idx_bytes];
151 compressedDataOut.dataCompressed = (uint8_t*)&response->data_out[len];
153 expandedDataInput.numBlocks = 16;
154 com_fn(expandedDataInput, &compressedDataOut);
155 len += ((3 * expandedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)16);
156 block_idx_bytes += 16*expandedDataInput.numDataElements;
158 }else if(remRBs >= 4){
159 expandedDataInput.numBlocks = 4;
160 com_fn(expandedDataInput, &compressedDataOut);
161 len += ((3 * expandedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)4);
162 block_idx_bytes +=4*expandedDataInput.numDataElements;
164 }else if (remRBs >= 1){
165 expandedDataInput.numBlocks = 1;
166 com_fn(expandedDataInput, &compressedDataOut);
167 len += ((3 * expandedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)1);
168 block_idx_bytes +=1*expandedDataInput.numDataElements;
173 response->len = ((3 * expandedDataInput.iqWidth) + 1) * totalRBs;
179 xranlib_decompress_avx512(const struct xranlib_decompress_request *request,
180 struct xranlib_decompress_response *response)
182 BlockFloatCompander::CompressedData compressedDataInput;
183 BlockFloatCompander::ExpandedData expandedDataOut;
185 xran_bfp_decompress_fn decom_fn = NULL;
186 uint16_t totalRBs = request->numRBs;
187 uint16_t remRBs = totalRBs;
189 int16_t block_idx_bytes = 0;
191 switch (request->iqWidth) {
196 decom_fn = BlockFloatCompander::BFPExpandUserPlaneAvx512;
199 decom_fn = BlockFloatCompander::BFPExpandRef;
203 compressedDataInput.iqWidth = request->iqWidth;
204 compressedDataInput.numDataElements = 24;
207 compressedDataInput.dataCompressed = (uint8_t*)&request->data_in[block_idx_bytes];
208 expandedDataOut.dataExpanded = &response->data_out[len];
210 compressedDataInput.numBlocks = 16;
211 decom_fn(compressedDataInput, &expandedDataOut);
212 len += 16*compressedDataInput.numDataElements;
213 block_idx_bytes += ((3 * compressedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)16);
215 }else if(remRBs >= 4){
216 compressedDataInput.numBlocks = 4;
217 decom_fn(compressedDataInput, &expandedDataOut);
218 len += 4*compressedDataInput.numDataElements;
219 block_idx_bytes += ((3 * compressedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)4);
221 }else if (remRBs >= 1){
222 compressedDataInput.numBlocks = 1;
223 decom_fn(compressedDataInput, &expandedDataOut);
224 len += 1*compressedDataInput.numDataElements;
225 block_idx_bytes += ((3 * compressedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)1);
230 response->len = totalRBs * compressedDataInput.numDataElements * sizeof(int16_t);
236 xranlib_compress_avx512_bfw(const struct xranlib_compress_request *request,
237 struct xranlib_compress_response *response)
239 BlockFloatCompander::ExpandedData expandedDataInput;
240 BlockFloatCompander::CompressedData compressedDataOut;
241 xran_bfp_compress_fn com_fn = NULL;
243 if (request->numRBs != 1){
244 printf("Unsupported numRBs %d\n", request->numRBs);
248 switch (request->iqWidth) {
253 switch (request->numDataElements) {
255 com_fn = BlockFloatCompander::BFPCompressCtrlPlane8Avx512;
258 com_fn = BlockFloatCompander::BFPCompressCtrlPlane16Avx512;
261 com_fn = BlockFloatCompander::BFPCompressCtrlPlane32Avx512;
264 com_fn = BlockFloatCompander::BFPCompressCtrlPlane64Avx512;
268 printf("Unsupported numDataElements %d\n", request->numDataElements);
274 printf("Unsupported iqWidth %d\n", request->iqWidth);
279 expandedDataInput.iqWidth = request->iqWidth;
280 expandedDataInput.numDataElements = request->numDataElements;
281 expandedDataInput.numBlocks = 1;
282 expandedDataInput.dataExpanded = &request->data_in[0];
283 compressedDataOut.dataCompressed = (uint8_t*)&response->data_out[0];
285 com_fn(expandedDataInput, &compressedDataOut);
287 response->len = (((expandedDataInput.numDataElements * expandedDataInput.iqWidth) >> 3) + 1)
294 xranlib_decompress_avx512_bfw(const struct xranlib_decompress_request *request,
295 struct xranlib_decompress_response *response)
297 BlockFloatCompander::CompressedData compressedDataInput;
298 BlockFloatCompander::ExpandedData expandedDataOut;
299 xran_bfp_decompress_fn decom_fn = NULL;
301 if (request->numRBs != 1){
302 printf("Unsupported numRBs %d\n", request->numRBs);
306 switch (request->iqWidth) {
311 switch (request->numDataElements) {
313 decom_fn = BlockFloatCompander::BFPExpandCtrlPlane8Avx512;
316 decom_fn = BlockFloatCompander::BFPExpandCtrlPlane16Avx512;
319 decom_fn = BlockFloatCompander::BFPExpandCtrlPlane32Avx512;
322 decom_fn = BlockFloatCompander::BFPExpandCtrlPlane64Avx512;
326 printf("Unsupported numDataElements %d\n", request->numDataElements);
332 printf("Unsupported iqWidth %d\n", request->iqWidth);
337 compressedDataInput.iqWidth = request->iqWidth;
338 compressedDataInput.numDataElements = request->numDataElements;
339 compressedDataInput.numBlocks = 1;
340 compressedDataInput.dataCompressed = (uint8_t*)&request->data_in[0];
341 expandedDataOut.dataExpanded = &response->data_out[0];
343 decom_fn(compressedDataInput, &expandedDataOut);
345 response->len = request->numRBs * compressedDataInput.numDataElements * sizeof(int16_t);