/****************************************************************************** * * Copyright (c) 2020 Intel. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *******************************************************************************/ /** * @brief xRAN BFP compression/decompression U-plane implementation and interface functions * * @file xran_compression.cpp * @ingroup group_source_xran * @author Intel Corporation **/ #include "xran_compression.hpp" #include "xran_compression.h" #include #include #include #include #include using namespace BlockFloatCompander; /** callback function type for Symbol packet */ typedef void (*xran_bfp_compress_fn)(const BlockFloatCompander::ExpandedData& dataIn, BlockFloatCompander::CompressedData* dataOut); /** callback function type for Symbol packet */ typedef void (*xran_bfp_decompress_fn)(const BlockFloatCompander::CompressedData& dataIn, BlockFloatCompander::ExpandedData* dataOut); int32_t xranlib_compress_avxsnc(const struct xranlib_compress_request *request, struct xranlib_compress_response *response) { BlockFloatCompander::ExpandedData expandedDataInput; BlockFloatCompander::CompressedData compressedDataOut; xran_bfp_compress_fn com_fn = NULL; uint16_t totalRBs = request->numRBs; uint16_t remRBs = totalRBs; int16_t len = 0; int16_t block_idx_bytes = 0; switch (request->iqWidth) { case 8: case 9: case 10: case 12: com_fn = BlockFloatCompander::BFPCompressUserPlaneAvxSnc; break; default: com_fn = BlockFloatCompander::BFPCompressRef; break; } expandedDataInput.iqWidth = request->iqWidth; expandedDataInput.numDataElements = 24; while (remRBs){ expandedDataInput.dataExpanded = &request->data_in[block_idx_bytes]; compressedDataOut.dataCompressed = (uint8_t*)&response->data_out[len]; if(remRBs >= 16){ expandedDataInput.numBlocks = 16; com_fn(expandedDataInput, &compressedDataOut); len += ((3 * expandedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)16); block_idx_bytes += 16*expandedDataInput.numDataElements; remRBs -= 16; }else if(remRBs >= 4){ expandedDataInput.numBlocks = 4; com_fn(expandedDataInput, &compressedDataOut); len += ((3 * expandedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)4); block_idx_bytes +=4*expandedDataInput.numDataElements; remRBs -=4; }else if (remRBs >= 1){ expandedDataInput.numBlocks = 1; com_fn(expandedDataInput, &compressedDataOut); len += ((3 * expandedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)1); block_idx_bytes +=1*expandedDataInput.numDataElements; remRBs = remRBs - 1; } } response->len = ((3 * expandedDataInput.iqWidth) + 1) * totalRBs; return 0; } int32_t xranlib_decompress_avxsnc(const struct xranlib_decompress_request *request, struct xranlib_decompress_response *response) { BlockFloatCompander::CompressedData compressedDataInput; BlockFloatCompander::ExpandedData expandedDataOut; xran_bfp_decompress_fn decom_fn = NULL; uint16_t totalRBs = request->numRBs; uint16_t remRBs = totalRBs; int16_t len = 0; int16_t block_idx_bytes = 0; switch (request->iqWidth) { case 8: case 9: case 10: case 12: decom_fn = BlockFloatCompander::BFPExpandUserPlaneAvxSnc; break; default: decom_fn = BlockFloatCompander::BFPExpandRef; break; } compressedDataInput.iqWidth = request->iqWidth; compressedDataInput.numDataElements = 24; while(remRBs) { compressedDataInput.dataCompressed = (uint8_t*)&request->data_in[block_idx_bytes]; expandedDataOut.dataExpanded = &response->data_out[len]; if(remRBs >= 16){ compressedDataInput.numBlocks = 16; decom_fn(compressedDataInput, &expandedDataOut); len += 16*compressedDataInput.numDataElements; block_idx_bytes += ((3 * compressedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)16); remRBs -= 16; }else if(remRBs >= 4){ compressedDataInput.numBlocks = 4; decom_fn(compressedDataInput, &expandedDataOut); len += 4*compressedDataInput.numDataElements; block_idx_bytes += ((3 * compressedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)4); remRBs -=4; }else if (remRBs >= 1){ compressedDataInput.numBlocks = 1; decom_fn(compressedDataInput, &expandedDataOut); len += 1*compressedDataInput.numDataElements; block_idx_bytes += ((3 * compressedDataInput.iqWidth) + 1) * std::min((int16_t)BlockFloatCompander::k_maxNumBlocks,(int16_t)1); remRBs = remRBs - 1; } } response->len = totalRBs * compressedDataInput.numDataElements * sizeof(int16_t); return 0; } int32_t xranlib_compress_avxsnc_bfw(const struct xranlib_compress_request *request, struct xranlib_compress_response *response) { BlockFloatCompander::ExpandedData expandedDataInput; BlockFloatCompander::CompressedData compressedDataOut; xran_bfp_compress_fn com_fn = NULL; if (request->numRBs != 1){ printf("Unsupported numRBs %d\n", request->numRBs); return -1; } switch (request->iqWidth) { case 8: case 9: case 10: case 12: switch (request->numDataElements) { case 16: com_fn = BlockFloatCompander::BFPCompressCtrlPlane8AvxSnc; break; case 32: com_fn = BlockFloatCompander::BFPCompressCtrlPlane16AvxSnc; break; case 64: com_fn = BlockFloatCompander::BFPCompressCtrlPlane32AvxSnc; break; case 128: com_fn = BlockFloatCompander::BFPCompressCtrlPlane64AvxSnc; break; case 24: default: printf("Unsupported numDataElements %d\n", request->numDataElements); return -1; break; } break; default: printf("Unsupported iqWidth %d\n", request->iqWidth); return -1; break; } expandedDataInput.iqWidth = request->iqWidth; expandedDataInput.numDataElements = request->numDataElements; expandedDataInput.numBlocks = 1; expandedDataInput.dataExpanded = &request->data_in[0]; compressedDataOut.dataCompressed = (uint8_t*)&response->data_out[0]; com_fn(expandedDataInput, &compressedDataOut); response->len = (((expandedDataInput.numDataElements * expandedDataInput.iqWidth) >> 3) + 1) * request->numRBs; return 0; } int32_t xranlib_decompress_avxsnc_bfw(const struct xranlib_decompress_request *request, struct xranlib_decompress_response *response) { BlockFloatCompander::CompressedData compressedDataInput; BlockFloatCompander::ExpandedData expandedDataOut; xran_bfp_decompress_fn decom_fn = NULL; if (request->numRBs != 1){ printf("Unsupported numRBs %d\n", request->numRBs); return -1; } switch (request->iqWidth) { case 8: case 9: case 10: case 12: switch (request->numDataElements) { case 16: decom_fn = BlockFloatCompander::BFPExpandCtrlPlane8AvxSnc; break; case 32: decom_fn = BlockFloatCompander::BFPExpandCtrlPlane16AvxSnc; break; case 64: decom_fn = BlockFloatCompander::BFPExpandCtrlPlane32AvxSnc; break; case 128: decom_fn = BlockFloatCompander::BFPExpandCtrlPlane64AvxSnc; break; case 24: default: printf("Unsupported numDataElements %d\n", request->numDataElements); return -1; break; } break; default: printf("Unsupported iqWidth %d\n", request->iqWidth); return -1; break; } compressedDataInput.iqWidth = request->iqWidth; compressedDataInput.numDataElements = request->numDataElements; compressedDataInput.numBlocks = 1; compressedDataInput.dataCompressed = (uint8_t*)&request->data_in[0]; expandedDataOut.dataExpanded = &response->data_out[0]; decom_fn(compressedDataInput, &expandedDataOut); response->len = request->numRBs * compressedDataInput.numDataElements * sizeof(int16_t); return 0; }