O-RAN E Maintenance Release contribution for ODULOW
[o-du/phy.git] / fhi_lib / lib / src / xran_compression_snc.cpp
1 /******************************************************************************
2 *
3 *   Copyright (c) 2020 Intel.
4 *
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
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 *******************************************************************************/
18
19 /**
20  * @brief xRAN BFP compression/decompression U-plane implementation and interface functions
21  *
22  * @file xran_compression.cpp
23  * @ingroup group_source_xran
24  * @author Intel Corporation
25  **/
26 #include "xran_compression.hpp"
27 #include "xran_compression.h"
28 #include <complex>
29 #include <algorithm>
30 #include <immintrin.h>
31 #include <limits.h>
32 #include <cstring>
33
34 using namespace BlockFloatCompander;
35
36 /** callback function type for Symbol packet */
37 typedef void (*xran_bfp_compress_fn)(const BlockFloatCompander::ExpandedData& dataIn,
38                                      BlockFloatCompander::CompressedData* dataOut);
39
40 /** callback function type for Symbol packet */
41 typedef void (*xran_bfp_decompress_fn)(const BlockFloatCompander::CompressedData& dataIn, BlockFloatCompander::ExpandedData* dataOut);
42
43 int32_t
44 xranlib_compress_avxsnc(const struct xranlib_compress_request *request,
45                         struct xranlib_compress_response *response)
46 {
47     BlockFloatCompander::ExpandedData expandedDataInput;
48     BlockFloatCompander::CompressedData compressedDataOut;
49     xran_bfp_compress_fn com_fn = NULL;
50     uint16_t totalRBs = request->numRBs;
51     uint16_t remRBs   = totalRBs;
52     int16_t len = 0;
53     int16_t block_idx_bytes = 0;
54
55     switch (request->iqWidth) {
56         case 8:
57         case 9:
58         case 10:
59         case 12:
60             com_fn = BlockFloatCompander::BFPCompressUserPlaneAvxSnc;
61             break;
62         default:
63             com_fn = BlockFloatCompander::BFPCompressRef;
64             break;
65     }
66
67     expandedDataInput.iqWidth = request->iqWidth;
68     expandedDataInput.numDataElements =  24;
69
70     while (remRBs){
71         expandedDataInput.dataExpanded   = &request->data_in[block_idx_bytes];
72         compressedDataOut.dataCompressed = (uint8_t*)&response->data_out[len];
73         if(remRBs >= 16){
74             expandedDataInput.numBlocks = 16;
75             com_fn(expandedDataInput, &compressedDataOut);
76             len  += ((3 * expandedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)16);
77             block_idx_bytes += 16*expandedDataInput.numDataElements;
78             remRBs -= 16;
79         }else if(remRBs >= 4){
80             expandedDataInput.numBlocks = 4;
81             com_fn(expandedDataInput, &compressedDataOut);
82             len  += ((3 * expandedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)4);
83             block_idx_bytes +=4*expandedDataInput.numDataElements;
84             remRBs -=4;
85         }else if (remRBs >= 1){
86             expandedDataInput.numBlocks = 1;
87             com_fn(expandedDataInput, &compressedDataOut);
88             len  += ((3 * expandedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)1);
89             block_idx_bytes +=1*expandedDataInput.numDataElements;
90             remRBs = remRBs - 1;
91         }
92     }
93
94     response->len =  ((3 * expandedDataInput.iqWidth) + 1) * totalRBs;
95
96     return 0;
97 }
98
99 int32_t
100 xranlib_decompress_avxsnc(const struct xranlib_decompress_request *request,
101     struct xranlib_decompress_response *response)
102 {
103     BlockFloatCompander::CompressedData compressedDataInput;
104     BlockFloatCompander::ExpandedData expandedDataOut;
105
106     xran_bfp_decompress_fn decom_fn = NULL;
107     uint16_t totalRBs = request->numRBs;
108     uint16_t remRBs   = totalRBs;
109     int16_t len = 0;
110     int16_t block_idx_bytes = 0;
111
112     switch (request->iqWidth) {
113     case 8:
114     case 9:
115     case 10:
116     case 12:
117         decom_fn = BlockFloatCompander::BFPExpandUserPlaneAvxSnc;
118         break;
119     default:
120         decom_fn = BlockFloatCompander::BFPExpandRef;
121         break;
122     }
123
124     compressedDataInput.iqWidth         =  request->iqWidth;
125     compressedDataInput.numDataElements =  24;
126
127     while(remRBs) {
128         compressedDataInput.dataCompressed = (uint8_t*)&request->data_in[block_idx_bytes];
129         expandedDataOut.dataExpanded       = &response->data_out[len];
130         if(remRBs >= 16){
131             compressedDataInput.numBlocks = 16;
132             decom_fn(compressedDataInput, &expandedDataOut);
133             len  += 16*compressedDataInput.numDataElements;
134             block_idx_bytes  += ((3 * compressedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)16);
135             remRBs -= 16;
136         }else if(remRBs >= 4){
137             compressedDataInput.numBlocks = 4;
138             decom_fn(compressedDataInput, &expandedDataOut);
139             len  += 4*compressedDataInput.numDataElements;
140             block_idx_bytes  += ((3 * compressedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)4);
141             remRBs -=4;
142         }else if (remRBs >= 1){
143             compressedDataInput.numBlocks = 1;
144             decom_fn(compressedDataInput, &expandedDataOut);
145             len  += 1*compressedDataInput.numDataElements;
146             block_idx_bytes  += ((3 * compressedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)1);
147             remRBs = remRBs - 1;
148         }
149     }
150
151     response->len = totalRBs * compressedDataInput.numDataElements * sizeof(int16_t);
152
153     return 0;
154 }
155
156 int32_t
157 xranlib_compress_avxsnc_bfw(const struct xranlib_compress_request *request,
158                         struct xranlib_compress_response *response)
159 {
160     BlockFloatCompander::ExpandedData expandedDataInput;
161     BlockFloatCompander::CompressedData compressedDataOut;
162     xran_bfp_compress_fn com_fn = NULL;
163
164     if (request->numRBs != 1){
165         printf("Unsupported numRBs %d\n", request->numRBs);
166         return -1;
167     }
168
169     switch (request->iqWidth) {
170         case 8:
171         case 9:
172         case 10:
173         case 12:
174         switch (request->numDataElements) {
175             case 16:
176                 com_fn = BlockFloatCompander::BFPCompressCtrlPlane8AvxSnc;
177                 break;
178             case 32:
179                 com_fn = BlockFloatCompander::BFPCompressCtrlPlane16AvxSnc;
180                 break;
181             case 64:
182                 com_fn = BlockFloatCompander::BFPCompressCtrlPlane32AvxSnc;
183                 break;
184             case 128:
185                 com_fn = BlockFloatCompander::BFPCompressCtrlPlane64AvxSnc;
186                 break;
187             case 24:
188             default:
189                 printf("Unsupported numDataElements %d\n", request->numDataElements);
190                 return -1;
191                 break;
192         }
193         break;
194     default:
195         printf("Unsupported iqWidth %d\n", request->iqWidth);
196         return -1;
197         break;
198     }
199
200     expandedDataInput.iqWidth         = request->iqWidth;
201     expandedDataInput.numDataElements = request->numDataElements;
202     expandedDataInput.numBlocks       = 1;
203     expandedDataInput.dataExpanded    = &request->data_in[0];
204     compressedDataOut.dataCompressed  = (uint8_t*)&response->data_out[0];
205
206     com_fn(expandedDataInput, &compressedDataOut);
207
208     response->len =  (((expandedDataInput.numDataElements  * expandedDataInput.iqWidth) >> 3) + 1)
209                             * request->numRBs;
210
211     return 0;
212 }
213
214 int32_t
215 xranlib_decompress_avxsnc_bfw(const struct xranlib_decompress_request *request,
216                         struct xranlib_decompress_response *response)
217 {
218     BlockFloatCompander::CompressedData compressedDataInput;
219     BlockFloatCompander::ExpandedData expandedDataOut;
220     xran_bfp_decompress_fn decom_fn = NULL;
221
222     if (request->numRBs != 1){
223         printf("Unsupported numRBs %d\n", request->numRBs);
224         return -1;
225     }
226
227     switch (request->iqWidth) {
228         case 8:
229         case 9:
230         case 10:
231         case 12:
232         switch (request->numDataElements) {
233             case 16:
234                 decom_fn = BlockFloatCompander::BFPExpandCtrlPlane8AvxSnc;
235                 break;
236             case 32:
237                 decom_fn = BlockFloatCompander::BFPExpandCtrlPlane16AvxSnc;
238                 break;
239             case 64:
240                 decom_fn = BlockFloatCompander::BFPExpandCtrlPlane32AvxSnc;
241                 break;
242             case 128:
243                 decom_fn = BlockFloatCompander::BFPExpandCtrlPlane64AvxSnc;
244                 break;
245             case 24:
246             default:
247                 printf("Unsupported numDataElements %d\n", request->numDataElements);
248                 return -1;
249                 break;
250         }
251         break;
252     default:
253         printf("Unsupported iqWidth %d\n", request->iqWidth);
254         return -1;
255         break;
256     }
257
258     compressedDataInput.iqWidth         = request->iqWidth;
259     compressedDataInput.numDataElements = request->numDataElements;
260     compressedDataInput.numBlocks       = 1;
261     compressedDataInput.dataCompressed  = (uint8_t*)&request->data_in[0];
262     expandedDataOut.dataExpanded        = &response->data_out[0];
263
264     decom_fn(compressedDataInput, &expandedDataOut);
265
266     response->len = request->numRBs * compressedDataInput.numDataElements * sizeof(int16_t);
267
268     return 0;
269 }
270