* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / test / test_xran / compander_functional.cc
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 #include "common.hpp"
20 #include "xran_fh_o_du.h"
21 #include "xran_compression.h"
22 #include "xran_compression.hpp"
23
24 #include <stdint.h>
25 #include <random>
26 #include <algorithm>
27 #include <iterator>
28 #include <iostream>
29 #include <cstring>
30
31 const std::string module_name = "bfp";
32
33 extern int _may_i_use_cpu_feature(unsigned __int64);
34
35 template <typename T>
36 int checkData(T* inVec1, T* inVec2, int numVals)
37 {
38   int checkSum = 0;
39   for (int n = 0; n < numVals; ++n)
40   {
41     checkSum += std::abs(inVec1[n] - inVec2[n]);
42   }
43   if (checkSum == 0)
44   {
45     //std::cout << "Test Passed\n";
46     return 0;
47   }
48   else
49   {
50     //std::cout << "Test Failed\n";
51     return 1;
52   }
53 }
54 template int checkData(int8_t*, int8_t*, int);
55 template int checkData(int16_t*, int16_t*, int);
56
57 int checkDataApprox(int16_t *inVec1, int16_t *inVec2, int numVals)
58 {
59   int checkSum = 0;
60   for (int n = 0; n < numVals; ++n)
61   {
62     if (std::abs(inVec1[n] & 0xFF00)   - std::abs(inVec2[n] & 0xFF00)){;
63         printf("[%d]: %d %d\n",n, inVec1[n] & 0xFF00, inVec2[n] & 0xFF00);
64         checkSum += 1;
65     }
66   }
67   if (checkSum == 0)
68   {
69     //std::cout << "Test Passed\n";
70     return 0;
71   }
72   else
73   {
74     //std::cout << "Test Failed\n";
75     return 1;
76   }
77 }
78
79
80 class BfpCheck : public KernelTests
81 {
82 protected:
83     void SetUp() override {
84         init_test("bfp_functional");
85     }
86
87     /* It's called after an execution of the each test case.*/
88     void TearDown() override {
89     }
90 };
91
92 CACHE_ALIGNED int16_t loc_dataExpandedIn[288*128];
93 CACHE_ALIGNED int16_t loc_dataExpandedRes[288*128];
94 CACHE_ALIGNED uint8_t loc_dataCompressedDataOut[2*288*128];
95
96 class BfpPerfEx : public KernelTests
97 {
98 protected:
99     struct xranlib_decompress_request  bfp_decom_req;
100     struct xranlib_decompress_response bfp_decom_rsp;
101     struct xranlib_compress_request  bfp_com_req;
102     struct xranlib_compress_response bfp_com_rsp;
103
104     void SetUp() override {
105         init_test("bfp_performace_ex");
106         int32_t resSum  = 0;
107         int16_t len = 0;
108         int16_t compMethod = XRAN_COMPMETHOD_BLKFLOAT;
109         int16_t iqWidth    = get_input_parameter<int16_t>("iqWidth");
110         int16_t numRBs = get_input_parameter<int16_t>("nRBsize");
111         // Create random number generator
112         std::random_device rd;
113         std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
114         std::uniform_int_distribution<int16_t> randInt16(-32768, 32767);
115         std::uniform_int_distribution<int> randExpShift(0, 4);
116
117         BlockFloatCompander::ExpandedData expandedData;
118         expandedData.dataExpanded = &loc_dataExpandedIn[0];
119         BlockFloatCompander::ExpandedData expandedDataRes;
120         expandedDataRes.dataExpanded = &loc_dataExpandedRes[0];
121
122         //printf("iqWidth %d numRBs %d\n", iqWidth, numRBs);
123
124         for (int m = 0; m < 18*BlockFloatCompander::k_maxNumBlocks; ++m) {
125             auto shiftVal = randExpShift(gen);
126             for (int n = 0; n < 24; ++n) {
127                 expandedData.dataExpanded[m*24+n] = int16_t(randInt16(gen) >> shiftVal);
128             }
129         }
130
131         BlockFloatCompander::CompressedData compressedData;
132         compressedData.dataCompressed = &loc_dataCompressedDataOut[0];
133
134         std::memset(&loc_dataCompressedDataOut[0], 0, 288*24);
135         std::memset(&loc_dataExpandedRes[0], 0, 288*24);
136
137         std::memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
138         std::memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
139         std::memset(&bfp_decom_req, 0, sizeof(struct xranlib_decompress_request));
140         std::memset(&bfp_decom_rsp, 0, sizeof(struct xranlib_decompress_response));
141
142         bfp_com_req.data_in    = (int16_t *)expandedData.dataExpanded;
143         bfp_com_req.numRBs     = numRBs;
144         bfp_com_req.len        = numRBs*12*2*2;
145         bfp_com_req.compMethod = compMethod;
146         bfp_com_req.iqWidth    = iqWidth;
147
148         bfp_com_rsp.data_out   = (int8_t *)(compressedData.dataCompressed);
149         bfp_com_rsp.len        = 0;
150
151         bfp_decom_req.data_in    = (int8_t *)(compressedData.dataCompressed);
152         bfp_decom_req.numRBs     = numRBs;
153         bfp_decom_req.len        = ((3 * iqWidth) + 1) * numRBs;
154         bfp_decom_req.compMethod = compMethod;
155         bfp_decom_req.iqWidth    = iqWidth;
156
157         bfp_decom_rsp.data_out   = (int16_t *)expandedDataRes.dataExpanded;
158         bfp_decom_rsp.len        = 0;
159     }
160
161     /* It's called after an execution of the each test case.*/
162     void TearDown() override {
163
164     }
165 };
166
167
168 class BfpPerfCp : public KernelTests
169 {
170 protected:
171     struct xranlib_decompress_request  bfp_decom_req;
172     struct xranlib_decompress_response bfp_decom_rsp;
173     struct xranlib_compress_request  bfp_com_req;
174     struct xranlib_compress_response bfp_com_rsp;
175
176     void SetUp() override {
177         init_test("bfp_performace_cp");
178         int32_t resSum  = 0;
179         int16_t len = 0;
180         int16_t compMethod = XRAN_COMPMETHOD_BLKFLOAT;
181         int16_t iqWidth    = get_input_parameter<int16_t>("iqWidth");
182         int16_t AntElm     = get_input_parameter<int16_t>("AntElm");
183         int16_t numDataElements = 0;
184         int16_t numRBs = 1;
185         // Create random number generator
186         std::random_device rd;
187         std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
188         std::uniform_int_distribution<int16_t> randInt16(-32768, 32767);
189         std::uniform_int_distribution<int> randExpShift(0, 4);
190
191         BlockFloatCompander::ExpandedData expandedData;
192         expandedData.dataExpanded = &loc_dataExpandedIn[0];
193         BlockFloatCompander::ExpandedData expandedDataRes;
194         expandedDataRes.dataExpanded = &loc_dataExpandedRes[0];
195
196         //printf("iqWidth %d numRBs %d\n", iqWidth, numRBs);
197         numDataElements = 2*AntElm;
198
199         // Generate input data
200         for (int m = 0; m < numRBs; ++m)
201         {
202           auto shiftVal = randExpShift(gen);
203           for (int n = 0; n < numDataElements; ++n)
204           {
205             expandedData.dataExpanded[m * numDataElements + n] = int16_t(randInt16(gen) >> shiftVal);
206           }
207         }
208
209         BlockFloatCompander::CompressedData compressedData;
210         compressedData.dataCompressed = &loc_dataCompressedDataOut[0];
211
212         std::memset(&loc_dataCompressedDataOut[0], 0, 288*128);
213         std::memset(&loc_dataExpandedRes[0], 0, 288*128);
214
215         std::memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
216         std::memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
217         std::memset(&bfp_decom_req, 0, sizeof(struct xranlib_decompress_request));
218         std::memset(&bfp_decom_rsp, 0, sizeof(struct xranlib_decompress_response));
219
220         bfp_com_req.data_in    = (int16_t *)expandedData.dataExpanded;
221         bfp_com_req.numRBs     = numRBs;
222         bfp_com_req.numDataElements = numDataElements;
223         bfp_com_req.len        = AntElm*4;
224         bfp_com_req.compMethod = compMethod;
225         bfp_com_req.iqWidth    = iqWidth;
226
227         bfp_com_rsp.data_out   = (int8_t *)(compressedData.dataCompressed);
228         bfp_com_rsp.len        = 0;
229
230         bfp_decom_req.data_in    = (int8_t *)(compressedData.dataCompressed);
231         bfp_decom_req.numRBs     = numRBs;
232         bfp_decom_req.numDataElements = numDataElements;
233         bfp_decom_req.len        = (((numDataElements  * iqWidth) >> 3) + 1) * numRBs;
234         bfp_decom_req.compMethod = compMethod;
235         bfp_decom_req.iqWidth    = iqWidth;
236
237         bfp_decom_rsp.data_out   = (int16_t *)expandedDataRes.dataExpanded;
238         bfp_decom_rsp.len        = 0;
239     }
240
241     /* It's called after an execution of the each test case.*/
242     void TearDown() override {
243
244     }
245 };
246
247 struct ErrorData
248 {
249   int checkSum;
250   float errorAccum;
251   int errorCount;
252 };
253
254 template <typename T>
255 void compareData(T* inVecRef, T* inVecTest, ErrorData& err, int numVals)
256 {
257   for (int n = 0; n < numVals; ++n)
258   {
259     auto valDiff = std::abs(inVecRef[n] - inVecTest[n]);
260     err.checkSum += valDiff;
261     if (inVecRef[n] != 0)
262     {
263       err.errorAccum += (float)valDiff / std::abs((float)inVecRef[n]);
264       err.errorCount++;
265     }
266   }
267 }
268 template void compareData(int8_t*, int8_t*, ErrorData&, int);
269 template void compareData(int16_t*, int16_t*, ErrorData&, int);
270
271 int checkPass(ErrorData& err, int testType)
272 {
273   if (testType == 0)
274   {
275     if (err.checkSum == 0)
276     {
277       /*std::cout << "PASS "; */
278       return 0;
279     }
280     else
281     {
282       std::cout << "FAIL ";
283       return 1;
284     }
285   }
286   else
287   {
288     //std::cout << err.errorAccum / err.errorCount;
289     if (err.errorAccum / err.errorCount < 0.1)
290     {
291       /*std::cout << " PASS ";*/
292       return 0;
293     }
294     else
295     {
296       std::cout << " FAIL ";
297       return 1;
298     }
299   }
300 }
301 template <typename KERN_TYPE, typename T1, typename T2>
302 void timeThis(KERN_TYPE kernel, T1& inData, T2* outData)
303 {
304   uint64_t startTime;
305   uint64_t finishTime;
306   uint64_t thisDuration;
307   uint64_t meanTime = 0;
308   uint64_t minTime;
309   int numRuns = 1000000;
310   for (int cnt = 0; cnt < numRuns; ++cnt)
311   {
312     startTime = __rdtsc();
313     kernel(inData, outData);
314     kernel(inData, outData);
315     kernel(inData, outData);
316     kernel(inData, outData);
317     kernel(inData, outData);
318     kernel(inData, outData);
319     kernel(inData, outData);
320     kernel(inData, outData);
321     kernel(inData, outData);
322     kernel(inData, outData);
323     finishTime = __rdtsc();
324     thisDuration = (finishTime - startTime);
325     meanTime += thisDuration;
326     if (cnt == 0)
327     {
328       minTime = thisDuration;
329     }
330     else if (thisDuration < minTime)
331     {
332       minTime = thisDuration;
333     }
334   }
335   meanTime = meanTime / numRuns;
336   //std::cout << "10 Executions: Mean Time = " << meanTime << ", Min Time = " << minTime << "\n";
337   printf("10 Executions: Mean Time = %5ld Min Time = %5ld\n", meanTime, minTime);
338 }
339
340
341 int runTest(const int runMode, const int iqWidth, const int numRB, const int numDataElements, const int totNumBlocks)
342 {
343   BlockFloatCompander::ExpandedData expandedDataInput;
344   BlockFloatCompander::CompressedData compressedDataRef;
345   BlockFloatCompander::CompressedData compressedDataKern;
346   BlockFloatCompander::ExpandedData expandedDataRef;
347   BlockFloatCompander::ExpandedData expandedDataKern;
348
349   ErrorData errRef = ErrorData();
350   ErrorData errComp = ErrorData();
351   ErrorData errExp = ErrorData();
352
353   // Create random number generator
354   std::random_device rd;
355   std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
356   std::uniform_int_distribution<int16_t> randInt16(-32767, 32767);
357   std::uniform_int_distribution<int> randExpShift(0, 4);
358
359  // expandedDataInput.dataExpanded    = &expandedDataInput.dataExpandedIn[0];
360  // compressedDataRef.dataCompressed  = &compressedDataRef.dataCompressedDataOut[0];
361  // compressedDataKern.dataCompressed = &compressedDataKern.dataCompressedDataOut[0];
362  // expandedDataRef.dataExpanded      = &expandedDataRef.dataExpandedIn[0];
363  // expandedDataKern.dataExpanded     = &expandedDataKern.dataExpandedIn[0];
364
365   expandedDataInput.iqWidth = iqWidth;
366   expandedDataInput.numBlocks = numRB;
367   expandedDataInput.numDataElements = numDataElements;
368   int totExpValsPerCall = numRB * numDataElements;
369   int totCompValsPerCall = (((numDataElements * iqWidth) >> 3) + 1) * numRB;
370
371   // Assign pointers to input/output data arrays
372   CACHE_ALIGNED int16_t DATAEXPANDED_IN[BlockFloatCompander::k_numSampsExpanded] = { 0 };
373   CACHE_ALIGNED uint8_t DATACOMPRESSED_REF[BlockFloatCompander::k_numSampsCompressed] = { 0 };
374   CACHE_ALIGNED uint8_t DATACOMPRESSED_KERN[BlockFloatCompander::k_numSampsCompressed] = { 0 };
375   CACHE_ALIGNED int16_t DATAEXPANDED_REF[BlockFloatCompander::k_numSampsExpanded] = { 0 };
376   CACHE_ALIGNED int16_t DATAEXPANDED_KERN[BlockFloatCompander::k_numSampsExpanded] = { 0 };
377   expandedDataInput.dataExpanded = DATAEXPANDED_IN;
378   compressedDataRef.dataCompressed = DATACOMPRESSED_REF;
379   expandedDataRef.dataExpanded = DATAEXPANDED_REF;
380   compressedDataKern.dataCompressed = DATACOMPRESSED_KERN;
381   expandedDataKern.dataExpanded = DATAEXPANDED_KERN;
382
383   //-------------------------------------------------------------------------
384   // KERNEL VERIFICATION LOOP
385   //-------------------------------------------------------------------------
386   for (int blk = 0; blk < totNumBlocks; ++blk)
387   {
388     // Generate input data
389     for (int m = 0; m < numRB; ++m)
390     {
391       auto shiftVal = randExpShift(gen);
392       for (int n = 0; n < numDataElements; ++n)
393       {
394         DATAEXPANDED_IN[m * numDataElements + n] = int16_t(randInt16(gen) >> shiftVal);
395       }
396     }
397     // Generate reference
398     BlockFloatCompander::BFPCompressRef(expandedDataInput, &compressedDataRef);
399     BlockFloatCompander::BFPExpandRef(compressedDataRef, &expandedDataRef);
400     // Generate kernel output
401     if (runMode == 1)
402     {
403       // Run Sunny Cove version
404       switch (numDataElements)
405       {
406       case 16:
407         BlockFloatCompander::BFPCompressCtrlPlane8AvxSnc(expandedDataInput, &compressedDataKern);
408         BlockFloatCompander::BFPExpandCtrlPlane8AvxSnc(compressedDataRef, &expandedDataKern);
409         break;
410       case 24:
411         BlockFloatCompander::BFPCompressUserPlaneAvxSnc(expandedDataInput, &compressedDataKern);
412         BlockFloatCompander::BFPExpandUserPlaneAvxSnc(compressedDataRef, &expandedDataKern);
413         break;
414       case 32:
415         BlockFloatCompander::BFPCompressCtrlPlane16AvxSnc(expandedDataInput, &compressedDataKern);
416         BlockFloatCompander::BFPExpandCtrlPlane16AvxSnc(compressedDataRef, &expandedDataKern);
417         break;
418       case 64:
419         BlockFloatCompander::BFPCompressCtrlPlane32AvxSnc(expandedDataInput, &compressedDataKern);
420         BlockFloatCompander::BFPExpandCtrlPlane32AvxSnc(compressedDataRef, &expandedDataKern);
421         break;
422       case 128:
423         BlockFloatCompander::BFPCompressCtrlPlane64AvxSnc(expandedDataInput, &compressedDataKern);
424         BlockFloatCompander::BFPExpandCtrlPlane64AvxSnc(compressedDataRef, &expandedDataKern);
425         break;
426       }
427     }
428     else
429     {
430         // Default Skylake/Palm Cove AVX512 version
431           switch (numDataElements)
432         {
433         case 16:
434           BlockFloatCompander::BFPCompressCtrlPlane8Avx512(expandedDataInput, &compressedDataKern);
435           BlockFloatCompander::BFPExpandCtrlPlane8Avx512(compressedDataRef, &expandedDataKern);
436           break;
437         case 24:
438           if ((iqWidth == 9) && (numRB == 16))
439           {
440             BlockFloatCompander::BFPCompressUserPlaneAvx512_9b16RB(expandedDataInput, &compressedDataKern);
441             BlockFloatCompander::BFPExpandUserPlaneAvx512_9b16RB(compressedDataRef, &expandedDataKern);
442           }
443           else
444           {
445             BlockFloatCompander::BFPCompressUserPlaneAvx512(expandedDataInput, &compressedDataKern);
446             BlockFloatCompander::BFPExpandUserPlaneAvx512(compressedDataRef, &expandedDataKern);
447           }
448           break;
449         case 32:
450           BlockFloatCompander::BFPCompressCtrlPlane16Avx512(expandedDataInput, &compressedDataKern);
451           BlockFloatCompander::BFPExpandCtrlPlane16Avx512(compressedDataRef, &expandedDataKern);
452           break;
453         case 64:
454           BlockFloatCompander::BFPCompressCtrlPlane32Avx512(expandedDataInput, &compressedDataKern);
455           BlockFloatCompander::BFPExpandCtrlPlane32Avx512(compressedDataRef, &expandedDataKern);
456           break;
457         case 128:
458           BlockFloatCompander::BFPCompressCtrlPlane64Avx512(expandedDataInput, &compressedDataKern);
459           BlockFloatCompander::BFPExpandCtrlPlane64Avx512(compressedDataRef, &expandedDataKern);
460           break;
461     }
462 }
463     // Check data
464     compareData(expandedDataInput.dataExpanded, expandedDataRef.dataExpanded, errRef, totExpValsPerCall);
465     compareData(compressedDataRef.dataCompressed, compressedDataKern.dataCompressed, errComp, totCompValsPerCall);
466     compareData(expandedDataRef.dataExpanded, expandedDataKern.dataExpanded, errRef, totExpValsPerCall);
467   }
468   // Verify Reference
469   int resSum = 0;
470   /*std::cout << "Valid Reference: ";*/
471   resSum += checkPass(errRef, 1);
472   // Verify Kernel
473   /*std::cout << "Compression: ";*/
474   resSum += checkPass(errComp, 0);
475   /*std::cout << "Expansion: ";*/
476   resSum += checkPass(errExp, 0);
477   /*std::cout << "\n";*/
478   //-------------------------------------------------------------------------
479   // KERNEL TIMING LOOP
480   //-------------------------------------------------------------------------
481   // Generate input data
482
483   for (int m = 0; m < numRB; ++m)
484   {
485     auto shiftVal = randExpShift(gen);
486     for (int n = 0; n < numDataElements; ++n)
487     {
488       DATAEXPANDED_IN[m * numDataElements + n] = int16_t(randInt16(gen) >> shiftVal);
489     }
490   }
491   // Generate reference
492   BlockFloatCompander::BFPCompressRef(expandedDataInput, &compressedDataRef);
493
494   if (runMode == 1)
495   {
496     // Run Sunny Cove version
497     switch (numDataElements)
498     {
499     case 16:
500       //std::cout << "Timing Control Plane 8 Antennas (SNC)...\n";
501       //std::cout << "Compression: ";
502       printf("BFPCompressCtrlPlane8AvxSnc         iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
503       timeThis(BlockFloatCompander::BFPCompressCtrlPlane8AvxSnc, expandedDataInput, &compressedDataKern);
504       //std::cout << "Expansion  : ";
505       printf("BFPExpandCtrlPlane8AvxSnc           iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
506       timeThis(BlockFloatCompander::BFPExpandCtrlPlane8AvxSnc, compressedDataRef, &expandedDataKern);
507       break;
508     case 24:
509       //std::cout << "Timing User Plane (SNC)...\n";
510       //std::cout << "Compression: ";
511       printf("BFPCompressUserPlaneAvxSnc          iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
512       timeThis(BlockFloatCompander::BFPCompressUserPlaneAvxSnc, expandedDataInput, &compressedDataKern);
513       //std::cout << "Expansion  : ";
514       printf("BFPExpandUserPlaneAvxSnc            iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
515       timeThis(BlockFloatCompander::BFPExpandUserPlaneAvxSnc, compressedDataRef, &expandedDataKern);
516       break;
517     case 32:
518       //std::cout << "Timing Control Plane 16 Antennas (SNC)...\n";
519       //std::cout << "Compression: ";
520       printf("BFPCompressCtrlPlane16AvxSnc        iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
521       timeThis(BlockFloatCompander::BFPCompressCtrlPlane16AvxSnc, expandedDataInput, &compressedDataKern);
522       //std::cout << "Expansion  : ";
523       printf("BFPExpandCtrlPlane16AvxSnc          iqWidth %2d numRB %2d numDataElements %3d ", iqWidth, numRB, numDataElements);
524       timeThis(BlockFloatCompander::BFPExpandCtrlPlane16AvxSnc, compressedDataRef, &expandedDataKern);
525       break;
526     case 64:
527       //std::cout << "Timing Control Plane 32 Antennas (SNC)...\n";
528       //std::cout << "Compression: ";
529       printf("BFPCompressCtrlPlane32AvxSnc        iqWidth %2d numRB %2d numDataElements %3d ", iqWidth, numRB, numDataElements);
530       timeThis(BlockFloatCompander::BFPCompressCtrlPlane32AvxSnc, expandedDataInput, &compressedDataKern);
531       //std::cout << "Expansion  : ";
532       printf("BFPExpandCtrlPlane32AvxSnc          iqWidth %2d numRB %2d numDataElements %3d ", iqWidth, numRB, numDataElements);
533       timeThis(BlockFloatCompander::BFPExpandCtrlPlane32AvxSnc, compressedDataRef, &expandedDataKern);
534       break;
535     case 128:
536       //std::cout << "Timing Control Plane 64 Antennas (SNC)...\n";
537       //std::cout << "Compression: ";
538       printf("BFPCompressCtrlPlane64AvxSnc        iqWidth %2d numRB %2d numDataElements %3d ", iqWidth, numRB, numDataElements);
539       timeThis(BlockFloatCompander::BFPCompressCtrlPlane64AvxSnc, expandedDataInput, &compressedDataKern);
540       //std::cout << "Expansion  : ";
541       printf("BFPExpandCtrlPlane64AvxSnc          iqWidth %2d numRB %2d numDataElements %3d ", iqWidth, numRB, numDataElements);
542       timeThis(BlockFloatCompander::BFPExpandCtrlPlane64AvxSnc, compressedDataRef, &expandedDataKern);
543       break;
544     }
545   }
546   else
547   {
548     // Default Skylake/Palm Cove AVX512 version
549     switch (numDataElements)
550     {
551     case 16:
552       //std::cout << "Timing Control Plane 8 Antennas (AVX512)...\n";
553       //std::cout << "Compression: ";
554       printf("BFPCompressCtrlPlane8Avx512         iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
555       timeThis(BlockFloatCompander::BFPCompressCtrlPlane8Avx512, expandedDataInput, &compressedDataKern);
556       //std::cout << "Expansion  : ";
557       printf("BFPExpandCtrlPlane8Avx512           iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
558       timeThis(BlockFloatCompander::BFPExpandCtrlPlane8Avx512, compressedDataRef, &expandedDataKern);
559       break;
560     case 24:
561       if ((iqWidth == 9) && (numRB == 16))
562       {
563           //std::cout << "Timing User Plane (AVX512)...\n";
564           //std::cout << "Compression: ";
565           printf("BFPCompressUserPlaneAvx512_9b16RB   iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
566           timeThis(BlockFloatCompander::BFPCompressUserPlaneAvx512_9b16RB, expandedDataInput, &compressedDataKern);
567           //std::cout << "Expansion  : ";
568           printf("BFPExpandUserPlaneAvx512_9b16RB     iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
569           timeThis(BlockFloatCompander::BFPExpandUserPlaneAvx512_9b16RB, compressedDataRef, &expandedDataKern);
570       }
571       else
572       {
573           //std::cout << "Timing User Plane (AVX512)...\n";
574           //std::cout << "Compression: ";
575           printf("BFPCompressUserPlaneAvx512          iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
576           timeThis(BlockFloatCompander::BFPCompressUserPlaneAvx512, expandedDataInput, &compressedDataKern);
577           //std::cout << "Expansion  : ";
578           printf("BFPExpandUserPlaneAvx512            iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
579           timeThis(BlockFloatCompander::BFPExpandUserPlaneAvx512, compressedDataRef, &expandedDataKern);
580       }
581       break;
582     case 32:
583       //std::cout << "Timing Control Plane 16 Antennas (AVX512)...\n";
584       //std::cout << "Compression: ";
585       printf("BFPCompressCtrlPlane16Avx512        iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
586       timeThis(BlockFloatCompander::BFPCompressCtrlPlane16Avx512, expandedDataInput, &compressedDataKern);
587       //std::cout << "Expansion  : ";
588       printf("BFPExpandCtrlPlane16Avx512          iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
589       timeThis(BlockFloatCompander::BFPExpandCtrlPlane16Avx512, compressedDataRef, &expandedDataKern);
590       break;
591     case 64:
592       //std::cout << "Timing Control Plane 32 Antennas (AVX512)...\n";
593       //std::cout << "Compression: ";
594       printf("BFPCompressCtrlPlane32Avx512        iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
595       timeThis(BlockFloatCompander::BFPCompressCtrlPlane32Avx512, expandedDataInput, &compressedDataKern);
596       //std::cout << "Expansion  : ";
597       printf("BFPExpandCtrlPlane32Avx512          iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
598       timeThis(BlockFloatCompander::BFPExpandCtrlPlane32Avx512, compressedDataRef, &expandedDataKern);
599       break;
600     case 128:
601       //std::cout << "Timing Control Plane 64 Antennas (AVX512)...\n";
602       //std::cout << "Compression: ";
603       printf("BFPCompressCtrlPlane64Avx512        iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
604       timeThis(BlockFloatCompander::BFPCompressCtrlPlane64Avx512, expandedDataInput, &compressedDataKern);
605       //std::cout << "Expansion  : ";
606       printf("BFPExpandCtrlPlane64Avx512          iqWidth %2d numRB %2d numDataElements %3d ",iqWidth, numRB, numDataElements);
607       timeThis(BlockFloatCompander::BFPExpandCtrlPlane64Avx512, compressedDataRef, &expandedDataKern);
608       break;
609     }
610   }
611
612   return resSum;
613 }
614
615 TEST_P(BfpCheck, AVX512_bfp_main)
616 {
617   int resSum = 0;
618   int iqWidth[4] = { 8, 9, 10, 12 };
619   int numRB[3] = { 1, 4, 16 };
620   int numDataElementsUPlane = 24;
621   int numDataElementsCPlane8 = 16;
622   int numDataElementsCPlane16 = 32;
623   int numDataElementsCPlane32 = 64;
624   int numDataElementsCPlane64 = 128;
625   int totNumBlocks = 100;
626
627   ASSERT_EQ(0, bind_to_cpu(BenchmarkParameters::cpu_id)) << "Failed to bind to cpu!";
628
629   for (int iqw = 0; iqw < 4; ++iqw)
630   {
631     for (int nrb = 0; nrb < 3; ++nrb)
632     {
633       //std::cout << "\n";
634
635       // USER PLANE TESTS
636       //std::cout << "U-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsUPlane << ": ";
637       resSum += runTest(0, iqWidth[iqw], numRB[nrb], numDataElementsUPlane, totNumBlocks);
638
639       // CONTROL PLANE TESTS : 8 Antennas
640       //std::cout << "C-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsCPlane8 << ": ";
641       resSum += runTest(0, iqWidth[iqw], numRB[nrb], numDataElementsCPlane8, totNumBlocks);
642
643       // CONTROL PLANE TESTS : 16 Antennas
644       //std::cout << "C-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsCPlane16 << ": ";
645       resSum += runTest(0, iqWidth[iqw], numRB[nrb], numDataElementsCPlane16, totNumBlocks);
646
647       // CONTROL PLANE TESTS : 32 Antennas
648       //std::cout << "C-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsCPlane32 << ": ";
649       resSum += runTest(0, iqWidth[iqw], numRB[nrb], numDataElementsCPlane32, totNumBlocks);
650
651       // CONTROL PLANE TESTS : 64 Antennas
652       //std::cout << "C-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsCPlane64 << ": ";
653       resSum += runTest(0, iqWidth[iqw], numRB[nrb], numDataElementsCPlane64, totNumBlocks);
654     }
655   }
656
657   ASSERT_EQ(0, resSum);
658 }
659
660 TEST_P(BfpCheck, AVXSNC_bfp_main)
661 {
662   int resSum = 0;
663   int iqWidth[4] = { 8, 9, 10, 12 };
664   int numRB[3] = { 1, 4, 16 };
665   int numDataElementsUPlane = 24;
666   int numDataElementsCPlane8 = 16;
667   int numDataElementsCPlane16 = 32;
668   int numDataElementsCPlane32 = 64;
669   int numDataElementsCPlane64 = 128;
670   int totNumBlocks = 100;
671
672   ASSERT_EQ(0, bind_to_cpu(BenchmarkParameters::cpu_id)) << "Failed to bind to cpu!";
673
674   if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52) == 0)
675      return;
676
677   for (int iqw = 0; iqw < 4; ++iqw)
678   {
679     for (int nrb = 0; nrb < 3; ++nrb)
680     {
681       //std::cout << "\n";
682
683       // USER PLANE TESTS
684       //std::cout << "U-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsUPlane << ": ";
685       resSum += runTest(1, iqWidth[iqw], numRB[nrb], numDataElementsUPlane, totNumBlocks);
686
687       // CONTROL PLANE TESTS : 8 Antennas
688       //std::cout << "C-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsCPlane8 << ": ";
689       resSum += runTest(1, iqWidth[iqw], numRB[nrb], numDataElementsCPlane8, totNumBlocks);
690
691       // CONTROL PLANE TESTS : 16 Antennas
692       //std::cout << "C-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsCPlane16 << ": ";
693       resSum += runTest(1, iqWidth[iqw], numRB[nrb], numDataElementsCPlane16, totNumBlocks);
694
695       // CONTROL PLANE TESTS : 32 Antennas
696       //std::cout << "C-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsCPlane32 << ": ";
697       resSum += runTest(1, iqWidth[iqw], numRB[nrb], numDataElementsCPlane32, totNumBlocks);
698
699       // CONTROL PLANE TESTS : 64 Antennas
700       //std::cout << "C-Plane: Testing iqWidth = " << iqWidth[iqw] << ", numRB = " << numRB[nrb] << ", numElements = " << numDataElementsCPlane64 << ": ";
701       resSum += runTest(1, iqWidth[iqw], numRB[nrb], numDataElementsCPlane64, totNumBlocks);
702     }
703   }
704
705   ASSERT_EQ(0, resSum);
706 }
707
708 TEST_P(BfpCheck, AVX512_sweep_xranlib)
709 {
710     int32_t resSum  = 0;
711     int16_t len = 0;
712
713     int16_t compMethod = XRAN_COMPMETHOD_BLKFLOAT;
714     int16_t iqWidth[]    = {8, 9, 10, 12};
715
716     int16_t numRBs[] = {16, 18, 32, 36, 48, 70, 113, 273};
717     struct xranlib_decompress_request  bfp_decom_req;
718     struct xranlib_decompress_response bfp_decom_rsp;
719
720     struct xranlib_compress_request  bfp_com_req;
721     struct xranlib_compress_response bfp_com_rsp;
722
723     int numDataElements = 24;
724
725     // Create random number generator
726     std::random_device rd;
727     std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
728     std::uniform_int_distribution<int16_t> randInt16(-32768, 32767);
729     std::uniform_int_distribution<int> randExpShift(0, 4);
730
731     BlockFloatCompander::ExpandedData expandedData;
732     expandedData.dataExpanded = &loc_dataExpandedIn[0];
733     BlockFloatCompander::ExpandedData expandedDataRes;
734     expandedDataRes.dataExpanded = &loc_dataExpandedRes[0];
735     for (unsigned int iq_w_id = 0; iq_w_id < sizeof(iqWidth)/sizeof(iqWidth[0]); iq_w_id ++){
736         for (unsigned int tc = 0; tc < sizeof(numRBs)/sizeof(numRBs[0]); tc ++){
737
738             //printf("[%d]numRBs %d [%d] iqWidth %d\n",tc, numRBs[tc], iq_w_id, iqWidth[iq_w_id]);
739             // Generate random test data for compression kernel
740
741             for (int m = 0; m < 18*BlockFloatCompander::k_maxNumBlocks; ++m) {
742                 auto shiftVal = randExpShift(gen);
743                 for (int n = 0; n < numDataElements; ++n) {
744                     expandedData.dataExpanded[m*numDataElements+n] = int16_t(randInt16(gen) >> shiftVal);
745                 }
746             }
747
748             BlockFloatCompander::CompressedData compressedData;
749             compressedData.dataCompressed = &loc_dataCompressedDataOut[0];
750
751             std::memset(&loc_dataCompressedDataOut[0], 0, 288*numDataElements);
752             std::memset(&loc_dataExpandedRes[0], 0, 288*numDataElements);
753
754             std::memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
755             std::memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
756             std::memset(&bfp_decom_req, 0, sizeof(struct xranlib_decompress_request));
757             std::memset(&bfp_decom_rsp, 0, sizeof(struct xranlib_decompress_response));
758
759             bfp_com_req.data_in    = (int16_t *)expandedData.dataExpanded;
760             bfp_com_req.numRBs     = numRBs[tc];
761             bfp_com_req.numDataElements = 24;
762             bfp_com_req.len        = numRBs[tc]*12*2*2;
763             bfp_com_req.compMethod = compMethod;
764             bfp_com_req.iqWidth    = iqWidth[iq_w_id];
765
766             bfp_com_rsp.data_out   = (int8_t *)(compressedData.dataCompressed);
767             bfp_com_rsp.len        = 0;
768
769             xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
770
771             bfp_decom_req.data_in    = (int8_t *)(compressedData.dataCompressed);
772             bfp_decom_req.numRBs     = numRBs[tc];
773             bfp_decom_req.len        = bfp_com_rsp.len;
774             bfp_decom_req.numDataElements = 24;
775             bfp_decom_req.compMethod = compMethod;
776             bfp_decom_req.iqWidth    = iqWidth[iq_w_id];
777
778             bfp_decom_rsp.data_out   = (int16_t *)expandedDataRes.dataExpanded;
779             bfp_decom_rsp.len        = 0;
780
781             xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp);
782
783             resSum += checkDataApprox(expandedData.dataExpanded, expandedDataRes.dataExpanded, numRBs[tc]*numDataElements);
784
785             ASSERT_EQ(numRBs[tc]*12*2*2, bfp_decom_rsp.len);
786             ASSERT_EQ(0, resSum);
787          }
788     }
789 }
790
791 TEST_P(BfpCheck, AVXSNC_sweep_xranlib)
792 {
793     int32_t resSum  = 0;
794     int16_t len = 0;
795
796     int16_t compMethod = XRAN_COMPMETHOD_BLKFLOAT;
797     int16_t iqWidth[]    = {8, 9, 10, 12};
798
799     int16_t numRBs[] = {16, 18, 32, 36, 48, 70, 113, 273};
800     struct xranlib_decompress_request  bfp_decom_req;
801     struct xranlib_decompress_response bfp_decom_rsp;
802
803     struct xranlib_compress_request  bfp_com_req;
804     struct xranlib_compress_response bfp_com_rsp;
805
806     int numDataElements = 24;
807
808
809     if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52) == 0)
810         return;
811
812     // Create random number generator
813     std::random_device rd;
814     std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
815     std::uniform_int_distribution<int16_t> randInt16(-32768, 32767);
816     std::uniform_int_distribution<int> randExpShift(0, 4);
817
818     BlockFloatCompander::ExpandedData expandedData;
819     expandedData.dataExpanded = &loc_dataExpandedIn[0];
820     BlockFloatCompander::ExpandedData expandedDataRes;
821     expandedDataRes.dataExpanded = &loc_dataExpandedRes[0];
822     for (unsigned int iq_w_id = 0; iq_w_id < sizeof(iqWidth)/sizeof(iqWidth[0]); iq_w_id ++){
823         for (unsigned int tc = 0; tc < sizeof(numRBs)/sizeof(numRBs[0]); tc ++){
824
825             //printf("[%d]numRBs %d [%d] iqWidth %d\n",tc, numRBs[tc], iq_w_id, iqWidth[iq_w_id]);
826             // Generate random test data for compression kernel
827
828             for (int m = 0; m < 18*BlockFloatCompander::k_maxNumBlocks; ++m) {
829                 auto shiftVal = randExpShift(gen);
830                 for (int n = 0; n < numDataElements; ++n) {
831                     expandedData.dataExpanded[m*numDataElements+n] = int16_t(randInt16(gen) >> shiftVal);
832                 }
833             }
834
835             BlockFloatCompander::CompressedData compressedData;
836             compressedData.dataCompressed = &loc_dataCompressedDataOut[0];
837
838             std::memset(&loc_dataCompressedDataOut[0], 0, 288*numDataElements);
839             std::memset(&loc_dataExpandedRes[0], 0, 288*numDataElements);
840
841             std::memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
842             std::memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
843             std::memset(&bfp_decom_req, 0, sizeof(struct xranlib_decompress_request));
844             std::memset(&bfp_decom_rsp, 0, sizeof(struct xranlib_decompress_response));
845
846             bfp_com_req.data_in    = (int16_t *)expandedData.dataExpanded;
847             bfp_com_req.numRBs     = numRBs[tc];
848             bfp_com_req.numDataElements = 24;
849             bfp_com_req.len        = numRBs[tc]*12*2*2;
850             bfp_com_req.compMethod = compMethod;
851             bfp_com_req.iqWidth    = iqWidth[iq_w_id];
852
853             bfp_com_rsp.data_out   = (int8_t *)(compressedData.dataCompressed);
854             bfp_com_rsp.len        = 0;
855
856             xranlib_compress_avxsnc(&bfp_com_req, &bfp_com_rsp);
857
858             bfp_decom_req.data_in    = (int8_t *)(compressedData.dataCompressed);
859             bfp_decom_req.numRBs     = numRBs[tc];
860             bfp_decom_req.len        = bfp_com_rsp.len;
861             bfp_decom_req.numDataElements = 24;
862             bfp_decom_req.compMethod = compMethod;
863             bfp_decom_req.iqWidth    = iqWidth[iq_w_id];
864
865             bfp_decom_rsp.data_out   = (int16_t *)expandedDataRes.dataExpanded;
866             bfp_decom_rsp.len        = 0;
867
868             xranlib_decompress_avxsnc(&bfp_decom_req, &bfp_decom_rsp);
869
870             resSum += checkDataApprox(expandedData.dataExpanded, expandedDataRes.dataExpanded, numRBs[tc]*numDataElements);
871
872             ASSERT_EQ(numRBs[tc]*12*2*2, bfp_decom_rsp.len);
873             ASSERT_EQ(0, resSum);
874          }
875     }
876 }
877
878 TEST_P(BfpCheck, AVX512_cp_sweep_xranlib)
879 {
880     int32_t resSum  = 0;
881     int16_t len = 0;
882
883     int16_t compMethod = XRAN_COMPMETHOD_BLKFLOAT;
884     int16_t iqWidth[]    = {8, 9, 10, 12};
885     int16_t numRB = 1;
886     int16_t antElm[] = {8, 16, 32, 64};
887
888     struct xranlib_decompress_request  bfp_decom_req;
889     struct xranlib_decompress_response bfp_decom_rsp;
890
891     struct xranlib_compress_request  bfp_com_req;
892     struct xranlib_compress_response bfp_com_rsp;
893     int32_t numDataElements;
894
895     // Create random number generator
896     std::random_device rd;
897     std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
898     std::uniform_int_distribution<int16_t> randInt16(-32768, 32767);
899     std::uniform_int_distribution<int> randExpShift(0, 4);
900
901     BlockFloatCompander::ExpandedData expandedData;
902     expandedData.dataExpanded = &loc_dataExpandedIn[0];
903     BlockFloatCompander::ExpandedData expandedDataRes;
904     expandedDataRes.dataExpanded = &loc_dataExpandedRes[0];
905
906     for (unsigned int iq_w_id = 0; iq_w_id < sizeof(iqWidth)/sizeof(iqWidth[0]); iq_w_id ++){
907         for (unsigned int tc = 0; tc < sizeof(antElm)/sizeof(antElm[0]); tc ++){
908
909             numDataElements = 2*antElm[tc];
910
911             // Generate input data
912             for (int m = 0; m < numRB; ++m)
913             {
914               auto shiftVal = randExpShift(gen);
915               for (int n = 0; n < numDataElements; ++n)
916               {
917                 expandedData.dataExpanded[m * numDataElements + n] = int16_t(randInt16(gen) >> shiftVal);
918               }
919             }
920
921             BlockFloatCompander::CompressedData compressedData;
922             compressedData.dataCompressed = &loc_dataCompressedDataOut[0];
923
924             std::memset(&loc_dataCompressedDataOut[0], 0, 288*numDataElements);
925             std::memset(&loc_dataExpandedRes[0], 0, 288*numDataElements);
926
927             std::memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
928             std::memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
929             std::memset(&bfp_decom_req, 0, sizeof(struct xranlib_decompress_request));
930             std::memset(&bfp_decom_rsp, 0, sizeof(struct xranlib_decompress_response));
931
932             bfp_com_req.data_in    = (int16_t *)expandedData.dataExpanded;
933             bfp_com_req.numRBs     = numRB;
934             bfp_com_req.numDataElements = numDataElements;
935             bfp_com_req.len        = antElm[tc]*4;
936             bfp_com_req.compMethod = compMethod;
937             bfp_com_req.iqWidth    = iqWidth[iq_w_id];
938
939             bfp_com_rsp.data_out   = (int8_t *)(compressedData.dataCompressed);
940             bfp_com_rsp.len        = 0;
941
942             xranlib_compress_avx512_bfw(&bfp_com_req, &bfp_com_rsp);
943
944             bfp_decom_req.data_in         = (int8_t *)(compressedData.dataCompressed);
945             bfp_decom_req.numRBs          = numRB;
946             bfp_decom_req.numDataElements = numDataElements;
947             bfp_decom_req.len             = bfp_com_rsp.len;
948             bfp_decom_req.compMethod      = compMethod;
949             bfp_decom_req.iqWidth         = iqWidth[iq_w_id];
950
951             bfp_decom_rsp.data_out   = (int16_t *)expandedDataRes.dataExpanded;
952             bfp_decom_rsp.len        = 0;
953
954             xranlib_decompress_avx512_bfw(&bfp_decom_req, &bfp_decom_rsp);
955
956             resSum += checkDataApprox(expandedData.dataExpanded, expandedDataRes.dataExpanded, numRB*numDataElements);
957
958             ASSERT_EQ(antElm[tc]*4, bfp_decom_rsp.len);
959             ASSERT_EQ(0, resSum);
960          }
961     }
962 }
963
964 TEST_P(BfpCheck, AVXSNC_cp_sweep_xranlib)
965 {
966     int32_t resSum  = 0;
967     int16_t len = 0;
968
969     int16_t compMethod = XRAN_COMPMETHOD_BLKFLOAT;
970     int16_t iqWidth[]    = {8, 9, 10, 12};
971     int16_t numRB = 1;
972     int16_t antElm[] = {8, 16, 32, 64};
973
974     struct xranlib_decompress_request  bfp_decom_req;
975     struct xranlib_decompress_response bfp_decom_rsp;
976
977     struct xranlib_compress_request  bfp_com_req;
978     struct xranlib_compress_response bfp_com_rsp;
979     int32_t numDataElements;
980
981     // Create random number generator
982     std::random_device rd;
983     std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
984     std::uniform_int_distribution<int16_t> randInt16(-32768, 32767);
985     std::uniform_int_distribution<int> randExpShift(0, 4);
986
987     BlockFloatCompander::ExpandedData expandedData;
988     expandedData.dataExpanded = &loc_dataExpandedIn[0];
989     BlockFloatCompander::ExpandedData expandedDataRes;
990     expandedDataRes.dataExpanded = &loc_dataExpandedRes[0];
991
992     if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52) == 0)
993         return;
994
995     for (unsigned int iq_w_id = 0; iq_w_id < sizeof(iqWidth)/sizeof(iqWidth[0]); iq_w_id ++){
996         for (unsigned int tc = 0; tc < sizeof(antElm)/sizeof(antElm[0]); tc ++){
997
998             numDataElements = 2*antElm[tc];
999
1000             // Generate input data
1001             for (int m = 0; m < numRB; ++m)
1002             {
1003               auto shiftVal = randExpShift(gen);
1004               for (int n = 0; n < numDataElements; ++n)
1005               {
1006                 expandedData.dataExpanded[m * numDataElements + n] = int16_t(randInt16(gen) >> shiftVal);
1007               }
1008             }
1009
1010             BlockFloatCompander::CompressedData compressedData;
1011             compressedData.dataCompressed = &loc_dataCompressedDataOut[0];
1012
1013             std::memset(&loc_dataCompressedDataOut[0], 0, 288*numDataElements);
1014             std::memset(&loc_dataExpandedRes[0], 0, 288*numDataElements);
1015
1016             std::memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
1017             std::memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
1018             std::memset(&bfp_decom_req, 0, sizeof(struct xranlib_decompress_request));
1019             std::memset(&bfp_decom_rsp, 0, sizeof(struct xranlib_decompress_response));
1020
1021             bfp_com_req.data_in    = (int16_t *)expandedData.dataExpanded;
1022             bfp_com_req.numRBs     = numRB;
1023             bfp_com_req.numDataElements = numDataElements;
1024             bfp_com_req.len        = antElm[tc]*4;
1025             bfp_com_req.compMethod = compMethod;
1026             bfp_com_req.iqWidth    = iqWidth[iq_w_id];
1027
1028             bfp_com_rsp.data_out   = (int8_t *)(compressedData.dataCompressed);
1029             bfp_com_rsp.len        = 0;
1030
1031             xranlib_compress_avxsnc_bfw(&bfp_com_req, &bfp_com_rsp);
1032
1033             bfp_decom_req.data_in         = (int8_t *)(compressedData.dataCompressed);
1034             bfp_decom_req.numRBs          = numRB;
1035             bfp_decom_req.numDataElements = numDataElements;
1036             bfp_decom_req.len             = bfp_com_rsp.len;
1037             bfp_decom_req.compMethod      = compMethod;
1038             bfp_decom_req.iqWidth         = iqWidth[iq_w_id];
1039
1040             bfp_decom_rsp.data_out   = (int16_t *)expandedDataRes.dataExpanded;
1041             bfp_decom_rsp.len        = 0;
1042
1043             xranlib_decompress_avxsnc_bfw(&bfp_decom_req, &bfp_decom_rsp);
1044
1045             resSum += checkDataApprox(expandedData.dataExpanded, expandedDataRes.dataExpanded, numRB*numDataElements);
1046
1047             ASSERT_EQ(antElm[tc]*4, bfp_decom_rsp.len);
1048             ASSERT_EQ(0, resSum);
1049          }
1050     }
1051 }
1052
1053 TEST_P(BfpPerfEx, AVX512_Comp)
1054 {
1055      performance("AVX512", module_name, xranlib_compress_avx512, &bfp_com_req, &bfp_com_rsp);
1056 }
1057
1058 TEST_P(BfpPerfEx, AVX512_DeComp)
1059 {
1060      performance("AVX512", module_name, xranlib_decompress_avx512, &bfp_decom_req, &bfp_decom_rsp);
1061 }
1062
1063 TEST_P(BfpPerfCp, AVX512_CpComp)
1064 {
1065      performance("AVX512", module_name, xranlib_compress_avx512_bfw, &bfp_com_req, &bfp_com_rsp);
1066 }
1067
1068 TEST_P(BfpPerfCp, AVX512_CpDeComp)
1069 {
1070      performance("AVX512", module_name, xranlib_decompress_avx512_bfw, &bfp_decom_req, &bfp_decom_rsp);
1071 }
1072
1073 TEST_P(BfpPerfEx,  AVXSNC_Comp)
1074 {
1075     if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52))
1076          performance("AVXSNC", module_name, xranlib_compress_avxsnc, &bfp_com_req, &bfp_com_rsp);
1077 }
1078
1079 TEST_P(BfpPerfEx, AVXSNC_DeComp)
1080 {
1081     if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52))
1082         performance("AVXSNC", module_name, xranlib_decompress_avxsnc, &bfp_decom_req, &bfp_decom_rsp);
1083 }
1084
1085 TEST_P(BfpPerfCp, AVXSNC_CpComp)
1086 {
1087     if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52))
1088         performance("AVXSNC", module_name, xranlib_compress_avxsnc_bfw, &bfp_com_req, &bfp_com_rsp);
1089 }
1090
1091 TEST_P(BfpPerfCp, AVXSNC_CpDeComp)
1092 {
1093     if(_may_i_use_cpu_feature(_FEATURE_AVX512IFMA52))
1094         performance("AVXSNC", module_name, xranlib_decompress_avxsnc_bfw, &bfp_decom_req, &bfp_decom_rsp);
1095 }
1096
1097 INSTANTIATE_TEST_CASE_P(UnitTest, BfpCheck,
1098                         testing::ValuesIn(get_sequence(BfpCheck::get_number_of_cases("bfp_functional"))));
1099
1100 INSTANTIATE_TEST_CASE_P(UnitTest, BfpPerfEx,
1101                         testing::ValuesIn(get_sequence(BfpPerfEx::get_number_of_cases("bfp_performace_ex"))));
1102
1103 INSTANTIATE_TEST_CASE_P(UnitTest, BfpPerfCp,
1104                         testing::ValuesIn(get_sequence(BfpPerfCp::get_number_of_cases("bfp_performace_cp"))));
1105