Merge remote-tracking branch 'origin/arm_fhi72' into integration_2025_w14_p2 (!3347)
feat(oran_fhlib_5g): O-RAN 7.2 FrontHaul Interface on Arm This MR is enabling the 7.2 FHI on Arm systems. Even though the performance are yet very bad (UE connection is very difficult, 100Mbps DL, almost no UL), still I would like to merge this now since the matter of making the FHI work is rather orthogonal to the performance issues. So merging this feature would provide a reliable settlement on top of which we could then progressively enhance the porting of OAI to Arm. Especially that would make our work easier by having less features to rebase regularly on develop. The main features this MR is made of are: 1. Make the xran patches dual We provide patches for both E and F releases of xran that handles x86 targets as well as Arm targets. Both patches have been tested on both types of machines (armix, broadbill). Thanks to @brobert and @changy for their work on xran. 2. Perform 9-bits BFP compression with ArmRAL Since the BFP compression implementation provided with xran does rely heavily on AVX512, we provide an alternative implementation that is relying on Arm's RAN Acceleration Library (ArmRAL). As of writing this commit description, only 9-bits compression is supported. Other IQ width will be added. This upcoming change does not prevent review to be performed since the BFP compression functions of ArmRAL are identical except for the IQ width. Adding further IQ width is therefore very straightforward. 3. Fixes in oran_fhlib_5g to support Arm The library oran_fhlib_5g needed few changes to successfully compile and run on Arm systems. Thanks to @brobert for his work on oran_fhlib_5g.
This commit is contained in:
@@ -410,6 +410,7 @@ class Containerize():
|
||||
result = re.search('native_arm', self.imageKind)
|
||||
if result is not None:
|
||||
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb', ''))
|
||||
imageNames.append(('ran-build-fhi72', 'build.fhi72.native_arm', 'ran-build-fhi72', ''))
|
||||
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup', ''))
|
||||
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', ''))
|
||||
imageNames.append(('oai-gnb-aerial', 'gNB.aerial', 'oai-gnb-aerial', ''))
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
#
|
||||
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
|
||||
#
|
||||
# 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.
|
||||
# ------------------------------------------------------------------------------
|
||||
# For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# contact@openairinterface.org
|
||||
#
|
||||
|
||||
# FindArmral
|
||||
# -------
|
||||
#
|
||||
# Finds the armral library.
|
||||
# the version is currently hardcoded to 25.01
|
||||
#
|
||||
# Optional options
|
||||
# ^^^^^^^^^^^^^^^^
|
||||
#
|
||||
# ``armral_LOCATION``
|
||||
# The location of the library.
|
||||
#
|
||||
# Imported Targets
|
||||
# ^^^^^^^^^^^^^^^^
|
||||
#
|
||||
# This module provides the following imported targets, if found:
|
||||
#
|
||||
# ``armral``
|
||||
# The armral library
|
||||
#
|
||||
# Result Variables
|
||||
# ^^^^^^^^^^^^^^^^
|
||||
#
|
||||
# This will define the following variables:
|
||||
#
|
||||
# ``armral_FOUND``
|
||||
# True if the system has the armral library.
|
||||
# ``armral_VERSION``
|
||||
# The version of the armral library which was found.
|
||||
# ``armral_INCLUDE_DIRS``
|
||||
# Include directories needed to use armral.
|
||||
# ``armral_LIBRARIES``
|
||||
# Libraries needed to link to armral.
|
||||
#
|
||||
# Cache Variables
|
||||
# ^^^^^^^^^^^^^^^
|
||||
#
|
||||
# The following cache variables may also be set:
|
||||
#
|
||||
# ``armral_INCLUDE_DIR``
|
||||
# The directory containing ``armral.h``.
|
||||
# ``armral_LIBRARY``
|
||||
# The path to the armral library.
|
||||
|
||||
option(armral_LOCATION "directory of ArmRAL library" "")
|
||||
if (NOT armral_LOCATION)
|
||||
set(armral_LOCATION "/usr/local")
|
||||
endif()
|
||||
if (NOT EXISTS ${armral_LOCATION})
|
||||
message(FATAL_ERROR "no such directory: ${armral_LOCATION}")
|
||||
endif()
|
||||
|
||||
find_path(armral_INCLUDE_DIR
|
||||
NAMES
|
||||
armral.h
|
||||
HINTS ${armral_LOCATION}
|
||||
PATH_SUFFIXES include
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
if (NOT armral_INCLUDE_DIR)
|
||||
message(FATAL_ERROR "could not detect armral header at ${armral_LOCATION}/include")
|
||||
endif()
|
||||
|
||||
find_library(armral_LIBRARY
|
||||
NAMES armral
|
||||
HINTS ${armral_LOCATION}
|
||||
PATH_SUFFIXES lib build
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
if (NOT armral_LIBRARY)
|
||||
message(FATAL_ERROR "could not detect armral build artifacts at neither ${armral_LOCATION}/lib nor ${armral_LOCATION}/build")
|
||||
endif()
|
||||
|
||||
# No way to retrieve the version from header or library
|
||||
set(armral_VERSION 25.01)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(armral
|
||||
FOUND_VAR armral_FOUND
|
||||
REQUIRED_VARS
|
||||
armral_LIBRARY
|
||||
armral_INCLUDE_DIR
|
||||
VERSION_VAR armral_VERSION
|
||||
)
|
||||
|
||||
if(armral_FOUND)
|
||||
set(armral_LIBRARIES ${armral_LIBRARY})
|
||||
set(armral_INCLUDE_DIRS ${armral_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if(armral_FOUND AND NOT TARGET armral)
|
||||
add_library(armral UNKNOWN IMPORTED)
|
||||
set_target_properties(armral PROPERTIES
|
||||
IMPORTED_LOCATION "${armral_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${armral_INCLUDE_DIRS}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
armral_INCLUDE_DIR
|
||||
armral_LIBRARY
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,8 @@ The hardware on which we have tried this tutorial:
|
||||
- The NIC card should support hardware PTP time stamping.
|
||||
- If you are using Intel servers then use only Ice Lake or newer generations. In case of AMD use only 4th generation, Genoa or newer.
|
||||
- If you try on any other server apart from the above listed, then choose a desktop/server with clock speed higher than 3.0 GHz and `avx512` capabilities.
|
||||
- This tutorial gives few instructions for Arm targets, but DU execution on Arm systems is yet not functional.
|
||||
This feature is intended to enable experiments and future improvements on Arm systems.
|
||||
|
||||
NICs we have tested so far:
|
||||
|
||||
@@ -403,7 +405,10 @@ git apply ~/openairinterface5g/cmake_targets/tools/oran_fhi_integration_patches/
|
||||
Compile the fronthaul interface library by calling `make` and the option
|
||||
`XRAN_LIB_SO=1` to have it build a shared object. Note that we provide two
|
||||
environment variables `RTE_SDK` for the path to the source tree of DPDK, and
|
||||
`XRAN_DIR` to set the path to the fronthaul library.
|
||||
`XRAN_DIR` to set the path to the fronthaul library.
|
||||
For building for a Arm target, set as well the environment variable `TARGET=armv8`.
|
||||
DU execution on Arm systems is yet not functional.
|
||||
This feature is intended to enable experiments and future improvements on Arm systems.
|
||||
|
||||
**Note**: you need at least gcc-11 and g++-11.
|
||||
|
||||
@@ -420,6 +425,31 @@ WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=~/dpdk-stable-20.11.9/ XRAN_DIR=~/phy/fhi_lib
|
||||
The shared library object `~/phy/fhi_lib/lib/build/libxran.so` must be present
|
||||
before proceeding.
|
||||
|
||||
## For Arm targets only: Install the Arm RAN Acceleration library
|
||||
|
||||
DU execution on Arm systems is yet not functional.
|
||||
This feature is intended to enable experiments and future improvements on Arm systems.
|
||||
|
||||
Clone, configure and build ArmRAL:
|
||||
|
||||
Note: Use option `-DCMAKE_INSTALL_PREFIX=<install-dir>` of cmake to set the installation directory of ArmRAL to `<install-dir>`.
|
||||
If you omit this option, ArmRAL is installed into `/usr/local`.
|
||||
|
||||
```
|
||||
git clone https://git.gitlab.arm.com/networking/ral.git ~/ral
|
||||
cd ~/ral
|
||||
git checkout armral-25.01
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -GNinja -DBUILD_SHARED_LIBS=On ../
|
||||
ninja
|
||||
```
|
||||
|
||||
Once ArmRAL is configured at your convenience and built, you can install it:
|
||||
```
|
||||
ninja install
|
||||
```
|
||||
|
||||
## Build OAI gNB
|
||||
|
||||
You can now proceed building OAI. You build it the same way as for other
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * 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.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
#
|
||||
# Dockerfile for the Open-Air-Interface RAN Build for FHI 7.2
|
||||
# Valid for UBUNTU 22.04
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
FROM ran-base:latest AS ran-base
|
||||
|
||||
ARG E2AP_VERSION=E2AP_V3
|
||||
ARG KPM_VERSION=KPM_V3_00
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Europe
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
|
||||
meson \
|
||||
wget \
|
||||
xz-utils \
|
||||
pkg-config \
|
||||
libnuma-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN rm -Rf /oai-ran
|
||||
WORKDIR /oai-ran
|
||||
COPY . .
|
||||
|
||||
## Download and build DPDK
|
||||
RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
|
||||
tar -xvf dpdk-20.11.9.tar.xz && \
|
||||
cd dpdk-stable-20.11.9 && \
|
||||
meson build && \
|
||||
ninja -C build && \
|
||||
ninja install -C build
|
||||
|
||||
## Build Fronthaul library
|
||||
RUN git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git /opt/phy && \
|
||||
cd /opt/phy && \
|
||||
git checkout oran_f_release_v1.0 &&\
|
||||
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch && \
|
||||
cd /opt/phy/fhi_lib/lib && \
|
||||
TARGET=armv8 WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
|
||||
|
||||
## Build Arm RAN Acceleration Library
|
||||
RUN git clone https://git.gitlab.arm.com/networking/ral.git /opt/ral && \
|
||||
cd /opt/ral && \
|
||||
git checkout armral-25.01 &&\
|
||||
mkdir build && \
|
||||
cd build && \
|
||||
cmake -GNinja -DBUILD_SHARED_LIBS=On /opt/ral/ && \
|
||||
ninja && \
|
||||
ninja install
|
||||
|
||||
FROM ran-base AS ran-build-fhi72
|
||||
## Build and install OAI
|
||||
#run build_oai to build the target image
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log && \
|
||||
./build_oai \
|
||||
--gNB \
|
||||
--build-lib "telnetsrv enbscope uescope nrscope" \
|
||||
-t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=/opt/phy/fhi_lib/lib \
|
||||
--build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \
|
||||
$BUILD_OPTION && \
|
||||
# Mainly to see if the sanitize option was perfectly executed
|
||||
ldd ran_build/build/nr-softmodem && \
|
||||
ldd ran_build/build/liboran_fhlib_5g.so && \
|
||||
ldd /opt/phy/fhi_lib/lib/build/libxran.so
|
||||
|
||||
## Build FlexRIC for SM Models
|
||||
RUN mkdir -p openair2/E2AP/flexric/build && \
|
||||
cd openair2/E2AP/flexric/build && \
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
|
||||
-DXAPP_MULTILANGUAGE=OFF \
|
||||
-DKPM_VERSION=$KPM_VERSION \
|
||||
-DE2AP_VERSION=$E2AP_VERSION \
|
||||
-DCMAKE_C_COMPILER=gcc-12 \
|
||||
-DCMAKE_CXX_COMPILER=g++-12 .. && \
|
||||
ninja && \
|
||||
ninja install
|
||||
@@ -65,7 +65,6 @@
|
||||
// /usr/lib/gcc/x86_64-redhat-linux/8/include/gfniintrin.h:57:1: error: inlining failed in call to always_inline ‘_mm_gf2p8affine_epi64_epi8’: target specific option mismatch
|
||||
#include <simde/x86/clmul.h>
|
||||
|
||||
#include <simde/arm/neon.h>
|
||||
#endif // x86_64 || i386
|
||||
#include <stdbool.h>
|
||||
#include "assertions.h"
|
||||
|
||||
@@ -17,12 +17,12 @@ add_library(oran_fhlib_5g MODULE
|
||||
)
|
||||
|
||||
find_package(xran REQUIRED)
|
||||
if(xran_VERSION VERSION_EQUAL 5.1.4)
|
||||
if(xran_VERSION VERSION_EQUAL 5.1.5)
|
||||
target_compile_definitions(oran_fhlib_5g PRIVATE E_RELEASE)
|
||||
elseif(xran_VERSION VERSION_EQUAL 6.1.1)
|
||||
elseif(xran_VERSION VERSION_EQUAL 6.1.2)
|
||||
target_compile_definitions(oran_fhlib_5g PRIVATE F_RELEASE)
|
||||
else()
|
||||
message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed 5.1.4 (E release) or 6.1.1 (F release)")
|
||||
message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed 5.1.5 (E release) or 6.1.2 (F release)")
|
||||
endif()
|
||||
|
||||
# Ignore xran-specific warning: we don't care/can't change the following warning, so suppress
|
||||
@@ -32,6 +32,11 @@ add_compile_options(-Wno-packed-not-aligned)
|
||||
set_target_properties(oran_fhlib_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native")
|
||||
target_link_libraries(oran_fhlib_5g PRIVATE xran::xran ${dpdk_LINK_LIBRARIES} ${T_LIB} pthread dl rt m numa)
|
||||
target_include_directories(oran_fhlib_5g PRIVATE ${dpdk_INCLUDE_DIRS})
|
||||
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||
find_package(armral REQUIRED)
|
||||
target_sources(oran_fhlib_5g PRIVATE armral_bfp_compression.c)
|
||||
target_link_libraries(oran_fhlib_5g PRIVATE armral)
|
||||
endif()
|
||||
|
||||
add_boolean_option(OAI_FHI72_USE_POLLING OFF "Enable polling in FHI72 driver" ON)
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
|
||||
*
|
||||
* 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.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file radio/fhi_72/armral_bfp_compression.c
|
||||
* \brief BFP compression for the O-RAN 7.2 FrontHaul Interface for Arm systems using the Arm RAN Acceleration Library
|
||||
* \author Romain Beurdouche
|
||||
* \date 2025
|
||||
* \company EURECOM
|
||||
* \email romain.beurdouche@eurecom.fr
|
||||
* \note ArmRAL available at https://git.gitlab.arm.com/networking/ral.git
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "armral.h"
|
||||
#include <rte_branch_prediction.h>
|
||||
|
||||
#include "armral_bfp_compression.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
/**
|
||||
* The function operates on a fixed block size of one Physical Resource Block
|
||||
* (PRB). Each block consists of 12 16-bit complex resource elements. Each block
|
||||
* taken as input is compressed into 24 samples with a common unsigned scaling factor.
|
||||
*
|
||||
* @param[in] iq_width Width in bits of compressed samples.
|
||||
* @param[in] n_prb The number of input resource blocks.
|
||||
* @param[in] src Points to the input complex samples sequence.
|
||||
* @param[out] dst Points to the output compressed data.
|
||||
*/
|
||||
void armral_bfp_compression(uint32_t iq_width, uint32_t n_prb, int16_t *src, int8_t *dst)
|
||||
{
|
||||
armral_status ret = ARMRAL_ARGUMENT_ERROR;
|
||||
switch (iq_width) {
|
||||
case 8:
|
||||
ret = armral_block_float_compr_8bit(n_prb, (armral_cmplx_int16_t *)src, (armral_compressed_data_8bit *)dst, NULL);
|
||||
if (unlikely(ret != ARMRAL_SUCCESS)) {
|
||||
LOG_E(HW, "armral_block_scaling_compr_8bit returned an error: %d\n", (int)ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case 9:
|
||||
ret = armral_block_float_compr_9bit(n_prb, (armral_cmplx_int16_t *)src, (armral_compressed_data_9bit *)dst, NULL);
|
||||
if (unlikely(ret != ARMRAL_SUCCESS)) {
|
||||
LOG_E(HW, "armral_block_scaling_compr_9bit returned an error: %d\n", (int)ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case 14:
|
||||
ret = armral_block_float_compr_14bit(n_prb, (armral_cmplx_int16_t *)src, (armral_compressed_data_14bit *)dst, NULL);
|
||||
if (unlikely(ret != ARMRAL_SUCCESS)) {
|
||||
LOG_E(HW, "armral_block_scaling_compr_14bit returned an error: %d\n", (int)ret);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(HW, "Unsupported IQ width in BFP compression: %d\n", iq_width);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The function operates on a fixed block size of one Physical Resource Block
|
||||
* (PRB). Each block consists of 12 compressed complex resource elements.
|
||||
* Each block taken as input is expanded into 12 16-bit complex samples.
|
||||
*
|
||||
* @param[in] iq_width Width in bits of compressed samples.
|
||||
* @param[in] n_prb The number of input resource blocks.
|
||||
* @param[in] src Points to the input compressed data.
|
||||
* @param[out] dst Points to the output complex samples sequence.
|
||||
*/
|
||||
void armral_bfp_decompression(uint32_t iq_width, uint32_t n_prb, int8_t *src, int16_t *dst)
|
||||
{
|
||||
armral_status ret = ARMRAL_ARGUMENT_ERROR;
|
||||
switch (iq_width) {
|
||||
case 8:
|
||||
ret = armral_block_float_decompr_8bit(n_prb, (armral_compressed_data_8bit *)src, (armral_cmplx_int16_t *)dst, NULL);
|
||||
if (unlikely(ret != ARMRAL_SUCCESS)) {
|
||||
LOG_E(HW, "armral_block_scaling_decompr_8bit returned an error: %d\n", (int)ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case 9:
|
||||
ret = armral_block_float_decompr_9bit(n_prb, (armral_compressed_data_9bit *)src, (armral_cmplx_int16_t *)dst, NULL);
|
||||
if (unlikely(ret != ARMRAL_SUCCESS)) {
|
||||
LOG_E(HW, "armral_block_scaling_decompr_9bit returned an error: %d\n", (int)ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case 14:
|
||||
ret = armral_block_float_decompr_14bit(n_prb, (armral_compressed_data_14bit *)src, (armral_cmplx_int16_t *)dst, NULL);
|
||||
if (unlikely(ret != ARMRAL_SUCCESS)) {
|
||||
LOG_E(HW, "armral_block_scaling_decompr_14bit returned an error: %d\n", (int)ret);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(HW, "Unsupported IQ width in BFP decompression: %d\n", iq_width);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
|
||||
*
|
||||
* 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.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file radio/fhi_72/armral_bfp_compression.h
|
||||
* \brief BFP compression for the O-RAN 7.2 FrontHaul Interface for Arm systems using the Arm RAN Acceleration Library
|
||||
* \author Romain Beurdouche
|
||||
* \date 2025
|
||||
* \company EURECOM
|
||||
* \email romain.beurdouche@eurecom.fr
|
||||
* \note ArmRAL available at https://git.gitlab.arm.com/networking/ral.git
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef __ARMRAL_BFP_COMPRESSION_H__
|
||||
#define __ARMRAL_BFP_COMPRESSION_H__
|
||||
|
||||
/**
|
||||
* The function operates on a fixed block size of one Physical Resource Block
|
||||
* (PRB). Each block consists of 12 16-bit complex resource elements. Each block
|
||||
* taken as input is compressed into 24 samples with a common unsigned scaling factor.
|
||||
*
|
||||
* @param[in] iq_width Width in bits of compressed samples.
|
||||
* @param[in] n_prb The number of input resource blocks.
|
||||
* @param[in] src Points to the input complex samples sequence.
|
||||
* @param[out] dst Points to the output compressed data.
|
||||
*/
|
||||
void armral_bfp_compression(uint32_t iq_width, uint32_t n_prb, int16_t *src, int8_t *dst);
|
||||
|
||||
/**
|
||||
* The function operates on a fixed block size of one Physical Resource Block
|
||||
* (PRB). Each block consists of 12 compressed complex resource elements.
|
||||
* Each block taken as input is expanded into 12 16-bit complex samples.
|
||||
*
|
||||
* @param[in] iq_width Width in bits of compressed samples.
|
||||
* @param[in] n_prb The number of input resource blocks.
|
||||
* @param[in] src Points to the input compressed data.
|
||||
* @param[out] dst Points to the output complex samples sequence.
|
||||
*/
|
||||
void armral_bfp_decompression(uint32_t iq_width, uint32_t n_prb, int8_t *src, int16_t *dst);
|
||||
|
||||
#endif
|
||||
+30
-6
@@ -24,9 +24,13 @@
|
||||
#include <stdlib.h>
|
||||
#include "xran_fh_o_du.h"
|
||||
#include "xran_compression.h"
|
||||
#include "armral_bfp_compression.h"
|
||||
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
#else
|
||||
// xran_cp_api.h uses SIMD, but does not include it
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#include "xran_cp_api.h"
|
||||
#include "xran_sync_api.h"
|
||||
#include "oran_isolate.h"
|
||||
@@ -212,12 +216,14 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot)
|
||||
}
|
||||
}
|
||||
} else if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_BLKFLOAT) {
|
||||
struct xranlib_decompress_request bfp_decom_req = {};
|
||||
struct xranlib_decompress_response bfp_decom_rsp = {};
|
||||
|
||||
int16_t local_dst[12 * 2 * N_SC_PER_PRB] __attribute__((aligned(64)));
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
struct xranlib_decompress_request bfp_decom_req = {};
|
||||
struct xranlib_decompress_response bfp_decom_rsp = {};
|
||||
int payload_len = (3 * ru_conf->iqWidth_PRACH + 1) * 12; // 12 = closest number of PRBs to 139 REs
|
||||
|
||||
bfp_decom_req.data_in = (int8_t *)src;
|
||||
bfp_decom_req.numRBs = 12; // closest number of PRBs to 139 REs
|
||||
bfp_decom_req.len = payload_len;
|
||||
@@ -227,6 +233,11 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot)
|
||||
bfp_decom_rsp.data_out = (int16_t *)local_dst;
|
||||
bfp_decom_rsp.len = 0;
|
||||
xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp);
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
armral_bfp_decompression(ru_conf->iqWidth_PRACH, 12, (int8_t *)src, (int16_t *)local_dst);
|
||||
#else
|
||||
AssertFatal(1 == 0, "BFP decompression not supported on this architecture");
|
||||
#endif
|
||||
// note: this is hardwired for 139 point PRACH sequence, kbar=2
|
||||
if (sym_idx == 0) //
|
||||
for (idx = 0; idx < (139 * 2); idx++)
|
||||
@@ -377,8 +388,6 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
|
||||
|
||||
uint32_t idxElm = 0;
|
||||
uint8_t *src = (uint8_t *)ptr;
|
||||
int16_t payload_len = 0;
|
||||
|
||||
|
||||
LOG_D(HW, "pRbMap->nPrbElm %d\n", pRbMap->nPrbElm);
|
||||
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
|
||||
@@ -409,10 +418,12 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
|
||||
memcpy((void *)dst2, (void *)local_dst, neg_len * 4);
|
||||
memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4);
|
||||
} else if (pRbElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
struct xranlib_decompress_request bfp_decom_req = {};
|
||||
struct xranlib_decompress_response bfp_decom_rsp = {};
|
||||
|
||||
payload_len = (3 * pRbElm->iqWidth + 1) * pRbElm->nRBSize;
|
||||
int16_t payload_len = (3 * pRbElm->iqWidth + 1) * pRbElm->nRBSize;
|
||||
|
||||
bfp_decom_req.data_in = (int8_t *)src;
|
||||
bfp_decom_req.numRBs = pRbElm->nRBSize;
|
||||
bfp_decom_req.len = payload_len;
|
||||
@@ -423,6 +434,11 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
|
||||
bfp_decom_rsp.len = 0;
|
||||
|
||||
xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp);
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
armral_bfp_decompression(pRbElm->iqWidth, pRbElm->nRBSize, (int8_t *)src, (int16_t *)local_dst);
|
||||
#else
|
||||
AssertFatal(1 == 0, "BFP compression not supported on this architecture");
|
||||
#endif
|
||||
memcpy((void *)dst2, (void *)local_dst, neg_len * 4);
|
||||
memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4);
|
||||
outcnt++;
|
||||
@@ -549,9 +565,12 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
for (idx = 0; idx < (pos_len + neg_len) * 2; idx++)
|
||||
((uint16_t *)dst16)[idx] = htons(((uint16_t *)local_src)[idx]);
|
||||
} else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
|
||||
payload_len = (3 * p_prbMapElm->iqWidth + 1) * p_prbMapElm->nRBSize;
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
struct xranlib_compress_request bfp_com_req = {};
|
||||
struct xranlib_compress_response bfp_com_rsp = {};
|
||||
payload_len = (3 * p_prbMapElm->iqWidth + 1) * p_prbMapElm->nRBSize;
|
||||
|
||||
bfp_com_req.data_in = (int16_t *)local_src;
|
||||
bfp_com_req.numRBs = p_prbMapElm->nRBSize;
|
||||
bfp_com_req.len = payload_len;
|
||||
@@ -562,6 +581,11 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
bfp_com_rsp.len = 0;
|
||||
|
||||
xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
armral_bfp_compression(p_prbMapElm->iqWidth, p_prbMapElm->nRBSize, (int16_t *)local_src, (int8_t *)dst);
|
||||
#else
|
||||
AssertFatal(1 == 0, "BFP compression not supported on this architecture");
|
||||
#endif
|
||||
|
||||
} else {
|
||||
printf("p_prbMapElm->compMethod == %d is not supported\n", p_prbMapElm->compMethod);
|
||||
|
||||
@@ -306,7 +306,14 @@ static void oran_allocate_buffers(void *handle,
|
||||
uint32_t xran_max_antenna_nr = RTE_MAX(fh_config->neAxc, fh_config->neAxcUl);
|
||||
uint32_t xran_max_sections_per_slot = RTE_MAX(fh_config->max_sections_per_slot, XRAN_MIN_SECTIONS_PER_SLOT);
|
||||
|
||||
pi->buf_list = _mm_malloc(sizeof(*pi->buf_list), 256);
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
// ARM-specific memory allocation
|
||||
int ret = posix_memalign((void**)&pi->buf_list, 256, sizeof(*pi->buf_list));
|
||||
AssertFatal(ret == 0, "out of memory\n");
|
||||
#else
|
||||
// Intel-specific memory allocation
|
||||
pi->buf_list = _mm_malloc(sizeof(*pi->buf_list), 256);
|
||||
#endif
|
||||
AssertFatal(pi->buf_list != NULL, "out of memory\n");
|
||||
oran_buf_list_t *bl = pi->buf_list;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user