Merge remote-tracking branch 'origin/vrtsim-speedup' into integration_2025_w51 (!3735)

vrtsim: Optimize channel modelling

Optimization pass for channel modelling on transmission in vrtsim. This
comes from a requirement of O-RU to perform channel modelling with minimum
latency. The latency measured in O-RU 4TX 2RX on the UE is lowered from
~400 uS to ~100uS.

- Reduced MAX_CHANNEL_LENGTH to 200 and introduced SAVED_SAMPLES_LEN
- Refactored channel modelling actor allocation to parallelize work better
- Improved batching and task creation for channel modelling
- Replaced static global saved_samples with local static buffer in vrtsim_write_with_chanmod

Create a new CI pipeline for testing with vrtsim on Gracehopper:
https://jenkins-oai.eurecom.fr/job/RAN-VRT-Sim-Test-5G/
This commit is contained in:
Jaroslava Fiedlerova
2025-12-19 15:54:06 +01:00
7 changed files with 783 additions and 57 deletions
+23
View File
@@ -380,6 +380,29 @@ pipeline {
}
}
}
stage ("VRT-Sim-Test-5G") {
when { expression {do5Gtest || do5GUeTest} }
steps {
script {
triggerSlaveJob ('RAN-VRT-Sim-Test-5G', 'VRT-Sim-Test-5G')
}
}
post {
always {
script {
// Using a unique variable name for each test stage to avoid overwriting on a global variable
// due to parallel-time concurrency
vrtSim5GStatus = finalizeSlaveJob('RAN-VRT-Sim-Test-5G')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
failingStages += vrtSim5GStatus
}
}
}
}
stage ("RF-Sim-Test-5G") {
when { expression {do5Gtest || do5GUeTest} }
steps {
@@ -0,0 +1,209 @@
Active_gNBs:
- gnb-rfsim
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity: none
gNBs:
##### Identification parameters:
- gNB_ID: 0xe00
gNB_name: gnb-rfsim
tracking_area_code: 1
plmn_list:
- mcc: 208
mnc: 99
mnc_length: 2
snssaiList:
- sst: 1
sd: 0xffffff
nr_cellid: 12345678
##### Physical parameters:
min_rxtxtime: 6
pusch_AntennaPorts: 2
pdsch_AntennaPorts_XP: 2
servingCellConfigCommon:
#spCellConfigCommon
- physCellId: 0
# downlinkConfigCommon
#frequencyInfoDL
# this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68
absoluteFrequencySSB: 621312
# this is 3300.60 MHz
dl_absoluteFrequencyPointA: 620040
#scs-SpecificCarrierList
dl_offstToCarrier: 0
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing: 1
dl_carrierBandwidth: 106
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=106 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth: 28875
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing: 1
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero: 11
initialDLBWPsearchSpaceZero: 0
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand: 78
#scs-SpecificCarrierList
ul_offstToCarrier: 0
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing: 1
ul_carrierBandwidth: 106
pMax: 20
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth: 28875
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing: 1
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex: 98
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM: 0
prach_msg1_FrequencyStart: 0
zeroCorrelationZoneConfig: 12
preambleReceivedTargetPower: -104
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax: 6
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep: 1
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR: 4
#one (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB: 15
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer: 7
rsrp_ThresholdSSB: 19
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR: 2
prach_RootSequenceIndex: 1
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
msg1_SubcarrierSpacing: 1
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig: 0
msg3_DeltaPreamble: 1
p0_NominalWithGrant: -90
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping: 0
hoppingId: 40
p0_nominal: -90
ssb_PositionsInBurst_Bitmap: 1
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell: 2
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position: 0
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing: 1
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing: 1
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity: 6
nrofDownlinkSlots: 7
nrofDownlinkSymbols: 6
nrofUplinkSlots: 2
nrofUplinkSymbols: 4
ssPBCH_BlockPower: -25
SCTP:
SCTP_INSTREAMS: 2
SCTP_OUTSTREAMS: 2
##### AMF parameters:
amf_ip_address:
- ipv4: 192.168.71.132
NETWORK_INTERFACES:
GNB_IPV4_ADDRESS_FOR_NG_AMF: 192.168.71.140
GNB_IPV4_ADDRESS_FOR_NGU: 192.168.71.140
GNB_PORT_FOR_S1U: 2152 # Spec 2152
MACRLCs:
- num_cc: 1
tr_s_preference: local_L1
tr_n_preference: local_RRC
pusch_TargetSNRx10: 200
pucch_TargetSNRx10: 200
L1s:
- num_cc: 1
tr_n_preference: local_mac
prach_dtx_threshold: 200
# pucch0_dtx_threshold = 150;
RUs:
- local_rf: yes
nb_tx: 2
nb_rx: 2
att_tx: 0
att_rx: 0
bands: [78]
max_pdschReferenceSignalPower: -27
max_rxgain: 75
eNB_instances: [0]
sf_extension: 0
security:
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms: [nea0]
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms: [nia2, nia0]
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering: yes
drb_integrity: no
log_config:
global_log_level: info
hw_log_level: info
phy_log_level: info
mac_log_level: info
rlc_log_level: info
pdcp_log_level: info
rrc_log_level: info
ngap_log_level: debug
f1ap_log_level: debug
channelmod:
max_chan: 10
modellist: DefaultChannelList
DefaultChannelList:
- model_name: server_tx_channel_model
type: AWGN
ploss_dB: 0
noise_power_dB: -100
forgetfact: 0
offset: 0
ds_tdl: 0
@@ -0,0 +1,20 @@
uicc0:
imsi: 208990100001100
key: fec86ba6eb707ed08905757b1bb44b8f
opc: C42449363BBAD02B66D16BC975D77CC1
dnn: oai
nssai_sst: 1
thread-pool: "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
channelmod:
max_chan: 10;
modellist: DefaultChannelList
DefaultChannelList:
- model_name: client_tx_channel_model
type: AWGN
ploss_dB: 0
noise_power_dB: -100
forgetfact: 0
offset: 0
ds_tdl: 0
@@ -0,0 +1,140 @@
<!--
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
-->
<testCaseList>
<htmlTabRef>vrtsim-5gnr-chanmod</htmlTabRef>
<htmlTabName>Monolithic gNB vrtsim + chanmod</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
111111
800813
000011
000012
000013
020011
020012
030011
030012
100011
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<node>localhost</node>
<images>oai-gnb oai-nr-ue</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<node>localhost</node>
</testCase>
<testCase id="000011">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_vrtsim_chanmod</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
</testCase>
<testCase id="000012">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G gNB+UE RF sim SA</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_vrtsim_chanmod</yaml_path>
<services>oai-gnb oai-nr-ue</services>
</testCase>
<testCase id="000013">
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<node>localhost</node>
</testCase>
<testCase id="020011">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<node>localhost</node>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020012">
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<node>localhost</node>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="030011">
<class>Iperf</class>
<desc>Iperf (DL/3Mbps/UDP)(20 sec)</desc>
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id>
<node>localhost</node>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="030012">
<class>Iperf</class>
<desc>Iperf (UL/1Mbps/UDP)(20 sec)</desc>
<iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_ue</id>
<node>localhost</node>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="100011">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 5G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_vrtsim_chanmod</yaml_path>
<d_retx_th>1,0,0,0</d_retx_th>
<u_retx_th>1,0,0,0</u_retx_th>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<node>localhost</node>
<images>oai-gnb oai-nr-ue</images>
</testCase>
</testCaseList>
@@ -0,0 +1,141 @@
<!--
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
-->
<testCaseList>
<htmlTabRef>vrtsim-5gnr-chanmod-gh</htmlTabRef>
<htmlTabName>Monolithic gNB vrtsim + chanmod</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
111111
800813
000011
000012
000013
020011
020012
030011
030012
100011
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<node>localhost</node>
<images>oai-gnb oai-nr-ue</images>
<tag_prefix>arm_</tag_prefix>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<node>localhost</node>
</testCase>
<testCase id="000011">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_vrtsim_chanmod</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
</testCase>
<testCase id="000012">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G gNB+UE RF sim SA</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_vrtsim_chanmod</yaml_path>
<services>oai-gnb oai-nr-ue</services>
</testCase>
<testCase id="000013">
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<node>localhost</node>
</testCase>
<testCase id="020011">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<node>localhost</node>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020012">
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<node>localhost</node>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="030011">
<class>Iperf</class>
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 30 -R</iperf_args>
<id>rfsim5g_ue</id>
<node>localhost</node>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="030012">
<class>Iperf</class>
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 30</iperf_args>
<id>rfsim5g_ue</id>
<node>localhost</node>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="100011">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 5G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_vrtsim_chanmod</yaml_path>
<d_retx_th>1,0,0,0</d_retx_th>
<u_retx_th>1,0,0,0</u_retx_th>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<node>localhost</node>
<images>oai-gnb oai-nr-ue</images>
</testCase>
</testCaseList>
@@ -0,0 +1,163 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
environment:
- TZ=Europe/Paris
- MYSQL_DATABASE=oai_db
- MYSQL_USER=test
- MYSQL_PASSWORD=test
- MYSQL_ROOT_PASSWORD=linux
healthcheck:
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
interval: 10s
timeout: 5s
start_period: 10s
start_interval: 500ms
retries: 30
networks:
public_net:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-amf/etc/config.yaml
depends_on:
- mysql
networks:
public_net:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-smf/etc/config.yaml
depends_on:
- oai-amf
networks:
public_net:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-upf/etc/config.yaml
depends_on:
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
cap_drop:
- ALL
privileged: true
networks:
public_net:
ipv4_address: 192.168.71.134
interface_name: eth0
traffic_net:
ipv4_address: 192.168.72.134
interface_name: eth1
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
depends_on:
- oai-upf
networks:
traffic_net:
ipv4_address: 192.168.72.135
healthcheck:
test: /bin/bash -c "ping -c 2 192.168.72.134"
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
start_interval: 500ms
oai-gnb:
image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop}
container_name: rfsim5g-oai-gnb
cap_drop:
- ALL
environment:
USE_ADDITIONAL_OPTIONS: -E --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role server --vrtsim.chanmod 1
depends_on:
- oai-ext-dn
networks:
public_net:
ipv4_address: 192.168.71.140
volumes:
- ../../conf_files/gnb.sa.band78.106prb.vrtsim.2x2.yaml:/opt/oai-gnb/etc/gnb.yaml
- tmp_data:/tmp/
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s
timeout: 5s
start_period: 10s
start_interval: 500ms
retries: 5
ipc: host
oai-nr-ue:
image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop}
container_name: rfsim5g-oai-nr-ue
cap_drop:
- ALL
cap_add:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --uicc0.imsi 208990100001100 --log_config.global_log_options level,nocolor,time --device.name vrtsim
depends_on:
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.71.150
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ../../conf_files/nrue.vrtsim.chanmod.yaml:/opt/oai-nr-ue/etc/nr-ue.yaml
- tmp_data:/tmp/
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
start_interval: 500ms
ipc: host
networks:
public_net:
driver: bridge
name: rfsim5g-oai-public-net
ipam:
config:
- subnet: 192.168.71.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-public"
traffic_net:
driver: bridge
name: rfsim5g-oai-traffic-net
ipam:
config:
- subnet: 192.168.72.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-traffic"
volumes:
tmp_data:
+87 -57
View File
@@ -54,7 +54,7 @@
typedef enum { ROLE_SERVER = 1, ROLE_CLIENT } role;
#define MAX_NUM_ANTENNAS_TX 4
#define MAX_CHANNEL_LENGTH (1 << 20)
#define SAVED_SAMPLES_LEN 256
#define ROLE_CLIENT_STRING "client"
#define ROLE_SERVER_STRING "server"
@@ -125,9 +125,6 @@ typedef struct {
int client_num_rx_antennas;
} vrtsim_state_t;
// Sample history for channel impulse response
static c16_t saved_samples[MAX_NUM_ANTENNAS_TX][MAX_CHANNEL_LENGTH] __attribute__((aligned(32))) = {0};
static void histogram_add(histogram_t *histogram, double diff)
{
histogram->num_samples++;
@@ -375,6 +372,9 @@ typedef struct {
int nbAnt;
int flags;
int aarx;
int batch_size;
int num_batches;
c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN];
} channel_modelling_args_t;
static void perform_channel_modelling(void *arg)
@@ -417,49 +417,55 @@ static void perform_channel_modelling(void *arg)
}
}
for (int aatx = 0; aatx < nb_tx_ant; aatx++) {
c16_t *previous_samples = saved_samples[aatx];
for (int i = 0; i < nsamps; i++) {
cf_t *impulse_response = channel_impulse_response_p[aatx];
for (int l = 0; l < channel_desc->channel_length; l++) {
int idx = i - l;
// TODO: Use AVX2 for this
c16_t tx_input = idx >= 0 ? input_samples[aatx][idx]
: previous_samples[(channel_modelling_args->timestamp + i + idx) % MAX_CHANNEL_LENGTH];
samples[i].r += tx_input.r * impulse_response[l].r - tx_input.i * impulse_response[l].i;
samples[i].i += tx_input.i * impulse_response[l].r + tx_input.r * impulse_response[l].i;
for (int batch_index = 0; batch_index < channel_modelling_args->num_batches; batch_index++) {
int start_sample = batch_index * channel_modelling_args->batch_size;
int num_samples = min(channel_modelling_args->batch_size, nsamps - start_sample);
if (start_sample >= nsamps) {
break;
}
for (int aatx = 0; aatx < nb_tx_ant; aatx++) {
for (int i = start_sample; i < start_sample + num_samples; i++) {
cf_t *impulse_response = channel_impulse_response_p[aatx];
for (int l = 0; l < channel_desc->channel_length; l++) {
int idx = i - l;
// TODO: Use AVX2 for this
c16_t tx_input = idx >= 0 ? input_samples[aatx][idx]
: channel_modelling_args->saved_samples[aatx][SAVED_SAMPLES_LEN + idx];
samples[i].r += tx_input.r * impulse_response[l].r - tx_input.i * impulse_response[l].i;
samples[i].i += tx_input.i * impulse_response[l].r + tx_input.r * impulse_response[l].i;
}
}
}
}
// Convert to c16_t
c16_t samples_out[aligned_nsamps] __attribute__((aligned(64)));
#if defined(__AVX512F__)
for (int i = 0; i < aligned_nsamps / 8; i++) {
simde__m512 *in = (simde__m512 *)&samples[i * 8];
simde__m256i *out = (simde__m256i *)&samples_out[i * 8];
*out = simde_mm512_cvtsepi32_epi16(simde_mm512_cvtps_epi32(*in));
}
#elif defined(__AVX2__)
for (int i = 0; i < aligned_nsamps / 4; i++) {
simde__m256 *in = (simde__m256 *)&samples[i * 4];
simde__m128i *out = (simde__m128i *)&samples_out[i * 4];
*out = simde_mm256_cvtsepi32_epi16(simde_mm256_cvtps_epi32(*in));
}
#else
for (int i = 0; i < nsamps; i++) {
samples_out[i].r = lroundf(samples[i].r);
samples_out[i].i = lroundf(samples[i].i);
}
#endif
// Convert to c16_t
c16_t samples_out[aligned_nsamps] __attribute__((aligned(64)));
#if defined(__AVX512F__)
for (int i = 0; i < aligned_nsamps / 8; i++) {
simde__m512 *in = (simde__m512 *)&samples[i * 8];
simde__m256i *out = (simde__m256i *)&samples_out[i * 8];
*out = simde_mm512_cvtsepi32_epi16(simde_mm512_cvtps_epi32(*in));
}
#elif defined(__AVX2__)
for (int i = 0; i < aligned_nsamps / 4; i++) {
simde__m256 *in = (simde__m256 *)&samples[i * 4];
simde__m128i *out = (simde__m128i *)&samples_out[i * 4];
*out = simde_mm256_cvtsepi32_epi16(simde_mm256_cvtps_epi32(*in));
}
#else
for (int i = 0; i < nsamps; i++) {
samples_out[i].r = lroundf(samples[i].r);
samples_out[i].i = lroundf(samples[i].i);
}
#endif
vrtsim_write_internal(channel_modelling_args->vrtsim_state,
channel_modelling_args->timestamp,
samples_out,
channel_modelling_args->nsamps,
aarx,
channel_modelling_args->flags,
aarx);
vrtsim_write_internal(channel_modelling_args->vrtsim_state,
channel_modelling_args->timestamp,
samples_out,
channel_modelling_args->nsamps,
aarx,
channel_modelling_args->flags,
aarx);
}
}
static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
@@ -469,7 +475,13 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
int nbAnt,
int flags)
{
AssertFatal(nbAnt < MAX_NUM_ANTENNAS_TX, "Number of antennas %d exceeds maximum %d\n", nbAnt, MAX_NUM_ANTENNAS_TX);
// Sample history for channel impulse response
static c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN] __attribute__((aligned(32))) = {0};
// Indicates what samples are saves in saved_samples
static openair0_timestamp last_timestamp = 0;
const int batch_size = 4096;
AssertFatal(nbAnt <= MAX_NUM_ANTENNAS_TX, "Number of antennas %d exceeds maximum %d\n", nbAnt, MAX_NUM_ANTENNAS_TX);
for (int aarx = 0; aarx < vrtsim_state->peer_info.num_rx_antennas; aarx++) {
notifiedFIFO_elt_t *task = newNotifiedFIFO_elt(sizeof(channel_modelling_args_t), 0, NULL, perform_channel_modelling);
channel_modelling_args_t *args = (channel_modelling_args_t *)NotifiedFifoData(task);
@@ -479,28 +491,45 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
args->nbAnt = nbAnt;
args->flags = flags;
args->aarx = aarx;
args->batch_size = batch_size;
args->num_batches = (nsamps + batch_size - 1) / batch_size;
for (int i = 0; i < nbAnt; i++) {
args->samples[i] = samplesVoid[i];
}
// Fill in saved_samples
size_t gap_samples = timestamp - last_timestamp;
if (gap_samples > 0) {
size_t gap_samples_needed = min(SAVED_SAMPLES_LEN, gap_samples);
for (int aatx = 0; aatx < nbAnt; aatx++) {
memset(&args->saved_samples[aatx][SAVED_SAMPLES_LEN - gap_samples_needed], 0, sizeof(c16_t) * gap_samples_needed);
if (gap_samples < SAVED_SAMPLES_LEN) {
size_t samples_from_saved = SAVED_SAMPLES_LEN - gap_samples_needed;
memcpy(&args->saved_samples[aatx][0], &saved_samples[aatx][SAVED_SAMPLES_LEN - samples_from_saved], sizeof(c16_t) * samples_from_saved);
}
}
} else {
for (int aatx = 0; aatx < nbAnt; aatx++)
memcpy(&args->saved_samples[aatx][0], saved_samples[aatx], sizeof(c16_t) * SAVED_SAMPLES_LEN);
}
memcpy(args->saved_samples, saved_samples, sizeof(saved_samples));
pushNotifiedFIFO(&vrtsim_state->channel_modelling_actors[aarx].fifo, task);
}
int start_index = timestamp % MAX_CHANNEL_LENGTH;
int end_index = min(start_index + nsamps, MAX_CHANNEL_LENGTH);
int cp_nsamps = end_index - start_index;
for (int aatx = 0; aatx < nbAnt; aatx++) {
c16_t *samples = (c16_t *)samplesVoid[aatx];
memcpy(&saved_samples[aatx][start_index], &samples[0], sizeof(c16_t) * cp_nsamps);
}
if (end_index < start_index + nsamps) {
// wrap around condition, write at beginning of buffer
cp_nsamps = nsamps - cp_nsamps; // remaining samples
start_index = 0;
// Save samples for next round
if (nsamps < SAVED_SAMPLES_LEN) {
for (int aatx = 0; aatx < nbAnt; aatx++) {
c16_t *samples = (c16_t *)samplesVoid[aatx];
memcpy(&saved_samples[aatx][start_index], &samples[0], sizeof(c16_t) * cp_nsamps);
memmove(&saved_samples[aatx][0], &saved_samples[aatx][nsamps], sizeof(c16_t) * (SAVED_SAMPLES_LEN - nsamps));
memcpy(&saved_samples[aatx][SAVED_SAMPLES_LEN - nsamps], samplesVoid[aatx], sizeof(c16_t) * nsamps);
}
} else {
for (int aatx = 0; aatx < nbAnt; aatx++) {
c16_t* samples = (c16_t*)samplesVoid[aatx];
memcpy(saved_samples[aatx], &samples[nsamps - SAVED_SAMPLES_LEN], sizeof(c16_t) * (SAVED_SAMPLES_LEN));
}
}
last_timestamp = timestamp + nsamps;
return nsamps;
}
@@ -630,6 +659,7 @@ static int vrtsim_set_freq(openair0_device *device, openair0_config_t *openair0_
__attribute__((__visibility__("default"))) int device_init(openair0_device *device, openair0_config_t *openair0_cfg)
{
randominit();
vrtsim_state_t *vrtsim_state = calloc_or_fail(1, sizeof(vrtsim_state_t));
vrtsim_readconfig(vrtsim_state);
LOG_I(HW,