Compare commits

...

110 Commits

Author SHA1 Message Date
Raymond Knopp
c21edcba55 ldpctest memory allocations 2025-10-28 12:02:55 +01:00
Raymond Knopp
4057b35034 fix for compiler definition 2025-09-22 11:56:19 +00:00
Raymond Knopp
d8dc0120b2 fix for use_gpu flag 2025-09-20 09:54:20 +00:00
Raymond Knopp
458797dba5 added build options for including CUDA in OAI L1 libraries. Some initial
memory allocations for CUDA targets (harq->b) for gNB transmitter
2025-09-20 11:43:58 +02:00
Raymond Knopp
75ea127b16 input processing on GPU 2025-09-15 00:14:10 +00:00
Raymond Knopp
e234f586bb modifications for Jetson 2025-09-15 01:16:45 +02:00
Raymond Knopp
905271e89b more GPU offloading (ldpc input processing, circular copy) 2025-09-14 21:31:53 +00:00
Raymond Knopp
162d3782b9 memory allocations for Jetson, gh200 and PCIe-based targets 2025-09-14 12:19:57 +02:00
jetson2-oai
01622f21f9 changes for jetson 2025-09-12 23:23:59 +02:00
Raymond Knopp
f9a87ac94c changes for gh200 (removal of cudaMemcpy) 2025-09-06 10:57:42 +00:00
Raymond Knopp
1088139162 Merge remote-tracking branch 'origin/develop' into ldpc_encoder_cuda 2025-09-06 09:49:32 +00:00
Jaroslava Fiedlerova
d372aa1b50 Merge branch 'integration_2025_w36' into 'develop'
Integration: `2025.w36`

* !3613 Speedup complex rotate for aarch64
* !3614 Ldpc encoder zc384 optimization
* !3625 gNB scheduler small fixes
* !3629 Fix for gNB max feedback time parameter
* !3619 Fix RA 2-Step MgsB Ack at UE
* !3626 Upgrade CI to Aerial 25-2

See merge request oai/openairinterface5g!3627
2025-09-04 16:36:42 +00:00
Jaroslava Fiedlerova
8e32225711 Merge remote-tracking branch 'origin/aerial_25-2' into integration_2025_w36 (!3626)
Upgrade CI to Aerial 25-2

The goal of this MR is to upgrade the Aerial setup to use release 25-2.
2025-09-03 17:00:43 +02:00
Reem Bahsoun
206e44ae54 Replace old nvIPC library with the new one 2025-09-03 13:30:49 +02:00
Jaroslava Fiedlerova
38ed261638 Merge remote-tracking branch 'origin/Fix_MsgB_Ack' into integration_2025_w36 (!3619)
Fix RA 2-Step MgsB Ack at UE

Update condition to prepare MsgB Ack the same way as Msg4 Ack
2025-09-03 12:57:00 +02:00
Jaroslava Fiedlerova
515eb988ab Merge remote-tracking branch 'origin/fix_set_max_fb_time' into integration_2025_w36 (!3629)
Fix for gNB max feedback time parameter

This bug is causing assertions like the following

Assertion (curr_pucch->active == 0) failed!
In nr_csi_meas_reporting() /oai-ran/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c:282
CSI structure is scheduled in advance. It should be free!

because the PUCCH structure would be smaller than it should be causing
overlapping.
2025-09-03 08:43:06 +02:00
Jaroslava Fiedlerova
1271d91676 Merge remote-tracking branch 'origin/minor_sched_fixes' into integration_2025_w36 (!3625)
gNB scheduler small fixes

A couple of fixes in gNB scheduling function. Removing a superfluous input from
CCE function and adding a missing call to reset beam allocation.
2025-09-02 20:51:09 +02:00
francescomani
225e640ca4 fix max feedback time parameter (needs to be computed every time we have that information) 2025-09-02 16:02:17 +02:00
Jaroslava Fiedlerova
774c390bbe Merge remote-tracking branch 'origin/ldpc_encoder_ZC384_optimization' into integration_2025_w36 (!3614)
Ldpc encoder zc384 optimization

This is a modification for the ldpc encoder which improves performance for
high-throughput cases. It contains a newly-generated file for innermost part of
the parity bit generation which, for AVX512, uses the mm512_permutex2var_epi8
instruction and for 128-bit (aarch64) the mm_alignr_epi8 (vextq_s8) in the
computation corresponding to each non-zero bit of the H matrix. This allows for
removing a very large memcpy and reduces the memory demand for the parity matrix
computation. For the moment this is limited to largest case in BG1, namely
Zc=384. This is the only format used when the number of segments after codeblock
segmentation is large (>8). This improves the timing required for ldpc parity
bits generation by more than a factor 2 with AVX512. This significantly reduces
the total time to generate the DLSCH/PDSCH.

See the merge request description for numbers.
2025-09-02 11:06:20 +02:00
Jaroslava Fiedlerova
9d2960eab8 Merge remote-tracking branch 'origin/cpx_rotate_aarch64' into integration_2025_w36 (!3613)
Speedup complex rotate for aarch64

This is a simple optimization for aarch64 for the "rotate_cpx_vector" used for
the phase_rotation in 5G NR. It provides a speedup of around 1.5 on high-end
aarch64 targets compared to the SIMDe translated version. It is implemented with
native NEON intrinsics and was largely inspired by suggestions from ChatGPT 5 :-)
2025-09-02 11:04:44 +02:00
Robert Schmidt
e69ef1d8cc UL scheduler log: print TDA, it has more info 2025-09-02 09:57:32 +02:00
Reem Bahsoun
69de8cbc24 Change cuBB tag to release 25-2 in YAML and documentation 2025-09-02 09:52:23 +02:00
Raymond Knopp
0e09c7c347 Add changes for avx512/aarch64 ldpc encoder optimizations
newly-generated files for innermost part of the parity bit
generation which, for AVX512, uses the mm512_permutex2var_epi8
instruction and for 128-bit (aarch64) the mm_alignr_epi8 (vextq_s8) in
the computation corresponding to each non-zero bit of the H matrix.

It is generated with ldpctest -n0 -g1. the changes for this are in a
future MR.  I did these changes to compare with the GPU version
(ldpc_encoder_cuda), so that the CPU version is as fast as possible. The
generator will come when we merge the GPU encoder/decoder which also has
a generator for the CUDA version. it was difficult to extract the
changes in ldpctest/ldpc_encoder.c so I just took the generated file.

This allows for removing a very large memcpy and reduces the memory
demand for the parity matrix computation. For the moment this is limited
to largest case in BG1, namely Zc=384. This is the only format used when
the number of segments after codeblock segmentation is large (>8).  This
improves the timing required for ldpc parity bits generation by more
than a factor 2 with AVX512. This significantly reduces the total time
to generate the DLSCH/PDSCH
2025-09-02 08:55:08 +02:00
Raymond Knopp
48d19e8a91 Add reset of dlsch_precoding timing counter in nr_dlsim 2025-09-02 08:48:32 +02:00
Raymond Knopp
5e3e8a70ff addition of aarch64 native implementation for rotate_cpx_vector for the case output_shift=15 2025-09-02 08:28:13 +02:00
Raymond Knopp
53813f522c Change target architecture in arm container build to armv8.2-a
This enables some additional instructions needed in the follow-up
commit.
2025-09-02 08:22:34 +02:00
Robert Schmidt
741e9ffae9 Simplify cross-compilation Dockerfile
Redirect to files and manual analysis as done in this Dockerfile is not
necessary since we just output all relevant build files to stdout.
Simplify to do the same here.

See: 35361db76b ("build_oai: don't redirect compilations to a file")
2025-09-02 08:19:40 +02:00
francescomani
2e15430731 adding other missing beam reaset in RA functions 2025-09-01 18:46:22 +02:00
francescomani
15bb046f9c adding a missing beam reaset in pf_dl 2025-09-01 17:25:01 +02:00
francescomani
169de8cdca remove unnecessary input in get_cce_index 2025-09-01 17:17:06 +02:00
Robert Schmidt
f155ad7202 Merge branch 'fix-oaiue-ota' into 'develop'
Fix OAIUE-OTA pipeline and increase tested traffic

I tried to "fix" the OAIUE pipeline in !3610 (merged) for making it more reliable, but inadvertently introduced many ULSCH DTX for UL traffic. Fix this, and increase DL traffic.

See merge request oai/openairinterface5g!3621
2025-08-29 16:22:17 +00:00
Robert Schmidt
2b75e09151 Increase DL UDP traffic for OAIUE OTA pipeline 2025-08-29 14:53:36 +02:00
Robert Schmidt
47d2ba1793 Fix RX gain for OAIUE-OTA pipeline
Adjust to avoid increased ULSCH DTX, probably because of saturation.

Fixes: 69cb71eddc ("Adjust configuration for OAI OTA test")
2025-08-29 14:53:31 +02:00
Robert Schmidt
fbb78ad825 Merge branch 'integration_2025_w35' into 'develop'
Integration: `2025.w35`

* !3604 Consider PDSCH EPRE to DMRS EPRE in NR UE
* !3606 Fix SRS TLV unpack
* !3602 Update RFsim CN
* !3516 [FHI72 M-plane] CM improvements and PM implementation
* !3538 add a new graphical T tracer to see gNB MAC scheduling decisions
* !3425 RFSim test for 10 UEs/process

Closes #950

See merge request oai/openairinterface5g!3610
2025-08-28 21:10:14 +00:00
ndomingues
0942927308 Fix RA 2-Step MgsB Ack at UE
Update condition to prepare MsgB Ack the same way as Msg4 Ack
2025-08-28 16:49:52 +01:00
Robert Schmidt
69cb71eddc Adjust configuration for OAI OTA test 2025-08-28 09:13:02 +02:00
Robert Schmidt
c2eadcbddb Merge remote-tracking branch 'origin/multi-ue-test' into integration_2025_w35 (!3425)
RFSim test for 10 UEs/process

This MR adds a testcase and changes required to run 10 UEs in a single
process with RFSim

- Added deregistration for all connected UEs
- Refactored MAC/RRC instance handling
- made map_current_symbol thread safe
- made opeanir0_cfg thread safe and local
- Added 10UE/process testcase
2025-08-28 08:59:05 +02:00
Raymond Knopp
ef8959c457 complex rotation optimization for NEON 2025-08-27 16:26:41 +00:00
Robert Schmidt
b11354126f Merge remote-tracking branch 'origin/t-gnb-mac' into integration_2025_w35 (!3538)
add a new graphical T tracer to see gNB MAC scheduling decisions

May be useful for debugging
2025-08-27 15:14:55 +02:00
Cedric Roux
c8aea1b970 T: replace 'subframe' by 'tick'
Some code in T tracers is used by both LTE and NR.

In LTE, we expect 10 subframes per frame, and the logging is done with
this assumption. We have one tick per subframe.

In NR, we deal with slots, not subframes. And we have n ticks per frame
(depending on mu). As of today, only n=20 is tested (corresponding to
mu=1).

A previous commit introduced 'subframes_per_frame' which had the correct
meaning for LTE but was truly 'slots per frame' for NR. This creates
confusion.

Let's replace 'subframe' by 'tick' to reduce confusion.
2025-08-27 15:13:59 +02:00
Cedric Roux
fcd0013981 T: add a tracer 'gnb_mac'
To see MAC scheduling decisions. May be useful for debugging.
2025-08-27 15:13:59 +02:00
Robert Schmidt
08a3f98ef0 Merge remote-tracking branch 'origin/oai-ci-update-cn-mbim' into integration_2025_w35 (!3602)
Update RFsim CN

- Update RFsim CNs to latest version
- update the MBIM stop script to remove IP addresses (we don't use this
  script directly, so it does not have an impact)
2025-08-27 13:52:00 +02:00
Robert Schmidt
78b14302be Merge remote-tracking branch 'origin/mplane-improv' into integration_2025_w35 (!3516)
[FHI72 M-plane] CM improvements and PM implementation

Configuration Management:

- addition of the RU username in the fhi_72 section of the config file;
  previously hardcoded to oranbenetel
- modification of the frequency offset, frame structure, fft size,
  cyclic prefix, and Tx gain;
- addition of the managed delay node;

for Tx/Rx endpoints.

Performance Management implementation where OAI gNB
activates/deactivates available RU performance measurements.
2025-08-27 13:50:43 +02:00
Jaroslava Fiedlerova
433d5c1099 CI: update XML and yaml files for 10 UEs/process RFSim test 2025-08-27 13:15:40 +02:00
Bartosz Podrygajlo
cd67c33ba2 Fix NR UE mislabeling MSG2 as DLSCH PDU 2025-08-27 13:15:40 +02:00
Bartosz Podrygajlo
acb2ae93bd Add RFSim 10 UEs/process RFSim test
Add an RFSim test for 10 UEs in a single process.
2025-08-27 13:15:40 +02:00
Bartosz Podrygajlo
d72ee11b32 Make openair0_cfg thread safe
Move openair0_cfg to PHY_VARS_NR_UE making it UE instance specific
and thread safe.
2025-08-27 13:15:37 +02:00
Bartosz Podrygajlo
62bcd822c5 Make map_current_symbol thread safe
Use local function pointers instead of static global variables.
2025-08-26 15:56:32 +02:00
Bartosz Podrygajlo
318d901ef6 Refactor RRC->MAC Communication: Replace ITTI with notifiedFIFO for Multi-UE Support
- Replaced ITTI message queues with notifiedFIFO for RRC to MAC communication in UE.
- Enables correct message delivery to multiple MAC instances running in parallel threads.
- Introduced `nr_mac_rrc_message_t` union for MAC-RRC messages.
- Updated all relevant message handling and initialization code to use notifiedFIFO.
2025-08-26 15:56:20 +02:00
Teodora
995cccc760 Update the FHI M-plane doc
Performance Management support explanation.

Example run modified according to:
- modification of the frequency offset, frame structure, fft size, cyclic prefix, and Tx gain;
- addition of the managed delay node;
for Tx/Rx endpoints.
2025-08-26 15:17:38 +02:00
Teodora
0367881ba9 Performance Management implementation
Introduced a parameter start_up_timing which indicates if PM activation is supported during the start-up
procedure. We initialize this parameter, based on the vendor.

Notification interval is set to 10s.
2025-08-26 15:17:38 +02:00
Teodora
625b4b0cde Add support for RU username parameter for connection to a RU via M-plane
The "sudo" access group is required by OAI gNB.
2025-08-26 15:17:38 +02:00
Teodora
e7db367c9d Rearrange <edit-config>, <validate>, and <commit> RPCs
Refactor these RPCs to facilitate their use in other Management functionalities,
not only Configuration Management.
2025-08-26 15:17:38 +02:00
Teodora
5291afe165 Add a comment for Rx gain correction
Definition in o-ran-uplane-conf.yang model:
"Gain correction of RF path linked with array element or array layers.
 Common part of overall gain_correction.
 gain_correction = common array-carrier gain-correction + eAxC gain correction."
2025-08-26 15:17:38 +02:00
Teodora
eee7d976ec Correct the Tx gain 2025-08-26 15:17:38 +02:00
Teodora
2e9101f833 Add managed delay node in Rx endpoint creation 2025-08-26 15:17:38 +02:00
Teodora
9bb15f15b8 Correctly fill the cyclic prefix for Tx/Rx endpoints 2025-08-26 15:17:38 +02:00
Teodora
8bd6e16ad1 Correctly fill the frame structure for Tx/Rx endpoints and fft size for Rx endpoints 2025-08-26 15:17:38 +02:00
Teodora
0b0e804f73 Properly pass the frequency offset to Tx/Rx endpoints 2025-08-26 15:17:38 +02:00
Teodora
10d60f71ce Separate Tx/Rx endpoint creation
As per o-ran-uplane-conf model, some nodes exist in Rx but not in Tx
(e.g. "ul-fft-sampling-offsets"), and vice versa.
2025-08-26 15:17:38 +02:00
Teodora
4e9e2b39e9 Set the correct yang node name for MTU retrieval 2025-08-26 15:17:38 +02:00
Robert Schmidt
89603f0649 Merge remote-tracking branch 'origin/fix_srs_tlv_unpack' into integration_2025_w35 (!3606)
Fix SRS TLV unpack

This MR changes the type of a variable to get the last index in which we
unpack the full 32 bits in a SRS TLV to int16 instead of uint16, in
order to be -1 when the TLV length is 0, thus skipping unpacking. This
only affects the SRS.indications sent by Aerial L1, which don't have
padding in the TLV, in case of OAI L1, we unpack in "full" 32 bit blocks
until the end of the TLV, if the length is 0, the unpacking loop exits
immediately. Furthermore, it also adds a check for the Report Type
parameter value in handle_nr_srs_measurements. If this value is zero,
according to SCF 222.10.04 Table 3-129 means a null report, so we can
skip processing it.
2025-08-26 14:54:42 +02:00
Robert Schmidt
417913dfaa Merge remote-tracking branch 'origin/fix-ue-pdsch-epre-ratio' into integration_2025_w35 (!3604)
Consider PDSCH EPRE to DMRS EPRE in NR UE

Fix UE PDSCH to DMRS EPRE ratio.

closes #950
2025-08-26 14:54:17 +02:00
Raymond Knopp
a7c53da958 Merge branch 'develop' into ldpc_encoder_cuda 2025-08-26 13:45:47 +02:00
Robert Schmidt
0ebb97c4ae nfapi.md: fix link to current document 2025-08-26 08:45:57 +02:00
Raymond.Knopp
964ffdbf8c remove warnings/errors related to cuda_support_init call on machine without GPUs. 2025-08-25 18:00:45 +02:00
Raymond Knopp
0f98b5a960 removed alignr option for AVX512, instruction is not amenable easily for more than 128-bit SIMD 2025-08-25 17:35:01 +02:00
Raymond Knopp
34ac55fa4e use permutex2var instead of alignr for AVX512 ldpc encoder after tests on AMD Siena (8004) 2025-08-25 12:53:16 +02:00
Raymond Knopp
06b18029c0 alignr for AVX512 in lpdc_encoder to compare 2025-08-25 12:41:02 +02:00
Raymond Knopp
faa19016c9 missing encoder file for aarch64/SSE 2025-08-25 10:37:34 +00:00
Raymond Knopp
3bea864336 some additional changes for AVX512 and AARCH64 and other minor stuff in ldpc_encoder 2025-08-25 09:34:18 +00:00
Thomas Schlichter
e5b68fb6ee NR UE: modify shift value in nr_dlsch_mmse() for improved performance 2025-08-25 09:29:38 +02:00
Raymond Knopp
42cc4d9320 test on AVX512_VBMI capable machine (AMD Genoa) 2025-08-24 21:55:47 +02:00
Raymond Knopp
b878fb0b72 ORAN version 2025-08-24 21:12:46 +02:00
Raymond Knopp
25c696697e added timing information for memcpy in LDPC encoder (CPU and CUDA). New
extension for AVX512 Zc=384 using permutex2var instruction
2025-08-24 21:08:53 +02:00
Raymond Knopp
28e998ebb7 support for PCIe NVidia GPUs (tested with A100) 2025-08-22 21:10:39 +02:00
Rúben Soares Silva
f1fbf4aa29 Skip unpacking SRS.indication TLV when report type is 0
Move the check for timing advance offset being 0xffff to before locking the scheduler
2025-08-22 15:33:35 +01:00
Bartosz Podrygajlo
0d651bf3a9 Add MAX_NUM_NR_UE_INST to NR UE MAC
- Use MAX_NUM_NR_UE_INST in NR UE MAC to control number of MAC instances.
 - Modify the MAC interface slightly so that nr_l2_init_ue only initializes one instance
2025-08-22 16:25:35 +02:00
Bartosz Podrygajlo
014be5326e Use MAX_NUM_NR_UE_INST in RRC
Use MAX_NUM_NR_UE_INST for number of NR UE RRC instances. Change the RRC
interface slightly so nr_rrc_init_ue initializes only one RRC instance pointed
to by the id given to the function
2025-08-22 16:21:46 +02:00
Rúben Soares Silva
c957e11682 Change last_idx type to int16 to properly avoid unpacking if the tlv length is 0 2025-08-22 15:17:47 +01:00
Bartosz Podrygajlo
32f8f258fa NR UE NAS: Use global define MAX_NUM_NR_UE_INST
Use NR UE global MAX_NUM_NR_UE_INST define instead of local define MAX_NAS_UE
2025-08-22 16:13:32 +02:00
Bartosz Podrygajlo
e58c52829d Introduce MAX_NUM_NR_UE_INST
Add a new define for maximum number of NR UE per process
2025-08-22 16:13:32 +02:00
Bartosz Podrygajlo
ba585cd96d Add deregistration for all UE instances. 2025-08-22 16:13:32 +02:00
Bartosz Podrygajlo
598fbb5a24 Consider PDSCH EPRE to DMRS EPRE in NR UE 2025-08-22 15:59:52 +02:00
Robert Schmidt
792a7faf09 MBIM stop script: remove IP address
The CI detects whether a UE connected (and has a PDU session) by trying
to read the IP address. It therefore assumes that as long as the UE is
not connected, no IP would be present.

With the existing stop_quectel_mbim.sh script, this was not the case; it
would simply leave the IP address.  Modify this script to flush all IP
addresses on disconnect to remedy this.
2025-08-21 18:19:06 +02:00
Robert Schmidt
2de3d1f525 CI: Upgrade RFsim CNs to v2.1.10 2025-08-21 18:18:13 +02:00
Raymond Knopp
32248a6628 use ldpc shared lib for sizes other than 384 or 384 with less than 9 segments 2025-08-19 16:23:27 +00:00
Cedric Roux
c4562df2e7 T: add some traces
To be used by next commit.
2025-08-18 15:26:10 +02:00
Cedric Roux
cc87c72ac3 T: fix a typo 2025-08-18 11:53:54 +02:00
Cedric Roux
c4acec706d T: make number of subframes per frame a configurable item
Think: NR with different number of slots per frame depending on mu.

The name 'subframes_per_frame' is a bit ambiguous. It is valid for LTE,
but for NR it should be 'slots_per_frame'.

For example, for sub-carrier spacing of 30KHz, we have 20 slots per
frame, so in this case subframes_per_frame = 20. In reality whatever
the numerology, there is always 10 subframes per frame in NR.

But how to name this variable which is used both for LTE and NR cases?
'subframes_or_slots_per_frame'? It's a bit long and also ambiguous.

Conclusion: no big deal I think. 'subframes_per_frame' and so be it.
2025-08-18 11:53:54 +02:00
Cedric Roux
138886ad5e T: tti view: add automax ability
Also, update a cmake file because compilation of the tracer 'ue' fails
otherwise.
2025-08-18 11:53:54 +02:00
Cedric Roux
595e650f9f T: scrolltti: handle tick discontinuities
For TDD.
2025-08-18 11:53:54 +02:00
Cedric Roux
645393f464 T: throughputlog: handle tick discontinuities
Think: TDD.
2025-08-18 11:53:54 +02:00
Cedric Roux
ee2668b7c3 T GUI: add a get_range() API function for xy_plot 2025-08-18 11:53:54 +02:00
Cedric Roux
c8d64f0dd1 nr rlc: add an API function to retrieve the occupancy of TX list 2025-08-18 11:53:54 +02:00
Raymond Knopp
9c77c7e513 added check for new tconcat timer 2025-08-15 16:23:46 +00:00
Raymond Knp
bdc8e1efa1 more optimization of segement concatenation at output of encoder 2025-08-15 16:41:09 +02:00
Raymond Knopp
b51697c2c1 128-bit NEON optimizations for input and output data formatting 2025-08-15 09:15:56 +00:00
Raymond Knopp
a3adab8312 added missing file for cuda encoder 2025-08-08 15:34:21 +00:00
Raymond Knopp
e4d3520648 add ldpc_encoder32.c. Cleanup of commented code in cuda encoder host functions 2025-08-08 15:32:59 +00:00
Raymond Knopp
3420c2df41 interleaver optimization 2025-08-08 08:27:36 +00:00
Raymond Knopp
7831e52798 handling of multiple 32-bit segment groups, segment interleaving/deinterleaving optimization 2025-08-07 16:45:48 +00:00
Raymond Knopp
b0cf5e4b27 generator for single-worker 2025-06-14 14:43:26 +00:00
Raymond Knopp
4ac89e6d46 removed ldpc_encoder generated file 2025-06-05 07:33:59 +00:00
Raymond Knopp
1c8f88bbb8 added ifdef for unified CPU/GPU memory configuration (e.g. Gracehopper). 2025-06-01 21:22:34 +00:00
Raymond Knopp
2ad88ae0f3 initial implementation of 32-segment interleaved LDPC encoder for NVidia GPU (CUDA). functionally correct and integrated in existing CUDA library. Works only BG1 Zc 384. Integrated into ldpctest 2025-06-01 10:34:20 +00:00
Raymond Knopp
b6a67635ee change to CODING/CMakeLists.txt 2025-05-30 13:01:45 +00:00
Raymond Knopp
3cf8f6344c added initial CUDA implementation (and code generator) for ldpc encoder 2025-05-30 12:56:44 +00:00
Raymond Knopp
6856460923 added entry LDPC encoder routines for CUDA parity check implementation. Limited to BG1 Zc=384 for now. Also, left unoptimized interleaving of input for 32-bit. Will do after with SIMD bit-interleaving. 2025-05-27 21:19:42 +00:00
Raymond Knopp
9a76f26b91 added first version of generator for CUDA LDPC encoder code 2025-05-27 13:31:38 +00:00
152 changed files with 9194 additions and 759 deletions

View File

@@ -170,7 +170,7 @@ endif()
if (NOT CROSS_COMPILE)
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -march=native")
else ()
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -march=armv8-a")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -march=armv8.2-a")
endif()
# add autotools definitions that were maybe used!
@@ -188,6 +188,10 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang
set(commonOpts "${commonOpts} -Wno-unused-command-line-argument")
endif()
if (ENABLE_CUDA)
set(commonOpts "${commonOpts} -DENABLE_CUDA")
endif()
set(CMAKE_C_FLAGS
"${C_FLAGS_PROCESSOR} ${commonOpts} -std=gnu11 -funroll-loops ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS
@@ -987,6 +991,8 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/srs_rx.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c
)
set(PHY_NR_SRC_CU
)
set(PHY_NR_UE_SRC
${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
${OPENAIR1_DIR}/PHY/MODULATION/nr_modulation.c
@@ -1064,7 +1070,17 @@ target_include_directories(PHY_UE PRIVATE ${blas_INCLUDE_DIRS} ${lapacke_INCLUDE
add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON})
target_link_libraries(PHY_NR_COMMON PUBLIC UTIL)
add_library(PHY_NR ${PHY_NR_SRC})
if (ENABLE_CUDA)
find_package(CUDA REQUIRED)
if (NOT CUDA_FOUND)
message(FATAL_ERROR "no CUDA found")
endif()
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-arch=sm_87;")
set(CUDA_VERBOS_BUILD_ON)
cuda_add_library(PHY_NR ${PHY_NR_SRC} ${PHY_NR_SRC_CU})
else()
add_library(PHY_NR ${PHY_NR_SRC})
endif()
target_link_libraries(PHY_NR nr_phy_common nr_common nr_fapi_p5)
add_library(PHY_NR_NO_AVX_256 ${PHY_NR_SRC})
@@ -1980,13 +1996,21 @@ target_link_libraries(smallblocktest PRIVATE
)
#if (ENABLE_CUDA)
# find_package(CUDA REQUIRED)
# if (NOT CUDA_FOUND)
# message(FATAL_ERROR "no CUDA found")
# endif()
# cuda_add_library(ldpctest)
#else()
#endif()
add_executable(ldpctest
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_load.c
)
target_link_libraries(ldpctest PRIVATE
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON -Wl,--end-group
m pthread dl shlib_loader ${T_LIB}
m pthread dl shlib_loader ${T_LIB} ${CUDA_LIBRARIES}
# link 'check_crc' to make it resolved in the LDPC coding libraries
# 'check_crc' is not used in ldpctest so it is not linked in the executable by default
# --whole-archive links 'check_crc' in the executable even though it is note used, see 'man ld'

View File

@@ -455,3 +455,93 @@ l2sim4g_ext_dn:
Host: "%%current_host%%"
NetworkScript: docker exec l2sim4g-trf-gen ip a show dev eth0
CmdPrefix: docker exec l2sim4g-trf-gen
rfsim5g_multiue1:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue1
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue1
AttachScript: docker start rfsim5g-oai-nr-ue
DetachScript: docker stop rfsim5g-oai-nr-ue
MTU: 1500
rfsim5g_multiue2:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue2
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue2
AttachScript: true
DetachScript: true
MTU: 1500
rfsim5g_multiue3:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue3
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue3
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue4:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue4
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue4
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue5:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue5
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue5
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue6:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue6
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue6
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue7:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue7
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue7
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue8:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue8
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue8
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue9:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue9
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue9
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue10:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue10
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue10
AttachScript: "true"
DetachScript: "true"
MTU: 1500

View File

@@ -389,13 +389,13 @@ class Containerize():
elif image != 'ran-build':
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
if image == 'oai-gnb-aerial':
cmd.run('cp -f /opt/nvidia-ipc/nvipc.src.2025.05.20.tar.gz .')
cmd.run('cp -f /opt/nvidia-ipc/nvipc_src.2025.08.27.tar.gz .')
logfile = f'{lSourcePath}/cmake_targets/log/{name}.docker.log'
ret = cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} {option} . > {logfile} 2>&1', timeout=1200)
t = (name, archiveArtifact(cmd, ctx, logfile))
log_files.append(t)
if image == 'oai-gnb-aerial':
cmd.run('rm -f nvipc.src.2025.05.20.tar.gz')
cmd.run('rm -f nvipc_src.2025.08.27.tar.gz')
# check the status of the build
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {name}:{imageTag}")
if ret.returncode != 0:

View File

@@ -112,7 +112,7 @@ gNBs =
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -70;
p0_nominal = -80;
ssb_PositionsInBurst_Bitmap = 1;
@@ -175,7 +175,7 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 180;
pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200;
}
);
@@ -184,7 +184,7 @@ L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
prach_dtx_threshold = 130;
#pucch0_dtx_threshold = 150;
}
);
@@ -198,7 +198,7 @@ RUs = (
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 65;
max_rxgain = 70;
eNB_instances = [0];
sf_extension = 0
sdr_addrs = "addr=192.168.80.52,clock_source=internal,time_source=internal"

View File

@@ -1,3 +1,7 @@
set -x
sudo mbimcli -p -d /dev/cdc-wdm0 --set-radio-state=off
IF=wwan0
sudo ip link set ${IF} down
sudo ip addr flush dev ${IF}

View File

@@ -0,0 +1,210 @@
<!--
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>rfsim-5gnr-tdd-multiue</htmlTabRef>
<htmlTabName>Monolithic SA TDD gNB multiue</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
111111
800813
000001
000002
000003
000008
020001
020002
020003
020004
020105
444445
030001
030002
444444
100001
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<images>oai-gnb-asan oai-nr-ue</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000002">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G gNB RF sim SA</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<services>oai-gnb</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000003">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<services>oai-nr-ue</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000008">
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10</id>
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020002">
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_multiue1</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020003">
<class>Ping</class>
<desc>Ping ext-dn from Second NR-UE</desc>
<id>rfsim5g_multiue2</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020004">
<class>Ping</class>
<desc>Ping Second NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_multiue2</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020005">
<class>Ping</class>
<desc>Ping ext-dn from both UEs</desc>
<id>rfsim5g_multiue1 rfsim5g_multiue2</id>
<nodes>acamas acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020105">
<class>Ping</class>
<desc>Ping ext-dn from all UEs</desc>
<id>rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10</id>
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25 -s 1016</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="030001">
<class>Iperf</class>
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="030002">
<class>Iperf</class>
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="444444">
<class>Detach_UE</class>
<desc>Detach OAI UEs</desc>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
</testCase>
<testCase id="100001">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<d_retx_th>1,0,0,0</d_retx_th>
<u_retx_th>1,0,0,0</u_retx_th>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<images>oai-gnb-asan oai-nr-ue</images>
</testCase>
</testCaseList>

View File

@@ -109,8 +109,8 @@
<testCase id="000100">
<class>Iperf</class>
<desc>iperf (DL/30Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 30M -t 30 -i 1 -R</iperf_args>
<desc>iperf (DL/60Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 60M -t 30 -i 1 -R</iperf_args>
<id>oai_ue_caracal</id>
<svr_id>oc-cn5g</svr_id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>

View File

@@ -24,7 +24,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -36,7 +36,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -48,7 +48,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -24,7 +24,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -36,7 +36,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -48,7 +48,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -37,9 +37,9 @@ Now pull images.
```bash
$ docker pull mysql:8.0
$ docker pull oaisoftwarealliance/oai-amf:v2.1.9
$ docker pull oaisoftwarealliance/oai-smf:v2.1.9
$ docker pull oaisoftwarealliance/oai-upf:v2.1.9
$ docker pull oaisoftwarealliance/oai-amf:v2.1.10
$ docker pull oaisoftwarealliance/oai-smf:v2.1.10
$ docker pull oaisoftwarealliance/oai-upf:v2.1.10
$ docker pull oaisoftwarealliance/trf-gen-cn5g:focal
$ docker pull oaisoftwarealliance/oai-gnb:develop
@@ -52,7 +52,7 @@ $ docker logout
**CAUTION: 2023/01/27 with the release `v1.5.0` of the `CN5G`, the previous version was not compatible any-more.**
**This new version is working only with the `v2.1.9` of the `CN5G`.**
**This new version is working only with `v2.1.9` or later of the `CN5G`.**
# 2. Deploy containers #

View File

@@ -24,7 +24,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -36,7 +36,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -48,7 +48,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -24,7 +24,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -36,7 +36,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -48,7 +48,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -24,7 +24,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -36,7 +36,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -48,7 +48,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -24,7 +24,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -36,7 +36,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -48,7 +48,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -24,7 +24,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -36,7 +36,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -48,7 +48,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -0,0 +1,146 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:8.0
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
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
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:focal
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
oai-gnb:
image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
container_name: rfsim5g-oai-gnb
cap_drop:
- ALL
environment:
USE_ADDITIONAL_OPTIONS: -E --rfsim --log_config.global_log_options level,nocolor,time
ASAN_OPTIONS: detect_leaks=0
depends_on:
- oai-ext-dn
networks:
public_net:
ipv4_address: 192.168.71.140
volumes:
- ../../conf_files/gnb.sa.band78.106prb.rfsim.yaml:/opt/oai-gnb/etc/gnb.yaml
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s
timeout: 5s
retries: 5
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 --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001100 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time --num-ues 10
depends_on:
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.71.150
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ./nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
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"

View File

@@ -0,0 +1,75 @@
uicc0 = {
imsi = "208990100001100";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc1 = {
imsi = "208990100001101";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc2 = {
imsi = "208990100001102";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc3 = {
imsi = "208990100001103";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc4 = {
imsi = "208990100001104";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc5 = {
imsi = "208990100001105";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc6 = {
imsi = "208990100001106";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc7 = {
imsi = "208990100001107";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc8 = {
imsi = "208990100001108";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc9 = {
imsi = "208990100001109";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
thread-pool: "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"

View File

@@ -24,7 +24,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -36,7 +36,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -48,7 +48,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -23,7 +23,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -35,7 +35,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -47,7 +47,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:

View File

@@ -24,7 +24,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -36,7 +36,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -48,7 +48,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -23,7 +23,7 @@ services:
- ../../../cmake_targets/share:/opt/cuBB/share
userns_mode: host
ipc: "shareable"
image: cubb-build:25-1
image: cubb-build:25-2
environment:
- cuBB_SDK=/opt/nvidia/cuBB
command: bash -c "sudo rm -rf /tmp/phy.log && sudo chmod +x /opt/nvidia/cuBB/aerial_l1_entrypoint.sh && /opt/nvidia/cuBB/aerial_l1_entrypoint.sh"

View File

@@ -135,6 +135,8 @@ Options:
CC=/usr/bin/clang CXX=/usr/bin/clang++ ./build_oai ... --sanitize-memory
--sanitize-thread | -fsanitize=thread
Enable the thread sanitizer on all targets
--use-cuda
Tell build to use NVCC for appropriate .cu files and cuda_runtime functions
-h | --help
Print this help"
}
@@ -386,6 +388,9 @@ function main() {
--sanitize-thread | -fsanitize=thread)
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_THREAD=True"
shift;;
--use-cuda)
CMAKE_CMD="$CMAKE_CMD -DENABLE_CUDA=True"
shift;;
--trace-asn1c-enc-dec)
CMAKE_CMD="$CMAKE_CMD -DTRACE_ASN1C_ENC_DEC=ON"
echo_info "Enabling asn1c internal traces via OAI logging system"

View File

@@ -3,6 +3,7 @@
genids
tracer/enb
tracer/gnb
tracer/gnb_mac
tracer/extract_config
tracer/record
tracer/replay

View File

@@ -92,9 +92,13 @@ ID = UE_PHY_INITIATE_RA_PROCEDURE
GROUP = ALL:PHY:UE:WIRESHARK
FORMAT = int,frame : int,subframe_or_slot : int,preamble : int,power
ID = GNB_PHY_DL_TICK
DESC = gNodeB downlink tick - one tick per ms at start of downlink processing
DESC = gNodeB downlink tick - one tick per slot at start of downlink processing
GROUP = ALL:PHY:GRAPHIC:GNB
FORMAT = int,gNB_ID : int,frame : int,subframe
FORMAT = int,gNB_ID : int,frame : int,slot
ID = GNB_PHY_UL_TICK
DESC = gNodeB uplink tick - one tick per slot at start of uplink processing
GROUP = ALL:PHY:GRAPHIC:GNB
FORMAT = int,gNB_ID : int,frame : int,slot
ID = ENB_PHY_MIB
DESC = MIB data
GROUP = ALL:PHY:ENB:WIRESHARK
@@ -221,6 +225,22 @@ ID = NRUE_MAC_DL_RAR_PDU_WITH_DATA
DESC = NR MAC downlink PDU for RAR
GROUP = ALL:MAC:UE:WIRESHARK
FORMAT = int,rnti : int,frame : int,slot : buffer,data
ID = GNB_MAC_DL
DESC = NR MAC downlink scheduler decision for an UE
GROUP = ALL:MAC:GNB
FORMAT = int,rnti : int,frame : int,slot : int,mcs : int,tbs
ID = GNB_MAC_LCID_DL
DESC = NR MAC downlink scheduler decision for an UE for a specific LCID
GROUP = ALL:MAC:GNB
FORMAT = int,rnti : int,frame : int,slot : int,lcid : int,data_size : int,tx_list_occupancy
ID = GNB_MAC_UL
DESC = NR MAC uplink scheduler decision for an UE
GROUP = ALL:MAC:GNB
FORMAT = int,rnti : int,frame : int,slot : int,mcs : int,tbs
ID = GNB_MAC_LCID_UL
DESC = NR MAC uplink traffic received for an UE for a specific LCID
GROUP = ALL:MAC:GNB
FORMAT = int,rnti : int,frame : int,slot : int,lcid : int,data_size
#RLC logs
ID = ENB_RLC_DL

View File

@@ -62,9 +62,13 @@ if(T_TRACER_GUI)
tracer_logger tracer_view tracer_events)
target_link_libraries(gnb PRIVATE png)
add_executable(ue ue.c)
target_link_libraries(ue PRIVATE tracer_utils tracer_filter tracer_gui
add_executable(gnb_mac gnb_mac.c)
target_link_libraries(gnb_mac PRIVATE tracer_utils tracer_filter tracer_gui
tracer_logger tracer_view tracer_events)
add_executable(ue ue.c)
target_link_libraries(ue PRIVATE tracer_utils tracer_view tracer_gui
tracer_logger tracer_filter tracer_events)
target_link_libraries(ue PRIVATE png)
add_executable(vcd vcd.c)
@@ -77,5 +81,5 @@ if(T_TRACER_GUI)
add_subdirectory(gui)
add_dependencies(T_tools enb gnb ue vcd to_vcd)
add_dependencies(T_tools enb gnb gnb_mac ue vcd to_vcd)
endif()

View File

@@ -8,7 +8,7 @@ XLIBS=-lX11 -lpng -lXft
all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
extract_input_subframe extract_output_subframe to_vcd extract multi \
gnb t_tracer_app_gnb t_tracer_app_ue
gnb t_tracer_app_gnb t_tracer_app_ue gnb_mac
record: utils.o record.o database.o configuration.o
$(CC) $(CFLAGS) -o record $^ $(LIBS)
@@ -65,14 +65,18 @@ gnb: utils.o gnb.o database.o event.o handler.o configuration.o \
filter/filter.a
$(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS)
t_tracer_app_gnb: utils.o t_tracer_app_gnb.o database.o event.o handler.o configuration.o \
logger/logger.a filter/filter.a
t_tracer_app_gnb: utils.o t_tracer_app_gnb.o database.o event.o handler.o \
configuration.o logger/logger.a filter/filter.a
$(CC) $(CFLAGS) -o t_tracer_app_gnb $^ $(LIBS) $(XLIBS)
t_tracer_app_ue: utils.o t_tracer_app_ue.o database.o event.o handler.o configuration.o \
logger/logger.a filter/filter.a
t_tracer_app_ue: utils.o t_tracer_app_ue.o database.o event.o handler.o \
configuration.o logger/logger.a filter/filter.a
$(CC) $(CFLAGS) -o t_tracer_app_ue $^ $(LIBS) $(XLIBS)
gnb_mac: gnb_mac.o gui/gui.a view/view.a logger/logger.a filter/filter.a \
utils.o database.o configuration.o handler.o event.o
$(CC) $(CFLAGS) -o gnb_mac $^ $(LIBS) $(XLIBS)
multi.o: ../incgen/T_IDs.h
../incgen/T_IDs.h: ../T_messages.txt
@@ -98,7 +102,8 @@ filter/filter.a:
clean:
rm -f *.o core tracer_remote textlog enb ue vcd record replay
rm -f extract_config macpdu2wireshark extract_input_subframe
rm -f extract_output_subframe to_vcd extract multi gnb t_tracer_app_gnb t_tracer_app_ue
rm -f extract_output_subframe to_vcd extract multi gnb
rm -f t_tracer_app_gnb t_tracer_app_ue gnb_mac
cd gui && $(MAKE) clean
cd view && $(MAKE) clean
cd logger && $(MAKE) clean

View File

@@ -340,12 +340,12 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
l = new_ttilog(h, database,
"ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "threshold", 0);
v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10);
logger_add_view(l, v);
e->pucch1_energy_ue_threshold_logger = l;
l = new_ttilog(h, database,
"ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "energy", 1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
logger_add_view(l, v);
e->pucch1_energy_ue_energy_logger = l;
@@ -368,7 +368,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
widget_add_child(g, line, w, -1);
l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
"ENB_PHY_DLSCH_UE_DCI", "mcs", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
logger_add_view(l, v);
e->dl_mcs_logger = l;
@@ -379,7 +379,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
widget_add_child(g, line, w, -1);
l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
"ENB_PHY_ULSCH_UE_DCI", "mcs", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
logger_add_view(l, v);
e->ul_mcs_logger = l;
@@ -394,8 +394,8 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
widget_add_child(g, col, w, -1);
container_set_child_growable(g, col, w, 1);
l = new_throughputlog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
"ENB_PHY_DLSCH_UE_DCI", "TBS");
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2);
"ENB_PHY_DLSCH_UE_DCI", "TBS", 10);
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 10);
logger_add_view(l, v);
/* UE x UL PHY (truly: DCI) throughput */
@@ -409,8 +409,8 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
widget_add_child(g, col, w, -1);
container_set_child_growable(g, col, w, 1);
l = new_throughputlog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
"ENB_PHY_ULSCH_UE_DCI", "TBS");
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2);
"ENB_PHY_ULSCH_UE_DCI", "TBS", 10);
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 10);
logger_add_view(l, v);
/* downlink/uplink UE DCIs */

View File

@@ -0,0 +1,332 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "utils.h"
#include "gui/gui.h"
#include "view/view.h"
#include "logger/logger.h"
#include "filter/filter.h"
#include "database.h"
#include "configuration.h"
#include "handler.h"
typedef struct {
int used;
} ue_list_item;
typedef struct {
widget *container;
} gnb_gui;
typedef struct {
int socket;
gui *g;
gnb_gui *gg;
event_handler *h;
void *database;
ue_list_item ues[65536];
int rnti_arg;
} gnb_data;
void *gui_thread(void *_g)
{
gui *g = _g;
gui_loop(g);
return 0;
}
void add_ue(gnb_data *gd, int rnti, int lcid)
{
event_handler *h = gd->h;
void *database = gd->database;
gnb_gui *gg = gd->gg;
gui *g = gd->g;
widget *line;
widget *w, *w2, *col;
view *v;
logger *l;
gd->ues[rnti].used = 1;
line = new_container(g, HORIZONTAL);
widget_add_child(g, gg->container, line, -1);
/* label */
char s[512];
sprintf(s, "UE %d", rnti);
widget *label = new_label(g, s);
widget_add_child(g, line, label, -1);
/* DL MCS */
w = new_xy_plot(g, 128, 55, "DL mcs", 20);
xy_plot_set_range(g, w, 0, 1024*20, -2, 30);
widget_add_child(g, line, w, -1);
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
"GNB_MAC_DL", "mcs", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
logger_add_view(l, v);
logger_set_filter(l,
filter_eq(
filter_evarg(database, "GNB_MAC_DL", "rnti"),
filter_int(rnti)));
/* DL TBS */
col = new_container(g, VERTICAL);
widget_add_child(g, line, col, -1);
w = new_xy_plot(g, 70, 10, "DL tbs", 35);
w2 = new_textarea(g, 70, 11, 64);
xy_plot_set_range(g, w, 0, 1024*20, 0, 1000);
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
widget_add_child(g, col, w2, -1);
widget_add_child(g, col, w, -1);
container_set_child_growable(g, col, w, 1);
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
"GNB_MAC_DL", "tbs", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
view_tti_enable_automax(v, w2);
logger_add_view(l, v);
logger_set_filter(l,
filter_eq(
filter_evarg(database, "GNB_MAC_DL", "rnti"),
filter_int(rnti)));
/* DL lcid throughput */
col = new_container(g, VERTICAL);
widget_add_child(g, line, col, -1);
sprintf(s, "DL lcid %d", lcid);
w = new_xy_plot(g, 70, 10, s, 35);
w2 = new_textarea(g, 70, 11, 64);
xy_plot_set_range(g, w, 0, 1000, 0, 100000);
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
widget_add_child(g, col, w2, -1);
widget_add_child(g, col, w, -1);
container_set_child_growable(g, col, w, 1);
l = new_throughputlog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
"GNB_MAC_LCID_DL", "data_size", 20);
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 20);
logger_add_view(l, v);
logger_set_filter(l,
filter_and(
filter_eq(
filter_evarg(database, "GNB_MAC_LCID_DL", "rnti"),
filter_int(rnti)),
filter_eq(
filter_evarg(database, "GNB_MAC_LCID_DL", "lcid"),
filter_int(lcid))));
/* UL MCS */
w = new_xy_plot(g, 128, 55, "UL mcs", 20);
xy_plot_set_range(g, w, 0, 1024*20, -2, 30);
widget_add_child(g, line, w, -1);
/* GNB_PHY_DL_TICK (and not UL) because GNB_MAC_UL is from DCI */
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
"GNB_MAC_UL", "mcs", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
logger_add_view(l, v);
logger_set_filter(l,
filter_eq(
filter_evarg(database, "GNB_MAC_UL", "rnti"),
filter_int(rnti)));
/* UL TBS */
col = new_container(g, VERTICAL);
widget_add_child(g, line, col, -1);
w = new_xy_plot(g, 70, 10, "UL tbs", 35);
w2 = new_textarea(g, 70, 11, 64);
xy_plot_set_range(g, w, 0, 1024*20, 0, 1000);
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
widget_add_child(g, col, w2, -1);
widget_add_child(g, col, w, -1);
container_set_child_growable(g, col, w, 1);
/* GNB_PHY_DL_TICK (and not UL) because GNB_MAC_UL is from DCI */
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
"GNB_MAC_UL", "tbs", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
view_tti_enable_automax(v, w2);
logger_add_view(l, v);
logger_set_filter(l,
filter_eq(
filter_evarg(database, "GNB_MAC_UL", "rnti"),
filter_int(rnti)));
/* UL lcid throughput */
col = new_container(g, VERTICAL);
widget_add_child(g, line, col, -1);
sprintf(s, "UL lcid %d", lcid);
w = new_xy_plot(g, 70, 10, s, 35);
w2 = new_textarea(g, 70, 11, 64);
xy_plot_set_range(g, w, 0, 1000, 0, 100000);
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
widget_add_child(g, col, w2, -1);
widget_add_child(g, col, w, -1);
container_set_child_growable(g, col, w, 1);
l = new_throughputlog(h, database, "GNB_PHY_UL_TICK", "frame", "slot",
"GNB_MAC_LCID_UL", "data_size", 20);
v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 20);
logger_add_view(l, v);
logger_set_filter(l,
filter_and(
filter_eq(
filter_evarg(database, "GNB_MAC_LCID_UL", "rnti"),
filter_int(rnti)),
filter_eq(
filter_evarg(database, "GNB_MAC_LCID_UL", "lcid"),
filter_int(lcid))));
/* lcid RLC tx buffer occupancy */
col = new_container(g, VERTICAL);
widget_add_child(g, line, col, -1);
sprintf(s, "rlc tx %d", lcid);
w = new_xy_plot(g, 70, 10, s, 35);
w2 = new_textarea(g, 70, 11, 64);
xy_plot_set_range(g, w, 0, 1024*20, 0, 1000);
xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK);
widget_add_child(g, col, w2, -1);
widget_add_child(g, col, w, -1);
container_set_child_growable(g, col, w, 1);
l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot",
"GNB_MAC_LCID_DL", "tx_list_occupancy", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20);
view_tti_enable_automax(v, w2);
logger_add_view(l, v);
logger_set_filter(l,
filter_and(
filter_eq(
filter_evarg(database, "GNB_MAC_LCID_DL", "rnti"),
filter_int(rnti)),
filter_eq(
filter_evarg(database, "GNB_MAC_LCID_DL", "lcid"),
filter_int(lcid))));
}
void build_gui(gnb_gui *gg, gui *g)
{
widget *main_window;
main_window = new_toplevel_window(g, 900, 1000, "gNB MAC tracer");
gg->container = new_container(g, VERTICAL);
widget_add_child(g, main_window, gg->container, -1);
}
void usage(void)
{
printf(
"options:\n"
" -d <database file> this option is mandatory\n"
" -ip <host> connect to given IP address (default %s)\n"
" -p <port> connect to given port (default %d)\n",
DEFAULT_REMOTE_IP,
DEFAULT_REMOTE_PORT
);
exit(1);
}
void check_new_ue(void *_gd, event e)
{
gnb_data *gd = _gd;
int rnti = e.e[gd->rnti_arg].i;
if (!gd->ues[rnti].used)
add_ue(gd, rnti, 4);
}
int main(int n, char **v)
{
gui *g;
gnb_gui gg;
gnb_data *gd;
char *database_filename = NULL;
void *database;
char *ip = DEFAULT_REMOTE_IP;
int port = DEFAULT_REMOTE_PORT;
event_handler *h;
int *is_on;
int number_of_events;
int i;
for (i = 1; i < n; i++) {
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
if (!strcmp(v[i], "-d")) { if (i > n-2) usage(); database_filename = v[++i]; continue; }
if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
if (!strcmp(v[i], "-p")) { if (i > n-2) usage(); port = atoi(v[++i]); continue; }
usage();
}
if (database_filename == NULL) {
printf("ERROR: provide a database file (-d)\n");
exit(1);
}
database = parse_database(database_filename);
load_config_file(database_filename);
number_of_events = number_of_ids(database);
is_on = calloc(number_of_events, sizeof(int));
if (is_on == NULL) abort();
on_off(database, "GNB_PHY_DL_TICK", is_on, 1);
on_off(database, "GNB_MAC_DL", is_on, 1);
on_off(database, "GNB_MAC_LCID_DL", is_on, 1);
on_off(database, "GNB_PHY_UL_TICK", is_on, 1);
on_off(database, "GNB_MAC_UL", is_on, 1);
on_off(database, "GNB_MAC_LCID_UL", is_on, 1);
gd = calloc(1, sizeof(*gd)); if (!gd) abort();
h = new_handler(database);
g = gui_init();
new_thread(gui_thread, g);
build_gui(&gg, g);
gd->g = g;
gd->gg = &gg;
gd->h = h;
gd->database = database;
/* get rnti_arg from event GNB_MAC_DL */
int event_id = event_id_from_name(database, "GNB_MAC_DL");
database_event_format f = get_format(database, event_id);
gd->rnti_arg = -1;
for (i = 0; i < f.count; i++) {
if (!strcmp(f.name[i], "rnti")) gd->rnti_arg = i;
}
if (gd->rnti_arg == -1) {
printf("fatal: event 'GNB_MAC_DL' does not have argument 'rnti'\n");
exit(1);
}
if (strcmp(f.type[gd->rnti_arg], "int") != 0) {
printf("fatal: argument 'rnti' of event 'GNB_MAC_DL' is not 'int'\n");
exit(1);
}
register_handler_function(h, event_id, check_new_ue, gd);
OBUF ebuf = {.osize = 0, .omaxsize = 0, .obuf = NULL};
gd->socket = -1;
restart:
clear_remote_config();
if (gd->socket != -1) close(gd->socket);
gd->socket = connect_to(ip, port);
/* send the first message - activate selected traces */
int t = 1;
if (socket_send(gd->socket, &t, 1) == -1 ||
socket_send(gd->socket, &number_of_events, sizeof(int)) == -1 ||
socket_send(gd->socket, is_on, number_of_events * sizeof(int)) == -1)
goto restart;
while (1) {
event e;
e = get_event(gd->socket, &ebuf, database);
if (e.type == -1) goto restart;
handle_event(h, e);
}
return 0;
}

View File

@@ -54,6 +54,8 @@ void container_set_child_growable(gui *_gui, widget *_this,
int xy_plot_new_plot(gui *gui, widget *this, int color);
void xy_plot_set_range(gui *gui, widget *this,
float xmin, float xmax, float ymin, float ymax);
void xy_plot_get_range(gui *gui, widget *this,
float *xmin, float *xmax, float *ymin, float *ymax);
void xy_plot_set_points(gui *gui, widget *this,
int plot, int npoints, float *x, float *y);
void xy_plot_get_dimensions(gui *gui, widget *this, int *width, int *height);

View File

@@ -280,6 +280,22 @@ void xy_plot_set_range(gui *_gui, widget *_this,
gunlock(g);
}
void xy_plot_get_range(gui *_gui, widget *_this,
float *xmin, float *xmax, float *ymin, float *ymax)
{
struct gui *g = _gui;
struct xy_plot_widget *this = _this;
glock(g);
*xmin = this->xmin;
*xmax = this->xmax;
*ymin = this->ymin;
*ymax = this->ymax;
gunlock(g);
}
void xy_plot_set_points(gui *_gui, widget *_this, int plot,
int npoints, float *x, float *y)
{

View File

@@ -15,8 +15,8 @@ logger *new_ticked_ttilog(void *event_handler, void *database,
char *event_name, char *data_varname,
int convert_to_dB, float empty_value);
logger *new_throughputlog(void *event_handler, void *database,
char *tick_event_name, char *frame_varname, char *subframe_varname,
char *event_name, char *data_varname);
char *tick_event_name, char *frame_varname, char *tick_varname,
char *event_name, char *data_varname, int ticks_per_frame);
logger *new_timelog(void *event_handler, void *database, char *event_name);
logger *new_ticklog(void *event_handler, void *database,
char *event_name, char *frame_name, char *subframe_name);

View File

@@ -13,13 +13,14 @@ struct throughputlog {
struct logger common;
void *database;
int tick_frame_arg;
int tick_subframe_arg;
int tick_tick_arg;
int data_frame_arg;
int data_subframe_arg;
int data_tick_arg;
int data_arg;
int last_tick_frame;
int last_tick_subframe;
unsigned long bits[1000];
int last_tick_tick;
int ticks_per_frame;
unsigned long *bits;
unsigned long total;
int insert_point;
char *tick_event_name;
@@ -32,16 +33,16 @@ static void _event(void *p, event e)
{
struct throughputlog *l = p;
int frame;
int subframe;
int tick;
unsigned long value;
if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0)
return;
frame = e.e[l->data_frame_arg].i;
subframe = e.e[l->data_subframe_arg].i;
tick = e.e[l->data_tick_arg].i;
if (frame != l->last_tick_frame || subframe != l->last_tick_subframe) {
if (frame != l->last_tick_frame || tick != l->last_tick_tick) {
printf("WARNING: %s:%d: data comes without previous tick!\n",
__FILE__, __LINE__);
return;
@@ -62,28 +63,34 @@ static void _tick_event(void *p, event e)
struct throughputlog *l = p;
int i;
int frame;
int subframe;
int tick;
if (l->tick_filter != NULL && filter_eval(l->tick_filter, e) == 0)
return;
frame = e.e[l->tick_frame_arg].i;
subframe = e.e[l->tick_subframe_arg].i;
tick = e.e[l->tick_tick_arg].i;
for (i = 0; i < l->common.vsize; i++)
l->common.v[i]->append(l->common.v[i], frame, subframe, (double)l->total);
l->common.v[i]->append(l->common.v[i], frame, tick, (double)l->total);
l->insert_point = (l->insert_point + 1) % 1000;
l->total -= l->bits[l->insert_point];
l->bits[l->insert_point] = 0;
while (l->last_tick_frame != frame || l->last_tick_tick != tick) {
l->insert_point = (l->insert_point + 1) % (100 * l->ticks_per_frame);
l->total -= l->bits[l->insert_point];
l->bits[l->insert_point] = 0;
l->last_tick_tick++;
if (l->last_tick_tick == l->ticks_per_frame) {
l->last_tick_tick = 0;
l->last_tick_frame++;
l->last_tick_frame %= 1024;
}
}
l->last_tick_frame = frame;
l->last_tick_subframe = subframe;
}
logger *new_throughputlog(event_handler *h, void *database,
char *tick_event_name, char *frame_varname, char *subframe_varname,
char *event_name, char *data_varname)
char *tick_event_name, char *frame_varname, char *tick_varname,
char *event_name, char *data_varname, int ticks_per_frame)
{
struct throughputlog *ret;
int event_id;
@@ -106,21 +113,21 @@ logger *new_throughputlog(event_handler *h, void *database,
f = get_format(database, event_id);
/* look for frame and subframe */
/* look for frame and tick */
ret->tick_frame_arg = -1;
ret->tick_subframe_arg = -1;
ret->tick_tick_arg = -1;
for (i = 0; i < f.count; i++) {
if (!strcmp(f.name[i], frame_varname)) ret->tick_frame_arg = i;
if (!strcmp(f.name[i], subframe_varname)) ret->tick_subframe_arg = i;
if (!strcmp(f.name[i], tick_varname)) ret->tick_tick_arg = i;
}
if (ret->tick_frame_arg == -1) {
printf("%s:%d: frame argument '%s' not found in event '%s'\n",
__FILE__, __LINE__, frame_varname, event_name);
abort();
}
if (ret->tick_subframe_arg == -1) {
printf("%s:%d: subframe argument '%s' not found in event '%s'\n",
__FILE__, __LINE__, subframe_varname, event_name);
if (ret->tick_tick_arg == -1) {
printf("%s:%d: tick argument '%s' not found in event '%s'\n",
__FILE__, __LINE__, tick_varname, event_name);
abort();
}
if (strcmp(f.type[ret->tick_frame_arg], "int") != 0) {
@@ -128,9 +135,9 @@ logger *new_throughputlog(event_handler *h, void *database,
__FILE__, __LINE__, frame_varname);
abort();
}
if (strcmp(f.type[ret->tick_subframe_arg], "int") != 0) {
if (strcmp(f.type[ret->tick_tick_arg], "int") != 0) {
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
__FILE__, __LINE__, subframe_varname);
__FILE__, __LINE__, tick_varname);
abort();
}
@@ -141,13 +148,13 @@ logger *new_throughputlog(event_handler *h, void *database,
f = get_format(database, event_id);
/* look for frame, subframe and data args */
/* look for frame, tick and data args */
ret->data_frame_arg = -1;
ret->data_subframe_arg = -1;
ret->data_tick_arg = -1;
ret->data_arg = -1;
for (i = 0; i < f.count; i++) {
if (!strcmp(f.name[i], frame_varname)) ret->data_frame_arg = i;
if (!strcmp(f.name[i], subframe_varname)) ret->data_subframe_arg = i;
if (!strcmp(f.name[i], tick_varname)) ret->data_tick_arg = i;
if (!strcmp(f.name[i], data_varname)) ret->data_arg = i;
}
if (ret->data_frame_arg == -1) {
@@ -155,9 +162,9 @@ logger *new_throughputlog(event_handler *h, void *database,
__FILE__, __LINE__, frame_varname, event_name);
abort();
}
if (ret->data_subframe_arg == -1) {
printf("%s:%d: subframe argument '%s' not found in event '%s'\n",
__FILE__, __LINE__, subframe_varname, event_name);
if (ret->data_tick_arg == -1) {
printf("%s:%d: tick argument '%s' not found in event '%s'\n",
__FILE__, __LINE__, tick_varname, event_name);
abort();
}
if (ret->data_arg == -1) {
@@ -170,9 +177,9 @@ logger *new_throughputlog(event_handler *h, void *database,
__FILE__, __LINE__, frame_varname);
abort();
}
if (strcmp(f.type[ret->data_subframe_arg], "int") != 0) {
if (strcmp(f.type[ret->data_tick_arg], "int") != 0) {
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
__FILE__, __LINE__, subframe_varname);
__FILE__, __LINE__, tick_varname);
abort();
}
if (strcmp(f.type[ret->data_arg], "int") != 0 &&
@@ -183,6 +190,10 @@ logger *new_throughputlog(event_handler *h, void *database,
abort();
}
ret->ticks_per_frame = ticks_per_frame;
ret->bits = calloc(100 * ticks_per_frame, sizeof(unsigned long));
if (ret->bits == NULL) abort();
return ret;
}

View File

@@ -250,15 +250,15 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -130, 35);
/*l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rssi", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#720c0c"));
v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10);
logger_add_view(l, v);
e->phy_meas_logger = l;*/
l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rsrp", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
logger_add_view(l, v);
e->phy_meas_logger = l;
l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "snr", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c720c"));
v = new_view_tti(10, g, w, new_color(g, "#0c720c"), 10);
logger_add_view(l, v);
e->phy_meas_logger = l;
@@ -277,7 +277,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
widget_add_child(g, line, w, -1);
l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe",
"UE_PHY_DLSCH_UE_DCI", "mcs", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
logger_add_view(l, v);
e->dl_mcs_logger = l;
@@ -288,7 +288,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
widget_add_child(g, line, w, -1);
l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe",
"UE_PHY_ULSCH_UE_DCI", "mcs", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
logger_add_view(l, v);
e->ul_mcs_logger = l;
@@ -301,12 +301,12 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
xy_plot_set_range(g, w, 0, 1024*10, -30, 50);
l = new_ttilog(h, database,
"UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "p0_pusch", 0);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
logger_add_view(l, v);
e->pusch_power_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "ampl", 1);
v = new_view_tti(10, g, w, new_color(g, "#720c0c"));
v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10);
logger_add_view(l, v);
e->pusch_ampl_logger = l;
@@ -319,12 +319,12 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
xy_plot_set_range(g, w, 0, 1024*10, -30, 50);
l = new_ttilog(h, database,
"UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "p0_pucch", 0);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10);
logger_add_view(l, v);
e->pucch_power_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "ampl", 1);
v = new_view_tti(10, g, w, new_color(g, "#720c0c"));
v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10);
logger_add_view(l, v);
e->pucch_ampl_logger = l;
@@ -335,22 +335,22 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
l = new_ttilog(h, database,
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level00", 1);
v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10);
logger_add_view(l, v);
e->pdsch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level01", 1);
v = new_view_tti(10, g, w, new_color(g, "#00ff00"));
v = new_view_tti(10, g, w, new_color(g, "#00ff00"), 10);
logger_add_view(l, v);
e->pdsch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level10", 1);
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"));
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"), 10);
logger_add_view(l, v);
e->pdsch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level11", 1);
v = new_view_tti(10, g, w, new_color(g, "#0000ff"));
v = new_view_tti(10, g, w, new_color(g, "#0000ff"), 10);
logger_add_view(l, v);
e->pdsch_energy_logger = l;
@@ -361,22 +361,22 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
l = new_ttilog(h, database,
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level00", 1);
v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10);
logger_add_view(l, v);
e->pdcch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level01", 1);
v = new_view_tti(10, g, w, new_color(g, "#00ff00"));
v = new_view_tti(10, g, w, new_color(g, "#00ff00"), 10);
logger_add_view(l, v);
e->pdcch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level10", 1);
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"));
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"), 10);
logger_add_view(l, v);
e->pdcch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level11", 1);
v = new_view_tti(10, g, w, new_color(g, "#0000ff"));
v = new_view_tti(10, g, w, new_color(g, "#0000ff"), 10);
logger_add_view(l, v);
e->pdcch_energy_logger = l;

View File

@@ -15,11 +15,14 @@ struct scrolltti {
int plot;
float refresh_rate;
pthread_mutex_t lock;
unsigned long data[1000];
unsigned long total; /* sum data[0..999] to have smoother value printed */
float xout[1000];
float yout[1000];
int ticks_per_frame;
unsigned long *data;
unsigned long total; /* sum data[0..n] to have smoother value printed */
float *xout;
float *yout;
int insert_point;
int next_tick_frame;
int next_tick_tick;
};
/* this array is used to get Y range 1000, 2000, 5000, 10000, ... */
@@ -38,21 +41,21 @@ static void *scrolltti_thread(void *_this)
/* TODO: optimize */
p = this->insert_point;
max = 0;
for (i = 0; i < 1000; i++) {
for (i = 0; i < this->ticks_per_frame * 100; i++) {
this->xout[i] = i;
this->yout[i] = this->data[p];
if (this->data[p] > max) max = this->data[p];
p = (p + 1) % 1000;
p = (p + 1) % (this->ticks_per_frame * 100);
}
bps(o, this->total/1000., "b/s");
bps(o, this->total/(this->ticks_per_frame * 100.), "b/s");
textarea_set_text(this->g, this->throughput_textarea, o);
/* for Y range we want 1000, 2000, 5000, 10000, 20000, 50000, etc. */
if (max < 1000) max = 1000;
mlog = pow(10, floor(log10(max)));
max = tolog[(int)ceil(max/mlog)] * mlog;
xy_plot_set_range(this->g, this->w, 0, 1000, 0, max);
xy_plot_set_range(this->g, this->w, 0, this->ticks_per_frame * 100, 0, max);
xy_plot_set_points(this->g, this->w, this->plot,
1000, this->xout, this->yout);
this->ticks_per_frame * 100, this->xout, this->yout);
if (pthread_mutex_unlock(&this->lock)) abort();
sleepms(1000/this->refresh_rate);
}
@@ -65,20 +68,40 @@ static void clear(view *this)
/* TODO */
}
static void append(view *_this, int frame, int subframe, double value)
static void insert(struct scrolltti *this, double value)
{
this->total -= this->data[this->insert_point];
this->data[this->insert_point] = value;
this->total += this->data[this->insert_point];
this->insert_point = (this->insert_point + 1) % (this->ticks_per_frame * 100);
}
static void next_tick(struct scrolltti *this)
{
this->next_tick_tick++;
if (this->next_tick_tick == this->ticks_per_frame) {
this->next_tick_tick = 0;
this->next_tick_frame++;
this->next_tick_frame %= 1024;
}
}
static void append(view *_this, int frame, int tick, double value)
{
struct scrolltti *this = (struct scrolltti *)_this;
if (pthread_mutex_lock(&this->lock)) abort();
this->total -= this->data[this->insert_point];
this->data[this->insert_point] = value;
this->total += this->data[this->insert_point];
this->insert_point = (this->insert_point + 1) % 1000;
while (this->next_tick_frame != frame || this->next_tick_tick != tick) {
insert(this, 0);
next_tick(this);
}
insert(this, value);
next_tick(this);
if (pthread_mutex_unlock(&this->lock)) abort();
}
view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color,
widget *throughput_textarea)
widget *throughput_textarea, int ticks_per_frame)
{
struct scrolltti *ret = calloc(1, sizeof(struct scrolltti));
if (ret == NULL) abort();
@@ -92,6 +115,14 @@ view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color,
ret->throughput_textarea = throughput_textarea;
ret->plot = xy_plot_new_plot(g, w, color);
ret->ticks_per_frame = ticks_per_frame;
ret->data = calloc(ticks_per_frame * 100, sizeof(unsigned long));
if (ret->data == NULL) abort();
ret->xout = calloc(ticks_per_frame * 100, sizeof(float));
if (ret->xout == NULL) abort();
ret->yout = calloc(ticks_per_frame * 100, sizeof(float));
if (ret->yout == NULL) abort();
if (pthread_mutex_init(&ret->lock, NULL)) abort();
new_thread(scrolltti_thread, ret);

View File

@@ -5,31 +5,36 @@
#include <pthread.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
struct tti {
view common;
gui *g;
widget *w;
int automax;
widget *w2;
int plot;
float refresh_rate;
pthread_mutex_t lock;
float data[1024*10];
int valid[1024*10];
float xout[1024*10];
float yout[1024*10];
float *data;
int *valid;
float *xout;
float *yout;
int last_insert_point;
int ticks_per_frame;
};
static int far_enough(int i, int last_insert, int plot_width)
static int far_enough(int i, int last_insert, int plot_width,
int ticks_per_frame)
{
int p1;
int p2;
int hole_size_px;
int hole_size_tti;
hole_size_px = 10;
hole_size_tti = 10240 * hole_size_px / plot_width;
hole_size_tti = 1024 * ticks_per_frame * hole_size_px / plot_width;
p1 = last_insert;
p2 = (last_insert + hole_size_tti) % (1024*10);
p2 = (last_insert + hole_size_tti) % (1024 * ticks_per_frame);
if (p1 < p2) {
return !(i > p1 && i < p2);
}
@@ -48,15 +53,31 @@ static void *tti_thread(void *_this)
if (pthread_mutex_lock(&this->lock)) abort();
xy_plot_get_dimensions(this->g, this->w, &plot_width, &plot_height);
length = 0;
double max = 0;
/* TODO: optimize */
for (i = 0; i < 1024*10; i++)
for (i = 0; i < 1024 * this->ticks_per_frame; i++)
/* do not take points too close after last insertion point */
if (this->valid[i] &&
far_enough(i, this->last_insert_point, plot_width)) {
far_enough(i, this->last_insert_point, plot_width,
this->ticks_per_frame)) {
this->xout[length] = i;
this->yout[length] = this->data[i];
if (this->data[i] > max) max = this->data[i];
length++;
}
if (this->automax) {
char o[128];
sprintf(o, "%d", (int)max);
textarea_set_text(this->g, this->w2, o);
/* for Y range we want 10, 20, 50, 100, 200, 500, etc. */
if (max < 10) max = 10;
double mlog = pow(10, floor(log10(max)));
static int tolog[11] = { -1, 1, 2, 5, 5, 5, 10, 10, 10, 10, 10 };
max = tolog[(int)ceil(max/mlog)] * mlog;
float xmin, xmax, ymin, ymax;
xy_plot_get_range(this->g, this->w, &xmin, &xmax, &ymin, &ymax);
xy_plot_set_range(this->g, this->w, xmin, xmax, 0, max);
}
xy_plot_set_points(this->g, this->w, this->plot,
length, this->xout, this->yout);
if (pthread_mutex_unlock(&this->lock)) abort();
@@ -71,11 +92,11 @@ static void clear(view *this)
/* TODO */
}
static void append(view *_this, int frame, int subframe, double value)
static void append(view *_this, int frame, int tick, double value)
{
struct tti *this = (struct tti *)_this;
int i;
int index = frame * 10 + subframe;
int index = frame * this->ticks_per_frame + tick;
if (pthread_mutex_lock(&this->lock)) abort();
@@ -84,10 +105,10 @@ static void append(view *_this, int frame, int subframe, double value)
* this may be wrong if delay between two append is
* greater than 1024 frames (something like that)
*/
i = (this->last_insert_point + 1) % (1024*10);
i = (this->last_insert_point + 1) % (1024 * this->ticks_per_frame);
while (i != index) {
this->valid[i] = 0;
i = (i + 1) % (1024*10);
i = (i + 1) % (1024 * this->ticks_per_frame);
}
this->data[index] = value;
@@ -98,7 +119,8 @@ static void append(view *_this, int frame, int subframe, double value)
if (pthread_mutex_unlock(&this->lock)) abort();
}
view *new_view_tti(float refresh_rate, gui *g, widget *w, int color)
view *new_view_tti(float refresh_rate, gui *g, widget *w, int color,
int ticks_per_frame)
{
struct tti *ret = calloc(1, sizeof(struct tti));
if (ret == NULL) abort();
@@ -115,7 +137,24 @@ view *new_view_tti(float refresh_rate, gui *g, widget *w, int color)
if (pthread_mutex_init(&ret->lock, NULL)) abort();
ret->ticks_per_frame = ticks_per_frame;
ret->data = calloc(ticks_per_frame * 1024, sizeof(float));
if (ret->data == NULL) abort();
ret->valid = calloc(ticks_per_frame * 1024, sizeof(int));
if (ret->valid == NULL) abort();
ret->xout = calloc(ticks_per_frame * 1024, sizeof(float));
if (ret->xout == NULL) abort();
ret->yout = calloc(ticks_per_frame * 1024, sizeof(float));
if (ret->yout == NULL) abort();
new_thread(tti_thread, ret);
return (view *)ret;
}
void view_tti_enable_automax(view *_tti, widget *w2)
{
struct tti *tti = (struct tti *)_tti;
tti->automax = 1;
tti->w2 = w2;
}

View File

@@ -17,15 +17,16 @@ view *new_view_stdout(void);
view *new_view_textlist(int maxsize, float refresh_rate, gui *g, widget *w);
view *new_view_xy(int length, float refresh_rate, gui *g, widget *w,
int color, enum xy_mode mode);
view *new_view_tti(float refresh_rate, gui *g, widget *w,
int color);
view *new_view_tti(float refresh_rate, gui *g, widget *w, int color,
int ticks_per_frame);
view *new_view_scrolltti(float refresh_rate, gui *g, widget *w,
int color, widget *throughput_label);
int color, widget *throughput_label, int ticks_per_frame);
view *new_view_time(int number_of_seconds, float refresh_rate,
gui *g, widget *w);
view *new_subview_time(view *time, int line, int color, int size);
view *new_view_ticktime(float refresh_rate, gui *g, widget *w);
view *new_subview_ticktime(view *ticktime, int line, int color, int size);
void ticktime_set_tick(view *ticktime, void *logger);
void view_tti_enable_automax(view *tti, widget *w2);
#endif /* _VIEW_H_ */

View File

@@ -1465,13 +1465,13 @@ frequency_range_t get_freq_range_from_band(uint16_t band)
return band <= 256 ? FR1 : FR2;
}
float get_beta_dmrs_pusch(int num_cdm_groups_no_data, pusch_dmrs_type_t dmrs_type)
float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2)
{
float beta_dmrs_pusch = 1.0;
if (num_cdm_groups_no_data == 2) {
beta_dmrs_pusch = powf(10.0, 3.0 / 20.0);
} else if (num_cdm_groups_no_data == 3) {
if (dmrs_type == pusch_dmrs_type2)
if (is_type2)
beta_dmrs_pusch = powf(10.0, 4.77 / 20.0);
}
return beta_dmrs_pusch;

View File

@@ -320,15 +320,15 @@ frequency_range_t get_freq_range_from_arfcn(uint32_t arfcn);
frequency_range_t get_freq_range_from_band(uint16_t band);
/**
* @brief Calculates the scaling factor for the ratio of PUSCH EPRE to DMRS EPRE.
* @brief Calculates the scaling factor for the ratio of PUSCH/PDSCH EPRE to DMRS EPRE.
*
* @param num_cdm_groups_no_data The number of CDM groups without data.
* @param dmrs_type The DMRS type.
* @return The calculated beta scaling factor for the ratio of PUSCH EPRE to DMRS EPRE.
* @param is_type2 true if calculating for DMRS configuration type 2
* @return The calculated beta scaling factor for the ratio of PUSCH/PDSCH EPRE to DMRS EPRE.
*
* @note The values are derived from TS 38.214 Table 6.2.2-1.
* @note The values are the same for PUSCH and PDSCH and are derived from TS 38.214 Table 6.2.2-1./4.1-1
*/
float get_beta_dmrs_pusch(int num_cdm_groups_no_data, pusch_dmrs_type_t dmrs_type);
float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2);
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))

View File

@@ -62,7 +62,7 @@ add_dependencies(telnetsrv telnetsrv_ci)
message(STATUS "Add CI specific telnet functions for nrUE in telnetsrv_ciUE.so")
add_library(telnetsrv_ciUE MODULE telnetsrv_ciUE.c)
target_link_libraries(telnetsrv_ciUE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(telnetsrv_ciUE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL)
add_dependencies(telnetsrv telnetsrv_ciUE)
message(STATUS "Add bearer specific telnet functions in libtelnetsrv_bearer.so")

View File

@@ -230,10 +230,10 @@ After preparing the L1 software, the container needs to be committed to create a
In this file the RU MAC address needs to be specified before commiting the image.
```bash
~$ docker commit nv-cubb cubb-build:25-1
~$ docker commit nv-cubb cubb-build:25-2
~$ docker image ls
..
cubb-build 25-1 824156e0334c 2 weeks ago 23.9GB
cubb-build 25-2 824156e0334c 2 weeks ago 23.9GB
-..
```

View File

@@ -1235,7 +1235,13 @@ You should be able to connect a UE now.
# OAI Management Plane
We support Configuration Management in OAI gNB, where gNB configures CU-planes, interfaces, TX/RX antennas, and TX/RX carriers for the RU.
In OAI gNB, we support:
* Configuration Management: interface(s) creation, configuration of RU CU-planes, Tx/Rx antennas, and Tx/Rx carriers.
* Performance Management: activation/deactivation of available RU performance measurements and its notification reception with 10s periodicity:
```bash
[HW] [MPLANE] [PM: "192.168.80.9"][RX_ON_TIME 773428][RX_EARLY 0][RX_LATE 0][RX_TOTAL 878881][RX_ON_TIME_C 104744][RX_EARLY_C 0][RX_LATE_C 0][TX_TOTAL 435922]
```
The reference specifications:
* `O-RAN.WG4.MP.0-v05.00`
* `O-RAN.WG4.MP-YANGs-v04.00`
@@ -1375,7 +1381,7 @@ Once the mplane service is successfully enabled on the RU, two new users are bei
oranbenetel:x:1000:1000::/home/oranbenetel:/bin/sh
oranext:x:1001:1001::/home/oranext:/bin/sh
```
Create `oranbenetel` home directory:
OAI gNB requires the `sudo` access group for NETCONF session. In the case of Benetel O-RUs, the corresponding user is `oranbenetel`. Therefore, please create its home directory:
```bash
mkdir /home/oranbenetel && chown oranbenetel:oranbenetel /home/oranbenetel
```
@@ -1393,7 +1399,7 @@ The reference gNB configuration file for one Benetel RAN550:
The reference DU configuration file for two Benetel RAN650:
[gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf)
In order to run gNB/DU with M-plane, we need to modify the `fhi_72` section in the configuration file.
In order to run gNB/DU with M-plane, we need to modify Tx gain `att_tx` in RU section, as well as the `fhi_72` section in the configuration file.
Example for one RU:
```bash
fhi_72 = {
@@ -1404,6 +1410,7 @@ fhi_72 = {
du_key_pair = ("<path-to>/.ssh/id_rsa.pub", "<path-to>/.ssh/id_rsa");
du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67"); # only one needed if one VF configured
vlan_tag = (9, 9); # only one needed if one VF configured
ru_username = ("oranbenetel");
ru_ip_addr = ("192.168.80.9");
fh_config = ({
T1a_cp_dl = (419, 470);
@@ -1423,6 +1430,7 @@ fhi_72 = {
du_key_pair = ("/home/oaicicd/.ssh/id_rsa.pub", "/home/oaicicd/.ssh/id_rsa");
du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67", "00:11:22:33:44:68", "00:11:22:33:44:69"); # only two needed if two VFs configured
vlan_tag = (9, 9, 11, 11); # only two needed if two VFs configured
ru_username = ("oranbenetel", "oranbenetel");
ru_ip_addr = ("192.168.80.9", "192.168.80.10");
fh_config = (
# RAN550 #1
@@ -1451,6 +1459,7 @@ fhi_72 = {
* `du_key_pair`: ssh public and private keys to authenticate RU with NETCONF
* `du_addr`: DU MAC address(es) to create CU-plane interface(s) in the RU
* `vlan_tag`: VLAN U and C plane tags to create CU-plane interface(s) in the RU
* `ru_username`: Username with `sudo` access to connect to the RU via M-plane
* `ru_ip_addr`: RU IP address to connect to the RU via M-plane
* `dpdk_mem_size`: [*]
* `dpdk_iova_mode`: [*]
@@ -1557,7 +1566,9 @@ sequenceDiagram
note over du: DU configures xran
du->ru: 12. DU and RU exchange packets
du->ru: 12. DU activates Performance Measurements
du->ru: 13. DU and RU exchange packets
```
@@ -1596,7 +1607,9 @@ sequenceDiagram
Band sector ID 0
CC ID 0
RU port ID 0
max Tx gain 24.0
[HW] [MPLANE] Successfully retrieved all the U-plane info - interface name, TX/RX carrier names, and TX/RX endpoint names.
[HW] [MPLANE] Successfully retreived all performance measurement names.
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <get-schema> for module "ietf-yang-metadata".
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <get-schema> for module "yang".
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <get-schema> for module "ietf-inet-types".
@@ -1636,6 +1649,59 @@ sequenceDiagram
<vlan-id xmlns="urn:o-ran:interfaces:1.0">9</vlan-id>
</interface>
</interfaces>
<performance-measurement-objects xmlns="urn:o-ran:performance-management:1.0">
<rx-window-measurement-interval>10</rx-window-measurement-interval>
<tx-measurement-interval>10</tx-measurement-interval>
<notification-interval>10</notification-interval>
<rx-window-measurement-objects>
<measurement-object>RX_ON_TIME</measurement-object>
<active>false</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_EARLY</measurement-object>
<active>false</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_LATE</measurement-object>
<active>false</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_TOTAL</measurement-object>
<active>false</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_ON_TIME_C</measurement-object>
<active>false</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_EARLY_C</measurement-object>
<active>false</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_LATE_C</measurement-object>
<active>false</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<tx-measurement-objects>
<measurement-object>TX_TOTAL</measurement-object>
<active>false</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</tx-measurement-objects>
</performance-measurement-objects>
<processing-elements xmlns="urn:o-ran:processing-element:1.0">
<transport-session-type>ETH-INTERFACE</transport-session-type>
<ru-elements>
@@ -1729,8 +1795,10 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
@@ -1746,8 +1814,10 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
@@ -1763,8 +1833,10 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
@@ -1780,8 +1852,10 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
@@ -1797,9 +1871,15 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<ul-fft-sampling-offsets>
<scs>KHZ_30</scs>
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
</ul-fft-sampling-offsets>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3840</band-sector-bitmask>
@@ -1807,6 +1887,7 @@ sequenceDiagram
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>0</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
</low-level-rx-endpoints>
<low-level-rx-endpoints>
<name>LowLevelRxPrachEndpoint0</name>
@@ -1814,9 +1895,15 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<ul-fft-sampling-offsets>
<scs>KHZ_30</scs>
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
</ul-fft-sampling-offsets>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3840</band-sector-bitmask>
@@ -1824,6 +1911,7 @@ sequenceDiagram
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>4</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
</low-level-rx-endpoints>
<low-level-rx-endpoints>
<name>LowLevelRxEndpoint1</name>
@@ -1831,9 +1919,15 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<ul-fft-sampling-offsets>
<scs>KHZ_30</scs>
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
</ul-fft-sampling-offsets>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3840</band-sector-bitmask>
@@ -1841,6 +1935,7 @@ sequenceDiagram
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>1</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
</low-level-rx-endpoints>
<low-level-rx-endpoints>
<name>LowLevelRxPrachEndpoint1</name>
@@ -1848,9 +1943,15 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<ul-fft-sampling-offsets>
<scs>KHZ_30</scs>
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
</ul-fft-sampling-offsets>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3840</band-sector-bitmask>
@@ -1858,6 +1959,7 @@ sequenceDiagram
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>5</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
</low-level-rx-endpoints>
<low-level-rx-endpoints>
<name>LowLevelRxEndpoint2</name>
@@ -1865,9 +1967,15 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<ul-fft-sampling-offsets>
<scs>KHZ_30</scs>
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
</ul-fft-sampling-offsets>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3840</band-sector-bitmask>
@@ -1875,6 +1983,7 @@ sequenceDiagram
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>2</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
</low-level-rx-endpoints>
<low-level-rx-endpoints>
<name>LowLevelRxPrachEndpoint2</name>
@@ -1882,9 +1991,15 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<ul-fft-sampling-offsets>
<scs>KHZ_30</scs>
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
</ul-fft-sampling-offsets>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3840</band-sector-bitmask>
@@ -1892,6 +2007,7 @@ sequenceDiagram
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>6</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
</low-level-rx-endpoints>
<low-level-rx-endpoints>
<name>LowLevelRxEndpoint3</name>
@@ -1899,9 +2015,15 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<ul-fft-sampling-offsets>
<scs>KHZ_30</scs>
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
</ul-fft-sampling-offsets>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3840</band-sector-bitmask>
@@ -1909,6 +2031,7 @@ sequenceDiagram
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>3</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
</low-level-rx-endpoints>
<low-level-rx-endpoints>
<name>LowLevelRxPrachEndpoint3</name>
@@ -1916,9 +2039,15 @@ sequenceDiagram
<iq-bitwidth>9</iq-bitwidth>
<compression-type>STATIC</compression-type>
</compression>
<cp-length>0</cp-length>
<cp-length-other>0</cp-length-other>
<frame-structure>193</frame-structure>
<cp-type>NORMAL</cp-type>
<cp-length>352</cp-length>
<cp-length-other>288</cp-length-other>
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
<ul-fft-sampling-offsets>
<scs>KHZ_30</scs>
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
</ul-fft-sampling-offsets>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3840</band-sector-bitmask>
@@ -1926,6 +2055,7 @@ sequenceDiagram
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>7</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
</low-level-rx-endpoints>
<tx-array-carriers>
<name>TxArray0</name>
@@ -1933,7 +2063,7 @@ sequenceDiagram
<center-of-channel-bandwidth>3950400000</center-of-channel-bandwidth>
<channel-bandwidth>100000000</channel-bandwidth>
<active>ACTIVE</active>
<gain>0.0</gain>
<gain>24.0</gain>
<downlink-radio-frame-offset>0</downlink-radio-frame-offset>
<downlink-sfn-offset>0</downlink-sfn-offset>
</tx-array-carriers>
@@ -1957,7 +2087,7 @@ sequenceDiagram
[HW] [MPLANE] Successfully validated candidate datastore for RU "192.168.80.9".
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <commit> candidate datastore.
[HW] [MPLANE] RPC reply = OK.
[HW] [MPLANE] Successfully commited CU-planes configuration into running datastore for RU "192.168.80.9".
[HW] [MPLANE] Successfully commited configuration into running datastore for RU "192.168.80.9".
[HW] [MPLANE] Usage state = "idle" for RU "192.168.80.9".
[HW] [MPLANE] Received notification from RU "192.168.80.9" at (2025-03-29T12:40:23.049085102+00:00)
{
@@ -2025,9 +2155,71 @@ sequenceDiagram
"operation": "create"
},
...
}
[HW] [MPLANE] RU "192.168.80.9" is now ready.
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <edit-config>:
<performance-measurement-objects xmlns="urn:o-ran:performance-management:1.0">
<rx-window-measurement-interval>10</rx-window-measurement-interval>
<tx-measurement-interval>10</tx-measurement-interval>
<notification-interval>10</notification-interval>
<rx-window-measurement-objects>
<measurement-object>RX_ON_TIME</measurement-object>
<active>true</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_EARLY</measurement-object>
<active>true</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_LATE</measurement-object>
<active>true</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_TOTAL</measurement-object>
<active>true</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_ON_TIME_C</measurement-object>
<active>true</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_EARLY_C</measurement-object>
<active>true</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<rx-window-measurement-objects>
<measurement-object>RX_LATE_C</measurement-object>
<active>true</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</rx-window-measurement-objects>
<tx-measurement-objects>
<measurement-object>TX_TOTAL</measurement-object>
<active>true</active>
<object-unit>RU</object-unit>
<report-info>COUNT</report-info>
</tx-measurement-objects>
</performance-measurement-objects>
[HW] [MPLANE] RPC reply = OK.
[HW] [MPLANE] Successfully edited the candidate datastore for RU "192.168.80.9".
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <validate> candidate datastore.
[HW] [MPLANE] RPC reply = OK.
[HW] [MPLANE] Successfully validated candidate datastore for RU "192.168.80.9".
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <commit> candidate datastore.
[HW] [MPLANE] RPC reply = OK.
[HW] [MPLANE] Successfully commited configuration into running datastore for RU "192.168.80.9".
[HW] [MPLANE] Sucessfully activated PM after start-up procedure for RU "192.168.80.9".
```
</details>

View File

@@ -171,7 +171,7 @@ After installing WLS, you can run the build command as shown below:
#### How to run OAI PNF with OAI VNF
Refer to the above steps in [Quickstart](.#quickstart), but run the PNF first as it is the WLS "master".
Refer to the above steps in [Quickstart](#quickstart), but run the PNF first as it is the WLS "master".
#### How to run OAI PNF with OSC/Radisys O-DU

View File

@@ -37,20 +37,11 @@ RUN /bin/sh oaienv && \
mkdir -p log ran_build/build ran_build/build-cross && \
cd ran_build/build && \
cmake ../../.. -GNinja && \
echo "====== Start of log for host-tools ======" && \
ninja ldpc_generators generate_T > ../../log/host-tools.txt 2>&1 && \
echo "====== End of log for host-tools ======" && \
ninja ldpc_generators generate_T && \
cd ../build-cross/ && \
# install missing libyaml-cpp-dev for arm64
apt install -y libyaml-cpp-dev:arm64 && \
cmake ../../.. -GNinja -DENABLE_TELNETSRV=ON \
-DCMAKE_TOOLCHAIN_FILE=../../../cmake_targets/cross-arm.cmake -DNATIVE_DIR=../build \
-DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror" && \
echo "====== Start of log for cross-build executables ======" && \
# making always passing so we can analyze the all.txt file
ninja -k10 dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim lte-softmodem nr-softmodem nr-cuup oairu lte-uesoftmodem nr-uesoftmodem params_libconfig coding rfsimulator telnetsrv > ../../log/all.txt 2>&1; \
# displaying errors and warnings
grep -E -A3 "warning:|error:" ../../log/all.txt || true && \
# will fail only if string "errors:" is found
grep -E "error:" -vqz ../../log/all.txt && \
echo "====== End of log for cross-build executables ======"
ninja -k10 dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim lte-softmodem nr-softmodem nr-cuup oairu lte-uesoftmodem nr-uesoftmodem params_libconfig coding rfsimulator telnetsrv

View File

@@ -45,7 +45,7 @@ WORKDIR /oai-ran
COPY . .
RUN /bin/sh oaienv && \
tar -xvzf nvipc* && \
tar -xvzf nvipc_src.*.tar.gz && \
cd nvipc_src.* && \
rm -rf build && mkdir build && cd build && \
cmake .. -DNVIPC_DPDK_ENABLE=OFF -DNVIPC_DOCA_ENABLE=OFF -DNVIPC_CUDA_ENABLE=OFF -DENABLE_SLT_RSP=ON && \

View File

@@ -45,7 +45,7 @@ WORKDIR /oai-ran
COPY . .
RUN /bin/sh oaienv && \
tar -xvzf nvipc* && \
tar -xvzf nvipc_src.*.tar.gz && \
cd nvipc_src.* && \
rm -rf build && mkdir build && cd build && \
cmake .. -DNVIPC_DPDK_ENABLE=OFF -DNVIPC_DOCA_ENABLE=OFF -DNVIPC_CUDA_ENABLE=OFF -DENABLE_SLT_RSP=ON && \

View File

@@ -174,6 +174,8 @@ static void rx_func(processingData_L1_t *info)
int slot_rx = info->slot_rx;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
T(T_GNB_PHY_UL_TICK, T_INT(gNB->Mod_id), T_INT(frame_rx), T_INT(slot_rx));
// RX processing
int rx_slot_type = nr_slot_select(cfg, frame_rx, slot_rx);
if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {

View File

@@ -878,11 +878,12 @@ static void fill_rf_config(RU_t *ru, char *rf_config_file)
}
}
static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_request_scf_t *config, int slots_per_frame, uint16_t ofdm_symbol_size)
static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_request_scf_t *config, const NR_DL_FRAME_PARMS *fp)
{
const nfapi_nr_prach_config_t *prach_config = &config->prach_config;
const nfapi_nr_tdd_table_t *tdd_table = &config->tdd_table;
const nfapi_nr_cell_config_t *cell_config = &config->cell_config;
const nfapi_nr_carrier_config_t *carrier_config = &config->carrier_config;
DevAssert(prach_config->prach_ConfigurationIndex.tl.tag == NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG);
split7->prach_index = prach_config->prach_ConfigurationIndex.value;
@@ -893,7 +894,7 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_
if (cell_config->frame_duplex_type.value == 1 /* TDD */) {
DevAssert(tdd_table->tdd_period.tl.tag == NFAPI_NR_CONFIG_TDD_PERIOD_TAG);
int nb_periods_per_frame = get_nb_periods_per_frame(tdd_table->tdd_period.value);
split7->n_tdd_period = slots_per_frame / nb_periods_per_frame;
split7->n_tdd_period = fp->slots_per_frame / nb_periods_per_frame;
for (int slot = 0; slot < split7->n_tdd_period; ++slot) {
for (int sym = 0; sym < 14; ++sym) {
split7->slot_dirs[slot].sym_dir[sym] = tdd_table->max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[sym].slot_config.value;
@@ -901,7 +902,15 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_
}
}
split7->fftSize = log2(ofdm_symbol_size);
split7->fftSize = log2(fp->ofdm_symbol_size);
// M-plane related parameters
for (size_t i = 0; i < 5 ; i++) {
split7->dl_k0[i] = carrier_config->dl_k0[i].value;
split7->ul_k0[i] = carrier_config->ul_k0[i].value;
}
split7->cp_prefix0 = fp->nb_prefix_samples0;
split7->cp_prefix_other = fp->nb_prefix_samples;
}
/* this function maps the RU tx and rx buffers to the available rf chains.
@@ -1044,7 +1053,7 @@ void *ru_thread(void *param)
nr_dump_frame_parms(fp);
nr_phy_init_RU(ru);
fill_rf_config(ru, ru->rf_config_file);
fill_split7_2_config(&ru->openair0_cfg.split7, &ru->config, fp->slots_per_frame, fp->ofdm_symbol_size);
fill_split7_2_config(&ru->openair0_cfg.split7, &ru->config, fp);
// Start IF device if any
if (ru->nr_start_if) {

View File

@@ -96,6 +96,7 @@
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CONFIG_HLP_NOS1 "Disable s1 interface\n"
#define CONFIG_HLP_USEGPU "Use GPU for processing offload"
/*--------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for LOG utility */
@@ -126,7 +127,6 @@ extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int oai_exit;
extern openair0_config_t openair0_cfg[MAX_CARDS];
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;

View File

@@ -103,6 +103,7 @@ unsigned int mmapped_dma=0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
char *uecap_file;
uint32_t use_gpu;
runmode_t mode = normal_txrx;

View File

@@ -27,6 +27,7 @@
{"U" , CONFIG_HLP_ULBM_PHYTEST, 0, .u64ptr=&ulsch_slot_bitmap, .defintval=0, TYPE_UINT64, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, .iptr=&usrp_tx_thread, .defstrval=0, TYPE_INT, 0}, \
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \
{"use_gpu", CONFIG_HLP_USE_GPU, 0, .uptr=&use_gpu, .defintval=0, TYPE_UINT, 0}, \
}
// clang-format on
@@ -39,7 +40,7 @@ extern uint32_t target_ul_bw;
extern uint64_t dlsch_slot_bitmap;
extern uint64_t ulsch_slot_bitmap;
extern char *uecap_file;
extern uint32_t use_gpu;
// In nr-gnb.c
extern void init_gNB();
extern void stop_gNB(int);

View File

@@ -414,7 +414,7 @@ static void UE_synch(void *arg) {
syncData_t *syncD = (syncData_t *)arg;
PHY_VARS_NR_UE *UE = syncD->UE;
UE->is_synchronized = 0;
openair0_config_t *cfg0 = &openair0_cfg[UE->rf_map.card];
openair0_config_t *cfg0 = &UE->openair0_cfg[UE->rf_map.card];
if (UE->target_Nid_cell != -1) {
LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell);
@@ -523,7 +523,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx
radio_tx_burst_flag_t flags = TX_BURST_INVALID;
if (UE->received_config_request) {
if (openair0_cfg[0].duplex_mode == duplex_mode_FDD || get_softmodem_params()->continuous_tx) {
if (UE->openair0_cfg[0].duplex_mode == duplex_mode_FDD || get_softmodem_params()->continuous_tx) {
flags = TX_BURST_MIDDLE;
// In case of Sidelink, USRP write needed only in case transmission
// needs to be done in this slot and not based on tdd ULDL configuration.
@@ -696,8 +696,8 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE)
if (dl_CarrierFreq != fp->dl_CarrierFreq || ul_CarrierFreq != fp->ul_CarrierFreq) {
fp->dl_CarrierFreq = dl_CarrierFreq;
fp->ul_CarrierFreq = ul_CarrierFreq;
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &openair0_cfg[0]);
nr_rf_card_config_freq(&UE->openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &UE->openair0_cfg[UE->rf_map.card]);
init_symbol_rotation(fp);
}
@@ -731,12 +731,14 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
// process what RRC thread sent to MAC
MessageDef *msg = NULL;
do {
itti_poll_msg(TASK_MAC_UE, &msg);
if (msg)
process_msg_rcc_to_mac(msg);
} while (msg);
notifiedFIFO_elt_t *elt = pollNotifiedFIFO(&get_mac_inst(UE->Mod_id)->input_nf);
if (!elt) {
break;
}
process_msg_rcc_to_mac(NotifiedFifoData(elt), UE->Mod_id);
delNotifiedFIFO_elt(elt);
} while (true);
if (UE->if_inst)
UE->if_inst->slot_indication(UE->Mod_id, false);
@@ -966,7 +968,7 @@ void *UE_thread(void *arg)
void *rxp[NB_ANTENNAS_RX];
enum stream_status_e stream_status = STREAM_STATUS_UNSYNC;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int tmp = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
int tmp = openair0_device_load(&(UE->rfdevice), &UE->openair0_cfg[0]);
AssertFatal(tmp == 0, "Could not load the device\n");
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
sl_nr_phy_config_request_t *sl_cfg = NULL;
@@ -1032,12 +1034,10 @@ void *UE_thread(void *arg)
decoded_frame_rx = UE->SL_UE_PHY_PARAMS.sync_params.DFN;
else {
// We must wait the RRC layer decoded the MIB and sent us the frame number
MessageDef *msg = NULL;
itti_receive_msg(TASK_MAC_UE, &msg);
if (msg)
process_msg_rcc_to_mac(msg);
else
LOG_E(PHY, "It seems we arbort while trying to sync\n");
notifiedFIFO_elt_t *elt = pullNotifiedFIFO(&mac->input_nf);
AssertFatal(elt != NULL, "fifo error while waiting for MIB");
process_msg_rcc_to_mac(NotifiedFifoData(elt), UE->Mod_id);
delNotifiedFIFO_elt(elt);
decoded_frame_rx = mac->mib_frame;
}
LOG_A(PHY,
@@ -1284,20 +1284,19 @@ void *UE_thread(void *arg)
void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file)
{
NR_UE_RRC_INST_t *rrc_inst = nr_rrc_init_ue(uecap_file, nb_inst, get_nrUE_params()->nb_antennas_tx);
NR_UE_MAC_INST_t *mac_inst = nr_l2_init_ue(nb_inst);
AssertFatal(mac_inst, "Couldn't allocate MAC module\n");
for (int instance_id = 0; instance_id < nb_inst; instance_id++) {
NR_UE_RRC_INST_t* rrc = nr_rrc_init_ue(uecap_file, instance_id, get_nrUE_params()->nb_antennas_tx);
NR_UE_MAC_INST_t *mac = nr_l2_init_ue(instance_id);
for (int i = 0; i < nb_inst; i++) {
NR_UE_MAC_INST_t *mac = get_mac_inst(i);
mac->if_module = nr_ue_if_module_init(i);
nr_rrc_set_mac_queue(instance_id, &mac->input_nf);
mac->if_module = nr_ue_if_module_init(instance_id);
AssertFatal(mac->if_module, "can not initialize IF module\n");
if (!IS_SA_MODE(get_softmodem_params()) && !get_softmodem_params()->sl_mode) {
init_nsa_message(&rrc_inst[i], reconfig_file, rbconfig_file);
nr_rlc_activate_srb0(mac_inst[i].crnti, NULL, send_srb0_rrc);
init_nsa_message(rrc, reconfig_file, rbconfig_file);
nr_rlc_activate_srb0(mac->crnti, NULL, send_srb0_rrc);
}
//TODO: Move this call to RRC
start_sidelink((&rrc_inst[i])->ue_id);
start_sidelink(instance_id);
}
}

View File

@@ -121,8 +121,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
uint64_t sidelink_frequency[MAX_NUM_CCs][4];
// UE and OAI config variables
openair0_config_t openair0_cfg[MAX_CARDS];
int16_t node_synch_ref[MAX_NUM_CCs];
int otg_enabled;
double cpuf;
@@ -249,41 +247,42 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
}
static void init_openair0()
void init_openair0(PHY_VARS_NR_UE *ue)
{
int card;
int freq_off = 0;
NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
bool is_sidelink = (get_softmodem_params()->sl_mode) ? true : false;
if (is_sidelink)
frame_parms = &PHY_vars_UE_g[0][0]->SL_UE_PHY_PARAMS.sl_frame_params;
frame_parms = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
for (card=0; card<MAX_CARDS; card++) {
openair0_config_t *cfg = &ue->openair0_cfg[card];
uint64_t dl_carrier, ul_carrier;
openair0_cfg[card].configFilename = NULL;
openair0_cfg[card].sample_rate = frame_parms->samples_per_subframe * 1e3;
openair0_cfg[card].samples_per_frame = frame_parms->samples_per_frame;
cfg->configFilename = NULL;
cfg->sample_rate = frame_parms->samples_per_subframe * 1e3;
cfg->samples_per_frame = frame_parms->samples_per_frame;
if (frame_parms->frame_type==TDD)
openair0_cfg[card].duplex_mode = duplex_mode_TDD;
cfg->duplex_mode = duplex_mode_TDD;
else
openair0_cfg[card].duplex_mode = duplex_mode_FDD;
cfg->duplex_mode = duplex_mode_FDD;
openair0_cfg[card].Mod_id = 0;
openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL;
openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
openair0_cfg[card].tune_offset = get_softmodem_params()->tune_offset;
openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx);
openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx);
cfg->Mod_id = 0;
cfg->num_rb_dl = frame_parms->N_RB_DL;
cfg->clock_source = get_softmodem_params()->clock_source;
cfg->time_source = get_softmodem_params()->timing_source;
cfg->tune_offset = get_softmodem_params()->tune_offset;
cfg->tx_num_channels = min(4, frame_parms->nb_antennas_tx);
cfg->rx_num_channels = min(4, frame_parms->nb_antennas_rx);
LOG_I(PHY,
"HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
card,
openair0_cfg[card].sample_rate,
openair0_cfg[card].tx_num_channels,
openair0_cfg[card].rx_num_channels,
duplex_mode_txt[openair0_cfg[card].duplex_mode]);
cfg->sample_rate,
cfg->tx_num_channels,
cfg->rx_num_channels,
duplex_mode_txt[cfg->duplex_mode]);
if (is_sidelink) {
dl_carrier = frame_parms->dl_CarrierFreq;
@@ -291,16 +290,18 @@ static void init_openair0()
} else
nr_get_carrier_frequencies(PHY_vars_UE_g[0][0], &dl_carrier, &ul_carrier);
nr_rf_card_config_freq(&openair0_cfg[card], ul_carrier, dl_carrier, freq_off);
nr_rf_card_config_freq(cfg, ul_carrier, dl_carrier, freq_off);
nr_rf_card_config_gain(&openair0_cfg[card], rx_gain_off);
nr_rf_card_config_gain(cfg, rx_gain_off);
openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
if (get_nrUE_params()->usrp_args) openair0_cfg[card].sdr_addrs = get_nrUE_params()->usrp_args;
if (get_nrUE_params()->tx_subdev) openair0_cfg[card].tx_subdev = get_nrUE_params()->tx_subdev;
if (get_nrUE_params()->rx_subdev) openair0_cfg[card].rx_subdev = get_nrUE_params()->rx_subdev;
cfg->configFilename = get_softmodem_params()->rf_config_file;
if (get_nrUE_params()->usrp_args)
cfg->sdr_addrs = get_nrUE_params()->usrp_args;
if (get_nrUE_params()->tx_subdev)
cfg->tx_subdev = get_nrUE_params()->tx_subdev;
if (get_nrUE_params()->rx_subdev)
cfg->rx_subdev = get_nrUE_params()->rx_subdev;
}
}
@@ -326,9 +327,11 @@ static void trigger_stop(int sig)
static void trigger_deregistration(int sig)
{
if (!stop_immediately && IS_SA_MODE(get_softmodem_params())) {
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DEREGISTRATION_REQ);
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
itti_send_msg_to_task(TASK_NAS_NRUE, 0, msg);
for (int ue_inst = 0; ue_inst < NB_UE_INST; ue_inst++) {
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, ue_inst, NAS_DEREGISTRATION_REQ);
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
itti_send_msg_to_task(TASK_NAS_NRUE, ue_inst, msg);
}
stop_immediately = true;
static const char m[] = "Press ^C again to trigger immediate shutdown\n";
__attribute__((unused)) int unused = write(STDOUT_FILENO, m, sizeof(m) - 1);
@@ -386,7 +389,6 @@ int main(int argc, char **argv)
}
//set_softmodem_sighandler();
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS);
memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
// initialize logging
logInit();
@@ -425,12 +427,11 @@ int main(int argc, char **argv)
char *pckg = strdup(OAI_PACKAGE_VERSION);
LOG_I(HW, "Version: %s\n", pckg);
PHY_vars_UE_g = malloc(sizeof(*PHY_vars_UE_g) * NB_UE_INST);
PHY_vars_UE_g = calloc_or_fail(NB_UE_INST, sizeof(*PHY_vars_UE_g));
for (int inst = 0; inst < NB_UE_INST; inst++) {
PHY_vars_UE_g[inst] = malloc(sizeof(*PHY_vars_UE_g[inst]) * MAX_NUM_CCs);
PHY_vars_UE_g[inst] = calloc_or_fail(MAX_NUM_CCs, sizeof(*PHY_vars_UE_g[inst]));
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
PHY_vars_UE_g[inst][CC_id] = malloc(sizeof(*PHY_vars_UE_g[inst][CC_id]));
memset(PHY_vars_UE_g[inst][CC_id], 0, sizeof(*PHY_vars_UE_g[inst][CC_id]));
PHY_vars_UE_g[inst][CC_id] = calloc_or_fail(1, sizeof(*PHY_vars_UE_g[inst][CC_id]));
// All instances use the same coding interface
PHY_vars_UE_g[inst][CC_id]->nrLDPC_coding_interface = nrLDPC_coding_interface;
}
@@ -498,12 +499,14 @@ int main(int argc, char **argv)
get_softmodem_params()->numerology,
nr_band);
} else {
MessageDef *msg = NULL;
do {
itti_poll_msg(TASK_MAC_UE, &msg);
if (msg)
process_msg_rcc_to_mac(msg);
} while (msg);
do {
notifiedFIFO_elt_t *elt = pollNotifiedFIFO(&mac->input_nf);
if (!elt) {
break;
}
process_msg_rcc_to_mac(NotifiedFifoData(elt), inst);
delNotifiedFIFO_elt(elt);
} while (true);
fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, mac->nr_band);
}
@@ -538,10 +541,10 @@ int main(int argc, char **argv)
get_nrUE_params()->ofdm_offset_divisor);
sl_ue_phy_init(UE[CC_id]);
}
init_openair0(UE[CC_id]);
}
}
init_openair0();
lock_memory_to_ram();
if (IS_SOFTMODEM_DOSCOPE) {

View File

@@ -5,6 +5,7 @@
#include "common/utils/threadPool/thread-pool.h"
#include "PHY/defs_nr_UE.h"
#define MAX_NUM_NR_UE_INST 32
extern int NB_UE_INST;
extern uint16_t ue_id_g;

View File

@@ -2308,7 +2308,7 @@ uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8
}
}
#else
const uint16_t last_idx = ((report_tlv->length + 3) / 4) - 1;
const int16_t last_idx = ((report_tlv->length + 3) / 4) - 1;
for (int i = 0; i < last_idx; i++) {
if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
return 0;

View File

@@ -13,6 +13,7 @@ target_link_libraries(coding PRIVATE log_headers)
add_library(ldpc_orig MODULE
nrLDPC_decoder/nrLDPC_decoder.c
nrLDPC_encoder/ldpc_encoder.c
nrLDPC_encoder/ldpc_encoder32.c
)
set_target_properties(ldpc_orig PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
target_link_libraries(ldpc_orig PRIVATE ldpc_segment ldpc_gen_HEADERS)
@@ -20,6 +21,7 @@ target_link_libraries(ldpc_orig PRIVATE ldpc_segment ldpc_gen_HEADERS)
add_library(ldpc MODULE
nrLDPC_decoder/nrLDPC_decoder.c
nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
nrLDPC_encoder/ldpc_encoder32.c
)
set_target_properties(ldpc PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
target_link_libraries(ldpc PRIVATE ldpc_segment ldpc_gen_HEADERS)
@@ -42,22 +44,28 @@ if (ENABLE_LDPC_CUDA)
if (NOT CUDA_FOUND)
message(FATAL_ERROR "no CUDA found")
endif()
SET(CUDA_NVCC_FLAG "${CUDA_NVCC_FLAGS};-arch=sm_60;")
SET(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-arch=sm_87;")
SET(CUDA_VERBOSE_BUILD ON)
cuda_add_library(ldpc_cuda MODULE
nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
# nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
nrLDPC_decoder/nrLDPC_decoder.c
nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
nrLDPC_encoder/ldpc_encoder_cuda32.c
nrLDPC_encoder/ldpc_BG1_Zc384_32bit.cu
nrLDPC_encoder/ldpc_input.cu
# The slot coding layer cannot be linked with
# target_link_libraries like above
# because of cuda_add_library
# which already uses target_link_libraries
nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c
nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder_cuda.c
nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c
nrLDPC_coding/nrLDPC_coding_segment/nr_rate_matching.c
)
target_link_libraries(ldpc_cuda ldpc_gen_HEADERS ${T_LIB})
set_target_properties(ldpc_cuda PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
set_target_properties(ldpc_cuda PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
target_compile_definitions(ldpc_cuda PRIVATE ENABLE_CUDA)
add_dependencies(ldpctest ldpc_cuda)
add_dependencies(nr-softmodem ldpc_cuda)
add_dependencies(nr-uesoftmodem ldpc_cuda)

View File

@@ -34,6 +34,9 @@
#include "openair1/PHY/defs_nr_common.h"
#include "coding_unitary_defs.h"
#include "common/utils/LOG/log.h"
#ifdef ENABLE_CUDA
#include <cuda_runtime.h>
#endif
#define MAX_BLOCK_LENGTH 8448
@@ -104,14 +107,16 @@ one_measurement_t test_ldpc(short max_iterations,
unsigned char qbits,
short Kprime,
unsigned int ntrials,
int n_segments)
int n_segments,
int gen_code,
int use32bit)
{
one_measurement_t ret = {0};
reset_meas(&ret.time_optim);
reset_meas(&ret.time_decoder);
// clock initiate
// time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder;
time_stats_t time, tinput, tprep, tparity, toutput;
time_stats_t time, tinput, tinput_memcpy, tprep, tparity, toutput;
double n_iter_mean = 0;
double n_iter_std = 0;
int n_iter_max = 0;
@@ -119,14 +124,22 @@ one_measurement_t test_ldpc(short max_iterations,
double sigma;
sigma = 1.0 / sqrt(2 * SNR);
cpu_meas_enabled = 1;
uint8_t *test_input[MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * NR_MAX_NB_LAYERS];
uint8_t estimated_output[MAX_NUM_DLSCH_SEGMENTS][Kprime];
#ifdef ENABLE_CUDA
uint8_t **test_input,*test_input_p;
#else
uint8_t *test_input[n_segments * NR_MAX_NB_LAYERS];
#endif
uint8_t *channel_input[n_segments];
uint8_t estimated_output[n_segments][Kprime];
memset(estimated_output, 0, sizeof(estimated_output));
uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS];
uint8_t *channel_input_optim;
// double channel_output[68 * 384];
double modulated_input[MAX_NUM_DLSCH_SEGMENTS][68 * 384] = {0};
int8_t channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS][68 * 384] = {0};
double modulated_input[n_segments][68 * 384];
memset(modulated_input,0,sizeof(modulated_input));
int8_t channel_output_fixed[n_segments][68 * 384];
memset(channel_output_fixed,0,sizeof(channel_output_fixed));
short BG = 0, nrows = 0; //,ncols;
int i1, Kb = 0;
int R_ind = 0;
@@ -134,7 +147,7 @@ one_measurement_t test_ldpc(short max_iterations,
int code_rate_vec[8] = {15, 13, 25, 12, 23, 34, 56, 89};
// double code_rate_actual_vec[8] = {0.2, 0.33333, 0.4, 0.5, 0.66667, 0.73333, 0.81481, 0.88};
t_nrLDPC_dec_params decParams[MAX_NUM_DLSCH_SEGMENTS] = {0};
t_nrLDPC_dec_params decParams[n_segments];
t_nrLDPC_time_stats decoder_profiler = {0};
@@ -142,6 +155,7 @@ one_measurement_t test_ldpc(short max_iterations,
reset_meas(&time);
reset_meas(&tinput);
reset_meas(&tinput_memcpy);
reset_meas(&tprep);
reset_meas(&tparity);
reset_meas(&toutput);
@@ -259,18 +273,29 @@ one_measurement_t test_ldpc(short max_iterations,
printf("To: %d\n", (Kb + nrows - no_punctured_columns) * Zc - removed_bit);
printf("number of undecoded bits: %d\n", (Kb + nrows - no_punctured_columns - 2) * Zc - removed_bit);
// ldpc_toCompare.LDPCinit();
// generate input block
for (int j = 0; j < MAX_NUM_DLSCH_SEGMENTS; j++) {
#ifdef ENABLE_CUDA
cudaHostAlloc((void**)&test_input_p,n_segments*sizeof(uint8_t*),cudaHostAllocMapped);
test_input=(uint8_t **)test_input_p;
printf("test input %p\n",test_input);
#endif
for (int j = 0; j < n_segments; j++) {
#ifdef ENABLE_CUDA
cudaHostAlloc((void**)&test_input[j],((K + 7) & ~7) / 8,cudaHostAllocMapped);
printf("test input[%d] %p\n",j,test_input[j]);
#else
test_input[j] = malloc16(((K + 7) & ~7) / 8);
memset(test_input[j], 0, ((K + 7) & ~7) / 8);
#endif
channel_input[j] = malloc16(68 * 384);
memset(channel_input[j], 0, 68 * 384);
}
channel_input_optim = malloc16(68 * 384);
memset(channel_input_optim, 0, 68 * 384);
channel_input_optim = malloc16(68 * 384 * sizeof(uint32_t));
if (use32bit ==0) memset(channel_input_optim, 0, 68 * 384 * sizeof(uint32_t));
// Fill input segments with random values
for (int j = 0; j < MAX_NUM_DLSCH_SEGMENTS; j++) {
for (int j = 0; j < n_segments; j++) {
int i = 0;
for (i = 0; i < ((Kprime + 7) & ~7) / 8; i++)
test_input[j][i] = (uint8_t)rand();
@@ -282,13 +307,17 @@ one_measurement_t test_ldpc(short max_iterations,
}
encoder_implemparams_t impp = {.Zc = Zc, .Kb = Kb, .BG = BG, .K = K};
impp.gen_code = 1;
impp.gen_code = gen_code;
impp.tparity = &tparity;
impp.tinput = &tinput;
impp.tinput_memcpy = &tinput_memcpy;
impp.toutput = &toutput;
if (ntrials == 0)
ldpc_orig.LDPCencoder(test_input, channel_input[0], &impp);
impp.gen_code = 0;
decode_abort_t dec_abort;
init_abort(&dec_abort);
uint32_t **output32;
for (int trial = 0; trial < ntrials; trial++) {
unsigned int segment_bler = 0;
//// encoder
@@ -301,26 +330,27 @@ one_measurement_t test_ldpc(short max_iterations,
impp.n_segments = n_segments;
start_meas(&ret.time_optim);
impp.first_seg = 0;
ldpc_toCompare.LDPCencoder(test_input, channel_input_optim, &impp);
if (use32bit==0) ldpc_toCompare.LDPCencoder(test_input, channel_input_optim, &impp);
else output32=ldpc_toCompare.LDPCencoder32(test_input, &impp);
stop_meas(&ret.time_optim);
if (ntrials == 1)
for (int j = 0; j < n_segments; j++)
for (int i = 0; i < K + (nrows - no_punctured_columns) * Zc - removed_bit; i++) {
if (channel_input[j][i] != ((channel_input_optim[i] >> j) & 0x1)) {
printf("differ in seg %d pos %d (%u,%u)\n", j, i, channel_input[j][i], (channel_input_optim[i] >> j) & 0x1);
return ret;
}
if (((use32bit == 0) && (channel_input[j][i] != ((channel_input_optim[i] >> j) & 0x1))) || ((use32bit == 1) && (channel_input[j][i] != (((output32[0][i] >> j) & 0x1))))) {
printf("differ in seg %d pos %d (%u,%u)\n", j, i, channel_input[j][i], (((uint32_t*)channel_input_optim)[i] >> j) & 0x1);
return ret;
}
}
int bit;
for (int j = 0; j < n_segments; j++) {
for (int i = 2 * Zc; i < (Kb + nrows - no_punctured_columns) * Zc - removed_bit; i++) {
#ifdef DEBUG_CODER
if ((i & 0xf) == 0)
printf("\ne %d..%d: ", i, i + 15);
#endif
if (((channel_input_optim[i - 2 * Zc] >> j) & 0x1) == 0)
bit = (use32bit==0) ? ((channel_input_optim[i - 2 * Zc] >> j) & 0x1) : ((output32[0][i - 2 * Zc] >> j) & 0x1);
if (bit == 0)
modulated_input[j][i] = 1.0; /// sqrt(2); //QPSK
else
modulated_input[j][i] = -1.0; /// sqrt(2);
@@ -345,7 +375,6 @@ one_measurement_t test_ldpc(short max_iterations,
decParams[j].numMaxIter = max_iterations;
decParams[j].outMode = nrLDPC_outMode_BIT;
decParams[j].Kprime = Kprime;
ldpc_toCompare.LDPCinit();
}
for (int j = 0; j < n_segments; j++) {
start_meas(&ret.time_decoder);
@@ -388,8 +417,12 @@ one_measurement_t test_ldpc(short max_iterations,
ret.errors_bit_uncoded = ret.errors_bit_uncoded / (double)((Kb + nrows - no_punctured_columns - 2) * Zc - removed_bit);
for (int j = 0; j < MAX_NUM_DLSCH_SEGMENTS; j++) {
for (int j = 0; j < n_segments; j++) {
#ifdef ENABLE_CUDA
cudaFree(test_input[j]);
#else
free(test_input[j]);
#endif
free(channel_input[j]);
}
free(channel_input_optim);
@@ -397,6 +430,7 @@ one_measurement_t test_ldpc(short max_iterations,
print_meas(&time, "ldpc_encoder", NULL, NULL);
print_meas(&ret.time_optim, "ldpc_encoder_optim", NULL, NULL);
print_meas(&tinput, "ldpc_encoder_optim(input)", NULL, NULL);
print_meas(&tinput_memcpy, "ldpc_encoder_optim(input memcpy)", NULL, NULL);
print_meas(&tprep, "ldpc_encoder_optim(prep)", NULL, NULL);
print_meas(&tparity, "ldpc_encoder_optim(parity)", NULL, NULL);
print_meas(&toutput, "ldpc_encoder_optim(output)", NULL, NULL);
@@ -437,19 +471,20 @@ int main(int argc, char *argv[])
int n_trials = 1;
double SNR_step = 0.1;
int gen_code = 1;
randominit(0);
int test_uncoded = 0;
n_iter_stats_t dec_iter[400] = {0};
short BG = 0, Zc;
int use32bit=0;
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) {
exit_fun("[LDPCTEST] Error, configuration module init failed\n");
}
logInit();
while ((c = getopt(argc, argv, "--:O:q:r:s:S:l:G:n:d:i:t:u:hv:")) != -1) {
while ((c = getopt(argc, argv, "--:O:q:r:s:S:l:Gn:d:i:t:u:hv:g:")) != -1) {
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
if (c == 1 || c == '-' || c == 'O')
@@ -475,6 +510,7 @@ int main(int argc, char *argv[])
case 'G':
ldpc_version = "_cuda";
use32bit=1;
break;
case 'n':
@@ -503,6 +539,11 @@ int main(int argc, char *argv[])
case 'v':
ldpc_version = strdup(optarg);
break;
case 'g':
gen_code = atoi(optarg);
AssertFatal(gen_code <= 4, "gen_code %d is not allowed\n",gen_code);
n_trials=0;
break;
case 'h':
default:
printf("CURRENTLY SUPPORTED CODE RATES: \n");
@@ -559,7 +600,9 @@ int main(int argc, char *argv[])
qbits,
Kprime, // block length bytes
n_trials,
n_segments);
n_segments,
gen_code,
use32bit);
decoded_errors[i] = res.errors;
dec_iter[i] = res.dec_iter;

View File

@@ -152,6 +152,7 @@ typedef struct nrLDPC_segment_encoding_parameters_s{
time_stats_t ts_interleave;
time_stats_t ts_rate_match;
time_stats_t ts_ldpc_encode;
time_stats_t ts_output;
} nrLDPC_segment_encoding_parameters_t;
/**
@@ -201,6 +202,7 @@ typedef struct nrLDPC_TB_encoding_parameters_s{
uint32_t C;
nrLDPC_segment_encoding_parameters_t *segments;
unsigned char *output;
uint8_t **c_dev;
} nrLDPC_TB_encoding_parameters_t;
/**
@@ -226,10 +228,13 @@ typedef struct nrLDPC_slot_encoding_parameters_s{
int nb_TBs;
tpool_t *threadPool;
time_stats_t *tinput;
time_stats_t *tinput_memcpy;
time_stats_t *tprep;
time_stats_t *tparity;
time_stats_t *toutput;
time_stats_t *tconcat;
nrLDPC_TB_encoding_parameters_t *TBs;
uint32_t use_gpu;
} nrLDPC_slot_encoding_parameters_t;
typedef int32_t(nrLDPC_coding_init_t)(void);

View File

@@ -281,6 +281,11 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de
int32_t nrLDPC_coding_init(void)
{
LOG_I(NR_PHY,"Initializing coding library\n");
#ifdef ENABLE_CUDA
LOG_I(NR_PHY,"Calling cuda_support_init()\n");
#endif
cuda_support_init();
return 0;
}

View File

@@ -367,9 +367,11 @@ static int nrLDPC_launch_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_s
encoder_implemparams_t common_segment_params = {
.n_segments = nrLDPC_TB_encoding_parameters->C,
.tinput = nrLDPC_slot_encoding_parameters->tinput,
.tinput_memcpy = nrLDPC_slot_encoding_parameters->tinput_memcpy,
.tprep = nrLDPC_slot_encoding_parameters->tprep,
.tparity = nrLDPC_slot_encoding_parameters->tparity,
.toutput = nrLDPC_slot_encoding_parameters->toutput,
.tconcat = nrLDPC_slot_encoding_parameters->tconcat,
.Kb = nrLDPC_TB_encoding_parameters->Kb,
.Zc = nrLDPC_TB_encoding_parameters->Z,
.BG = nrLDPC_TB_encoding_parameters->BG,
@@ -406,16 +408,24 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
for (int dlsch_id = 0; dlsch_id < nrLDPC_slot_encoding_parameters->nb_TBs; dlsch_id++) {
// Compute number of tasks to encode TB
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = &nrLDPC_slot_encoding_parameters->TBs[dlsch_id];
size_t n_seg = (nrLDPC_TB_encoding_parameters->C / 8 + ((nrLDPC_TB_encoding_parameters->C & 7) == 0 ? 0 : 1));
nbTasks += n_seg;
// Search for maximum E for sizing encoder output f and f2
for (int seg_id = 0; seg_id < nrLDPC_TB_encoding_parameters->C; seg_id++) {
uint32_t E = nrLDPC_TB_encoding_parameters->segments[seg_id].E;
Emax = E > Emax ? E : Emax;
#if defined(ENABLE_CUDA)
if (nrLDPC_slot_encoding_parameters->use_gpu && nrLDPC_TB_encoding_parameters->C > 8 && nrLDPC_TB_encoding_parameters->Z == 384) {
nrLDPC_coding_encoder32(nrLDPC_slot_encoding_parameters,nrLDPC_TB_encoding_parameters);
}
}
else {
#endif
size_t n_seg = (nrLDPC_TB_encoding_parameters->C / 8 + ((nrLDPC_TB_encoding_parameters->C & 7) == 0 ? 0 : 1));
nbTasks += n_seg;
// Search for maximum E for sizing encoder output f and f2
for (int seg_id = 0; seg_id < nrLDPC_TB_encoding_parameters->C; seg_id++) {
uint32_t E = nrLDPC_TB_encoding_parameters->segments[seg_id].E;
Emax = E > Emax ? E : Emax;
}
#if defined(ENABLE_CUDA)
}
#endif
}
// Create f and f2 to old encoding tasks outputs
uint32_t Emax_ceil_mod = ceil_mod(Emax, 64);
uint8_t f[nbTasks][Emax_ceil_mod] __attribute__((aligned(64)));
@@ -432,6 +442,10 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
// For easier indexing we store the pointers to sub arrays of f and f2 in pointer arrays
// Then a function to which we pass the pointer arrays can directly use f_2d[j] ans f2_2d[j]
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = &nrLDPC_slot_encoding_parameters->TBs[dlsch_id];
#if defined(ENABLE_CUDA)
if (nrLDPC_slot_encoding_parameters->use_gpu && nrLDPC_TB_encoding_parameters->C > 8 && nrLDPC_TB_encoding_parameters->Z == 384)
continue;
#endif
size_t n_seg = (nrLDPC_TB_encoding_parameters->C / 8 + ((nrLDPC_TB_encoding_parameters->C & 7) == 0 ? 0 : 1));
uint8_t *f_2d[n_seg];
uint8_t *f2_2d[n_seg];
@@ -449,16 +463,21 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
completed_many_task_ans(&ans, nbTasks - nbEncode);
}
// Execute thread pool tasks
join_task_ans(&ans);
if (nbTasks > 0) join_task_ans(&ans);
// Write output
time_stats_t *tconcat = nrLDPC_slot_encoding_parameters->tconcat;
if(tconcat != NULL) start_meas(tconcat);
nbTasks = 0;
for (int dlsch_id = 0; dlsch_id < nrLDPC_slot_encoding_parameters->nb_TBs; dlsch_id++) {
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = &nrLDPC_slot_encoding_parameters->TBs[dlsch_id];
uint32_t C = nrLDPC_TB_encoding_parameters->C;
#if defined(ENABLE_CUDA)
if (nrLDPC_slot_encoding_parameters->use_gpu && C > 8 && nrLDPC_TB_encoding_parameters->Z == 384)
continue;
#endif
size_t n_seg = (C / 8 + ((C & 7) == 0 ? 0 : 1));
time_stats_t *toutput = nrLDPC_slot_encoding_parameters->toutput;
for (int j = 0; j < n_seg; j++) {
unsigned int macro_segment = j * 8;
@@ -478,7 +497,6 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
}
}
if(toutput != NULL) start_meas(toutput);
uint32_t Eoffset=0;
for (int s=0; s<macro_segment; s++)
@@ -494,10 +512,10 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
nrLDPC_TB_encoding_parameters->output,
Eoffset);
if(toutput != NULL) stop_meas(toutput);
}
nbTasks += n_seg;
}
if(tconcat != NULL) stop_meas(tconcat);
return 0;
}

View File

@@ -0,0 +1,688 @@
/*
* 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.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.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 PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c
* \brief Top-level routines for implementing LDPC encoding of transport channels
*/
#include "nr_rate_matching.h"
#include "PHY/defs_gNB.h"
#include "PHY/CODING/coding_extern.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h"
#include "PHY/CODING/nrLDPC_extern.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "SCHED_NR/sched_nr.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
#include "common/utils/nr/nr_common.h"
#include <openair2/UTIL/OPT/opt.h>
#include <syscall.h>
//#define DEBUG_LDPC_ENCODING
//#define DEBUG_LDPC_ENCODING_FREE 1
extern uint32_t **d_host;
static void unpack_output(uint32_t *f,
uint32_t E,
uint32_t *f2,
uint32_t E2,
uint32_t E2_first_segment32,
uint32_t E2_first_segment,
uint32_t nb_segments,
uint8_t *output) {
uint32_t s;
// int s0;
uint32_t *fp;
int foffset;
uint32_t *output_p = (uint32_t *)output;
//printf("unpack: E %d, E2 %d, E2_first_segment %d, E2_first_segment32 %d, nb_segments %d\n",E,E2,E2_first_segment,E2_first_segment32,nb_segments);
uint32_t bit_index = 0;
#ifdef __AVX2__
simde__m256i shift0=simde_mm256_set_epi32(7,6,5,4,3,2,1,0);
simde__m256i shift1=simde_mm256_set_epi32(15,14,13,12,11,10,9,8);
simde__m256i shift2=simde_mm256_set_epi32(23,22,21,20,19,18,17,16);
simde__m256i shift3=simde_mm256_set_epi32(31,30,29,28,27,26,25,24);
simde__m256i vmask0=simde_mm256_set_epi32(0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1);
simde__m256i vmask1=simde_mm256_set_epi32(0x8000,0x4000,0x2000,0x1000,0x800,0x400,0x200,0x100);
simde__m256i vmask2=simde_mm256_set_epi32(0x800000,0x400000,0x200000,0x100000,0x80000,0x40000,0x20000,0x10000);
simde__m256i vmask3=simde_mm256_set_epi32(0x80000000,0x40000000,0x20000000,0x10000000,0x8000000,0x4000000,0x2000000,0x1000000);
int s2=0;
for (s = 0; s < E2_first_segment ; s++) {
s2 = s&31;
foffset = (s>>5)*E;
fp = f+foffset;
int i;
if ((bit_index&31) == 0 ) {
for (i = 0; i < (E>>5)<<5; i+=32) {
simde__m256i f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i],s2);
simde__m256i cshift = simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift0),vmask0);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+8],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift1),vmask1),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+16],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift2),vmask2),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+24],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift3),vmask3),cshift);
*(output_p + (bit_index>>5)) = simde_mm256_extract_epi32(cshift,0) |
simde_mm256_extract_epi32(cshift,1) |
simde_mm256_extract_epi32(cshift,2) |
simde_mm256_extract_epi32(cshift,3) |
simde_mm256_extract_epi32(cshift,4) |
simde_mm256_extract_epi32(cshift,5) |
simde_mm256_extract_epi32(cshift,6) |
simde_mm256_extract_epi32(cshift,7);
bit_index+=32;
}
uint32_t Emod32=E&31;
if (Emod32 != 0) {
simde__m256i f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i],s2);
simde__m256i cshift = simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift0),vmask0);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+8],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift1),vmask1),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+16],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift2),vmask2),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+24],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift3),vmask3),cshift);
*(output_p + (bit_index>>5)) = (simde_mm256_extract_epi32(cshift,0) |
simde_mm256_extract_epi32(cshift,1) |
simde_mm256_extract_epi32(cshift,2) |
simde_mm256_extract_epi32(cshift,3) |
simde_mm256_extract_epi32(cshift,4) |
simde_mm256_extract_epi32(cshift,5) |
simde_mm256_extract_epi32(cshift,6) |
simde_mm256_extract_epi32(cshift,7))&((1<<Emod32)-1);
bit_index+=Emod32;
}
}
else {
for (i = 0; i < (E>>5)<<5; i+=32) {
simde__m256i f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i],s2);
simde__m256i cshift = simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift0),vmask0);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+8],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift1),vmask1),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+16],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift2),vmask2),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+24],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift3),vmask3),cshift);
uint32_t tmp = simde_mm256_extract_epi32(cshift,0) |
simde_mm256_extract_epi32(cshift,1) |
simde_mm256_extract_epi32(cshift,2) |
simde_mm256_extract_epi32(cshift,3) |
simde_mm256_extract_epi32(cshift,4) |
simde_mm256_extract_epi32(cshift,5) |
simde_mm256_extract_epi32(cshift,6) |
simde_mm256_extract_epi32(cshift,7);
*(output_p + (bit_index>>5)) |= (tmp<<(bit_index&31));
*(output_p + (bit_index>>5)+1) |= (tmp>>(32-(bit_index&31)));
bit_index+=32;
}
uint32_t Emod32=E&31;
if (Emod32 != 0) {
simde__m256i f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i],s2);
simde__m256i cshift = simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift0),vmask0);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+8],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift1),vmask1),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+16],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift2),vmask2),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+24],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift3),vmask3),cshift);
uint32_t tmp = (simde_mm256_extract_epi32(cshift,0) |
simde_mm256_extract_epi32(cshift,1) |
simde_mm256_extract_epi32(cshift,2) |
simde_mm256_extract_epi32(cshift,3) |
simde_mm256_extract_epi32(cshift,4) |
simde_mm256_extract_epi32(cshift,5) |
simde_mm256_extract_epi32(cshift,6) |
simde_mm256_extract_epi32(cshift,7))&((1<<Emod32)-1);
*(output_p + (bit_index>>5)) |= (tmp<<(bit_index&31));
*(output_p + (bit_index>>5)+1) |= (tmp>>(32-(bit_index&31)));
bit_index+=Emod32;
}
}
}
for ( ; s < nb_segments ; s++){
s2 = s&31;
foffset = ((s>>5)-E2_first_segment32)*E2;
fp = f2+foffset;
int i;
if ((bit_index&31) == 0 ) {
for (i = 0; i < (E2>>5)<<5; i+=32) {
simde__m256i f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i],s2);
simde__m256i cshift = simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift0),vmask0);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+8],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift1),vmask1),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+16],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift2),vmask2),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+24],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift3),vmask3),cshift);
*(output_p + (bit_index>>5)) = simde_mm256_extract_epi32(cshift,0) |
simde_mm256_extract_epi32(cshift,1) |
simde_mm256_extract_epi32(cshift,2) |
simde_mm256_extract_epi32(cshift,3) |
simde_mm256_extract_epi32(cshift,4) |
simde_mm256_extract_epi32(cshift,5) |
simde_mm256_extract_epi32(cshift,6) |
simde_mm256_extract_epi32(cshift,7);
bit_index+=32;
}
uint32_t E2mod32=E2&31;
if (E2mod32 != 0) {
simde__m256i f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i],s2);
simde__m256i cshift = simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift0),vmask0);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+8],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift1),vmask1),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+16],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift2),vmask2),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+24],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift3),vmask3),cshift);
*(output_p + (bit_index>>5)) = (simde_mm256_extract_epi32(cshift,0) |
simde_mm256_extract_epi32(cshift,1) |
simde_mm256_extract_epi32(cshift,2) |
simde_mm256_extract_epi32(cshift,3) |
simde_mm256_extract_epi32(cshift,4) |
simde_mm256_extract_epi32(cshift,5) |
simde_mm256_extract_epi32(cshift,6) |
simde_mm256_extract_epi32(cshift,7))&((1<<E2mod32)-1);
bit_index+=E2mod32;
}
}
else {
for (i = 0; i < (E2>>5)<<5; i+=32) {
simde__m256i f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i],s2);
simde__m256i cshift = simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift0),vmask0);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+8],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift1),vmask1),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+16],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift2),vmask2),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+24],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift3),vmask3),cshift);
uint32_t tmp = simde_mm256_extract_epi32(cshift,0) |
simde_mm256_extract_epi32(cshift,1) |
simde_mm256_extract_epi32(cshift,2) |
simde_mm256_extract_epi32(cshift,3) |
simde_mm256_extract_epi32(cshift,4) |
simde_mm256_extract_epi32(cshift,5) |
simde_mm256_extract_epi32(cshift,6) |
simde_mm256_extract_epi32(cshift,7);
*(output_p + (bit_index>>5)) |= (tmp<<(bit_index&31));
*(output_p + (bit_index>>5)+1) |= (tmp>>(32-(bit_index&31)));
bit_index+=32;
}
uint32_t E2mod32=E2&31;
if (E2mod32 != 0) {
simde__m256i f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i],s2);
simde__m256i cshift = simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift0),vmask0);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+8],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift1),vmask1),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+16],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift2),vmask2),cshift);
f256 = simde_mm256_srli_epi32(*(simde__m256i*)&fp[i+24],s2);
cshift = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_sllv_epi32(f256,shift3),vmask3),cshift);
uint32_t tmp = (simde_mm256_extract_epi32(cshift,0) |
simde_mm256_extract_epi32(cshift,1) |
simde_mm256_extract_epi32(cshift,2) |
simde_mm256_extract_epi32(cshift,3) |
simde_mm256_extract_epi32(cshift,4) |
simde_mm256_extract_epi32(cshift,5) |
simde_mm256_extract_epi32(cshift,6) |
simde_mm256_extract_epi32(cshift,7))&((1<<E2mod32)-1);
*(output_p + (bit_index>>5)) |= (tmp<<(bit_index&31));
*(output_p + (bit_index>>5)+1) |= (tmp>>(32-(bit_index&31)));
bit_index+=E2mod32;
}
}
}
#elif defined(__aarch64__)
const int32_t ucShift0[32][4] = { {0,1,2,3}, {-1,0,1,2},{-2,-1,0,1}, {-3,-2,-1,0}, {-4,-3,-2,-1}, {-5,-4,-3,-2}, {-6,-5,-4,-3}, {-7,-6,-5,-4}, {-8,-7,-6,-5}, {-9,-8,-7,-6}, {-10,-9,-8,-7}, {-11,-10,-9,-8}, {-12,-11,-10,-9}, {-13,-12,-11,-10}, {-14,-13,-12,-11}, {-15,-14,-13,-12}, {-16,-15,-14,-13}, {-17,-16,-15,-14}, {-18,-17,-16,-15}, {-19,-18,-17,-16}, {-20,-19,-18,-17}, {-21,-20,-19,-18}, {-22,-21,-20,-19}, {-23,-22,-21,-20}, {-24,-23,-22,-21}, {-25,-24,-23,-22}, {-26,-25,-24,-23}, {-27,-26,-25,-24}, {-28,-27,-26,-25}, {-29,-28,-27,-26}, {-30,-29,-28,-27}, {-31,-30,-29,-28}};
const int32_t ucShift1[32][4] = { {4,5,6,7}, {3,4,5,6}, {2,3,4,5}, {1,2,3,4}, {0,1,2,3}, {-1,0,1,2},{-2,-1,0,1}, {-3,-2,-1,0}, {-4,-3,-2,-1}, {-5,-4,-3,-2}, {-6,-5,-4,-3}, {-7,-6,-5,-4}, {-8,-7,-6,-5}, {-9,-8,-7,-6}, {-10,-9,-8,-7}, {-11,-10,-9,-8}, {-12,-11,-10,-9}, {-13,-12,-11,-10}, {-14,-13,-12,-11}, {-15,-14,-13,-12}, {-16,-15,-14,-13}, {-17,-16,-15,-14}, {-18,-17,-16,-15}, {-19,-18,-17,-16}, {-20,-19,-18,-17}, {-21,-20,-19,-18}, {-22,-21,-20,-19}, {-23,-22,-21,-20}, {-24,-23,-22,-21}, {-25,-24,-23,-22}, {-26,-25,-24,-23}, {-27,-26,-25,-24}};
const int32_t ucShift2[32][4] = { {8,9,10,11},{7,8,9,10}, {6,7,8,9}, {5,6,7,8}, {4,5,6,7}, {3,4,5,6}, {2,3,4,5}, {1,2,3,4}, {0,1,2,3}, {-1,0,1,2},{-2,-1,0,1}, {-3,-2,-1,0}, {-4,-3,-2,-1}, {-5,-4,-3,-2}, {-6,-5,-4,-3}, {-7,-6,-5,-4}, {-8,-7,-6,-5}, {-9,-8,-7,-6}, {-10,-9,-8,-7}, {-11,-10,-9,-8}, {-12,-11,-10,-9}, {-13,-12,-11,-10}, {-14,-13,-12,-11}, {-15,-14,-13,-12}, {-16,-15,-14,-13}, {-17,-16,-15,-14}, {-18,-17,-16,-15}, {-19,-18,-17,-16}, {-20,-19,-18,-17}, {-21,-20,-19,-18}, {-22,-21,-20,-19},{-23,-22,-21,-20}};
const int32_t ucShift3[32][4] = { {12,13,14,15}, {11,12,13,14}, {10,11,12,13}, {9,10,11,12}, {8,9,10,11},{7,8,9,10}, {6,7,8,9}, {5,6,7,8}, {4,5,6,7}, {3,4,5,6}, {2,3,4,5}, {1,2,3,4}, {0,1,2,3}, {-1,0,1,2},{-2,-1,0,1}, {-3,-2,-1,0}, {-4,-3,-2,-1}, {-5,-4,-3,-2}, {-6,-5,-4,-3}, {-7,-6,-5,-4}, {-8,-7,-6,-5}, {-9,-8,-7,-6}, {-10,-9,-8,-7}, {-11,-10,-9,-8}, {-12,-11,-10,-9}, {-13,-12,-11,-10}, {-14,-13,-12,-11}, {-15,-14,-13,-12}, {-16,-15,-14,-13}, {-17,-16,-15,-14}, {-18,-17,-16,-15}, {-19,-18,-17,-16}};
const int32_t ucShift4[32][4] = { {16,17,18,19}, {15,16,17,18}, {14,15,16,17}, {13,14,15,16}, {12,13,14,15}, {11,12,13,14}, {10,11,12,13}, {9,10,11,12}, {8,9,10,11},{7,8,9,10}, {6,7,8,9}, {5,6,7,8}, {4,5,6,7}, {3,4,5,6}, {2,3,4,5}, {1,2,3,4}, {0,1,2,3}, {-1,0,1,2},{-2,-1,0,1}, {-3,-2,-1,0}, {-4,-3,-2,-1}, {-5,-4,-3,-2}, {-6,-5,-4,-3}, {-7,-6,-5,-4}, {-8,-7,-6,-5}, {-9,-8,-7,-6}, {-10,-9,-8,-7}, {-11,-10,-9,-8}, {-12,-11,-10,-9}, {-13,-12,-11,-10}, {-14,-13,-12,-11}, {-15,-14,-13,-12}};
const int32_t ucShift5[32][4] = { {20,21,22,23}, {19,20,21,22}, {18,19,20,21}, {17,18,19,20}, {16,17,18,19}, {15,16,17,18}, {14,15,16,17}, {13,14,15,16}, {12,13,14,15}, {11,12,13,14}, {10,11,12,13}, {9,10,11,12}, {8,9,10,11},{7,8,9,10}, {6,7,8,9}, {5,6,7,8}, {4,5,6,7}, {3,4,5,6}, {2,3,4,5}, {1,2,3,4}, {0,1,2,3}, {-1,0,1,2},{-2,-1,0,1}, {-3,-2,-1,0}, {-4,-3,-2,-1}, {-5,-4,-3,-2}, {-6,-5,-4,-3}, {-7,-6,-5,-4}, {-8,-7,-6,-5}, {-9,-8,-7,-6}, {-10,-9,-8,-7}, {-11,-10,-9,-8}};
const int32_t ucShift6[32][4] = { {24,25,26,27}, {23,24,25,26}, {22,23,24,25}, {21,22,23,24}, {20,21,22,23}, {19,20,21,22}, {18,19,20,21}, {17,18,19,20}, {16,17,18,19}, {15,16,17,18}, {14,15,16,17}, {13,14,15,16}, {12,13,14,15}, {11,12,13,14}, {10,11,12,13}, {9,10,11,12}, {8,9,10,11},{7,8,9,10}, {6,7,8,9}, {5,6,7,8}, {4,5,6,7}, {3,4,5,6}, {2,3,4,5}, {1,2,3,4}, {0,1,2,3}, {-1,0,1,2},{-2,-1,0,1}, {-3,-2,-1,0}, {-4,-3,-2,-1}, {-5,-4,-3,-2}, {-6,-5,-4,-3}, {-7,-6,-5,-4}};
const int32_t ucShift7[32][4] = { {28,29,30,31}, {27,28,29,30}, {26,27,28,29}, {25,26,27,28}, {24,25,26,27}, {23,24,25,26}, {22,23,24,25}, {21,22,23,24}, {20,21,22,23}, {19,20,21,22}, {18,19,20,21}, {17,18,19,20}, {16,17,18,19}, {15,16,17,18}, {14,15,16,17}, {13,14,15,16}, {12,13,14,15}, {11,12,13,14}, {10,11,12,13}, {9,10,11,12}, {8,9,10,11},{7,8,9,10}, {6,7,8,9}, {5,6,7,8}, {4,5,6,7}, {3,4,5,6}, {2,3,4,5}, {1,2,3,4}, {0,1,2,3}, {-1,0,1,2},{-2,-1,0,1}, {-3,-2,-1,0}};
const uint32_t __attribute__ ((aligned (16))) masks0[4] = {0x1,0x2,0x4,0x8};
const uint32_t __attribute__ ((aligned (16))) masks1[4] = {0x10,0x20,0x40,0x80};
const uint32_t __attribute__ ((aligned (16))) masks2[4] = {0x100,0x200,0x400,0x800};
const uint32_t __attribute__ ((aligned (16))) masks3[4] = {0x1000,0x2000,0x4000,0x8000};
const uint32_t __attribute__ ((aligned (16))) masks4[4] = {0x10000,0x20000,0x40000,0x80000};
const uint32_t __attribute__ ((aligned (16))) masks5[4] = {0x100000,0x200000,0x400000,0x800000};
const uint32_t __attribute__ ((aligned (16))) masks6[4] = {0x1000000,0x2000000,0x4000000,0x8000000};
const uint32_t __attribute__ ((aligned (16))) masks7[4] = {0x10000000,0x20000000,0x40000000,0x80000000};
int32x4_t vshift0[32],vshift1[32],vshift2[32],vshift3[32],vshift4[32],vshift5[32],vshift6[32],vshift7[32];
for (int n=0;n<32;n++) {
vshift0[n] = vld1q_s32(ucShift0[n]);
vshift1[n] = vld1q_s32(ucShift1[n]);
vshift2[n] = vld1q_s32(ucShift2[n]);
vshift3[n] = vld1q_s32(ucShift3[n]);
vshift4[n] = vld1q_s32(ucShift4[n]);
vshift5[n] = vld1q_s32(ucShift5[n]);
vshift6[n] = vld1q_s32(ucShift6[n]);
vshift7[n] = vld1q_s32(ucShift7[n]);
}
uint32x4_t vmask0 = vld1q_u32(masks0);
uint32x4_t vmask1 = vld1q_u32(masks1);
uint32x4_t vmask2 = vld1q_u32(masks2);
uint32x4_t vmask3 = vld1q_u32(masks3);
uint32x4_t vmask4 = vld1q_u32(masks4);
uint32x4_t vmask5 = vld1q_u32(masks5);
uint32x4_t vmask6 = vld1q_u32(masks6);
uint32x4_t vmask7 = vld1q_u32(masks7);
uint32_t output_tmp=0;
int s2=0;
for (s = 0; s < E2_first_segment ; s++) {
s2 = s&31;
foffset = (s>>5)*E;
fp = f+foffset;
int i;
if ((bit_index&31) == 0 ) {
for (i = 0; i < (E>>5)<<5; i+=32) {
uint32x4_t *fp128 = (uint32x4_t*)&fp[i];
uint32x4_t cshift = vandq_u32(vshlq_u32(fp128[0],vshift0[s2]),vmask0);
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[1],vshift1[s2]),vmask1));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[2],vshift2[s2]),vmask2));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[3],vshift3[s2]),vmask3));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[4],vshift4[s2]),vmask4));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[5],vshift5[s2]),vmask5));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[6],vshift6[s2]),vmask6));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[7],vshift7[s2]),vmask7));
*(output_p + (bit_index>>5)) = vaddvq_u32(cshift);
bit_index+=32;
}
uint32_t Emod32=E&31;
if (Emod32 != 0) {
uint32x4_t *fp128 = (uint32x4_t*)&fp[i];
uint32x4_t cshift = vandq_u32(vshlq_u32(fp128[0],vshift0[s2]),vmask0);
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[1],vshift1[s2]),vmask1));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[2],vshift2[s2]),vmask2));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[3],vshift3[s2]),vmask3));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[4],vshift4[s2]),vmask4));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[5],vshift5[s2]),vmask5));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[6],vshift6[s2]),vmask6));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[7],vshift7[s2]),vmask7));
*(output_p + (bit_index>>5)) = vaddvq_u32(cshift)&((1<<Emod32)-1);
bit_index+=Emod32;
}
}
else {
for (i = 0; i < (E>>5)<<5; i+=32) {
uint32x4_t *fp128 = (uint32x4_t*)&fp[i];
uint32x4_t cshift = vandq_u32(vshlq_u32(fp128[0],vshift0[s2]),vmask0);
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[1],vshift1[s2]),vmask1));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[2],vshift2[s2]),vmask2));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[3],vshift3[s2]),vmask3));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[4],vshift4[s2]),vmask4));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[5],vshift5[s2]),vmask5));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[6],vshift6[s2]),vmask6));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[7],vshift7[s2]),vmask7));
/*
uint32_t tmp = vaddvq_u32(cshift);
*(output_p + (bit_index>>5)) |= (tmp<<(bit_index&31));
*(output_p + (bit_index>>5)+1) |= (tmp>>(32-(bit_index&31)));
*/
uint64_t tmp = (uint64_t)vaddvq_u32(cshift);
*(uint64_t*)(output_p + (bit_index>>5)) |= (tmp<<(bit_index&31));
bit_index+=32;
}
uint32_t Emod32=E&31;
if (Emod32 != 0) {
uint32x4_t *fp128 = (uint32x4_t*)&fp[i];
uint32x4_t cshift = vandq_u32(vshlq_u32(fp128[0],vshift0[s2]),vmask0);
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[1],vshift1[s2]),vmask1));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[2],vshift2[s2]),vmask2));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[3],vshift3[s2]),vmask3));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[4],vshift4[s2]),vmask4));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[5],vshift5[s2]),vmask5));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[6],vshift6[s2]),vmask6));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[7],vshift7[s2]),vmask7));
uint32_t tmp = vaddvq_u32(cshift);
tmp&=((1<<Emod32)-1);
*(output_p + (bit_index>>5)) |= (tmp<<(bit_index&31));
*(output_p + (bit_index>>5)+1) |= (tmp>>(32-(bit_index&31)));
bit_index+=Emod32;
}
}
}
// s0 = s;
for ( ; s < nb_segments ; s++){
s2 = s&31;
foffset = ((s>>5)-E2_first_segment32)*E2;
fp = f2+foffset;
int i;
if ((bit_index&31) == 0 ) {
for (i = 0; i < (E2>>5)<<5; i+=32) {
uint32x4_t *fp128 = (uint32x4_t*)&fp[i];
uint32x4_t cshift = vandq_u32(vshlq_u32(fp128[0],vshift0[s2]),vmask0);
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[1],vshift1[s2]),vmask1));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[2],vshift2[s2]),vmask2));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[3],vshift3[s2]),vmask3));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[4],vshift4[s2]),vmask4));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[5],vshift5[s2]),vmask5));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[6],vshift6[s2]),vmask6));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[7],vshift7[s2]),vmask7));
*(output_p + (bit_index>>5)) = vaddvq_u32(cshift);
bit_index+=32;
}
uint32_t E2mod32=E2&31;
if (E2mod32 != 0) {
uint32x4_t *fp128 = (uint32x4_t*)&fp[i];
uint32x4_t cshift = vandq_u32(vshlq_u32(fp128[0],vshift0[s2]),vmask0);
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[1],vshift1[s2]),vmask1));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[2],vshift2[s2]),vmask2));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[3],vshift3[s2]),vmask3));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[4],vshift4[s2]),vmask4));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[5],vshift5[s2]),vmask5));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[6],vshift6[s2]),vmask6));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[7],vshift7[s2]),vmask7));
*(output_p + (bit_index>>5)) = vaddvq_u32(cshift)&((1<<E2mod32)-1);
bit_index+=E2mod32;
}
}
else {
for (i = 0; i < (E2>>5)<<5; i+=32) {
uint32x4_t *fp128 = (uint32x4_t*)&fp[i];
uint32x4_t cshift = vandq_u32(vshlq_u32(fp128[0],vshift0[s2]),vmask0);
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[1],vshift1[s2]),vmask1));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[2],vshift2[s2]),vmask2));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[3],vshift3[s2]),vmask3));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[4],vshift4[s2]),vmask4));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[5],vshift5[s2]),vmask5));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[6],vshift6[s2]),vmask6));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[7],vshift7[s2]),vmask7));
uint32_t tmp = vaddvq_u32(cshift);
*(output_p + (bit_index>>5)) |= (tmp<<(bit_index&31));
*(output_p + (bit_index>>5)+1) |= (tmp>>(32-(bit_index&31)));
bit_index+=32;
}
uint32_t E2mod32=E2&31;
if (E2mod32 != 0) {
uint32x4_t *fp128 = (uint32x4_t*)&fp[i];
uint32x4_t cshift = vandq_u32(vshlq_u32(fp128[0],vshift0[s2]),vmask0);
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[1],vshift1[s2]),vmask1));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[2],vshift2[s2]),vmask2));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[3],vshift3[s2]),vmask3));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[4],vshift4[s2]),vmask4));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[5],vshift5[s2]),vmask5));
cshift = vorrq_u32(cshift,vandq_u32(vshlq_u32(fp128[6],vshift6[s2]),vmask6));
uint32_t tmp = vaddvq_u32(cshift);
tmp&=((1<<E2mod32)-1);
*(output_p + (bit_index>>5)) |= (tmp<<(bit_index&31));
*(output_p + (bit_index>>5)+1) |= (tmp>>(32-(bit_index&31)));
bit_index+=E2mod32;
}
}
}
#else // non SIMD version
unsigned int segpos,s2;
for (s = 0; s < E2_first_segment ; s++) {
foffset = (s>>5)*E;
fp = f+foffset;
s2=s&31;
segpos = (1<<s2);
// printf("E %d s %d: foffset %d, s2 %d, segpos %u\n",E,s,foffset,s2,segpos);
for (int i = 0; i < E; i++) {
output_p[bit_index>>5]|=((fp[i] & segpos)!=0)<<(bit_index&31);
//printf("bit_index %d, output_p[%d] %x\n",bit_index, bit_index>>5,output_p[bit_index>>5]);
bit_index++;
}
}
for ( ; s < nb_segments ; s++){
foffset = ((s>>5)-E2_first_segment32)*E2;
fp = f2+foffset;
s2=s&31;
segpos = (1<<s2);
// printf("E2 %d s %d: foffset %d, s2 %d, segpos %u\n",E2,s,foffset,s2,segpos);
for (int i = 0; i < E2; i++) {
output_p[bit_index>>5]|=((fp[i] & segpos)!=0)<<(bit_index&31);
bit_index++;
}
}
#endif
}
/**
* \typedef ldpc8blocks_args_t
* \struct ldpc8blocks_args_s
* \brief Arguments of an encoding task
* encode up to 8 code blocks
* \var nrLDPC_TB_encoding_parameters TB encoding parameters as defined in the coding library interface
* \var impp encoder implementation specific parameters for the task
* \var f first interleaver output to be filled by the task
* \var f2 second interleaver output to be filled by the task
* in case of a shift of E in the code blocks group processed by the task
*/
static void ldpcnblocks(nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters, encoder_implemparams_t impp)
{
uint8_t mod_order = nrLDPC_TB_encoding_parameters->Qm;
uint16_t nb_rb = nrLDPC_TB_encoding_parameters->nb_rb;
uint32_t A = nrLDPC_TB_encoding_parameters->A;
unsigned int G = nrLDPC_TB_encoding_parameters->G;
LOG_D(PHY, "dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n", A, impp.K, G, nb_rb, (int)mod_order);
// nrLDPC_encoder output is in "d"
// let's make this interface happy!
// uint32_t d[4][68*384];
uint8_t *c[nrLDPC_TB_encoding_parameters->C];
if (!nrLDPC_TB_encoding_parameters->c_dev)
for (int r = 0; r < nrLDPC_TB_encoding_parameters->C; r++)
c[r] = nrLDPC_TB_encoding_parameters->segments[r].c;
start_meas(&nrLDPC_TB_encoding_parameters->segments[impp.first_seg].ts_ldpc_encode);
LDPCencoder32(nrLDPC_TB_encoding_parameters->c_dev ? nrLDPC_TB_encoding_parameters->c_dev : c, &impp);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[impp.first_seg].ts_ldpc_encode);
// Compute where to place in output buffer that is concatenation of all segments
#ifdef DEBUG_LDPC_ENCODING
LOG_D(PHY, "rvidx in encoding = %d\n", nrLDPC_TB_encoding_parameters->rv_index);
#endif
const uint32_t E = nrLDPC_TB_encoding_parameters->segments[0].E;
uint32_t E2=E;
uint32_t Emax = E;
int n_seg = nrLDPC_TB_encoding_parameters->C>>5;
int n_seg2 = n_seg;
if ((nrLDPC_TB_encoding_parameters->C & 31) > 0) n_seg2++;
int r_shift = n_seg2;
int r_shift2 = nrLDPC_TB_encoding_parameters->C;
for (int s=0;s<nrLDPC_TB_encoding_parameters->C;s++) {
//printf("segment %d E %d\n",s,nrLDPC_TB_encoding_parameters->segments[s].E);
if (nrLDPC_TB_encoding_parameters->segments[s].E != E) {
E2=nrLDPC_TB_encoding_parameters->segments[s].E;
if(E2 > Emax)
Emax = E2;
r_shift = s>>5;
r_shift2 = s;
// printf("r_shift %d, r_shift2 %d\n",r_shift,r_shift2);
break;
}
}
LOG_D(NR_PHY,
"Rate Matching, Code segment %d...%d r_shift %d n_seg2 %d (coded bits (G) %u, E %d, E2 %d Filler bits %d, Filler offset %d mod_order %d, nb_rb "
"%d,nrOfLayer %d)...\n",
0,
impp.n_segments-1,
r_shift,
n_seg2,
G,
E,E2,
impp.F,
impp.K - impp.F - 2 * impp.Zc,
mod_order,
nb_rb,
nrLDPC_TB_encoding_parameters->nb_layers);
/*
printf("Rate Matching, Code segment 0..%d r_shift %d r_shift2 %d n_seg2 %d (coded bits (G) %u, E %d, E2 %d Filler bits %d, Filler offset %d mod_order %d, nb_rb "
"%d,nrOfLayer %d)...\n",
impp.n_segments-1,
r_shift,
r_shift2,
n_seg2,
G,
E,E2,
impp.F,
impp.K - impp.F - 2 * impp.Zc,
mod_order,
nb_rb,
nrLDPC_TB_encoding_parameters->nb_layers);
*/
uint32_t Tbslbrm = nrLDPC_TB_encoding_parameters->tbslbrm;
uint32_t e[E*(r_shift+1)];
uint32_t e2[E2*(n_seg2-r_shift)];
uint32_t f[E*(r_shift+1)] __attribute__ ((aligned (64)));
uint32_t f2[E2*(n_seg2-r_shift)] __attribute__ ((aligned (64)));
// Interleaver outputs are stored in the output arrays
uint8_t *output = nrLDPC_TB_encoding_parameters->output;
start_meas(&nrLDPC_TB_encoding_parameters->segments[0].ts_rate_match);
memset(e,0,sizeof(e));
memset(f,0,sizeof(f));
if (1/*r_shift < n_seg2*/) {
memset(e2,0,sizeof(e2));
memset(f2,0,sizeof(f2));
}
for (int r=0;r<n_seg2;r++) {
if (r<=r_shift)
nr_rate_matching_ldpc32(Tbslbrm,
impp.BG,
impp.Zc,
d_host[r],
e+(r*E),
impp.n_segments,
impp.F,
impp.K - impp.F - 2 * impp.Zc,
nrLDPC_TB_encoding_parameters->rv_index,
E);
if (r>=r_shift)
nr_rate_matching_ldpc32(Tbslbrm,
impp.BG,
impp.Zc,
d_host[r],
e2+((r-r_shift)*E2),
impp.n_segments,
impp.F,
impp.K - impp.F - 2 * impp.Zc,
nrLDPC_TB_encoding_parameters->rv_index,
E2);
/*
if (r==(n_seg2-1)) {
for (int i=0;i<16;i++) printf("rm: %x %x\n",d[n_seg2-1][i],e2[((n_seg2-1)*E2)+i]);
}
*/
}
stop_meas(&nrLDPC_TB_encoding_parameters->segments[0].ts_rate_match);
if (impp.K - impp.F - 2 * impp.Zc > E) {
LOG_E(PHY,
"dlsch coding A %d Kr %d G %d (nb_rb %d, mod_order %d)\n",
A,
impp.K,
G,
nb_rb,
(int)mod_order);
LOG_E(NR_PHY,
"Rate Matching, Code segments 0..%d (coded bits (G) %u, E %d, Kr %d, Filler bits %d, Filler offset %d mod_order %d, "
"nb_rb %d)...\n",
impp.n_segments,
G,
E,
impp.K,
impp.F,
impp.K - impp.F - 2 * impp.Zc,
mod_order,
nb_rb);
}
//printf("interleaving r_shift %d, n_seg2 %d\n",r_shift,n_seg2);
start_meas(&nrLDPC_TB_encoding_parameters->segments[0].ts_interleave);
for (int r=0;r<=r_shift;r++)
nr_interleaving_ldpc32(E,
mod_order,
e+E*r,
f+E*r);
for (int r=r_shift;r<n_seg2;r++)
nr_interleaving_ldpc32(E2,
mod_order,
e2+E2*(r-r_shift),
f2+E2*(r-r_shift));
/*
for (int i=0;i<16;i++) printf("intl (f offset %d): %x %x\n",(n_seg2-1)*E2,e2[((n_seg2-1)*E2)+i],f2[((n_seg2-1)*E2)+i]);
printf("-------------------\n");
for (int i=E2-16;i<E2;i++) printf("intl (f offset %d): %x %x\n",(n_seg2-1)*E2,e2[((n_seg2-1)*E2)+i],f2[((n_seg2-1)*E2)+i]);
*/
stop_meas(&nrLDPC_TB_encoding_parameters->segments[0].ts_interleave);
if (impp.tconcat) start_meas(impp.tconcat);
unpack_output(f,E,f2,E2,r_shift,r_shift2,nrLDPC_TB_encoding_parameters->C,output);
if (impp.tconcat) stop_meas(impp.tconcat);
}
int nrLDPC_coding_encoder32(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters, nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters)
{
encoder_implemparams_t common_segment_params = {
.n_segments = nrLDPC_TB_encoding_parameters->C,
.tinput = nrLDPC_slot_encoding_parameters->tinput,
.tinput_memcpy = nrLDPC_slot_encoding_parameters->tinput_memcpy,
.tprep = nrLDPC_slot_encoding_parameters->tprep,
.tparity = nrLDPC_slot_encoding_parameters->tparity,
.toutput = nrLDPC_slot_encoding_parameters->toutput,
.tconcat = nrLDPC_slot_encoding_parameters->tconcat,
.Kb = nrLDPC_TB_encoding_parameters->Kb,
.Zc = nrLDPC_TB_encoding_parameters->Z,
.BG = nrLDPC_TB_encoding_parameters->BG,
.output = nrLDPC_TB_encoding_parameters->output,
.K = nrLDPC_TB_encoding_parameters->K,
.F = nrLDPC_TB_encoding_parameters->F,
};
LOG_D(NR_PHY,"Calling ldpcnblocks (C %d, Z %d, K %d)\n",common_segment_params.n_segments,common_segment_params.Zc,common_segment_params.K);
ldpcnblocks(nrLDPC_TB_encoding_parameters, common_segment_params);
return 0;
}

View File

@@ -24,7 +24,8 @@
#include "common/utils/LOG/log.h"
// #define RM_DEBUG 1
#define USE128BIT
static const uint8_t index_k0[2][4] = {{0, 17, 33, 56}, {0, 13, 25, 43}};
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e, uint8_t *f)
@@ -359,14 +360,15 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e, uint8_t *f)
f = (uint8_t *)f_512;
#endif
#ifdef USE128BIT
e0_128 = (simde__m128i *)e0;
e1_128 = (simde__m128i *)e1;
e2_128 = (simde__m128i *)e2;
e3_128 = (simde__m128i *)e3;
e4_128 = (simde__m128i *)e4;
e5_128 = (simde__m128i *)e5;
e6_128 = (simde__m128i *)e6;
e7_128 = (simde__m128i *)e7;
simde__m128i *e0_128 = (simde__m128i *)e0;
simde__m128i *e1_128 = (simde__m128i *)e1;
simde__m128i *e2_128 = (simde__m128i *)e2;
simde__m128i *e3_128 = (simde__m128i *)e3;
simde__m128i *e4_128 = (simde__m128i *)e4;
simde__m128i *e5_128 = (simde__m128i *)e5;
simde__m128i *e6_128 = (simde__m128i *)e6;
simde__m128i *e7_128 = (simde__m128i *)e7;
simde__m128i *f_128 = (simde__m128i *)f;
for (; i < (EQm & ~15); i += 16) {
simde__m128i e0j = simde_mm_loadu_si128(e0_128++);
simde__m128i e1j = simde_mm_loadu_si128(e1_128++);
@@ -444,6 +446,225 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e, uint8_t *f)
}
}
void nr_interleaving_ldpc32(uint32_t E, uint8_t Qm, uint32_t *e, uint32_t *f)
{
const uint32_t EQm = E / Qm;
memset(f, 0, E * sizeof(uint32_t));
switch(Qm) {
case 2: {
uint32_t *e0 = e;
uint32_t *e1 = e0 + EQm;
int i = 0;
for (; i < EQm; i++) {
*f++ = *e0++;
*f++ = *e1++;
}
} break;
case 4: {
uint32_t *e0 = e;
uint32_t *e1 = e0 + EQm;
uint32_t *e2 = e1 + EQm;
uint32_t *e3 = e2 + EQm;
int i = 0;
for (; i < EQm; i++) {
*f++ = *e0++;
*f++ = *e1++;
*f++ = *e2++;
*f++ = *e3++;
}
} break;
case 6: {
uint32_t *e0 = e;
uint32_t *e1 = e0 + EQm;
uint32_t *e2 = e1 + EQm;
uint32_t *e3 = e2 + EQm;
uint32_t *e4 = e3 + EQm;
uint32_t *e5 = e4 + EQm;
int i = 0;
simde__m128i *e0_128 = (simde__m128i *)e0;
simde__m128i *e1_128 = (simde__m128i *)e1;
simde__m128i *e2_128 = (simde__m128i *)e2;
simde__m128i *e3_128 = (simde__m128i *)e3;
simde__m128i *e4_128 = (simde__m128i *)e4;
simde__m128i *e5_128 = (simde__m128i *)e5;
simde__m128i *f128 = (simde__m128i *)f;
for (; i < (EQm & ~3); i += 4) {
simde__m128i e0j = simde_mm_loadu_si128(e0_128++);
simde__m128i e1j = simde_mm_loadu_si128(e1_128++);
simde__m128i e2j = simde_mm_loadu_si128(e2_128++);
simde__m128i e3j = simde_mm_loadu_si128(e3_128++);
simde__m128i e4j = simde_mm_loadu_si128(e4_128++);
simde__m128i e5j = simde_mm_loadu_si128(e5_128++);
simde__m128i tmp0 = simde_mm_unpacklo_epi32(e0j, e1j); // e0(i) e1(i) e0(i+1) e1(i+1)
simde__m128i tmp1 = simde_mm_unpacklo_epi32(e2j, e3j); // e2(i) e3(i) e2(i+1) e3(i+1)
simde__m128i tmp2 = simde_mm_unpacklo_epi32(e4j, e5j); // e4(i) e5(i) e4(i+1) e5(i+1)
simde_mm_storeu_si128(f128++,simde_mm_unpacklo_epi64(tmp0, tmp1)); // e0(i) e1(i) e2(i) e3(i)
simde_mm_storeu_si128(f128++,simde_mm_unpacklo_epi64(tmp2,simde_mm_unpackhi_epi64(tmp0,tmp0))); // e4(i) e5(i) e0(i+1) e1(i+1)
simde_mm_storeu_si128(f128++,simde_mm_unpackhi_epi64(tmp1,tmp2)); // e2(i+1) e3(i+1) e4(i+1) e5(i+1)
tmp0 = simde_mm_unpackhi_epi32(e0j, e1j); // e0(i+2) e1(i+2) e0(i+3) e1(i+3)
tmp1 = simde_mm_unpackhi_epi32(e2j, e3j); // e2(i+2) e3(i+2) e2(i+3) e3(i+3)
tmp2 = simde_mm_unpackhi_epi32(e4j, e5j); // e4(i+2) e5(i+2) e4(i+3) e5(i+3)
simde_mm_storeu_si128(f128++,simde_mm_unpacklo_epi64(tmp0, tmp1)); // e0(i+2) e1(i+2) e2(i+2) e3(i+2)
simde_mm_storeu_si128(f128++,simde_mm_unpacklo_epi64(tmp2,simde_mm_unpackhi_epi64(tmp0,tmp0))); // e4(i+2) e5(i+2) e0(i+3) e1(i+3)
simde_mm_storeu_si128(f128++,simde_mm_unpackhi_epi64(tmp1,tmp2)); // e2(i+3) e3(i+3) e4(i+3) e5(i+3)
}
e0 = (uint32_t *)e0_128;
e1 = (uint32_t *)e1_128;
e2 = (uint32_t *)e2_128;
e3 = (uint32_t *)e3_128;
e4 = (uint32_t *)e4_128;
e5 = (uint32_t *)e5_128;
f = (uint32_t *)f128;
for (; i < EQm; i++) {
*f++ = *e0++;
*f++ = *e1++;
*f++ = *e2++;
*f++ = *e3++;
*f++ = *e4++;
*f++ = *e5++;
}
} break;
case 8: {
uint32_t *e0 = e;
uint32_t *e1 = e0 + EQm;
uint32_t *e2 = e1 + EQm;
uint32_t *e3 = e2 + EQm;
uint32_t *e4 = e3 + EQm;
uint32_t *e5 = e4 + EQm;
uint32_t *e6 = e5 + EQm;
uint32_t *e7 = e6 + EQm;
int i = 0;
#if 0 /*def __AVX2__, this needs to be fixed, revert to 128-bit below*/
simde__m256i *e0_256 = (simde__m256i *)e0;
simde__m256i *e1_256 = (simde__m256i *)e1;
simde__m256i *e2_256 = (simde__m256i *)e2;
simde__m256i *e3_256 = (simde__m256i *)e3;
simde__m256i *e4_256 = (simde__m256i *)e4;
simde__m256i *e5_256 = (simde__m256i *)e5;
simde__m256i *e6_256 = (simde__m256i *)e6;
simde__m256i *e7_256 = (simde__m256i *)e7;
simde__m256i *f256 = (simde__m256i *)f;
for (; i < (EQm & ~7); i += 8) {
simde__m256i e0j = simde_mm256_loadu_si256(e0_256++);
simde__m256i e1j = simde_mm256_loadu_si256(e1_256++);
simde__m256i e2j = simde_mm256_loadu_si256(e2_256++);
simde__m256i e3j = simde_mm256_loadu_si256(e3_256++);
simde__m256i e4j = simde_mm256_loadu_si256(e4_256++);
simde__m256i e5j = simde_mm256_loadu_si256(e5_256++);
simde__m256i e6j = simde_mm256_loadu_si256(e6_256++);
simde__m256i e7j = simde_mm256_loadu_si256(e7_256++);
simde__m256i tmp0 = simde_mm256_unpacklo_epi32(e0j, e1j); // e0(i) e1(i) e0(i+1) e1(i+1) e0(i+4) e1(i+4) e0(i+5) e1(i+5)
simde__m256i tmp1 = simde_mm256_unpacklo_epi32(e2j, e3j); // e2(i) e3(i) e2(i+1) e3(i+1) e2(i+4) e3(i+4) e2(i+5) e3(i+5)
simde__m256i tmp2 = simde_mm256_unpacklo_epi32(e4j, e5j); // e4(i) e5(i) e4(i+1) e5(i+1) e4(i+4) e5(i+4) e4(i+5) e5(i+5)
simde__m256i tmp3 = simde_mm256_unpacklo_epi32(e6j, e7j); // e6(i) e7(i) e6(i+1) e7(i+1) e6(i+4) e7(i+4) e6(i+5) e7(i+5)
//
simde__m256i tmp4 = simde_mm256_unpacklo_epi64(tmp0, tmp1); // e0(i) e1(i) e2(i) e3(i) e0(i+4) e1(i+4) e2(i+4) e3(i+4)
simde__m256i tmp5 = simde_mm256_unpacklo_epi64(tmp2, tmp3); // e4(i) e5(i) e6(i) e7(i) e4(i+4) e5(i+4) e6(i+4) e7(i+4)
simde_mm256_storeu_si256(f256++,_mm256_permute2x128_si256(tmp4,tmp5,0x20)); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) e6(i) e7(i)
simde__m256i tmp6 = simde_mm256_unpackhi_epi64(tmp0, tmp1); // e0(i+1) e1(i+1) e2(i+1) e3(i+1) e0(i+5) e1(i+5) e2(i+5) e3(i+5)
simde__m256i tmp7 = simde_mm256_unpackhi_epi64(tmp2, tmp3); // e4(i+1) e5(i+1) e6(i+1) e7(i+1) e4(i+5) e5(i+5) e6(i+5) e7(i+5)
simde_mm256_storeu_si256(f256++,_mm256_permute2x128_si256(tmp6,tmp7,0x20)); // e0(i+1) e1(i+1) e2(i+1) e3(i+1) e4(i+1) e5(i+1) e6(i+1) e7(i+1)
//
tmp0 = simde_mm256_unpackhi_epi32(e0j, e1j); // e0(i+2) e1(i+2) e0(i+3) e1(i+3) e0(i+6) e1(i+6) e0(i+7) e1(i+7)
tmp1 = simde_mm256_unpackhi_epi32(e2j, e3j); // e2(i+2) e3(i+2) e2(i+3) e3(i+3) e2(i+6) e3(i+6) e2(i+7) e3(i+7)
tmp2 = simde_mm256_unpackhi_epi32(e4j, e5j); // e4(i+2) e5(i+2) e4(i+3) e5(i+3) e4(i+6) e5(i+6) e4(i+7) e5(i+7)
tmp3 = simde_mm256_unpackhi_epi32(e6j, e7j); // e6(i+2) e7(i+2) e6(i+3) e7(i+3) e6(i+6) e7(i+6) e6(i+7) e7(i+7)
//
simde__m256i tmp8 = simde_mm256_unpacklo_epi64(tmp0, tmp1); // e0(i+2) e1(i+2) e2(i+2) e3(i+2) e0(i+6) e1(i+6) e2(i+6) e3(i+6)
simde__m256i tmp9 = simde_mm256_unpacklo_epi64(tmp2, tmp3); // e4(i+2) e5(i+2) e6(i+2) e7(i+2) e4(i+6) e5(i+6) e6(i+6) e7(i+6)
simde_mm256_storeu_si256(f256++,_mm256_permute2x128_si256(tmp8,tmp9,0x20)); // e0(i+2) e1(i+2) e2(i+2) e3(i+2) e4(i+2) e5(i+2) e6(i+2) e7(i+2)
simde__m256i tmp10 = simde_mm256_unpackhi_epi64(tmp0, tmp1); // e0(i+3) e1(i+3) e2(i+3) e3(i+3) e0(i+7) e1(i+7) e2(i+7) e3(i+7)
simde__m256i tmp11 = simde_mm256_unpackhi_epi64(tmp2, tmp3); // e4(i+3) e5(i+3) e6(i+3) e7(i+3) e4(i+7) e5(i+7) e6(i+7) e7(i+7)
simde_mm256_storeu_si256(f256++,_mm256_permute2x128_si256(tmp10,tmp11,0x20)); // e0(i+3) e1(i+3) e2(i+3) e3(i+3) e4(i+3) e5(i+3) e6(i+3) e7(i+3)
simde_mm256_storeu_si256(f256++,_mm256_permute2x128_si256(tmp4,tmp5,0x31)); // e0(i+4) e1(i+4) e2(i+4) e3(i+4) e4(i+4) e5(i+4) e6(i+4) e7(i+4)
simde_mm256_storeu_si256(f256++,_mm256_permute2x128_si256(tmp6,tmp7,0x31)); // e0(i+5) e1(i+5) e2(i+5) e3(i+5) e4(i+5) e5(i+5) e6(i+5) e7(i+5)
simde_mm256_storeu_si256(f256++,_mm256_permute2x128_si256(tmp8,tmp9,0x31)); // e0(i+6) e1(i+6) e2(i+6) e3(i+6) e4(i+6) e5(i+6) e6(i+6) e7(i+6)
simde_mm256_storeu_si256(f256++,_mm256_permute2x128_si256(tmp10,tmp11,0x31)); // e0(i+7) e1(i+7) e2(i+7) e3(i+7) e4(i+7) e5(i+7) e6(i+7) e7(i+7)
}
e0 = (uint32_t *)e0_256;
e1 = (uint32_t *)e1_256;
e2 = (uint32_t *)e2_256;
e3 = (uint32_t *)e3_256;
e4 = (uint32_t *)e4_256;
e5 = (uint32_t *)e5_256;
e6 = (uint32_t *)e6_256;
e7 = (uint32_t *)e7_256;
f = (uint32_t *)f256;
#endif
simde__m128i *e0_128 = (simde__m128i *)e0;
simde__m128i *e1_128 = (simde__m128i *)e1;
simde__m128i *e2_128 = (simde__m128i *)e2;
simde__m128i *e3_128 = (simde__m128i *)e3;
simde__m128i *e4_128 = (simde__m128i *)e4;
simde__m128i *e5_128 = (simde__m128i *)e5;
simde__m128i *e6_128 = (simde__m128i *)e6;
simde__m128i *e7_128 = (simde__m128i *)e7;
simde__m128i *f128 = (simde__m128i *)f;
for (; i < (EQm & ~3); i += 4) {
simde__m128i e0j = simde_mm_loadu_si128(e0_128++);
simde__m128i e1j = simde_mm_loadu_si128(e1_128++);
simde__m128i e2j = simde_mm_loadu_si128(e2_128++);
simde__m128i e3j = simde_mm_loadu_si128(e3_128++);
simde__m128i e4j = simde_mm_loadu_si128(e4_128++);
simde__m128i e5j = simde_mm_loadu_si128(e5_128++);
simde__m128i e6j = simde_mm_loadu_si128(e6_128++);
simde__m128i e7j = simde_mm_loadu_si128(e7_128++);
simde__m128i tmp0 = simde_mm_unpacklo_epi32(e0j, e1j); // e0(i) e1(i) e0(i+1) e1(i+1)
simde__m128i tmp1 = simde_mm_unpacklo_epi32(e2j, e3j); // e2(i) e3(i) e2(i+1) e3(i+1)
simde__m128i tmp2 = simde_mm_unpacklo_epi32(e4j, e5j); // e4(i) e5(i) e4(i+1) e5(i+1)
simde__m128i tmp3 = simde_mm_unpacklo_epi32(e6j, e7j); // e6(i) e7(i) e6(i+1) e7(i+1)
simde_mm_storeu_si128(f128++,simde_mm_unpacklo_epi64(tmp0, tmp1)); // e0(i) e1(i) e2(i) e3(i)
simde_mm_storeu_si128(f128++,simde_mm_unpacklo_epi64(tmp2, tmp3)); // e4(i) e5(i) e6(i) e7(i)
simde_mm_storeu_si128(f128++,simde_mm_unpackhi_epi64(tmp0, tmp1)); // e0(i+1) e1(i+1) e2(i+1) e3(i+1)
simde_mm_storeu_si128(f128++,simde_mm_unpackhi_epi64(tmp2, tmp3)); // e4(i+1) e5(i+1) e6(i+1) e7(i+1)
//
tmp0 = simde_mm_unpackhi_epi32(e0j, e1j); // e0(i+2) e1(i+2) e0(i+3) e1(i+3)
tmp1 = simde_mm_unpackhi_epi32(e2j, e3j); // e2(i+2) e3(i+2) e2(i+3) e3(i+3)
tmp2 = simde_mm_unpackhi_epi32(e4j, e5j); // e4(i+2) e5(i+2) e4(i+3) e5(i+3)
tmp3 = simde_mm_unpackhi_epi32(e6j, e7j); // e6(i+2) e7(i+2) e6(i+3) e7(i+3)
simde_mm_storeu_si128(f128++,simde_mm_unpacklo_epi64(tmp0, tmp1)); // e0(i+2) e1(i+2) e2(i+2) e3(i+2)
simde_mm_storeu_si128(f128++,simde_mm_unpacklo_epi64(tmp2, tmp3)); // e4(i+2) e5(i+2) e6(i+2) e7(i+2)
simde_mm_storeu_si128(f128++,simde_mm_unpackhi_epi64(tmp0, tmp1)); // e0(i+3) e1(i+3) e2(i+3) e3(i+3)
simde_mm_storeu_si128(f128++,simde_mm_unpackhi_epi64(tmp2, tmp3)); //e4(i+3) e5(i+3) e6(i+3) e7(i+3)
}
e0 = (uint32_t *)e0_128;
e1 = (uint32_t *)e1_128;
e2 = (uint32_t *)e2_128;
e3 = (uint32_t *)e3_128;
e4 = (uint32_t *)e4_128;
e5 = (uint32_t *)e5_128;
e6 = (uint32_t *)e6_128;
e7 = (uint32_t *)e7_128;
f = (uint32_t *)f128;
for (; i < EQm; i++) {
*f++ = *e0++;
*f++ = *e1++;
*f++ = *e2++;
*f++ = *e3++;
*f++ = *e4++;
*f++ = *e5++;
*f++ = *e6++;
*f++ = *e7++;
}
} break;
default:
AssertFatal(false, "Should be here!\n");
}
}
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e, int16_t *f)
{
switch (Qm) {
@@ -610,6 +831,103 @@ int nr_rate_matching_ldpc(uint32_t Tbslbrm,
return 0;
}
int nr_rate_matching_ldpc32(uint32_t Tbslbrm,
uint8_t BG,
uint16_t Z,
uint32_t *d,
uint32_t *e,
uint8_t C,
uint32_t F,
uint32_t Foffset,
uint8_t rvidx,
uint32_t E)
{
if (C == 0) {
LOG_E(PHY, "nr_rate_matching: invalid parameter C %d\n", C);
return -1;
}
//Bit selection
uint32_t N = (BG == 1) ? (66 * Z) : (50 * Z);
uint32_t Ncb;
if (Tbslbrm == 0)
Ncb = N;
else {
uint32_t Nref = 3 * Tbslbrm / (2 * C); //R_LBRM = 2/3
Ncb = min(N, Nref);
}
uint32_t ind = (index_k0[BG - 1][rvidx] * Ncb / N) * Z;
#ifdef RM_DEBUG
printf("nr_rate_matching_ldpc: E %u, F %u, Foffset %u, k0 %u, Ncb %u, rvidx %d, Tbslbrm %u\n",
E,
F,
Foffset,
ind,
Ncb,
rvidx,
Tbslbrm);
#endif
if (Foffset > E) {
LOG_E(PHY,
"nr_rate_matching: invalid parameters (Foffset %d > E %d) F %d, k0 %d, Ncb %d, rvidx %d, Tbslbrm %d\n",
Foffset,
E,
F,
ind,
Ncb,
rvidx,
Tbslbrm);
return -1;
}
if (Foffset > Ncb) {
LOG_E(PHY, "nr_rate_matching: invalid parameters (Foffset %d > Ncb %d)\n", Foffset, Ncb);
return -1;
}
if (ind >= Foffset && ind < (F + Foffset))
ind = F + Foffset;
uint32_t k = 0;
if (ind < Foffset) { // case where we have some bits before the filler and the rest after
memcpy((void *)e, (void *)(d + ind), (Foffset - ind)<<2);
if (E + F <= Ncb - ind) { // E+F doesn't contain all coded bits
memcpy((void *)(e + Foffset - ind), (void *)(d + Foffset + F), (E - Foffset + ind)<<2);
k = E;
} else {
memcpy((void *)(e + Foffset - ind), (void *)(d + Foffset + F), (Ncb - Foffset - F)<<2);
k = Ncb - F - ind;
}
} else {
if (E <= Ncb - ind) { // E+F doesn't contain all coded bits
memcpy((void *)(e), (void *)(d + ind), E<<2);
k = E;
} else {
memcpy((void *)(e), (void *)(d + ind), (Ncb - ind)<<2);
k = Ncb - ind;
}
}
while (k < E) { // case where we do repetitions (low mcs)
for (ind = 0; (ind < Ncb) && (k < E); ind++) {
#ifdef RM_DEBUG
printf("RM_TX k%u Ind: %u (%d)\n", k, ind, d[ind]);
#endif
if (ind == Foffset)
ind = F + Foffset; // skip filler bits
e[k++] = d[ind];
}
}
return 0;
}
int nr_rate_matching_ldpc_rx(uint32_t Tbslbrm,
uint8_t BG,
uint16_t Z,

View File

@@ -33,6 +33,15 @@
*/
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e, uint8_t *f);
/**
* \brief interleave a code segment after encoding and rate matching (32bit)
* \param E size of the code segment in bits
* \param Qm modulation order
* \param e input rate matched segment
* \param f output interleaved segment
*/
void nr_interleaving_ldpc32(uint32_t E, uint8_t Qm, uint32_t *e, uint32_t *f);
/**
* \brief deinterleave a code segment before RX rate matching and decoding
* \param E size of the code segment in bits
@@ -66,6 +75,30 @@ int nr_rate_matching_ldpc(uint32_t Tbslbrm,
uint8_t rvidx,
uint32_t E);
/**
* \brief rate match a code segment after encoding (32bit)
* \Tbslbrm Transport Block size LBRM
* \param BG LDPC base graph number
* \param Z segment lifting size
* \param d input encoded segment
* \param e output rate matched segment
* \param C number of segments in the Transport Block
* \param F number of filler bits in the segment
* \param Foffset offset of the filler bits in the segment
* \param rvidx redundancy version index
* \param E size of the code segment in bits
*/
int nr_rate_matching_ldpc32(uint32_t Tbslbrm,
uint8_t BG,
uint16_t Z,
uint32_t *d,
uint32_t *e,
uint8_t C,
uint32_t F,
uint32_t Foffset,
uint8_t rvidx,
uint32_t E);
/**
* \brief rate match a code segment before decoding
* \Tbslbrm Transport Block size LBRM

View File

@@ -161,6 +161,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr,
int32_t LDPCinit()
{
cuda_support_init();
return 0;
}

View File

@@ -55,9 +55,11 @@ typedef struct {
unsigned int first_seg; // optim8segmulti
unsigned char gen_code; // orig
time_stats_t *tinput;
time_stats_t *tinput_memcpy;
time_stats_t *tprep;
time_stats_t *tparity;
time_stats_t *toutput;
time_stats_t *tconcat;
/// Size in bits of the code segments
uint32_t K;
/// Number of lifting sizes to fit the payload
@@ -91,5 +93,7 @@ typedef int32_t(LDPC_decoderfunc_t)(t_nrLDPC_dec_params *p_decParams,
t_nrLDPC_time_stats *time_stats,
decode_abort_t *ab);
typedef int32_t(LDPC_encoderfunc_t)(uint8_t **, uint8_t *, encoder_implemparams_t *);
typedef uint32_t**(LDPC_encoderfunc32_t)(uint8_t **, encoder_implemparams_t *);
void cuda_support_init(void);
#endif

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,214 @@
#include <stdio.h>
#include <stdint.h>
#include <cuda_runtime.h>
// generated code for Zc=384, byte encoding
__global__ void ldpc_BG1_Zc384_worker(uint32_t *c[4],uint32_t *d[4]) {
uint32_t *c32=c[blockIdx.x];
uint32_t *d32=d[blockIdx.x]+8448-2*384;
int i2 = threadIdx.x;
int i1 = blockIdx.y;
if (i2 < 384) {
c32+=i2;
d32+=i2;
switch(i1) {
case 0:
d32[0]=c32[307]^c32[76]^c32[205]^c32[276]^c32[787]^c32[1018]^c32[855]^c32[1586]^c32[1612]^c32[1864]^c32[2673]^c32[2377]^c32[2304]^c32[3360]^c32[3404]^c32[3347]^c32[4021]^c32[3984]^c32[4096]^c32[4824]^c32[4769]^c32[4807]^c32[5707]^c32[5643]^c32[5529]^c32[6475]^c32[6304]^c32[6200]^c32[7229]^c32[7090]^c32[6975]^c32[7968]^c32[7809]^c32[7812]^c32[8557]^c32[8743]^c32[8753]^c32[9233]^c32[9558]^c32[9447]^c32[10341]^c32[10184]^c32[10325]^c32[10969]^c32[10840]^c32[10964]^c32[11735]^c32[11619]^c32[11573]^c32[12394]^c32[12642]^c32[12592]^c32[13170]^c32[13187]^c32[13356]^c32[14066]^c32[14064]^c32[14095]^c32[14772]^c32[14923]^c32[14797]^c32[15690]^c32[15373]^c32[15399]^c32[16474]^c32[16240]^c32[16485];
break;
case 1:
d32[384]=c32[307]^c32[308]^c32[77]^c32[206]^c32[277]^c32[787]^c32[788]^c32[1019]^c32[856]^c32[1586]^c32[1587]^c32[1613]^c32[1865]^c32[2673]^c32[2674]^c32[2378]^c32[2305]^c32[3361]^c32[3405]^c32[3348]^c32[4021]^c32[4022]^c32[3985]^c32[4097]^c32[4824]^c32[4825]^c32[4770]^c32[4808]^c32[5708]^c32[5644]^c32[5530]^c32[6476]^c32[6305]^c32[6201]^c32[7229]^c32[7230]^c32[7091]^c32[6976]^c32[7968]^c32[7969]^c32[7810]^c32[7813]^c32[8557]^c32[8558]^c32[8744]^c32[8754]^c32[9233]^c32[9234]^c32[9559]^c32[9448]^c32[10341]^c32[10342]^c32[10185]^c32[10326]^c32[10970]^c32[10841]^c32[10965]^c32[11735]^c32[11736]^c32[11620]^c32[11574]^c32[12394]^c32[12395]^c32[12643]^c32[12593]^c32[13171]^c32[13188]^c32[13357]^c32[14066]^c32[14067]^c32[14065]^c32[14096]^c32[14772]^c32[14773]^c32[14924]^c32[14798]^c32[15690]^c32[15691]^c32[15374]^c32[15400]^c32[16474]^c32[16475]^c32[16241]^c32[16486];
break;
case 2:
d32[768]=c32[308]^c32[77]^c32[205]^c32[206]^c32[276]^c32[277]^c32[788]^c32[1018]^c32[1019]^c32[855]^c32[856]^c32[1587]^c32[1613]^c32[1864]^c32[1865]^c32[2674]^c32[2378]^c32[2304]^c32[2305]^c32[3361]^c32[3404]^c32[3405]^c32[3347]^c32[3348]^c32[4022]^c32[3985]^c32[4096]^c32[4097]^c32[4825]^c32[4769]^c32[4770]^c32[4807]^c32[4808]^c32[5708]^c32[5643]^c32[5644]^c32[5529]^c32[5530]^c32[6476]^c32[6304]^c32[6305]^c32[6200]^c32[6201]^c32[7230]^c32[7091]^c32[6975]^c32[6976]^c32[7969]^c32[7809]^c32[7810]^c32[7812]^c32[7813]^c32[8558]^c32[8744]^c32[8753]^c32[8754]^c32[9234]^c32[9559]^c32[9447]^c32[9448]^c32[10342]^c32[10184]^c32[10185]^c32[10325]^c32[10326]^c32[10970]^c32[10840]^c32[10841]^c32[10964]^c32[10965]^c32[11736]^c32[11620]^c32[11573]^c32[11574]^c32[12395]^c32[12643]^c32[12592]^c32[12593]^c32[13171]^c32[13187]^c32[13188]^c32[13356]^c32[13357]^c32[14067]^c32[14064]^c32[14065]^c32[14095]^c32[14096]^c32[14773]^c32[14924]^c32[14797]^c32[14798]^c32[15691]^c32[15373]^c32[15374]^c32[15399]^c32[15400]^c32[16475]^c32[16241]^c32[16485]^c32[16486];
break;
case 3:
d32[1152]=c32[308]^c32[77]^c32[206]^c32[276]^c32[277]^c32[788]^c32[1019]^c32[855]^c32[856]^c32[1587]^c32[1613]^c32[1865]^c32[2674]^c32[2378]^c32[2304]^c32[2305]^c32[3361]^c32[3405]^c32[3347]^c32[3348]^c32[4022]^c32[3985]^c32[4097]^c32[4825]^c32[4770]^c32[4807]^c32[4808]^c32[5708]^c32[5644]^c32[5529]^c32[5530]^c32[6476]^c32[6305]^c32[6200]^c32[6201]^c32[7230]^c32[7091]^c32[6976]^c32[7969]^c32[7810]^c32[7812]^c32[7813]^c32[8558]^c32[8744]^c32[8753]^c32[8754]^c32[9234]^c32[9559]^c32[9447]^c32[9448]^c32[10342]^c32[10185]^c32[10325]^c32[10326]^c32[10970]^c32[10841]^c32[10964]^c32[10965]^c32[11736]^c32[11620]^c32[11574]^c32[12395]^c32[12643]^c32[12592]^c32[12593]^c32[13171]^c32[13188]^c32[13356]^c32[13357]^c32[14067]^c32[14065]^c32[14095]^c32[14096]^c32[14773]^c32[14924]^c32[14798]^c32[15691]^c32[15374]^c32[15399]^c32[15400]^c32[16475]^c32[16241]^c32[16485]^c32[16486];
break;
case 4:
d32[1536]=c32[332]^c32[949];
break;
case 5:
d32[1920]=c32[80]^c32[233]^c32[362]^c32[49]^c32[195]^c32[944]^c32[791]^c32[1012]^c32[782]^c32[1743]^c32[1769]^c32[1637]^c32[2446]^c32[2534]^c32[2461]^c32[2419]^c32[3133]^c32[3177]^c32[3120]^c32[4178]^c32[4141]^c32[3869]^c32[4981]^c32[4926]^c32[4964]^c32[5480]^c32[5416]^c32[5686]^c32[6248]^c32[6461]^c32[6357]^c32[7002]^c32[7247]^c32[7132]^c32[7741]^c32[7966]^c32[7969]^c32[8714]^c32[8516]^c32[8526]^c32[9390]^c32[9331]^c32[9220]^c32[9382]^c32[10114]^c32[10341]^c32[10098]^c32[11126]^c32[10997]^c32[11121]^c32[11892]^c32[11776]^c32[11730]^c32[12551]^c32[12415]^c32[12365]^c32[12529]^c32[13327]^c32[13344]^c32[13129]^c32[13839]^c32[13837]^c32[13868]^c32[14929]^c32[14696]^c32[14954]^c32[15463]^c32[15530]^c32[15556]^c32[16247]^c32[16397]^c32[16258]^c32[16179];
break;
case 6:
d32[2304]=c32[278]^c32[4865]^c32[7681]^c32[8799]^c32[10076]^c32[13309]^c32[13842]^c32[15585];
break;
case 7:
d32[2688]=c32[9]^c32[830]^c32[3388]^c32[5709]^c32[6434]^c32[10866];
break;
case 8:
d32[3072]=c32[374]^c32[94]^c32[143]^c32[247]^c32[272]^c32[375]^c32[376]^c32[343]^c32[62]^c32[63]^c32[307]^c32[854]^c32[958]^c32[1085]^c32[804]^c32[805]^c32[922]^c32[1025]^c32[1026]^c32[947]^c32[1653]^c32[1757]^c32[1679]^c32[1783]^c32[1547]^c32[1650]^c32[1651]^c32[2356]^c32[2460]^c32[2444]^c32[2548]^c32[2371]^c32[2474]^c32[2475]^c32[2469]^c32[3427]^c32[3147]^c32[3087]^c32[3190]^c32[3191]^c32[3414]^c32[3133]^c32[3134]^c32[4088]^c32[4192]^c32[4051]^c32[4155]^c32[4163]^c32[3882]^c32[3883]^c32[4891]^c32[4611]^c32[4836]^c32[4939]^c32[4940]^c32[4874]^c32[4977]^c32[4978]^c32[5390]^c32[5494]^c32[5710]^c32[5429]^c32[5430]^c32[5596]^c32[5699]^c32[5700]^c32[6158]^c32[6262]^c32[6371]^c32[6474]^c32[6475]^c32[6267]^c32[6370]^c32[6371]^c32[6912]^c32[7016]^c32[7157]^c32[7261]^c32[7042]^c32[7145]^c32[7146]^c32[8035]^c32[7755]^c32[7876]^c32[7979]^c32[7980]^c32[7879]^c32[7982]^c32[7983]^c32[8624]^c32[8728]^c32[8810]^c32[8530]^c32[8820]^c32[8539]^c32[8540]^c32[9300]^c32[9404]^c32[9241]^c32[9345]^c32[9514]^c32[9233]^c32[9234]^c32[9234]^c32[10024]^c32[10128]^c32[10251]^c32[10354]^c32[10355]^c32[10008]^c32[10111]^c32[10112]^c32[11036]^c32[10756]^c32[10907]^c32[11010]^c32[11011]^c32[11031]^c32[11134]^c32[11135]^c32[11802]^c32[11522]^c32[11686]^c32[11790]^c32[11640]^c32[11743]^c32[11744]^c32[12461]^c32[12565]^c32[12325]^c32[12429]^c32[12659]^c32[12378]^c32[12379]^c32[12327]^c32[13237]^c32[13341]^c32[13254]^c32[13357]^c32[13358]^c32[13423]^c32[13142]^c32[13143]^c32[14133]^c32[13853]^c32[14131]^c32[13850]^c32[13851]^c32[14162]^c32[13881]^c32[13882]^c32[14839]^c32[14943]^c32[14606]^c32[14710]^c32[14864]^c32[14967]^c32[14968]^c32[14816]^c32[15373]^c32[15477]^c32[15440]^c32[15543]^c32[15544]^c32[15466]^c32[15569]^c32[15570]^c32[16157]^c32[16261]^c32[16307]^c32[16411]^c32[16168]^c32[16271]^c32[16272]^c32[16496];
break;
case 9:
d32[3456]=c32[366]^c32[1000]^c32[8001]^c32[8581]^c32[10041]^c32[13359]^c32[13887]^c32[15442];
break;
case 10:
d32[3840]=c32[869]^c32[1875]^c32[3346]^c32[5487]^c32[6527]^c32[11106];
break;
case 11:
d32[4224]=c32[257]^c32[38]^c32[39]^c32[26]^c32[192]^c32[155]^c32[321]^c32[226]^c32[8]^c32[48]^c32[1121]^c32[902]^c32[903]^c32[968]^c32[1134]^c32[805]^c32[971]^c32[870]^c32[1536]^c32[1701]^c32[1702]^c32[1562]^c32[1728]^c32[1814]^c32[1596]^c32[2623]^c32[2404]^c32[2405]^c32[2327]^c32[2493]^c32[2638]^c32[2420]^c32[3310]^c32[3092]^c32[3354]^c32[3136]^c32[3297]^c32[3079]^c32[3971]^c32[4136]^c32[4137]^c32[3934]^c32[4100]^c32[4046]^c32[4212]^c32[4774]^c32[4939]^c32[4940]^c32[4719]^c32[4885]^c32[4757]^c32[4923]^c32[5657]^c32[5439]^c32[5593]^c32[5759]^c32[5479]^c32[5645]^c32[6425]^c32[6207]^c32[6254]^c32[6420]^c32[6150]^c32[6316]^c32[7179]^c32[6960]^c32[6961]^c32[7040]^c32[7206]^c32[6925]^c32[7091]^c32[7918]^c32[7699]^c32[7700]^c32[7759]^c32[7925]^c32[7762]^c32[7928]^c32[8507]^c32[8672]^c32[8673]^c32[8693]^c32[8475]^c32[8703]^c32[8485]^c32[9567]^c32[9348]^c32[9349]^c32[9508]^c32[9290]^c32[9397]^c32[9563]^c32[9224]^c32[10291]^c32[10072]^c32[10073]^c32[10134]^c32[10300]^c32[10275]^c32[10057]^c32[10919]^c32[11085]^c32[10790]^c32[10956]^c32[10914]^c32[11080]^c32[11685]^c32[11850]^c32[11851]^c32[11569]^c32[11735]^c32[11523]^c32[11689]^c32[12344]^c32[12509]^c32[12510]^c32[12592]^c32[12374]^c32[12542]^c32[12324]^c32[12335]^c32[13120]^c32[13286]^c32[13137]^c32[13303]^c32[13306]^c32[13088]^c32[14016]^c32[14181]^c32[14182]^c32[14014]^c32[14180]^c32[14045]^c32[13827]^c32[14722]^c32[14887]^c32[14888]^c32[14873]^c32[14655]^c32[14747]^c32[14913]^c32[15640]^c32[15421]^c32[15422]^c32[15707]^c32[15489]^c32[15733]^c32[15515]^c32[16424]^c32[16205]^c32[16206]^c32[16190]^c32[16356]^c32[16435]^c32[16217]^c32[16316];
break;
case 12:
d32[4608]=c32[77]^c32[954]^c32[7854]^c32[8680]^c32[10034]^c32[13898];
break;
case 13:
d32[4992]=c32[293]^c32[294]^c32[63]^c32[192]^c32[263]^c32[313]^c32[773]^c32[774]^c32[1005]^c32[842]^c32[1572]^c32[1573]^c32[1599]^c32[1851]^c32[2659]^c32[2660]^c32[2364]^c32[2675]^c32[2481]^c32[3347]^c32[3391]^c32[3334]^c32[4007]^c32[4008]^c32[3971]^c32[4083]^c32[4810]^c32[4811]^c32[4756]^c32[4794]^c32[5694]^c32[5630]^c32[5516]^c32[5642]^c32[6462]^c32[6291]^c32[6187]^c32[7215]^c32[7216]^c32[7077]^c32[6962]^c32[7954]^c32[7955]^c32[7796]^c32[7799]^c32[8543]^c32[8544]^c32[8730]^c32[8740]^c32[9219]^c32[9220]^c32[9545]^c32[9434]^c32[10327]^c32[10328]^c32[10171]^c32[10312]^c32[10956]^c32[10827]^c32[10951]^c32[11721]^c32[11722]^c32[11606]^c32[11560]^c32[12380]^c32[12381]^c32[12629]^c32[12579]^c32[13157]^c32[13174]^c32[13343]^c32[14052]^c32[14053]^c32[14051]^c32[14082]^c32[14758]^c32[14759]^c32[14910]^c32[14784]^c32[15676]^c32[15677]^c32[15360]^c32[15386]^c32[15475]^c32[16460]^c32[16461]^c32[16227]^c32[16472];
break;
case 14:
d32[5376]=c32[142]^c32[9464]^c32[11657]^c32[12377]^c32[13403]^c32[16140];
break;
case 15:
d32[5760]=c32[193]^c32[346]^c32[91]^c32[161]^c32[162]^c32[241]^c32[1057]^c32[904]^c32[1124]^c32[1125]^c32[770]^c32[1856]^c32[1882]^c32[1750]^c32[2559]^c32[2647]^c32[2573]^c32[2574]^c32[3246]^c32[3290]^c32[3232]^c32[3233]^c32[3907]^c32[3870]^c32[3982]^c32[4710]^c32[4655]^c32[4692]^c32[4693]^c32[5593]^c32[5529]^c32[5414]^c32[5415]^c32[6361]^c32[6190]^c32[6469]^c32[6470]^c32[7115]^c32[6976]^c32[7245]^c32[7854]^c32[7695]^c32[7697]^c32[7698]^c32[7890]^c32[8827]^c32[8629]^c32[8638]^c32[8639]^c32[9503]^c32[9444]^c32[9332]^c32[9333]^c32[10227]^c32[10070]^c32[10210]^c32[10211]^c32[10302]^c32[10855]^c32[11110]^c32[10849]^c32[10850]^c32[11621]^c32[11889]^c32[11843]^c32[12664]^c32[12528]^c32[12477]^c32[12478]^c32[13056]^c32[13073]^c32[13241]^c32[13242]^c32[13952]^c32[13950]^c32[13980]^c32[13981]^c32[13879]^c32[14658]^c32[14809]^c32[14683]^c32[15576]^c32[15643]^c32[15668]^c32[15669]^c32[16360]^c32[16510]^c32[16370]^c32[16371];
break;
case 16:
d32[6144]=c32[364]^c32[133]^c32[262]^c32[333]^c32[844]^c32[1075]^c32[912]^c32[781]^c32[1643]^c32[1669]^c32[1537]^c32[2346]^c32[2434]^c32[2361]^c32[2642]^c32[3417]^c32[3077]^c32[3404]^c32[4078]^c32[4041]^c32[4153]^c32[4881]^c32[4826]^c32[4864]^c32[5380]^c32[5700]^c32[5586]^c32[6148]^c32[6361]^c32[6257]^c32[7286]^c32[7147]^c32[7032]^c32[8025]^c32[7866]^c32[7869]^c32[8614]^c32[8800]^c32[8810]^c32[8505]^c32[9290]^c32[9231]^c32[9504]^c32[10014]^c32[10241]^c32[9998]^c32[11026]^c32[10897]^c32[11021]^c32[11792]^c32[11676]^c32[11630]^c32[12451]^c32[12315]^c32[12649]^c32[13227]^c32[13244]^c32[13413]^c32[14123]^c32[14121]^c32[14152]^c32[14829]^c32[14596]^c32[14854]^c32[15363]^c32[15430]^c32[15456]^c32[15649]^c32[16147]^c32[16297]^c32[16158];
break;
case 17:
d32[6528]=c32[260]^c32[11055]^c32[12369]^c32[13414]^c32[16503];
break;
case 18:
d32[6912]=c32[898]^c32[9379]^c32[10264]^c32[13956]^c32[14596];
break;
case 19:
d32[7296]=c32[145]^c32[981]^c32[5720]^c32[6386]^c32[7877];
break;
case 20:
d32[7680]=c32[366]^c32[135]^c32[264]^c32[335]^c32[187]^c32[846]^c32[1077]^c32[914]^c32[1645]^c32[1671]^c32[1539]^c32[2348]^c32[2436]^c32[2363]^c32[2510]^c32[3419]^c32[3079]^c32[3406]^c32[4080]^c32[4043]^c32[4155]^c32[4883]^c32[4828]^c32[4866]^c32[5382]^c32[5702]^c32[5588]^c32[6150]^c32[6363]^c32[6259]^c32[7288]^c32[7149]^c32[7034]^c32[7176]^c32[8027]^c32[7868]^c32[7871]^c32[8616]^c32[8802]^c32[8812]^c32[8789]^c32[9292]^c32[9233]^c32[9506]^c32[10016]^c32[10243]^c32[10000]^c32[11028]^c32[10899]^c32[11023]^c32[11794]^c32[11678]^c32[11632]^c32[12453]^c32[12317]^c32[12651]^c32[13229]^c32[13246]^c32[13415]^c32[14125]^c32[14123]^c32[14154]^c32[14831]^c32[14598]^c32[14856]^c32[15365]^c32[15432]^c32[15458]^c32[16149]^c32[16299]^c32[16160];
break;
case 21:
d32[8064]=c32[973]^c32[3942]^c32[12616]^c32[15573]^c32[16225];
break;
case 22:
d32[8448]=c32[30]^c32[9227]^c32[10217]^c32[13078];
break;
case 23:
d32[8832]=c32[792]^c32[1625]^c32[7741]^c32[13851];
break;
case 24:
d32[9216]=c32[157]^c32[310]^c32[55]^c32[126]^c32[298]^c32[1021]^c32[868]^c32[1089]^c32[1820]^c32[1846]^c32[1714]^c32[2523]^c32[2611]^c32[2538]^c32[2462]^c32[3210]^c32[3254]^c32[3197]^c32[3307]^c32[3871]^c32[4218]^c32[3946]^c32[4674]^c32[4619]^c32[4657]^c32[5557]^c32[5493]^c32[5379]^c32[6325]^c32[6154]^c32[6434]^c32[7079]^c32[6940]^c32[7209]^c32[7818]^c32[8043]^c32[8046]^c32[8791]^c32[8593]^c32[8603]^c32[8787]^c32[9467]^c32[9408]^c32[9297]^c32[10191]^c32[10034]^c32[10175]^c32[10819]^c32[11074]^c32[10814]^c32[11585]^c32[11853]^c32[11807]^c32[12628]^c32[12492]^c32[12442]^c32[13404]^c32[13421]^c32[13206]^c32[13916]^c32[13914]^c32[13945]^c32[14622]^c32[14773]^c32[14647]^c32[15540]^c32[15607]^c32[15633]^c32[16324]^c32[16474]^c32[16335];
break;
case 25:
d32[9600]=c32[840]^c32[4625]^c32[5759]^c32[11064];
break;
case 26:
d32[9984]=c32[71]^c32[1617]^c32[3148]^c32[11656];
break;
case 27:
d32[10368]=c32[962]^c32[4802]^c32[6245];
break;
case 28:
d32[10752]=c32[222]^c32[3091]^c32[14836]^c32[16402];
break;
case 29:
d32[11136]=c32[2]^c32[155]^c32[284]^c32[354]^c32[355]^c32[866]^c32[1097]^c32[933]^c32[934]^c32[1020]^c32[1665]^c32[1691]^c32[1559]^c32[2368]^c32[2456]^c32[2382]^c32[2383]^c32[3439]^c32[3099]^c32[3425]^c32[3426]^c32[4100]^c32[4063]^c32[4175]^c32[4903]^c32[4848]^c32[4885]^c32[4886]^c32[5402]^c32[5722]^c32[5607]^c32[5608]^c32[6170]^c32[6383]^c32[6278]^c32[6279]^c32[6924]^c32[7169]^c32[7054]^c32[8047]^c32[7888]^c32[7890]^c32[7891]^c32[8636]^c32[8822]^c32[8831]^c32[8448]^c32[9312]^c32[9253]^c32[9525]^c32[9526]^c32[10036]^c32[10263]^c32[10019]^c32[10020]^c32[11048]^c32[10919]^c32[11042]^c32[11043]^c32[10757]^c32[11814]^c32[11698]^c32[11652]^c32[12473]^c32[12337]^c32[12670]^c32[12671]^c32[13249]^c32[13266]^c32[13434]^c32[13435]^c32[14145]^c32[14143]^c32[14173]^c32[14174]^c32[13971]^c32[14851]^c32[14618]^c32[14876]^c32[15385]^c32[15452]^c32[15477]^c32[15478]^c32[16169]^c32[16319]^c32[16179]^c32[16180];
break;
case 30:
d32[11520]=c32[14]^c32[167]^c32[295]^c32[296]^c32[366]^c32[367]^c32[159]^c32[878]^c32[1108]^c32[1109]^c32[945]^c32[946]^c32[1677]^c32[1703]^c32[1570]^c32[1571]^c32[2380]^c32[2468]^c32[2394]^c32[2395]^c32[3451]^c32[3110]^c32[3111]^c32[3437]^c32[3438]^c32[4112]^c32[4075]^c32[4186]^c32[4187]^c32[4915]^c32[4859]^c32[4860]^c32[4897]^c32[4898]^c32[5414]^c32[5733]^c32[5734]^c32[5619]^c32[5620]^c32[6182]^c32[6394]^c32[6395]^c32[6290]^c32[6291]^c32[6936]^c32[7181]^c32[7065]^c32[7066]^c32[8059]^c32[7899]^c32[7900]^c32[7902]^c32[7903]^c32[7909]^c32[8648]^c32[8450]^c32[8459]^c32[8460]^c32[9324]^c32[9265]^c32[9537]^c32[9538]^c32[10048]^c32[10274]^c32[10275]^c32[10031]^c32[10032]^c32[10244]^c32[11060]^c32[10930]^c32[10931]^c32[11054]^c32[11055]^c32[11826]^c32[11710]^c32[11663]^c32[11664]^c32[12485]^c32[12349]^c32[12298]^c32[12299]^c32[13261]^c32[13277]^c32[13278]^c32[13062]^c32[13063]^c32[14157]^c32[14154]^c32[14155]^c32[14185]^c32[14186]^c32[14863]^c32[14630]^c32[14887]^c32[14888]^c32[15397]^c32[15463]^c32[15464]^c32[15489]^c32[15490]^c32[16181]^c32[16331]^c32[16191]^c32[16192];
break;
case 31:
d32[11904]=c32[181]^c32[180]^c32[334]^c32[333]^c32[79]^c32[78]^c32[150]^c32[148]^c32[149]^c32[1045]^c32[1044]^c32[892]^c32[891]^c32[1113]^c32[1111]^c32[1112]^c32[868]^c32[1844]^c32[1843]^c32[1870]^c32[1869]^c32[1738]^c32[1737]^c32[2547]^c32[2546]^c32[2635]^c32[2634]^c32[2562]^c32[2560]^c32[2561]^c32[3234]^c32[3233]^c32[3278]^c32[3277]^c32[3221]^c32[3219]^c32[3220]^c32[3895]^c32[3894]^c32[3858]^c32[3857]^c32[3970]^c32[3969]^c32[4698]^c32[4697]^c32[4643]^c32[4642]^c32[4681]^c32[4679]^c32[4680]^c32[5581]^c32[5580]^c32[5517]^c32[5516]^c32[5403]^c32[5401]^c32[5402]^c32[5591]^c32[6349]^c32[6348]^c32[6178]^c32[6177]^c32[6458]^c32[6456]^c32[6457]^c32[7103]^c32[7102]^c32[6964]^c32[6963]^c32[7233]^c32[7232]^c32[7842]^c32[7841]^c32[7683]^c32[7682]^c32[7686]^c32[7684]^c32[7685]^c32[8815]^c32[8814]^c32[8617]^c32[8616]^c32[8627]^c32[8625]^c32[8626]^c32[9491]^c32[9490]^c32[9432]^c32[9431]^c32[9321]^c32[9319]^c32[9320]^c32[10215]^c32[10214]^c32[10058]^c32[10057]^c32[10199]^c32[10197]^c32[10198]^c32[10843]^c32[10842]^c32[11098]^c32[11097]^c32[10838]^c32[10836]^c32[10837]^c32[11609]^c32[11608]^c32[11877]^c32[11876]^c32[11831]^c32[11830]^c32[12652]^c32[12651]^c32[12516]^c32[12515]^c32[12466]^c32[12464]^c32[12465]^c32[13428]^c32[13427]^c32[13061]^c32[13060]^c32[13230]^c32[13228]^c32[13229]^c32[13940]^c32[13939]^c32[13938]^c32[13937]^c32[13969]^c32[13967]^c32[13968]^c32[14646]^c32[14645]^c32[14797]^c32[14796]^c32[14671]^c32[14670]^c32[15564]^c32[15563]^c32[15631]^c32[15630]^c32[15657]^c32[15655]^c32[15656]^c32[16348]^c32[16347]^c32[16498]^c32[16497]^c32[16359]^c32[16357]^c32[16358];
break;
case 32:
d32[12288]=c32[211]^c32[364]^c32[108]^c32[109]^c32[179]^c32[180]^c32[102]^c32[1075]^c32[921]^c32[922]^c32[1142]^c32[1143]^c32[1874]^c32[1900]^c32[1767]^c32[1768]^c32[2577]^c32[2665]^c32[2591]^c32[2592]^c32[3264]^c32[3307]^c32[3308]^c32[3250]^c32[3251]^c32[3925]^c32[3888]^c32[3999]^c32[4000]^c32[4728]^c32[4672]^c32[4673]^c32[4710]^c32[4711]^c32[5611]^c32[5546]^c32[5547]^c32[5432]^c32[5433]^c32[6379]^c32[6207]^c32[6208]^c32[6487]^c32[6488]^c32[7133]^c32[6994]^c32[7262]^c32[7263]^c32[7872]^c32[7712]^c32[7713]^c32[7715]^c32[7716]^c32[8461]^c32[8647]^c32[8656]^c32[8657]^c32[9521]^c32[9462]^c32[9350]^c32[9351]^c32[9417]^c32[10245]^c32[10087]^c32[10088]^c32[10228]^c32[10229]^c32[10873]^c32[11127]^c32[11128]^c32[10867]^c32[10868]^c32[10927]^c32[11639]^c32[11523]^c32[11860]^c32[11861]^c32[12298]^c32[12546]^c32[12495]^c32[12496]^c32[13074]^c32[13090]^c32[13091]^c32[13259]^c32[13260]^c32[13970]^c32[13967]^c32[13968]^c32[13998]^c32[13999]^c32[14676]^c32[14827]^c32[14700]^c32[14701]^c32[15594]^c32[15660]^c32[15661]^c32[15686]^c32[15687]^c32[16378]^c32[16144]^c32[16388]^c32[16389];
break;
case 33:
d32[12672]=c32[1091]^c32[1544]^c32[8809]^c32[16233];
break;
case 34:
d32[13056]=c32[230]^c32[5524]^c32[11722]^c32[13368];
break;
case 35:
d32[13440]=c32[189]^c32[342]^c32[87]^c32[158]^c32[1053]^c32[900]^c32[1121]^c32[1088]^c32[1852]^c32[1878]^c32[1746]^c32[2555]^c32[2643]^c32[2570]^c32[3242]^c32[3286]^c32[3229]^c32[3903]^c32[3866]^c32[3978]^c32[4706]^c32[4651]^c32[4689]^c32[4943]^c32[5589]^c32[5525]^c32[5411]^c32[6357]^c32[6186]^c32[6466]^c32[7111]^c32[6972]^c32[7241]^c32[7850]^c32[7691]^c32[7694]^c32[8823]^c32[8625]^c32[8635]^c32[9499]^c32[9440]^c32[9329]^c32[9218]^c32[10223]^c32[10066]^c32[10207]^c32[10851]^c32[11106]^c32[10846]^c32[11617]^c32[11885]^c32[11839]^c32[12660]^c32[12524]^c32[12474]^c32[13436]^c32[13069]^c32[13238]^c32[13948]^c32[13946]^c32[13977]^c32[14654]^c32[14805]^c32[14679]^c32[15572]^c32[15639]^c32[15665]^c32[16356]^c32[16506]^c32[16367];
break;
case 36:
d32[13824]=c32[210]^c32[11065]^c32[11817]^c32[13845];
break;
case 37:
d32[14208]=c32[38]^c32[39]^c32[192]^c32[321]^c32[8]^c32[902]^c32[903]^c32[1134]^c32[971]^c32[1037]^c32[1701]^c32[1702]^c32[1728]^c32[1596]^c32[2404]^c32[2405]^c32[2493]^c32[2420]^c32[3092]^c32[3136]^c32[3079]^c32[4136]^c32[4137]^c32[4100]^c32[4212]^c32[4939]^c32[4940]^c32[4885]^c32[4923]^c32[5439]^c32[5759]^c32[5645]^c32[6207]^c32[6420]^c32[6316]^c32[6960]^c32[6961]^c32[7206]^c32[7091]^c32[7699]^c32[7700]^c32[7925]^c32[7928]^c32[8672]^c32[8673]^c32[8475]^c32[8485]^c32[9348]^c32[9349]^c32[9290]^c32[9563]^c32[10072]^c32[10073]^c32[10300]^c32[10057]^c32[10066]^c32[11085]^c32[10956]^c32[11080]^c32[11850]^c32[11851]^c32[11735]^c32[11689]^c32[12509]^c32[12510]^c32[12374]^c32[12324]^c32[13286]^c32[13303]^c32[13088]^c32[14181]^c32[14182]^c32[14180]^c32[13827]^c32[14887]^c32[14888]^c32[14655]^c32[14913]^c32[15421]^c32[15422]^c32[15489]^c32[15515]^c32[16205]^c32[16206]^c32[16356]^c32[16217];
break;
case 38:
d32[14592]=c32[185]^c32[7089]^c32[7969]^c32[9430];
break;
case 39:
d32[14976]=c32[1026]^c32[2397]^c32[5722]^c32[14889];
break;
case 40:
d32[15360]=c32[175]^c32[6181]^c32[13368];
break;
case 41:
d32[15744]=c32[820]^c32[2618]^c32[7051]^c32[14112];
break;
case 42:
d32[16128]=c32[142]^c32[295]^c32[39]^c32[40]^c32[110]^c32[111]^c32[113]^c32[1006]^c32[852]^c32[853]^c32[1073]^c32[1074]^c32[1805]^c32[1831]^c32[1698]^c32[1699]^c32[2508]^c32[2596]^c32[2522]^c32[2523]^c32[3195]^c32[3238]^c32[3239]^c32[3181]^c32[3182]^c32[3086]^c32[3856]^c32[4203]^c32[3930]^c32[3931]^c32[4659]^c32[4987]^c32[4988]^c32[4641]^c32[4642]^c32[5542]^c32[5477]^c32[5478]^c32[5747]^c32[5748]^c32[6310]^c32[6522]^c32[6523]^c32[6418]^c32[6419]^c32[7064]^c32[6925]^c32[7193]^c32[7194]^c32[7803]^c32[8027]^c32[8028]^c32[8030]^c32[8031]^c32[8776]^c32[8578]^c32[8587]^c32[8588]^c32[9452]^c32[9393]^c32[9281]^c32[9282]^c32[10176]^c32[10018]^c32[10019]^c32[10159]^c32[10160]^c32[10804]^c32[11058]^c32[11059]^c32[10798]^c32[10799]^c32[11570]^c32[11838]^c32[11791]^c32[11792]^c32[12613]^c32[12477]^c32[12426]^c32[12427]^c32[13389]^c32[13405]^c32[13406]^c32[13190]^c32[13191]^c32[13901]^c32[13898]^c32[13899]^c32[13929]^c32[13930]^c32[14607]^c32[14758]^c32[14631]^c32[14632]^c32[15525]^c32[15591]^c32[15592]^c32[15617]^c32[15618]^c32[16309]^c32[16459]^c32[16319]^c32[16320];
break;
case 43:
d32[16512]=c32[92]^c32[245]^c32[374]^c32[60]^c32[61]^c32[956]^c32[803]^c32[1023]^c32[1024]^c32[881]^c32[1755]^c32[1781]^c32[1649]^c32[2458]^c32[2546]^c32[2472]^c32[2473]^c32[3145]^c32[3189]^c32[3131]^c32[3132]^c32[4190]^c32[4153]^c32[3881]^c32[4609]^c32[4938]^c32[4975]^c32[4976]^c32[5492]^c32[5428]^c32[5697]^c32[5698]^c32[6260]^c32[6473]^c32[6368]^c32[6369]^c32[7014]^c32[7259]^c32[7144]^c32[7753]^c32[7978]^c32[7980]^c32[7981]^c32[8726]^c32[8528]^c32[8537]^c32[8538]^c32[9402]^c32[9343]^c32[9231]^c32[9232]^c32[10126]^c32[10353]^c32[10109]^c32[10110]^c32[10754]^c32[11009]^c32[11132]^c32[11133]^c32[11520]^c32[11788]^c32[11742]^c32[12563]^c32[12427]^c32[12376]^c32[12377]^c32[12420]^c32[13339]^c32[13356]^c32[13140]^c32[13141]^c32[13851]^c32[13849]^c32[13879]^c32[13880]^c32[13938]^c32[14941]^c32[14708]^c32[14966]^c32[15475]^c32[15542]^c32[15567]^c32[15568]^c32[16259]^c32[16409]^c32[16269]^c32[16270];
break;
case 44:
d32[16896]=c32[197]^c32[350]^c32[95]^c32[166]^c32[80]^c32[1061]^c32[908]^c32[1129]^c32[1860]^c32[1886]^c32[1754]^c32[2563]^c32[2651]^c32[2578]^c32[3250]^c32[3294]^c32[3237]^c32[3911]^c32[3874]^c32[3986]^c32[4714]^c32[4659]^c32[4697]^c32[5597]^c32[5533]^c32[5419]^c32[5454]^c32[6365]^c32[6194]^c32[6474]^c32[7119]^c32[6980]^c32[7249]^c32[7075]^c32[7858]^c32[7699]^c32[7702]^c32[8831]^c32[8633]^c32[8643]^c32[9507]^c32[9448]^c32[9337]^c32[10231]^c32[10074]^c32[10215]^c32[10859]^c32[11114]^c32[10854]^c32[11625]^c32[11893]^c32[11847]^c32[12668]^c32[12532]^c32[12482]^c32[13060]^c32[13077]^c32[13246]^c32[13956]^c32[13954]^c32[13985]^c32[14662]^c32[14813]^c32[14687]^c32[15580]^c32[15647]^c32[15673]^c32[16364]^c32[16130]^c32[16375];
break;
case 45:
d32[17280]=c32[903]^c32[4757]^c32[7695];
break;
}
}
}
extern "C" int ldpc_BG1_Zc384_cuda32(uint32_t *c[4],uint32_t *d[4],int n_inputs) {
dim3 numblocks(n_inputs,46);
ldpc_BG1_Zc384_worker<<<numblocks,384>>>(c,d);
cudaError_t err=cudaPeekAtLastError();
if (err!=cudaSuccess) {
printf("cuda error: %s (c %p, d %p)\n",cudaGetErrorString(err),c,d);
exit(-1);
}
cudaDeviceSynchronize();
return(0);
}

View File

@@ -36,13 +36,27 @@
#include "assertions.h"
#include "common/utils/LOG/log.h"
#define USE_PERMUTEX
#ifdef __aarch64__
#define USE_ALIGNR
#endif
#ifdef __AVX512F__
#if defined(__AVX512VBMI__) && defined(USE_PERMUTEX)
// For AVX512 machines, use an AVX512 version of the encoder for Zc=384 only for now. This is used almost exclusively for
// high-throughput cases. The version with "permutex2var" instruction uses less memory (i.e. 1/64th of the memory to store the
// input), but uses more reads instead of creating 64 shifts of the input with memcpy
#include "ldpc384_simd512_permutex_byte.c"
#else
#include "ldpc384_simd512_byte.c"
#endif
#else
#include "ldpc384_byte.c"
#endif
#ifdef USE_ALIGNR
#include "ldpc384_alignr_byte_128.c"
#else
#include "ldpc384_byte_128.c"
#endif
#include "ldpc352_byte.c"
#include "ldpc352_byte_128.c"
#include "ldpc320_byte.c"
@@ -89,16 +103,24 @@
#include "ldpc_BG2_Zc80_byte.c"
#include "ldpc_BG2_Zc72_byte.c"
static void encode_parity_check_part_optim(uint8_t *cc, uint8_t *d, short BG,short Zc,short Kb, int simd_size, int ncols)
static void encode_parity_check_part_optim(uint8_t *cc, uint8_t *d, short BG,short Zc,short Kb, int simd_size, int ncols,time_stats_t *tinput_memcpy)
{
unsigned char c[2 * 22 * Zc * simd_size] __attribute__((aligned(64))); //double size matrix of c
if (tinput_memcpy) start_meas(tinput_memcpy);
for (int i1 = 0; i1 < ncols; i1++) {
memcpy(&c[2 * i1 * Zc], &cc[i1 * Zc], Zc * sizeof(unsigned char));
memcpy(&c[(2 * i1 + 1) * Zc], &cc[i1 * Zc], Zc * sizeof(unsigned char));
}
for (int i1 = 1; i1 < simd_size; i1++) {
memcpy(&c[(2 * ncols * Zc * i1)], &c[i1], (2 * ncols * Zc * sizeof(unsigned char)) - i1);
#if (defined(USE_PERMUTEX) && defined(__AVX512VBMI__)) || defined(USE_ALIGNR)
if (Zc < 384 || BG == 2)
#endif
{
for (int i1 = 1; i1 < simd_size; i1++) {
memcpy(&c[(2 * ncols * Zc * i1)], &c[i1], (2 * ncols * Zc * sizeof(unsigned char)) - i1);
}
}
if (tinput_memcpy) stop_meas(tinput_memcpy);
if (BG == 1) {
switch (Zc) {
case 176:

View File

@@ -0,0 +1,94 @@
/*
* 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 ldpc_encode_parity_check.c
* \brief Parity check function used by ldpc encoders
* \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
* \email openair_tech@eurecom.fr
* \date 27-03-2018
* \version 1.0
* \note
* \warning
*/
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "assertions.h"
#include "common/utils/LOG/log.h"
#include <cuda_runtime.h>
int ldpc_BG1_Zc384_cuda32(uint32_t **c,uint32_t **d,int n_inputs);
void encode_parity_check_part_cuda(uint32_t **c, uint32_t **d, short BG,short Zc,short Kb, int ncols, int n_inputs)
{
if (BG == 1) {
switch (Zc) {
case 176:
case 192:
case 208:
case 224:
case 240:
case 256:
case 288:
case 320:
case 352:
AssertFatal(1==0,"BG %d Zc %d not supported yet for CUDA\n",BG, Zc);
break;
case 384:
ldpc_BG1_Zc384_cuda32(c, d, n_inputs);
break;
default:
AssertFatal(false, "BG %d Zc %d is not supported yet\n", BG, Zc);
}
} else if (BG == 2) {
switch (Zc) {
case 72:
case 80:
case 88:
case 96:
case 104:
case 112:
case 120:
case 128:
case 144:
case 160:
case 176:
case 192:
case 208:
case 224:
case 240:
case 256:
case 288:
case 320:
case 352:
case 384:
default:
AssertFatal(false , "BG %d Zc %d is not supported yet\n", BG, Zc);
}
} else
AssertFatal(false, "BG %d is not supported\n", BG);
}

View File

@@ -58,11 +58,10 @@ int LDPCencoder(unsigned char **inputArray, unsigned char *outputArray, encoder_
int no_punctured_columns, removed_bit;
int nind=0;
int indlist[1000];
int indlist2[1000];
const short *Gen_shift_values = choose_generator_matrix(BG, Zc);
if (Gen_shift_values==NULL) {
printf("ldpc_encoder_orig: could not find generator matrix\n");
printf("ldpc_encoder_orig: could not find generator matrix BG %d Zc %d\n",BG,Zc);
return(-1);
}
@@ -93,32 +92,35 @@ int LDPCencoder(unsigned char **inputArray, unsigned char *outputArray, encoder_
// parity check part
if (gen_code>=1)
if (gen_code==1 || gen_code==2 || gen_code==3)
{
char fname[100];
sprintf(fname,"ldpc_BG%d_Zc%d_byte.c",BG,Zc);
FILE *fd=fopen(fname,"w");
AssertFatal(fd!=NULL,"cannot open %s\n",fname);
sprintf(fname,"ldpc_BG%d_Zc%d_16bit.c",BG,Zc);
FILE *fd2=fopen(fname,"w");
AssertFatal(fd2!=NULL,"cannot open %s\n",fname);
int shift;
char data_type[100];
char xor_command[100];
int mask;
char permutex_command[100];
int use_permutex=0;
char alignr_command[100];
int use_alignr=0;
fprintf(fd,"#include \"PHY/sse_intrin.h\"\n");
fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n");
if (gen_code == 1 && (Zc&63)==0) {
shift=6;
mask=63;
strcpy(data_type,"__m512i");
strcpy(xor_command,"_mm512_xor_si512");
strcpy(permutex_command,"_mm512_permutex2var_epi8");
strcpy(alignr_command,"_mm512_alignr_epi8");
use_alignr=1;
}
else if (gen_code == 1 && (Zc&31)==0) {
shift=5; // AVX2 - 256-bit SIMD
@@ -126,14 +128,15 @@ int LDPCencoder(unsigned char **inputArray, unsigned char *outputArray, encoder_
strcpy(data_type,"simde__m256i");
strcpy(xor_command,"simde_mm256_xor_si256");
}
else if ((Zc&15)==0) {
else if ((gen_code <=2) && (Zc&15)==0) {
shift=4; // SSE4 - 128-bit SIMD
mask=15;
strcpy(data_type,"simde__m128i");
strcpy(xor_command,"simde_mm_xor_si128");
strcpy(alignr_command,"simde_mm_alignr_epi8");
use_alignr=1;
}
else if ((Zc&7)==0) {
else if ((gen_code <=2) && (Zc&7)==0) {
shift=3; // MMX - 64-bit SIMD
mask=7;
strcpy(data_type,"simde__m64");
@@ -145,21 +148,30 @@ int LDPCencoder(unsigned char **inputArray, unsigned char *outputArray, encoder_
strcpy(data_type,"uint8_t");
strcpy(xor_command,"scalar_xor");
fprintf(fd,"#define scalar_xor(a,b) ((a)^(b))\n");
fprintf(fd2,"#define scalar_xor(a,b) ((a)^(b))\n");
}
fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc);
fprintf(fd2,"// generated code for Zc=%d, 16bit encoding\n",Zc);
if (use_permutex==1) {
fprintf(fd," const uint8_t abshift_bytes[%d][%d] __attribute__((aligned(64)))= {\n",1+mask,1+mask);
for (int i=0;i<=mask;i++) {
fprintf(fd,"{");
for (int j=0;j<=mask;j++) {
fprintf(fd,"%d",i+j);
if (j<mask) fprintf(fd,",");
else fprintf(fd,"}");
}
if (i<mask) fprintf(fd,",\n");
else fprintf(fd,"};\n");
}
fprintf(fd,"static inline __m512i abshift_get(int r)\n {\n");
fprintf(fd," return * (const __m512i *) abshift_bytes[r];\n}");
}
fprintf(fd,"static inline void ldpc_BG%d_Zc%d_byte(uint8_t *c,uint8_t *d) {\n",BG,Zc);
fprintf(fd2,"static inline void ldpc_BG%d_Zc%d_16bit(uint16_t *c,uint16_t *d) {\n",BG,Zc);
fprintf(fd," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
fprintf(fd2," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
fprintf(fd," %s *c2,*d2;\n\n",data_type);
fprintf(fd2," %s *c2,*d2;\n\n",data_type);
fprintf(fd," int i2;\n");
fprintf(fd2," int i2;\n");
fprintf(fd," for (i2=0; i2<%d; i2++) {\n",Zc>>shift);
if (shift > 0)
fprintf(fd2," for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1));
for (i2=0; i2 < 1; i2++)
{
//t=Kb*Zc+i2;
@@ -169,53 +181,122 @@ int LDPCencoder(unsigned char **inputArray, unsigned char *outputArray, encoder_
fprintf(fd," c2=&csimd[i2];\n");
fprintf(fd," d2=&dsimd[i2];\n");
fprintf(fd2," c2=&csimd[i2];\n");
fprintf(fd2," d2=&dsimd[i2];\n");
for (i1 = 0; i1 < nrows; i1++)
{
fprintf(fd,"\n//row: %d\n",i1);
fprintf(fd2,"\n//row: %d\n",i1);
AssertFatal(shift > 0 , "The result of the right shift is undefined because the right operand is negative\n");
AssertFatal(shift >= 0 , "The result of the right shift is undefined because the right operand is negative\n");
fprintf(fd," d2[%d]=",(Zc*i1)>>shift);
fprintf(fd2," d2[%d]=",(Zc*i1)>>(shift-1));
nind=0;
for (i3=0; i3 < ncols; i3++)
{
temp_prime=i1 * ncols + i3;
for (i4=0; i4 < no_shift_values[temp_prime]; i4++)
{
{
var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc);
int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc;
printf("var %d, i3 %d, i4 %d, index %d, shift %d, Zc %d, pointer_shift_values[%d] %d gen_shift_value %d\n",var,i3,i4,index,shift,Zc,temp_prime,pointer_shift_values[temp_prime],Gen_shift_values[pointer_shift_values[temp_prime]]);
indlist[nind] = ((index&mask)*((2*Zc*ncols)>>shift)/* *Kb */)+(index>>shift);
printf("indlist[%d] %d, index&mask %d, index>>shift %d\n",nind,indlist[nind],index&mask,index>>shift);
indlist2[nind++] = ((index&(mask>>1))*((2*Zc*ncols)>>(shift-1))*Kb)+(index>>(shift-1));
}
}
printf("indlist[%d] %d, index&mask %d, index>>shift %d\n",nind,indlist[nind],index&mask,index>>shift);
if (use_permutex==1 || use_alignr==1) {
indlist[nind++] = index;
}
else {
indlist[nind] = ((index&mask)*((2*Zc*ncols)>>shift)/* *Kb */)+(index>>shift);
}
}//i4
}//i3
for (i4=0;i4<nind-1;i4++) {
fprintf(fd,"%s(c2[%d],",xor_command,indlist[i4]);
fprintf(fd2,"%s(c2[%d],",xor_command,indlist2[i4]);
if (use_permutex==0 && use_alignr==0) {
fprintf(fd,"%s(c2[%d],",xor_command,indlist[i4]);
}
else {
if ((indlist[i4]&mask) == 0) {
fprintf(fd,"%s(c2[%d],",xor_command,indlist[i4]>>shift);
}
else if (use_permutex==1) {
fprintf(fd,"%s(%s(c2[%d],abshift_get(%d),c2[%d]),",xor_command,permutex_command,(indlist[i4]>>shift),indlist[i4]&mask,(indlist[i4]>>shift)+1);
}
else if (use_alignr==1) {
fprintf(fd,"%s(%s(c2[%d],c2[%d],%d),",xor_command,alignr_command,(indlist[i4]>>shift)+1,(indlist[i4]>>shift),indlist[i4]&mask);
}
}
} //i4
if (use_permutex==0 && use_alignr==0)
fprintf(fd,"c2[%d]",indlist[i4]);
else {
if ((indlist[i4]&mask) == 0) {
fprintf(fd,"c2[%d]",indlist[i4]>>shift);
}
else if (use_permutex==1){
fprintf(fd,"%s(c2[%d],abshift_get(%d),c2[%d])",permutex_command,(indlist[i4]>>shift),indlist[i4]&mask,(indlist[i4]>>shift)+1);
}
else if (use_alignr==1) {
fprintf(fd,"%s(c2[%d],c2[%d],%d)",alignr_command,(indlist[i4]>>shift)+1,(indlist[i4]>>shift),indlist[i4]&mask);
}
}
fprintf(fd,"c2[%d]",indlist[i4]);
fprintf(fd2,"c2[%d]",indlist2[i4]);
for (i4=0;i4<nind-1;i4++) { fprintf(fd,")"); fprintf(fd2,")"); }
fprintf(fd,";\n");
fprintf(fd2, ";\n");
}
fprintf(fd," }\n}\n");
fprintf(fd2," }\n}\n");
}
for (i4=0;i4<nind-1;i4++) fprintf(fd,")");
fprintf(fd,";\n");
} // i1
fprintf(fd," }\n}\n");
} // i2
fclose(fd);
}
else if (gen_code == 4) { // CUDA
char fname[100];
sprintf(fname,"ldpc_BG%d_Zc%d_32bit.cu",BG,Zc);
FILE *fd=fopen(fname,"w");
AssertFatal(fd!=NULL,"cannot open %s\n",fname);
printf("Writing to %s\n",fname);
fprintf(fd,"#include <stdio.h>\n#include <stdint.h>\n#include <cuda_runtime.h>\n");
fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc);
fprintf(fd,"__global__ void ldpc_BG%d_Zc%d_worker(uint32_t *c[4],uint32_t *d[4]) {\n",BG,Zc);
fprintf(fd," uint32_t *c32=c[blockIdx.x];\n uint32_t *d32=d[blockIdx.x];\n\n");
fprintf(fd," int i2 = threadIdx.x;\n");
fprintf(fd," int i1 = blockIdx.y;\n");
fprintf(fd," if (i2 < %d) {\n",Zc);
fprintf(fd," c32+=i2;\n");
fprintf(fd," d32+=i2;\n");
fprintf(fd," switch(i1) {\n");
for (int i1=0;i1<nrows;i1++) {
nind = 0;
fprintf(fd," case %d:\n",i1);
fprintf(fd," d32[%d]=",(Zc*i1));
for (i3=0; i3 < ncols; i3++)
{
temp_prime=i1 * ncols + i3;
for (i4=0; i4 < no_shift_values[temp_prime]; i4++)
{
var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc);
int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc;
printf("var %d, i3 %d, i4 %d, index %d (index mod 2Zc) %d, Zc %d, pointer_shift_values[%d] %d gen_shift_value %d offset %d\n",var,i3,i4,index,index%(2*Zc),Zc,temp_prime,pointer_shift_values[temp_prime],Gen_shift_values[pointer_shift_values[temp_prime]],(i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc);
if (index%(2*Zc) >= Zc) printf("***********************\n");
indlist[nind] = index;
printf("indlist[%d] %d, index %d\n",nind,indlist[nind],index);
nind++;
} //i4
} // i3
for (i4=0;i4<nind-1;i4++) {
fprintf(fd,"c32[%d]^",indlist[i4]);
} //i4
fprintf(fd,"c32[%d];\n\n",indlist[i4]);
fprintf(fd," break;\n");
}// i1
fprintf(fd," }\n");
fprintf(fd," }\n");
fprintf(fd,"}\n");
fprintf(fd,"extern \"C\" int ldpc_BG%d_Zc%d_cuda32(uint32_t *c[4],uint32_t *d[4],int n_inputs) { \n",BG,Zc);
fprintf(fd,"dim3 numblocks(n_inputs,%d);\n",nrows);
fprintf(fd,"ldpc_BG%d_Zc%d_worker<<<numblocks,%d>>>(c,d);\n",BG,Zc,Zc);
fprintf(fd," cudaDeviceSynchronize();\n");
fprintf(fd," return(0);\n");
fprintf(fd,"}\n");
fclose(fd);
fclose(fd2);
}
else if(gen_code==0)
{
@@ -241,10 +322,12 @@ int LDPCencoder(unsigned char **inputArray, unsigned char *outputArray, encoder_
for (i4 = 0; i4 < no_shift_values[temp_prime]; i4++) {
channel_temp = channel_temp ^ c[i3 * Zc + Gen_shift_values[pointer_shift_values[temp_prime] + i4]];
//if (i1==0) printf("index %d\n",i3 * Zc + Gen_shift_values[pointer_shift_values[temp_prime] + i4]);
}
}
d[i2+i1*Zc]=channel_temp;
//if (i1==0) printf("reference: d[%d] %d c[%d] %d\n",i2,d[i2],i2,c[i2]);
// output[t+i1*Zc]=channel_temp;
}
}

View File

@@ -0,0 +1,52 @@
/*
* 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 ldpc_encoder.c
* \brief Defines the LDPC encoder
* \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
* \email openair_tech@eurecom.fr
* \date 27-03-2018
* \version 1.0
* \note
* \warning
*/
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "defs.h"
#include "assertions.h"
#include "openair1/PHY/CODING/nrLDPC_defs.h"
#include "openair1/PHY/CODING/nrLDPC_extern.h"
#include "ldpc_generate_coefficient.c"
void cuda_support_init() {
return;
}
uint32_t **LDPCencoder32(uint8_t **input,encoder_implemparams_t *impp)
{
AssertFatal(1==0,"Should not be getting here\n");
}

View File

@@ -0,0 +1,791 @@
/*
* 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 ldpc_encoder_optim8segmulti.c
* \brief Defines the optimized LDPC encoder
* \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
* \email openair_tech@eurecom.fr
* \date 27-03-2018
* \version 1.0
* \note
* \warning
*/
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "assertions.h"
#include "common/utils/LOG/log.h"
#include "time_meas.h"
#include "openair1/PHY/CODING/nrLDPC_defs.h"
#include "PHY/sse_intrin.h"
#include "openair1/PHY/CODING/nrLDPC_extern.h"
#include "ldpc_generate_coefficient.c"
#include <cuda_runtime.h>
//#define DEBUG_LDPC 1
#include "ldpc_encode_parity_check_cuda.c"
uint32_t *c_dev;
uint32_t **c_host;
uint32_t *c_devh[4];
uint32_t *d_dev;
uint32_t **d_host;
uint32_t *d_devh[4];
uint32_t *cc_dev;
uint32_t **cc_host;
uint32_t *cc_devh[4];
uint32_t *input_dev;
uint32_t **input_host;
uint32_t *input_devh[128];
int managed = 0, concurrent = 0, uva = 0, pageable = 0, pageable_uses_host = 0, register_host = 0;
#define USE_GPU_CIRCCOPY 1
#define USE_GPU_FOR_INPUT 1
void cuda_support_init() {
int dev = 0;
struct cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, dev);
cudaDeviceGetAttribute(&managed, cudaDevAttrManagedMemory, dev);
cudaDeviceGetAttribute(&concurrent, cudaDevAttrConcurrentManagedAccess, dev);
cudaDeviceGetAttribute(&uva, cudaDevAttrUnifiedAddressing, dev);
cudaDeviceGetAttribute(&pageable, cudaDevAttrPageableMemoryAccess, dev);
cudaDeviceGetAttribute(&pageable_uses_host, cudaDevAttrPageableMemoryAccessUsesHostPageTables, dev);
cudaDeviceGetAttribute(&register_host, cudaDevAttrHostRegisterSupported,dev);
LOG_I(NR_PHY,"Device: %s (cc %d.%d)\n", prop.name, prop.major, prop.minor);
LOG_I(NR_PHY,"Unified Virtual Addressing (UVA): %s\n", uva ? "YES" : "NO");
LOG_I(NR_PHY,"Managed (Unified) Memory: %s\n", managed ? "YES" : "NO");
LOG_I(NR_PHY,"Concurrent managed access: %s\n", concurrent ? "YES" : "NO");
LOG_I(NR_PHY,"Pageable memory access: %s\n", pageable ? "YES" : "NO");
LOG_I(NR_PHY,"Uses host page tables: %s\n", pageable_uses_host ? "YES" : "NO");
LOG_I(NR_PHY,"Host Register supported: %s\n", register_host ? "YES" : "NO");
// initialize input and output memory
if (!pageable && !register_host) {
cudaError_t err=cudaMalloc((void **)&c_dev,4*sizeof(uint32_t*));
AssertFatal(err == cudaSuccess,"CUDA Error (c_dev): %s\n", cudaGetErrorString(err));
err=cudaHostAlloc((void **)&c_host,4*sizeof(uint32_t*),cudaHostAllocDefault);
AssertFatal(err == cudaSuccess,"CUDA Error (c_host): %s\n", cudaGetErrorString(err));
for (int i=0;i<4;i++) {
err=cudaMalloc((void**)&c_devh[i],2*22*384*sizeof(uint32_t));
AssertFatal(err == cudaSuccess,"CUDA Error (c_devh[%d]): %s\n", i,cudaGetErrorString(err));
err=cudaHostAlloc((void**)&c_host[i],2*22*384*sizeof(uint32_t),cudaHostAllocDefault);
AssertFatal(err == cudaSuccess,"CUDA Error (chost[%d]): %s\n", i,cudaGetErrorString(err));
}
err = cudaMemcpy(c_dev,c_devh,4*sizeof(uint32_t*),cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess,"CUDA Error (memcpy c_devh -> c_dev): %s\n", cudaGetErrorString(err));
err=cudaMalloc((void**)&d_dev,4*sizeof(uint32_t*));
AssertFatal(err == cudaSuccess,"CUDA Error: %s\n", cudaGetErrorString(err));
err=cudaHostAlloc((void **)&d_host,4*sizeof(uint32_t*),cudaHostAllocDefault);
AssertFatal(err == cudaSuccess,"CUDA Error (d_host): %s\n", cudaGetErrorString(err));
for (int i=0;i<4;i++) {
err=cudaMalloc((void**)&d_devh[i],68*384*sizeof(uint32_t));
AssertFatal(err == cudaSuccess,"CUDA Error (d_devh[%d]: %s\n", i,cudaGetErrorString(err));
err=cudaHostAlloc((void**)&d_host[i],68*384*sizeof(uint32_t),cudaHostAllocDefault);
AssertFatal(err == cudaSuccess,"CUDA Error (d_host[%d]): %s\n", i,cudaGetErrorString(err));
}
err=cudaMemcpy(d_dev,d_devh,4*sizeof(uint32_t*),cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess,"CUDA Error (memcpy d_devh -> d_dev): %s\n", cudaGetErrorString(err));
err=cudaMalloc((void**)&cc_dev,4*sizeof(uint32_t*));
AssertFatal(err == cudaSuccess,"CUDA Error: %s\n", cudaGetErrorString(err));
err=cudaHostAlloc((void **)&cc_host,4*sizeof(uint32_t*),cudaHostAllocDefault);
AssertFatal(err == cudaSuccess,"CUDA Error (cc_host): %s\n", cudaGetErrorString(err));
for (int i=0;i<4;i++) {
err=cudaMalloc((void**)&cc_devh[i],68*384*sizeof(uint32_t));
AssertFatal(err == cudaSuccess,"CUDA Error (cc_devh[%d]: %s\n", i,cudaGetErrorString(err));
err=cudaHostAlloc((void**)&cc_host[i],68*384*sizeof(uint32_t),cudaHostAllocDefault);
AssertFatal(err == cudaSuccess,"CUDA Error (cc_host[%d]): %s\n", i,cudaGetErrorString(err));
}
err=cudaMemcpy(cc_dev,cc_devh,4*sizeof(uint32_t*),cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess,"CUDA Error (memcpy cc_devh -> d_dev): %s\n", cudaGetErrorString(err));
err=cudaMalloc((void**)&input_dev,128*sizeof(uint8_t*));
AssertFatal(err == cudaSuccess,"CUDA Error: %s\n", cudaGetErrorString(err));
err=cudaHostAlloc((void **)&input_host,128*sizeof(uint8_t*),cudaHostAllocDefault);
AssertFatal(err == cudaSuccess,"CUDA Error (cc_host): %s\n", cudaGetErrorString(err));
for (int i=0;i<128;i++) {
err=cudaMalloc((void**)&input_devh[i],(8448/8)*sizeof(uint8_t));
AssertFatal(err == cudaSuccess,"CUDA Error (input_devh[%d]: %s\n", i,cudaGetErrorString(err));
err=cudaHostAlloc((void**)&input_host[i],(8448/8)*sizeof(uint8_t),cudaHostAllocDefault);
AssertFatal(err == cudaSuccess,"CUDA Error (input_host[%d]): %s\n", i,cudaGetErrorString(err));
}
err=cudaMemcpy(input_dev,input_devh,128*sizeof(uint8_t*),cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess,"CUDA Error (memcpy cc_devh -> d_dev): %s\n", cudaGetErrorString(err));
}
else {
LOG_I(NR_PHY,"Allocating c,d,cc arrays for CPU/GPU shared-memory\n");
cudaError_t err=cudaHostAlloc((void **)&c_host,4*sizeof(uint32_t*),cudaHostAllocMapped|cudaHostAllocPortable);
AssertFatal(err == cudaSuccess,"CUDA Error (c_host): %s\n", cudaGetErrorString(err));
err = cudaHostGetDevicePointer((void**)&c_dev, c_host, 0);
AssertFatal(err == cudaSuccess,"CUDA Error (c_dev): %s\n", cudaGetErrorString(err));
LOG_I(NR_PHY,"c_host %p, c_dev %p\n",c_host,c_dev);
for (int i=0;i<4;i++) {
err=cudaHostAlloc((void**)&c_host[i],2*22*384*sizeof(uint32_t),cudaHostAllocMapped);
AssertFatal(err == cudaSuccess,"CUDA Error (c_host[%d]): %s\n", i,cudaGetErrorString(err));
err = cudaHostGetDevicePointer((void**)&c_devh[i], c_host[i], 0);
AssertFatal(err == cudaSuccess,"CUDA Error (c_devh[%d]): %s\n", i,cudaGetErrorString(err));
}
err=cudaMemcpy(c_dev,c_devh,4*sizeof(uint32_t*),cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess,"CUDA Error (memcpy c_devh -> c_dev): %s\n", cudaGetErrorString(err));
err=cudaHostAlloc((void **)&d_host,4*sizeof(uint32_t*),cudaHostAllocMapped);
AssertFatal(err == cudaSuccess,"CUDA Error (d_host): %s\n", cudaGetErrorString(err));
err=cudaHostGetDevicePointer((void**)&d_dev, d_host, 0);
AssertFatal(err == cudaSuccess,"CUDA Error cudaHostGetDevicePointer(d_dev): %s\n", cudaGetErrorString(err));
LOG_I(NR_PHY,"d_host %p, d_dev %p\n",d_host,d_dev);
for (int i=0;i<4;i++) {
err=cudaHostAlloc((void**)&d_host[i],68*384*sizeof(uint32_t),cudaHostAllocMapped);
AssertFatal(err == cudaSuccess,"CUDA Error (d_host[%d]): %s\n", i,cudaGetErrorString(err));
err=cudaHostGetDevicePointer((void**)&d_devh[i], d_host[i], 0);
AssertFatal(err == cudaSuccess,"CUDA Error (cudaHostGetDevicePointer) d_devh[%d]: %s\n", i,cudaGetErrorString(err));
}
err=cudaMemcpy(d_dev,d_devh,4*sizeof(uint32_t*),cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess,"CUDA Error (memcpy d_devh -> d_dev): %s\n", cudaGetErrorString(err));
err=cudaHostAlloc((void **)&cc_host,4*sizeof(uint32_t*),cudaHostAllocMapped);
AssertFatal(err == cudaSuccess,"CUDA Error (cc_host): %s\n", cudaGetErrorString(err));
err=cudaHostGetDevicePointer((void**)&cc_dev, cc_host, 0);
AssertFatal(err == cudaSuccess,"CUDA Error cudaHostGetDevicePointer(cc_dev): %s\n", cudaGetErrorString(err));
LOG_I(NR_PHY,"cc_host %p, cc_dev %p\n",cc_host,cc_dev);
for (int i=0;i<4;i++) {
err=cudaHostAlloc((void**)&cc_host[i],68*384*sizeof(uint32_t),cudaHostAllocMapped);
AssertFatal(err == cudaSuccess,"CUDA Error (cc_host[%d]): %s\n", i,cudaGetErrorString(err));
err=cudaHostGetDevicePointer((void**)&cc_devh[i], cc_host[i], 0);
AssertFatal(err == cudaSuccess,"CUDA Error (cudaHostGetDevicePointer) cc_devh[%d]: %s\n", i,cudaGetErrorString(err));
}
err=cudaMemcpy(cc_dev,cc_devh,4*sizeof(uint32_t*),cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess,"CUDA Error (memcpy d_devh -> d_dev): %s\n", cudaGetErrorString(err));
err=cudaHostAlloc((void **)&input_host,128*sizeof(uint8_t*),cudaHostAllocMapped);
AssertFatal(err == cudaSuccess,"CUDA Error (input_host): %s\n", cudaGetErrorString(err));
err=cudaHostGetDevicePointer((void**)&input_dev, input_host, 0);
AssertFatal(err == cudaSuccess,"CUDA Error cudaHostGetDevicePointer(cc_host): %s\n", cudaGetErrorString(err));
LOG_I(NR_PHY,"input_host %p, input_dev %p\n",input_host,input_dev);
/*
for (int i=0;i<128;i++) {
err=cudaHostAlloc((void**)&input_host[i],(8448/8)*sizeof(uint8_t),cudaHostAllocMapped);
AssertFatal(err == cudaSuccess,"CUDA Error (input_host[%d]): %s\n", i,cudaGetErrorString(err));
err=cudaHostGetDevicePointer((void**)&input_devh[i], input_host[i], 0);
AssertFatal(err == cudaSuccess,"CUDA Error (cudaHostGetDevicePointer) input_devh[%d]: %s\n", i,cudaGetErrorString(err));
}
err=cudaMemcpy(input_dev,input_devh,128*sizeof(uint8_t*),cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess,"CUDA Error (memcpy input_devh -> input_dev): %s\n", cudaGetErrorString(err));
*/
}
}
uint32_t **LDPCencoder32(uint8_t **input, encoder_implemparams_t *impp)
{
//set_log(PHY, 4);
int Zc = impp->Zc;
int Kb = impp->Kb;
short block_length = impp->K;
short BG = impp->BG;
int nrows=0,ncols=0;
int rate=3;
int no_punctured_columns,removed_bit;
if(impp->tinput != NULL) start_meas(impp->tinput);
//determine number of bits in codeword
if (BG==1)
{
nrows=46; //parity check bits
ncols=22; //info bits
rate=3;
}
else if (BG==2)
{
nrows=42; //parity check bits
ncols=10; // info bits
rate=5;
}
#ifdef DEBUG_LDPC
LOG_I(PHY,"ldpc_encoder_cuda32: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,impp->n_segments);
LOG_I(PHY,"ldpc_encoder_cuda32: PDU (seg 0) %x %x %x %x\n",input[0][0],input[0][1],input[0][2],input[0][3]);
#endif
AssertFatal(Zc > 0, "no valid Zc found for block length %d\n", block_length);
int n_inputs = (impp->n_segments/32)+(((impp->n_segments&31) > 0) ? 1: 0);
// uint32_t cc[4][22*Zc]; //padded input, unpacked, max size
// calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
// clear input
/*
for (int i=0;i<n_inputs;i++) {
if (!pageable && !register_host)
cudaMemset(cc_devh[i],0,22*Zc*sizeof(uint32_t));
else
memset(cc_host[i],0,22*Zc*sizeof(uint32_t));
}*/
#if 0
// unoptimized version of input processing
unsigned int temp;
for (int i_dword=0; i_dword < block_length; i_dword++) {
unsigned int i = i_dword;
for (int j = 0; j < impp->n_segments; j++) {
temp = (input[j][i/8]&(128>>(i&7)))>>(7-(i&7));
cc[j>>5][i] |= (temp << (j&31));
}
}
#else
// uint32_t *ccp[4];
// for (int s=0;s<n_inputs;s++) ccp[s]=cc[s];
#ifdef USE_GPU_FOR_INPUT
if (!pageable && !register_host) {
for (int r=0;r<impp->n_segments;r++) {
cudaMemcpy(input_devh[r],input[r],block_length>>3,cudaMemcpyHostToDevice);
}
}
ldpc_input(pageable||register_host? input : input_dev,(uint32_t**)cc_dev,block_length,impp->n_segments);
// for (int i=0;i<16;i++) printf("i %d: cc[0] %x\n",i,cc[0][i]);
#else
#ifndef __aarch64__
simde__m256i andmask = simde_mm256_set_epi32(0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80); // every 8 bits -> 8 bytes, pattern repeats.
simde__m256i zero256 = simde_mm256_setzero_si256();
simde__m256i masks[32];
register simde__m256i c256;
for (int i=0;i<32;i++) {
masks[i] = simde_mm256_set1_epi32(1<<i);
}
int i;
for (i=0; i < block_length; i += 8) {
unsigned int i8 = i >> 3;
for (int j0=0;j0<n_inputs;j0++) {
c256 = simde_mm256_and_si256(simde_mm256_cmpeq_epi32(simde_mm256_andnot_si256(simde_mm256_set1_epi32(input[j0<<5][i8]),andmask),zero256),masks[0]);
int j2 = 32;
if (j0==(n_inputs-1)) j2= impp->n_segments-(j0<<5);
for (int j=1; j < j2; j++) {
c256 = simde_mm256_or_si256(simde_mm256_and_si256(simde_mm256_cmpeq_epi32(simde_mm256_andnot_si256(simde_mm256_set1_epi32(input[(j0<<5)+j][i8]),andmask),zero256),masks[j]),c256);
}
((simde__m256i *)cc_host[j0])[i8] = c256;
}
}
#else
int i2=0;
const int32_t ucShifta[32][4] = {
{-7,-6,-5,-4}, // 0
{-6,-5,-4,-3}, // 1
{-5,-4,-3,-2}, // 2
{-4,-3,-2,-1}, // 3
{-3,-2,-1,0}, // 4
{-2,-1,0,1}, // 5
{-1,0,1,2}, // 6
{0,1,2,3}, // 7
{1,2,3,4}, // 8
{2,3,4,5}, // 9
{3,4,5,6}, // 10
{4,5,6,7}, // 11
{5,6,7,8}, // 12
{6,7,8,9}, // 13
{7,8,9,10}, // 14
{8,9,10,11}, // 15
{9,10,11,12}, // 16
{10,11,12,13}, // 17
{11,12,13,14}, // 18
{12,13,14,15}, // 19
{13,14,15,16}, // 20
{14,15,16,17}, // 21
{15,16,17,18}, // 22
{16,17,18,19}, // 23
{17,18,19,20}, // 24
{18,19,20,21}, // 25
{19,20,21,22}, // 26
{20,21,22,23}, // 27
{21,22,23,24}, // 28
{22,23,24,25}, // 29
{23,24,25,26}, // 30
{24,25,26,27}}; // 31
const int32_t ucShiftb[32][4] = {
{-3,-2,-1,0}, // 0
{-2,-1,0,1}, // 1
{-1,0,1,2}, // 2
{0,1,2,3}, // 3
{1,2,3,4}, // 4
{2,3,4,5}, // 5
{3,4,5,6}, // 6
{4,5,6,7}, // 7
{5,6,7,8}, // 8
{6,7,8,9}, // 9
{7,8,9,10}, // 10
{8,9,10,11}, // 11
{9,10,11,12}, // 12
{10,11,12,13}, // 13
{11,12,13,14}, // 14
{12,13,14,15}, // 15
{13,14,15,16}, // 16
{14,15,16,17}, // 17
{15,16,17,18}, // 18
{16,17,18,19}, // 19
{17,18,19,20}, // 20
{18,19,20,21}, // 21
{19,20,21,22}, // 22
{20,21,22,23}, // 23
{21,22,23,24}, // 24
{22,23,24,25}, // 25
{23,24,25,26}, // 26
{24,25,26,27}, // 27
{25,26,27,28}, // 28
{26,27,28,29}, // 29
{27,28,29,30}, // 30
{28,29,30,31}}; // 31
const int32_t ucShiftc[32][4] = {
{-15,-14,-13,-12}, // 0
{-14,-13,-12,-11}, // 1
{-13,-12,-11,-10}, // 2
{-12,-11,-10,-9}, // 3
{-11,-10,-9,-8}, // 4
{-10,-9,-8,-7}, // 5
{-9,-8,-7,-6}, // 6
{-8,-7,-6,-5}, // 7
{-7,-6,-5,-4}, // 8
{-6,-5,-4,-3}, // 9
{-5,-4,-3,-2}, // 10
{-4,-3,-2,-1}, // 11
{-3,-2,-1,0}, // 12
{-2,-1,0,1}, // 13
{-1,0,1,2}, // 14
{0,1,2,3}, // 15
{1,2,3,4}, // 16
{2,3,4,5}, // 17
{3,4,5,6}, // 18
{4,5,6,7}, // 19
{5,6,7,8}, // 20
{6,7,8,9}, // 21
{7,8,9,10}, // 22
{8,9,10,11}, // 23
{9,10,11,12}, // 24
{10,11,12,13}, // 25
{11,12,13,14}, // 26
{12,13,14,15}, // 27
{13,14,15,16}, // 28
{14,15,16,17}, // 29
{15,16,17,18}, // 30
{16,17,18,19}}; // 31
const int32_t ucShiftd[32][4] = {
{-11,-10,-9,-8}, // 0
{-10,-9,-8,-7}, // 1
{-9,-8,-7,-6}, // 2
{-8,-7,-6,-5}, // 3
{-7,-6,-5,-4}, // 4
{-6,-5,-4,-3}, // 5
{-5,-4,-3,-2}, // 6
{-4,-3,-2,-1}, // 7
{-3,-2,-1,0}, // 8
{-2,-1,0,1}, // 9
{-1,0,1,2}, // 10
{0,1,2,3}, // 11
{1,2,3,4}, // 12
{2,3,4,5}, // 13
{3,4,5,6}, // 14
{4,5,6,7}, // 15
{5,6,7,8}, // 16
{6,7,8,9}, // 17
{7,8,9,10}, // 18
{8,9,10,11}, // 19
{9,10,11,12}, // 20
{10,11,12,13}, // 21
{11,12,13,14}, // 22
{12,13,14,15}, // 23
{13,14,15,16}, // 24
{14,15,16,17}, // 25
{15,16,17,18}, // 26
{16,17,18,19}, // 27
{17,18,19,20}, // 28
{18,19,20,21}, // 29
{19,20,21,22}, // 30
{20,21,22,23}};// 31
const int32_t ucShifte[32][4] = {
{-23,-22,-21,-20}, // 0
{-22,-21,-20,-19}, // 1
{-21,-20,-19,-18}, // 2
{-20,-19,-18,-17}, // 3
{-19,-18,-17,-16}, // 4
{-18,-17,-16,-15}, // 5
{-17,-16,-15,-14}, // 6
{-16,-15,-14,-13}, // 7
{-15,-14,-13,-12}, // 8
{-14,-13,-12,-11}, // 9
{-13,-12,-11,-10}, // 10
{-12,-11,-10,-9}, // 11
{-11,-10,-9,-8}, // 12
{-10,-9,-8,-7}, // 13
{-9,-8,-7,-6}, // 14
{-8,-7,-6,-5}, // 15
{-7,-6,-5,-4}, // 16
{-6,-5,-4,-3}, // 17
{-5,-4,-3,-2}, // 18
{-4,-3,-2,-1}, // 19
{-3,-2,-1,0}, // 20
{-2,-1,0,1}, // 21
{-1,0,1,2}, // 22
{0,1,2,3}, // 23
{1,2,3,4}, // 24
{2,3,4,5}, // 25
{3,4,5,6}, // 26
{4,5,6,7}, // 27
{5,6,7,8}, // 28
{6,7,8,9}, // 29
{7,8,9,10}, // 30
{8,9,10,11}}; // 31
const int32_t ucShiftf[32][4] = {
{-19,-18,-17,-16}, // 0
{-18,-17,-16,-15}, // 1
{-17,-16,-15,-14}, // 2
{-16,-15,-14,-13}, // 3
{-15,-14,-13,-12}, // 4
{-14,-13,-12,-11}, // 5
{-13,-12,-11,-10}, // 6
{-12,-11,-10,-9}, // 7
{-11,-10,-9,-8}, // 8
{-10,-9,-8,-7}, // 9
{-9,-8,-7,-6}, // 10
{-8,-7,-6,-5}, // 11
{-7,-6,-5,-4}, // 12
{-6,-5,-4,-3}, // 13
{-5,-4,-3,-2}, // 14
{-4,-3,-2,-1}, // 15
{-3,-2,-1,0}, // 16
{-2,-1,0,1}, // 17
{-1,0,1,2}, // 18
{0,1,2,3}, // 19
{1,2,3,4}, // 20
{2,3,4,5}, // 21
{3,4,5,6}, // 22
{4,5,6,7}, // 23
{5,6,7,8}, // 24
{6,7,8,9}, // 25
{7,8,9,10}, // 26
{8,9,10,11}, // 27
{9,10,11,12}, // 28
{10,11,12,13}, // 29
{11,12,13,14}, // 30
{12,13,14,15}}; // 31
const int32_t ucShiftg[32][4] = {
{-31,-30,-29,-28},
{-30,-29,-28,-27},
{-29,-28,-27,-26},
{-28,-27,-26,-25},
{-27,-26,-25,-24},
{-26,-25,-24,-23},
{-25,-24,-23,-22},
{-24,-23,-22,-21},
{-23,-22,-21,-20}, // 0
{-22,-21,-20,-19}, // 1
{-21,-20,-19,-18}, // 2
{-20,-19,-18,-17}, // 3
{-19,-18,-17,-16}, // 4
{-18,-17,-16,-15}, // 5
{-17,-16,-15,-14}, // 6
{-16,-15,-14,-13}, // 7
{-15,-14,-13,-12}, // 8
{-14,-13,-12,-11}, // 9
{-13,-12,-11,-10}, // 10
{-12,-11,-10,-9}, // 11
{-11,-10,-9,-8}, // 12
{-10,-9,-8,-7}, // 13
{-9,-8,-7,-6}, // 14
{-8,-7,-6,-5}, // 15
{-7,-6,-5,-4}, // 16
{-6,-5,-4,-3}, // 17
{-5,-4,-3,-2}, // 18
{-4,-3,-2,-1}, // 19
{-3,-2,-1,0}, // 20
{-2,-1,0,1}, // 21
{-1,0,1,2}, // 22
{0,1,2,3}}; // 23
const int32_t ucShifth[32][4] = {
{-27,-26,-25,-24}, // 0
{-26,-25,-24,-23}, // 1
{-25,-24,-23,-22}, // 2
{-24,-23,-22,-21}, // 3
{-23,-22,-21,-20}, // 4
{-22,-21,-20,-19}, // 5
{-21,-20,-19,-18}, // 6
{-20,-19,-18,-17}, // 7
{-19,-18,-17,-16}, // 8
{-18,-17,-16,-15}, // 9
{-17,-16,-15,-14}, // 10
{-16,-15,-14,-13}, // 11
{-15,-14,-13,-12}, // 12
{-14,-13,-12,-11}, // 13
{-13,-12,-11,-10}, // 14
{-12,-11,-10,-9}, // 15
{-11,-10,-9,-8}, // 16
{-10,-9,-8,-7}, // 17
{-9,-8,-7,-6}, // 18
{-8,-7,-6,-5}, // 19
{-7,-6,-5,-4}, // 20
{-6,-5,-4,-3}, // 21
{-5,-4,-3,-2}, // 22
{-4,-3,-2,-1}, // 23
{-3,-2,-1,0}, // 24
{-2,-1,0,1}, // 25
{-1,0,1,2}, // 26
{0,1,2,3}, // 27
{1,2,3,4}, // 28
{2,3,4,5}, // 29
{3,4,5,6}, // 30
{4,5,6,7}}; // 31
const uint32_t __attribute__ ((aligned (16))) masksa[4] = {0x80,0x40,0x20,0x10};
const uint32_t __attribute__ ((aligned (16))) masksb[4] = {0x8,0x4,0x2,0x1};
const uint32_t __attribute__ ((aligned (16))) masksc[4] = {0x8000,0x4000,0x2000,0x1000};
const uint32_t __attribute__ ((aligned (16))) masksd[4] = {0x800,0x400,0x200,0x100};
const uint32_t __attribute__ ((aligned (16))) maskse[4] = {0x800000,0x400000,0x200000,0x100000};
const uint32_t __attribute__ ((aligned (16))) masksf[4] = {0x80000,0x40000,0x20000,0x10000};
const uint32_t __attribute__ ((aligned (16))) masksg[4] = {0x80000000,0x40000000,0x20000000,0x10000000};
const uint32_t __attribute__ ((aligned (16))) masksh[4] = {0x8000000,0x4000000,0x2000000,0x1000000};
int32x4_t vshifta[32],vshiftb[32],vshiftc[32],vshiftd[32],vshifte[32],vshiftf[32],vshiftg[32],vshifth[32];
uint32x4_t vmasksa = vld1q_u32(masksa);
uint32x4_t vmasksb = vld1q_u32(masksb);
uint32x4_t vmasksc = vld1q_u32(masksc);
uint32x4_t vmasksd = vld1q_u32(masksd);
uint32x4_t vmaskse = vld1q_u32(maskse);
uint32x4_t vmasksf = vld1q_u32(masksf);
uint32x4_t vmasksg = vld1q_u32(masksg);
uint32x4_t vmasksh = vld1q_u32(masksh);
uint32x4_t in;
for (int n=0;n<32;n++) {
vshifta[n] = vld1q_s32(ucShifta[n]);
vshiftb[n] = vld1q_s32(ucShiftb[n]);
vshiftc[n] = vld1q_s32(ucShiftc[n]);
vshiftd[n] = vld1q_s32(ucShiftd[n]);
vshifte[n] = vld1q_s32(ucShifte[n]);
vshiftf[n] = vld1q_s32(ucShiftf[n]);
vshiftg[n] = vld1q_s32(ucShiftg[n]);
vshifth[n] = vld1q_s32(ucShifth[n]);
}
i2=0;
int j0=0,j1=0,j2=0,j3=0;
if (impp->n_segments <= 32) {
j0=impp->n_segments;
}
else if (impp->n_segments <= 64) {
j0=32;
j1=impp->n_segments-32;
}
else if (impp->n_segments <= 96) {
j0=32; j1=32;
j2=impp->n_segments-64;
}
else if (impp->n_segments <= 128) {
j0=32; j1=32; j2=32;
j3=impp->n_segments-96;
}
uint32x4_t *ccp,cc0,cc1,cc2,cc3,cc4,cc5,cc6,cc7;
for (int i=0; i < (block_length>>5); i++,i2+=8) {
in = vdupq_n_u32(((uint32_t*)input[0])[i]);
cc0 = vshlq_u32(vandq_u32(in,vmasksa),vshifta[0]);
cc1 = vshlq_u32(vandq_u32(in,vmasksb),vshiftb[0]);
cc2 = vshlq_u32(vandq_u32(in,vmasksc),vshiftc[0]);
cc3 = vshlq_u32(vandq_u32(in,vmasksd),vshiftd[0]);
cc4 = vshlq_u32(vandq_u32(in,vmaskse),vshifte[0]);
cc5 = vshlq_u32(vandq_u32(in,vmasksf),vshiftf[0]);
cc6 = vshlq_u32(vandq_u32(in,vmasksg),vshiftg[0]);
cc7 = vshlq_u32(vandq_u32(in,vmasksh),vshifth[0]);
for (int j = 1; j < j0; j++) {
in = vdupq_n_u32(((uint32_t*)input[j])[i]);
cc0 = vorrq_u32(cc0,vshlq_u32(vandq_u32(in,vmasksa),vshifta[j]));
cc1 = vorrq_u32(cc1,vshlq_u32(vandq_u32(in,vmasksb),vshiftb[j]));
cc2 = vorrq_u32(cc2,vshlq_u32(vandq_u32(in,vmasksc),vshiftc[j]));
cc3 = vorrq_u32(cc3,vshlq_u32(vandq_u32(in,vmasksd),vshiftd[j]));
cc4 = vorrq_u32(cc4,vshlq_u32(vandq_u32(in,vmaskse),vshifte[j]));
cc5 = vorrq_u32(cc5,vshlq_u32(vandq_u32(in,vmasksf),vshiftf[j]));
cc6 = vorrq_u32(cc6,vshlq_u32(vandq_u32(in,vmasksg),vshiftg[j]));
cc7 = vorrq_u32(cc7,vshlq_u32(vandq_u32(in,vmasksh),vshifth[j]));
}
ccp=&((uint32x4_t *)cc_host[0])[i2];
ccp[0] = cc0;
ccp[1] = cc1;
ccp[2] = cc2;
ccp[3] = cc3;
ccp[4] = cc4;
ccp[5] = cc5;
ccp[6] = cc6;
ccp[7] = cc7;
if (j1>0) {
in = vdupq_n_u32(((uint32_t*)input[32])[i]);
cc0 = vshlq_u32(vandq_u32(in,vmasksa),vshifta[0]);
cc1 = vshlq_u32(vandq_u32(in,vmasksb),vshiftb[0]);
cc2 = vshlq_u32(vandq_u32(in,vmasksc),vshiftc[0]);
cc3 = vshlq_u32(vandq_u32(in,vmasksd),vshiftd[0]);
cc4 = vshlq_u32(vandq_u32(in,vmaskse),vshifte[0]);
cc5 = vshlq_u32(vandq_u32(in,vmasksf),vshiftf[0]);
cc6 = vshlq_u32(vandq_u32(in,vmasksg),vshiftg[0]);
cc7 = vshlq_u32(vandq_u32(in,vmasksh),vshifth[0]);
for (int j = 1; j < j1; j++) {
in = vdupq_n_u32(((uint32_t*)input[32+j])[i]);
cc0 = vorrq_u32(cc0,vshlq_u32(vandq_u32(in,vmasksa),vshifta[j]));
cc1 = vorrq_u32(cc1,vshlq_u32(vandq_u32(in,vmasksb),vshiftb[j]));
cc2 = vorrq_u32(cc2,vshlq_u32(vandq_u32(in,vmasksc),vshiftc[j]));
cc3 = vorrq_u32(cc3,vshlq_u32(vandq_u32(in,vmasksd),vshiftd[j]));
cc4 = vorrq_u32(cc4,vshlq_u32(vandq_u32(in,vmaskse),vshifte[j]));
cc5 = vorrq_u32(cc5,vshlq_u32(vandq_u32(in,vmasksf),vshiftf[j]));
cc6 = vorrq_u32(cc6,vshlq_u32(vandq_u32(in,vmasksg),vshiftg[j]));
cc7 = vorrq_u32(cc7,vshlq_u32(vandq_u32(in,vmasksh),vshifth[j]));
}
ccp=&((uint32x4_t *)cc_host[1])[i2];
ccp[0] = cc0;
ccp[1] = cc1;
ccp[2] = cc2;
ccp[3] = cc3;
ccp[4] = cc4;
ccp[5] = cc5;
ccp[6] = cc6;
ccp[7] = cc7;
}
if (j2>0) {
in = vdupq_n_u32(((uint32_t*)input[64])[i]);
cc0 = vshlq_u32(vandq_u32(in,vmasksa),vshifta[0]);
cc1 = vshlq_u32(vandq_u32(in,vmasksb),vshiftb[0]);
cc2 = vshlq_u32(vandq_u32(in,vmasksc),vshiftc[0]);
cc3 = vshlq_u32(vandq_u32(in,vmasksd),vshiftd[0]);
cc4 = vshlq_u32(vandq_u32(in,vmaskse),vshifte[0]);
cc5 = vshlq_u32(vandq_u32(in,vmasksf),vshiftf[0]);
cc6 = vshlq_u32(vandq_u32(in,vmasksg),vshiftg[0]);
cc7 = vshlq_u32(vandq_u32(in,vmasksh),vshifth[0]);
for (int j = 1; j < j2; j++) {
in = vdupq_n_u32(((uint32_t*)input[64+j])[i]);
cc0 = vorrq_u32(cc0,vshlq_u32(vandq_u32(in,vmasksa),vshifta[j]));
cc1 = vorrq_u32(cc1,vshlq_u32(vandq_u32(in,vmasksb),vshiftb[j]));
cc2 = vorrq_u32(cc2,vshlq_u32(vandq_u32(in,vmasksc),vshiftc[j]));
cc3 = vorrq_u32(cc3,vshlq_u32(vandq_u32(in,vmasksd),vshiftd[j]));
cc4 = vorrq_u32(cc4,vshlq_u32(vandq_u32(in,vmaskse),vshifte[j]));
cc5 = vorrq_u32(cc5,vshlq_u32(vandq_u32(in,vmasksf),vshiftf[j]));
cc6 = vorrq_u32(cc6,vshlq_u32(vandq_u32(in,vmasksg),vshiftg[j]));
cc7 = vorrq_u32(cc7,vshlq_u32(vandq_u32(in,vmasksh),vshifth[j]));
}
ccp=&((uint32x4_t *)cc_host[2])[i2];
ccp[0] = cc0;
ccp[1] = cc1;
ccp[2] = cc2;
ccp[3] = cc3;
ccp[4] = cc4;
ccp[5] = cc5;
ccp[6] = cc6;
ccp[7] = cc7;
}
if (j3>0) {
in = vdupq_n_u32(((uint32_t*)input[96])[i]);
cc0 = vshlq_u32(vandq_u32(in,vmasksa),vshifta[0]);
cc1 = vshlq_u32(vandq_u32(in,vmasksb),vshiftb[0]);
cc2 = vshlq_u32(vandq_u32(in,vmasksc),vshiftc[0]);
cc3 = vshlq_u32(vandq_u32(in,vmasksd),vshiftd[0]);
cc4 = vshlq_u32(vandq_u32(in,vmaskse),vshifte[0]);
cc5 = vshlq_u32(vandq_u32(in,vmasksf),vshiftf[0]);
cc6 = vshlq_u32(vandq_u32(in,vmasksg),vshiftg[0]);
cc7 = vshlq_u32(vandq_u32(in,vmasksh),vshifth[0]);
for (int j = 1; j < j3; j++) {
in = vdupq_n_u32(((uint32_t*)input[96+j])[i]);
cc0 = vorrq_u32(cc0,vshlq_u32(vandq_u32(in,vmasksa),vshifta[j]));
cc1 = vorrq_u32(cc1,vshlq_u32(vandq_u32(in,vmasksb),vshiftb[j]));
cc2 = vorrq_u32(cc2,vshlq_u32(vandq_u32(in,vmasksc),vshiftc[j]));
cc3 = vorrq_u32(cc3,vshlq_u32(vandq_u32(in,vmasksd),vshiftd[j]));
cc4 = vorrq_u32(cc4,vshlq_u32(vandq_u32(in,vmaskse),vshifte[j]));
cc5 = vorrq_u32(cc5,vshlq_u32(vandq_u32(in,vmasksf),vshiftf[j]));
cc6 = vorrq_u32(cc6,vshlq_u32(vandq_u32(in,vmasksg),vshiftg[j]));
cc7 = vorrq_u32(cc7,vshlq_u32(vandq_u32(in,vmasksh),vshifth[j]));
}
ccp=&((uint32x4_t *)cc_host[3])[i2];
ccp[0] = cc0;
ccp[1] = cc1;
ccp[2] = cc2;
ccp[3] = cc3;
ccp[4] = cc4;
ccp[5] = cc5;
ccp[6] = cc6;
ccp[7] = cc7;
}
}
#endif
#endif
#endif
if(impp->tinput != NULL) stop_meas(impp->tinput);
if(impp->tinput_memcpy != NULL) start_meas(impp->tinput_memcpy);
#ifdef USE_GPU_CIRCCOPY
circcopy_c(cc_dev,c_dev,n_inputs);
#else
#ifdef USE_CUDA_MEMCPY
for (int s=0;s<n_inputs;s++) {
for (int i1 = 0; i1 < ncols; i1++) {
cudaError_t err = cudaMemcpy(&c_devh[s][2 * i1 * Zc], &cc_devh[s][i1 * Zc], Zc * sizeof(uint32_t),cudaMemcpyDeviceToDevice);
AssertFatal(err == cudaSuccess, "1st memcpy cc_devh[%d] -> c_devh[%d] %p CUDA Error: %s\n", s, s, c_devh[s],cudaGetErrorString(err));
err = cudaMemcpy(&c_devh[s][(2 * i1 + 1) * Zc], &cc_devh[s][i1 * Zc], Zc * sizeof(uint32_t),cudaMemcpyDeviceToDevice);
AssertFatal(err == cudaSuccess, "2nd memcpy cc_devh[%d] -> c_devh[%d] %p CUDA Error: %s\n", s, s, c_devh[s],cudaGetErrorString(err));
}
#else
for (int s=0;s<n_inputs;s++) {
for (int i1 = 0; i1 < ncols; i1++) {
memcpy(&c_host[s][2 * i1 * Zc], &cc_host[s][i1 * Zc], Zc * sizeof(uint32_t));
memcpy(&c_host[s][(2 * i1 + 1) * Zc], &cc_host[s][i1 * Zc], Zc * sizeof(uint32_t));
}
if (!pageable && !register_host) {
cudaError_t err = cudaMemcpy(c_devh[s],c_host[s],sizeof(uint32_t)*2*22*Zc,cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess, "memcpy c_host[%d] -> c_devh[%d] %p CUDA Error: %s\n", s, s, c_devh[s],cudaGetErrorString(err));
}
}
#endif
#endif
if(impp->tinput != NULL) stop_meas(impp->tinput_memcpy);
if (BG==1 && Zc==384) {
//parity check part
if(impp->tparity != NULL) start_meas(impp->tparity);
encode_parity_check_part_cuda((uint32_t**)c_dev, (uint32_t**)d_dev, BG, Zc, Kb, ncols,n_inputs);
if(impp->tparity != NULL) stop_meas(impp->tparity);
}
else {
AssertFatal(1==0,"Only BG1 Zc=384 for now\n");
}
if(impp->toutput != NULL) start_meas(impp->toutput);
for (int s=0;s<n_inputs;s++) {
if (!pageable && !register_host) {
cudaMemcpy(d_host[s],&cc_devh[s][2*Zc],sizeof(uint32_t)*(block_length-(2*Zc)),cudaMemcpyDeviceToHost);
cudaError_t err = cudaMemcpy(&d_host[s][block_length-(2*Zc)],d_devh[s]+block_length-(2*Zc),sizeof(uint32_t)*((nrows-no_punctured_columns) * Zc-removed_bit),cudaMemcpyDeviceToHost);
AssertFatal(err == cudaSuccess, "d_dev[%d] %p CUDA Error: %s\n", s, d_devh[s],cudaGetErrorString(err));
}
else {
memcpy(d_host[s],&cc_host[s][2*Zc],sizeof(uint32_t)*(block_length-(2*Zc)));
}
}
if(impp->toutput != NULL) stop_meas(impp->toutput);
return d_host;
}

View File

@@ -43,6 +43,11 @@
#include "ldpc_encode_parity_check.c"
#include "ldpc_generate_coefficient.c"
void ini_input32_luts() {
return;
}
int LDPCencoder(uint8_t **input, uint8_t *output, encoder_implemparams_t *impp)
{
//set_log(PHY, 4);
@@ -107,7 +112,6 @@ int LDPCencoder(uint8_t **input, uint8_t *output, encoder_implemparams_t *impp)
//interleave up to 8 transport-block segements at a time
unsigned int i_byte = 0;
#if defined(__AVX512F__) && defined(__AVX512BW__) && defined(__AVX512VBMI__)
const __m512i masks5[8] = { _mm512_set1_epi8(0x1), _mm512_set1_epi8(0x2),
_mm512_set1_epi8(0x4), _mm512_set1_epi8(0x8),
@@ -193,12 +197,9 @@ int LDPCencoder(uint8_t **input, uint8_t *output, encoder_implemparams_t *impp)
if(impp->tinput != NULL) stop_meas(impp->tinput);
if ((BG==1 && Zc>=176) || (BG==2 && Zc>=72)) {
// extend matrix
if(impp->tprep != NULL) start_meas(impp->tprep);
if(impp->tprep != NULL) stop_meas(impp->tprep);
//parity check part
if(impp->tparity != NULL) start_meas(impp->tparity);
encode_parity_check_part_optim(cc, dd, BG, Zc, Kb, simd_size, ncols);
encode_parity_check_part_optim(cc, dd, BG, Zc, Kb, simd_size, ncols,impp->tinput_memcpy);
if(impp->tparity != NULL) stop_meas(impp->tparity);
}
else {
@@ -207,8 +208,10 @@ int LDPCencoder(uint8_t **input, uint8_t *output, encoder_implemparams_t *impp)
return(-1);
}
}
if(impp->toutput != NULL) start_meas(impp->toutput);
memcpy(output,&cc[2*Zc],(block_length-(2*Zc)));
memcpy(output+block_length-(2*Zc),dd,((nrows-no_punctured_columns) * Zc-removed_bit));
if(impp->toutput != NULL) stop_meas(impp->toutput);
return 0;
}

View File

@@ -0,0 +1,175 @@
#include <stdio.h>
#include <stdint.h>
#include <cuda_runtime.h>
/*
__device__ const uint32_t masks[4] = {0x80,0x8000,0x800000,0x80000000};
__global__ void ldpc_input_worker(uint32_t **input,uint32_t *cc[4],int block_length,int nseg) {
int block_off = blockIdx.x*blockDim.x<<2;
int i2 = threadIdx.x<<2;
uint32_t *out=cc[blockIdx.y] + block_off + i2;
int nseg0 = (blockIdx.y << 5);
int nseg1;
if ((nseg0 + 32) <= nseg) nseg1 = nseg0+32;
else nseg1 = nseg0 + (nseg&31);
int bit_offset = i2+block_off;
int uint32_offset = bit_offset>>5;
uint32_t mask = masks[(bit_offset&31)>>3];
uint32_t mask0 = mask>>(bit_offset&7);bit_offset++;
uint32_t mask1 = mask>>(bit_offset&7);bit_offset++;
uint32_t mask2 = mask>>(bit_offset&7);bit_offset++;
uint32_t mask3 = mask>>(bit_offset&7);
uint32_t tmp,jmod;
uint32_t otmp0,otmp1,otmp2,otmp3;
if (bit_offset < block_length) {
tmp=input[nseg0][uint32_offset];
otmp0 = ((tmp&mask0) > 0);
otmp1 = ((tmp&mask1) > 0);
otmp2 = ((tmp&mask2) > 0);
otmp3 = ((tmp&mask3) > 0);
for (int j=nseg0+1;j<nseg1;j++) {
tmp=input[j][uint32_offset];
jmod = j&31;
otmp0 |= (((tmp&mask0) > 0)<<jmod);
otmp1 |= (((tmp&mask1) > 0)<<jmod);
otmp2 |= (((tmp&mask2) > 0)<<jmod);
otmp3 |= (((tmp&mask3) > 0)<<jmod);
}
out[0]=otmp0;
out[1]=otmp1;
out[2]=otmp2;
out[3]=otmp3;
}
}
*/
#define ITERATIONS 1
#define NTHREADS 384
__device__ uint32_t masks[32] = {
0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1,
0x8000,0x4000,0x2000,0x1000,0x800,0x400,0x200,0x100,
0x800000,0x400000,0x200000,0x100000,0x80000,0x40000,0x20000,0x10000,
0x80000000,0x40000000,0x20000000,0x10000000,0x8000000,0x4000000,0x2000000,0x1000000};
__global__ void ldpc_input_worker(uint32_t **input,uint32_t *cc[4],int block_length,int nseg) {
int block_off = blockIdx.x*blockDim.x*ITERATIONS;
int i2 = threadIdx.x*ITERATIONS;
uint32_t *out=cc[blockIdx.y] + block_off + i2;
int nseg0 = (blockIdx.y << 5);
int nseg1;
if ((nseg0 + 32) <= nseg) nseg1 = nseg0+32;
else nseg1 = nseg0 + (nseg&31);
int bit_offset = i2+block_off;
int uint32_offset = bit_offset>>5;
#if ITERATIONS==1
uint32_t mask0 = masks[bit_offset&31];
#else
uint32_t *mask = &masks[bit_offset&31];
uint32_t mask0 = mask[0];
#endif
#if ITERATIONS==4 || ITERATIONS==8
uint32_t mask1 = mask[1];
uint32_t mask2 = mask[2];
uint32_t mask3 = mask[3];
#endif
#if ITERATIONS==8
uint32_t mask4 = mask[4];
uint32_t mask5 = mask[5];
uint32_t mask6 = mask[6];
uint32_t mask7 = mask[7];
#endif
uint32_t tmp,jmod;
uint32_t otmp0;
#if ITERATIONS==4 || ITERATIONS==8
uint32_t otmp1,otmp2,otmp3;
#endif
#if ITERATIONS==8
uint32_t otmp4,otmp5,otmp6,otmp7;
#endif
if (bit_offset < block_length) {
tmp=input[nseg0][uint32_offset];
otmp0 = ((tmp&mask0) > 0);
#if ITERATIONS==4 || ITERATIONS==8
otmp1 = ((tmp&mask1) > 0);
otmp2 = ((tmp&mask2) > 0);
otmp3 = ((tmp&mask3) > 0);
#endif
#if ITERATIONS==8
otmp4 = ((tmp&mask4) > 0);
otmp5 = ((tmp&mask5) > 0);
otmp6 = ((tmp&mask6) > 0);
otmp7 = ((tmp&mask7) > 0);
#endif
for (int j=nseg0+1;j<nseg1;j++) {
tmp=input[j][uint32_offset];
jmod = j&31;
otmp0 |= (((tmp&mask0) > 0)<<jmod);
#if ITERATIONS==4 || ITERATIONS==8
otmp1 |= (((tmp&mask1) > 0)<<jmod);
otmp2 |= (((tmp&mask2) > 0)<<jmod);
otmp3 |= (((tmp&mask3) > 0)<<jmod);
#endif
#if ITERATIONS==8
otmp4 |= (((tmp&mask4) > 0)<<jmod);
otmp5 |= (((tmp&mask5) > 0)<<jmod);
otmp6 |= (((tmp&mask6) > 0)<<jmod);
otmp7 |= (((tmp&mask7) > 0)<<jmod);
#endif
}
out[0]=otmp0;
#if ITERATIONS==4 || ITERATIONS==8
out[1]=otmp1;
out[2]=otmp2;
out[3]=otmp3;
#endif
#if ITERATIONS==8
out[4]=otmp4;
out[5]=otmp5;
out[6]=otmp6;
out[7]=otmp7;
#endif
}
}
__global__ void circcopy_c_worker(uint32_t **cc,uint32_t **c) {
int s = blockIdx.x;
int i1 = blockIdx.y;
int i = threadIdx.x;
uint32_t tmp;
if (i<384) {
tmp = cc[s][(i1*384) + i];
c[s][2*i1*384 + i] = tmp;
c[s][(2*i1+1)*384 + i] = tmp;
}
}
extern "C" int ldpc_input(uint32_t **input,uint32_t *cc[4],int block_length,int nseg) {
int numb = block_length/(NTHREADS*ITERATIONS);
if ((block_length%(NTHREADS*ITERATIONS)) > 0) numb++;
int ns = nseg>>5;
if ((nseg&31)>0) ns++;
dim3 numblocks(numb,ns);
ldpc_input_worker<<<numblocks,NTHREADS>>>(input,cc,block_length,nseg);
cudaError_t err=cudaPeekAtLastError();
if (err!=cudaSuccess) {
printf("cuda error: %s (input %p, cc %p, block_length %d, nseg %d, numb %d, ns %d)\n",cudaGetErrorString(err),input,cc,block_length,nseg,numb,ns);
exit(-1);
}
cudaDeviceSynchronize();
return(0);
}
extern "C" int circcopy_c(uint32_t **cc,uint32_t **c,int n_inputs) {
dim3 numblocks(n_inputs,22);
circcopy_c_worker<<<numblocks,384>>>(cc,c);
cudaError_t err=cudaPeekAtLastError();
if (err!=cudaSuccess) {
printf("cuda error: %s (cc %p, c %p, n_inputs %d)\n",cudaGetErrorString(err),cc,c,n_inputs);
exit(-1);
}
cudaDeviceSynchronize();
return(0);
}

View File

@@ -29,6 +29,7 @@ typedef struct ldpc_interface_s {
LDPC_shutdownfunc_t *LDPCshutdown;
LDPC_decoderfunc_t *LDPCdecoder;
LDPC_encoderfunc_t *LDPCencoder;
LDPC_encoderfunc32_t *LDPCencoder32;
} ldpc_interface_t;
/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
@@ -37,6 +38,7 @@ int free_LDPClib(ldpc_interface_t *ldpc_interface);
LDPC_decoderfunc_t LDPCdecoder;
LDPC_encoderfunc_t LDPCencoder;
LDPC_encoderfunc32_t LDPCencoder32;
// inline functions:
#endif

View File

@@ -56,14 +56,17 @@ int load_LDPClib(char *version, ldpc_interface_t *itf)
loader_shlibfunc_t shlib_fdesc[] = {{.fname = "LDPCinit"},
{.fname = "LDPCshutdown"},
{.fname = "LDPCdecoder"},
{.fname = "LDPCencoder"}};
{.fname = "LDPCencoder"},
{.fname = "LDPCencoder32"}};
int ret;
ret = load_module_version_shlib(libname, version, shlib_fdesc, sizeofArray(shlib_fdesc), NULL);
AssertFatal((ret >= 0), "Error loading ldpc decoder");
LOG_I(NR_PHY,"loading LDPC version %s\n",version);
itf->LDPCinit = (LDPC_initfunc_t *)shlib_fdesc[0].fptr;
itf->LDPCshutdown = (LDPC_shutdownfunc_t *)shlib_fdesc[1].fptr;
itf->LDPCdecoder = (LDPC_decoderfunc_t *)shlib_fdesc[2].fptr;
itf->LDPCencoder = (LDPC_encoderfunc_t *)shlib_fdesc[3].fptr;
itf->LDPCencoder32 = (LDPC_encoderfunc32_t *)shlib_fdesc[4].fptr;
AssertFatal(itf->LDPCinit() == 0, "error starting LDPC library %s %s\n", libname, version);

View File

@@ -21,6 +21,7 @@
#include "executables/softmodem-common.h"
#include "executables/nr-softmodem-common.h"
#include "executables/nr-softmodem.h"
#include "common/utils/nr/nr_common.h"
#include "common/ran_context.h"
#include "PHY/defs_gNB.h"
@@ -107,6 +108,8 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
NR_gNB_PRACH *const prach_vars = &gNB->prach_vars;
gNB->use_gpu = use_gpu;
common_vars->analog_bf = cfg->analog_beamforming_ve.analog_bf_vendor_ext.value;
LOG_I(PHY, "L1 configured with%s analog beamforming\n", common_vars->analog_bf ? "" : "out");
if (common_vars->analog_bf) {
@@ -421,7 +424,7 @@ void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg)
LOG_D(PHY, "Allocating Transport Channel Buffers for DLSCH %d/%d\n", i, gNB->max_nb_pdsch);
msg->dlsch[i] = (NR_gNB_DLSCH_t *)malloc16(num_cw * sizeof(NR_gNB_DLSCH_t));
for (int j = 0; j < num_cw; j++) {
msg->dlsch[i][j] = new_gNB_dlsch(fp, grid_size);
msg->dlsch[i][j] = new_gNB_dlsch(fp, grid_size, gNB->use_gpu);
}
}
}
@@ -434,7 +437,7 @@ void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg)
int num_cw = NR_MAX_NB_LAYERS > 4? 2:1;
for (int i = 0; i < gNB->max_nb_pdsch; i++) {
for (int j = 0; j < num_cw; j++) {
free_gNB_dlsch(&msg->dlsch[i][j], grid_size, fp);
free_gNB_dlsch(&msg->dlsch[i][j], grid_size, fp, gNB->use_gpu);
}
free(msg->dlsch[i]);
}

View File

@@ -499,8 +499,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
pusch_pdu->scid,
Ns,
symbol);
pusch_dmrs_type_t dmrs_type = pusch_pdu->dmrs_config_type == NFAPI_NR_DMRS_TYPE1 ? pusch_dmrs_type1 : pusch_dmrs_type2;
float beta_dmrs_pusch = get_beta_dmrs_pusch(pusch_pdu->num_dmrs_cdm_grps_no_data, dmrs_type);
float beta_dmrs_pusch = get_beta_dmrs(pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type == pusch_dmrs_type2);
int16_t dmrs_scaling = (1 / beta_dmrs_pusch) * (1 << 14);
nr_pusch_dmrs_rx(gNB,
Ns,

View File

@@ -117,7 +117,8 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
unsigned short p,
unsigned char lp,
unsigned short nb_pdsch_rb,
uint8_t config_type)
uint8_t config_type,
int16_t dmrs_scaling)
{
typedef int array_of_w[2];
const array_of_w *wf = (config_type == NFAPI_NR_DMRS_TYPE1) ? wf1 : wf2;
@@ -131,6 +132,7 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) {
int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]);
output[i] = get_modulated(nr_gold_pdsch, i, w == 1);
output[i] = c16mulRealShift(output[i], dmrs_scaling, 14);
#ifdef DEBUG_PDSCH
printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb);

View File

@@ -49,7 +49,8 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
unsigned short p,
unsigned char lp,
unsigned short nb_pdsch_rb,
uint8_t config_type);
uint8_t config_type,
int16_t dmrs_scaling);
void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling);
void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params);

View File

@@ -778,9 +778,11 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
time_stats_t *dlsch_encoding_stats = &gNB->dlsch_encoding_stats;
time_stats_t *tinput = &gNB->tinput;
time_stats_t *tinput_memcpy = &gNB->tinput_memcpy;
time_stats_t *tprep = &gNB->tprep;
time_stats_t *tparity = &gNB->tparity;
time_stats_t *toutput = &gNB->toutput;
time_stats_t *tconcat = &gNB->tconcat;
time_stats_t *dlsch_rate_matching_stats = &gNB->dlsch_rate_matching_stats;
time_stats_t *dlsch_interleaving_stats = &gNB->dlsch_interleaving_stats;
time_stats_t *dlsch_segmentation_stats = &gNB->dlsch_segmentation_stats;
@@ -827,9 +829,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
}
unsigned char output[size_output >> 3] __attribute__((aligned(64)));
bzero(output, sizeof(output));
start_meas(dlsch_encoding_stats);
bzero(output, sizeof(output));
if (nr_dlsch_encoding(gNB,
msgTx,
frame,
@@ -837,15 +838,18 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
frame_parms,
output,
tinput,
tinput_memcpy,
tprep,
tparity,
toutput,
tconcat,
dlsch_rate_matching_stats,
dlsch_interleaving_stats,
dlsch_segmentation_stats)
== -1) {
return;
}
stop_meas(dlsch_encoding_stats);
unsigned char *output_ptr = output;

View File

@@ -49,12 +49,14 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms,
unsigned char *output,
time_stats_t *tinput,
time_stats_t *tinput_memcpy,
time_stats_t *tprep,
time_stats_t *tparity,
time_stats_t *toutput,
time_stats_t *dlsch_rate_matching_stats,
time_stats_t *dlsch_interleaving_stats,
time_stats_t *dlsch_segmentation_stats);
time_stats_t *dlsch_segmentation_stats,
time_stats_t *dlsch_output_stats);
void dump_pdsch_stats(FILE *fd,PHY_VARS_gNB *gNB);

View File

@@ -39,10 +39,13 @@
#include <syscall.h>
#include <openair2/UTIL/OPT/opt.h>
#ifdef ENABLE_CUDA
#include <cuda_runtime.h>
#endif
// #define DEBUG_DLSCH_CODING
// #define DEBUG_DLSCH_FREE 1
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARMS *frame_parms)
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARMS *frame_parms, int use_gpumem)
{
int max_layers = (frame_parms->nb_antennas_tx < NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * max_layers;
@@ -54,7 +57,12 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
if (harq->b) {
free16(harq->b, a_segments * 1056);
#ifdef ENABLE_CUDA
if (use_gpumem)
cudaFreeHost(harq->b);
else
#endif
free16(harq->b, a_segments * 1056);
harq->b = NULL;
}
if (harq->f) {
@@ -68,7 +76,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
free(harq->c);
}
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB, int use_gpumem)
{
int max_layers = (frame_parms->nb_antennas_tx < NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * max_layers; // number of segments to be allocated
@@ -89,16 +97,35 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
bzero(harq->b, dlsch_bytes);
harq->c = (uint8_t **)malloc16(a_segments * sizeof(uint8_t *));
#ifdef ENABLE_CUDA
uint8_t *c_devh[a_segments];
#endif
for (int r = 0; r < a_segments; r++) {
// account for filler in first segment and CRCs for multiple segment case
// [hna] 8448 is the maximum CB size in NR
// 68*348 = 68*(maximum size of Zc)
// In section 5.3.2 in 38.212, the for loop is up to N + 2*Zc (maximum size of N is 66*Zc, therefore 68*Zc)
harq->c[r] = malloc16(8448);
#ifdef ENABLE_CUDA
if (use_gpumem) {
cudaHostAlloc((void**)&harq->c[r], 8448/8, cudaHostAllocMapped);
cudaError_t err=cudaHostAlloc((void**)&harq->c[r],(8448/8)*sizeof(uint8_t),cudaHostAllocMapped);
AssertFatal(err == cudaSuccess,"CUDA Error (harq->c[%d]): %s\n", r,cudaGetErrorString(err));
err=cudaHostGetDevicePointer((void**)&c_devh[r], harq->c[r], 0);
AssertFatal(err == cudaSuccess,"CUDA Error (cudaHostGetDevicePointer) harq->c_devh[%d]: %s\n", r,cudaGetErrorString(err));
}
else
#endif
harq->c[r] = malloc16(8448/8);
AssertFatal(harq->c[r], "cannot allocate harq->c[%d]\n", r);
bzero(harq->c[r], 8448);
bzero(harq->c[r], 8448/8);
}
#ifdef ENABLE_CUDA
if (use_gpumem) {
cudaError_t err=cudaMalloc((void**)&harq->c_dev,a_segments*sizeof(uint8_t*));
err=cudaMemcpy(harq->c_dev,c_devh,a_segments*sizeof(uint8_t*),cudaMemcpyHostToDevice);
AssertFatal(err == cudaSuccess,"CUDA Error (memcpy c_devh -> input_dev): %s\n", cudaGetErrorString(err));
}
#endif
harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
AssertFatal(harq->f, "cannot allocate harq->f\n");
bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
@@ -113,9 +140,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms,
unsigned char *output,
time_stats_t *tinput,
time_stats_t *tinput_memcpy,
time_stats_t *tprep,
time_stats_t *tparity,
time_stats_t *toutput,
time_stats_t *tconcat,
time_stats_t *dlsch_rate_matching_stats,
time_stats_t *dlsch_interleaving_stats,
time_stats_t *dlsch_segmentation_stats)
@@ -129,10 +158,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
.nb_TBs = msgTx->num_pdsch_slot,
.threadPool = &gNB->threadPool,
.tinput = tinput,
.tinput_memcpy = tinput_memcpy,
.tprep = tprep,
.tparity = tparity,
.toutput = toutput,
.TBs = TBs};
.tconcat = tconcat,
.TBs = TBs,
.use_gpu = gNB->use_gpu};
int num_segments = 0;
@@ -171,6 +203,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
phy_stats->dlsch_stats.current_Qm = rel15->qamModOrder[0];
}
start_meas(dlsch_segmentation_stats);
int max_bytes = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * rel15->nrOfLayers * 1056;
int B;
if (A > NR_MAX_PDSCH_TBS) {
@@ -205,7 +238,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
TB_parameters->BG = rel15->maintenance_parms_v3.ldpcBaseGraph;
TB_parameters->Z = harq->Z;
TB_parameters->A = A;
start_meas(dlsch_segmentation_stats);
TB_parameters->Kb = nr_segmentation(harq->b,
harq->c,
B,
@@ -277,7 +309,9 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
reset_meas(&segment_parameters->ts_rate_match);
reset_meas(&segment_parameters->ts_ldpc_encode);
}
#ifdef ENABLE_CUDA
if (gNB->use_gpu) TB_parameters->c_dev = (uint8_t**)harq->c_dev;
#endif
segments_offset += TB_parameters->C;
/* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits)

View File

@@ -106,9 +106,9 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
void nr_init_pbch_interleaver(uint8_t *interleaver);
uint32_t nr_pbch_extra_byte_generation(int sfn, int n_hf, int ssb_index, int ssb_sc_offset, int Lmax);
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB);
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB,int use_gpu);
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARMS *frame_parms);
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARMS *frame_parms,int use_gpu);
/** \brief This function is the top-level entry point to PUSCH demodulation, after frequency-domain transformation and channel estimation. It performs
- RB extraction (signal and channel estimates)

View File

@@ -19,6 +19,7 @@
* contact@openairinterface.org
*/
#include "nr_common.h"
#include <string.h>
#include "SCHED_NR_UE/defs.h"
#include "nr_estimation.h"
@@ -448,12 +449,15 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
peak_estimator(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size, &prs_toa, &ch_pwr, mean_val);
// adjusting the rx_gains for channel peak power
ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(frame_params->ofdm_symbol_size);
ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(frame_params->ofdm_symbol_size);
prs_meas[rxAnt]->rsrp_dBm =
10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
prs_meas[rxAnt]->rsrp_dBm = 10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
//prs measurements
// prs measurements
prs_meas[rxAnt]->gNB_id = gNB_id;
prs_meas[rxAnt]->sfn = proc->frame_rx;
prs_meas[rxAnt]->slot = proc->nr_slot_rx;
@@ -1258,6 +1262,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short scrambling_id,
unsigned short BWPStart,
uint8_t config_type,
int n_dmrs_cdm_groups,
uint16_t rb_offset,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch,
@@ -1291,8 +1296,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
c16_t pilot[3280] __attribute__((aligned(16)));
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
float beta_dmrs_pdsch = get_beta_dmrs(n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2);
int16_t dmrs_scaling = (int16_t)((1 / beta_dmrs_pdsch) * (1 << 14));
const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, scrambling_id, nscid, slot, symbol);
nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type);
nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling);
delay_t delay = {0};

View File

@@ -87,6 +87,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short scrambling_id,
unsigned short BWPStart,
uint8_t config_type,
int n_dmrs_cdm_groups,
uint16_t rb_offset,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch,
@@ -151,6 +152,7 @@ float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS);
bool use_SSS,
openair0_config_t *openair0_cfg);
/** @}*/
#endif

View File

@@ -157,7 +157,9 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]);
ue->measurements.wideband_cqi_tot[gNB_id] = ue->measurements.rx_power_tot_dB[gNB_id] - ue->measurements.n0_power_tot_dB;
ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - dB_fixed(ue->measurements.n0_power_avg);
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dB (%d dBm/RE), WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
gNB_id,
@@ -235,7 +237,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier);
float rsrp_db_per_re = 10 * log10(rsrp_avg);
openair0_config_t *cfg0 = &openair0_cfg[0];
openair0_config_t *cfg0 = &ue->openair0_cfg[0];
ue->measurements.ssb_rsrp_dBm[ssb_index] = rsrp_db_per_re + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)cfg0->rx_gain[0] - (int)cfg0->rx_gain_offset[0])
@@ -271,8 +273,8 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
const uint8_t k_length = 8;
uint8_t l_sss = (ue->symbol_offset + 2) % ue->frame_parms.symbols_per_slot;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
double rx_gain = openair0_cfg[0].rx_gain[0];
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
double rx_gain = ue->openair0_cfg[0].rx_gain[0];
double rx_gain_offset = ue->openair0_cfg[0].rx_gain_offset[0];
ue->measurements.n0_power_tot = 0;
@@ -344,7 +346,8 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS)
bool use_SSS,
openair0_config_t *openair0_cfg)
{
SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch;
uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;

View File

@@ -238,7 +238,7 @@ static int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
*rsrp = rsrp_sum/meas_count;
*rsrp_dBm = dB_fixed(*rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
#ifdef NR_CSIRS_DEBUG
LOG_I(NR_PHY, "RSRP = %i (%i dBm)\n", *rsrp, *rsrp_dBm);

View File

@@ -80,7 +80,7 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
/* compute the MMSE up to 4x4 matrices */
static void nr_dlsch_mmse(uint32_t rx_size_symbol,
unsigned char n_rx,
unsigned char n_tx, // number of layer
unsigned char nl, // number of layer
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t dl_ch_mag[][n_rx][rx_size_symbol],
c16_t dl_ch_magb[][n_rx][rx_size_symbol],
@@ -203,7 +203,7 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
uint32_t len,
unsigned short nb_rb);
static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol,
short n_tx,
short nl,
short n_rx,
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
int ***rho,
@@ -1456,7 +1456,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
int length,
uint32_t noise_var)
{
uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0);
uint32_t nb_rb_0 = (length + 11) / 12;
c16_t determ_fin[12 * nb_rb_0] __attribute__((aligned(32)));
///Allocate H^*H matrix elements and sub elements
@@ -1513,7 +1513,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
determ_fin, // determin
nb_rb_0,
fp_flag, // fixed point flag
shift - (fp_flag == 1 ? 2 : 0)); // the out put is Q15
shift - (fp_flag == 1 ? 1 : 0)); // the out put is Q15
// multiply Matrix inversion pf H_h_H by the rx signal vector
c16_t outtemp[12 * nb_rb_0] __attribute__((aligned(32)));
@@ -1531,7 +1531,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
(c16_t *)(rxdataF_comp[ctx][0] + symbol * rx_size_symbol),
outtemp,
sizeofArray(outtemp),
shift - (fp_flag == 1 ? 2 : 0));
shift - (fp_flag == 1 ? 1 : 0));
nr_a_sum_b(rxdataF_zforcing[rtx], outtemp, nb_rb_0); // a = a + b
}
#ifdef DEBUG_DLSCH_DEMOD
@@ -1582,13 +1582,9 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
dl_ch_mag128b_0[0] = mmtmpD2;
dl_ch_mag128r_0[0] = mmtmpD2;
dl_ch_mag128_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128);
dl_ch_mag128_0[0] = simde_mm_slli_epi16(dl_ch_mag128_0[0],1);
dl_ch_mag128b_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
dl_ch_mag128b_0[0] = simde_mm_slli_epi16(dl_ch_mag128b_0[0],1);
dl_ch_mag128r_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
dl_ch_mag128r_0[0] = simde_mm_slli_epi16(dl_ch_mag128r_0[0],1);
dl_ch_mag128_0[0] = simde_mm_mulhrs_epi16(dl_ch_mag128_0[0], QAM_amp128);
dl_ch_mag128b_0[0] = simde_mm_mulhrs_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
dl_ch_mag128r_0[0] = simde_mm_mulhrs_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
determ_fin_128 += 1;
dl_ch_mag128_0 += 1;

View File

@@ -518,7 +518,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
sync_params->DFN,
sync_params->slot_offset);
UE->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false);
UE->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false, UE->openair0_cfg);
UE->init_sync_frame = sync_params->remaining_frames;
result.rx_offset = sync_params->rx_offset;

View File

@@ -91,8 +91,8 @@ The function pointers are set once before calling the mapping funcion for
all symbols based on different parameters. Then the mapping is done for
each symbol by calling the function pointers.
*/
static void (*map_dmrs_ptr)(const unsigned int, const c16_t *, c16_t *);
static void (*map_data_dmrs_ptr)(const unsigned int num_cdm_no_data, const c16_t *, c16_t *);
typedef void (*map_dmrs_func_t)(const unsigned int, const c16_t *, c16_t *);
typedef void (*map_data_dmrs_func_t)(const unsigned int, const c16_t *, c16_t *);
/*
The following set of functions map dmrs and/or data REs in one RB based on
@@ -191,7 +191,9 @@ static void map_over_dc(const unsigned int right_dc,
const c16_t **ptrs,
const c16_t **dmrs,
const c16_t **data,
c16_t **out)
c16_t **out,
map_dmrs_func_t map_data_dmrs_ptr,
map_dmrs_func_t map_dmrs_ptr)
{
// if first RE is DC no need to map in this function
if (right_dc == 0)
@@ -277,7 +279,9 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
const c16_t *dmrs_seq,
const c16_t *ptrs_seq,
const c16_t **data,
c16_t *out)
c16_t *out,
map_dmrs_func_t map_dmrs_ptr,
map_data_dmrs_func_t map_data_dmrs_ptr)
{
const unsigned int abs_start_rb = p.bwp_start + p.start_rb;
const unsigned int start_sc = (p.first_sc_offset + abs_start_rb * NR_NB_SC_PER_RB) % p.fft_size;
@@ -297,7 +301,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
// map RB at DC
if (rb_over_dc) {
// if DC is in middle of RB, the following function handles it.
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, NULL, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, NULL, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
// else just move the pointer and following function will map the rb
@@ -315,7 +319,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
for (unsigned int rb = 0; rb < p.nb_rb; rb++) {
if (rb == dc_rb) {
if (rb_over_dc) {
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, &data_tmp, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
out_tmp -= p.fft_size;
@@ -339,7 +343,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
if (rb < non_ptrs_rb || ptrs_idx_rb % p.K_ptrs) {
if (rb == dc_rb) {
if (rb_over_dc) {
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
out_tmp -= p.fft_size;
@@ -351,7 +355,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
} else {
if (rb == dc_rb) {
if (rb_over_dc) {
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, ptrs_idx_re, &p_mod_ptrs, NULL, &data_tmp, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, ptrs_idx_re, &p_mod_ptrs, NULL, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
out_tmp -= p.fft_size;
@@ -370,7 +374,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
for (unsigned int rb = 0; rb < p.nb_rb; rb++) {
if (rb == dc_rb) {
if (rb_over_dc) {
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
out_tmp -= p.fft_size;
@@ -396,7 +400,7 @@ static void dmrs_amp_mult(const uint32_t dmrs_port,
const pusch_dmrs_type_t dmrs_type,
const unsigned int num_cdm_groups_no_data)
{
float beta_dmrs_pusch = get_beta_dmrs_pusch(num_cdm_groups_no_data, dmrs_type);
float beta_dmrs_pusch = get_beta_dmrs(num_cdm_groups_no_data, dmrs_type == pusch_dmrs_type2);
/* short array that hold amplitude for k_prime = 0 and k_prime = 1 */
int32_t alpha_dmrs[2] __attribute((aligned(16)));
for (int_fast8_t i = 0; i < sizeofArray(alpha_dmrs); i++) {
@@ -420,6 +424,8 @@ static void map_symbols(const nr_phy_pxsch_params_t p,
c16_t *out)
{
// asign the function pointers
map_dmrs_func_t map_dmrs_ptr = NULL;
map_data_dmrs_func_t map_data_dmrs_ptr = NULL;
if (p.dmrs_type == pusch_dmrs_type1) {
map_dmrs_ptr = map_dmrs_type1_cdm1_rb;
map_data_dmrs_ptr = (p.num_cdm_no_data == 1) ? map_data_dmrs_type1_cdm1_rb : NULL;
@@ -460,7 +466,9 @@ static void map_symbols(const nr_phy_pxsch_params_t p,
mod_dmrs_amp,
mod_ptrs_amp,
&cur_data, // increments every symbol
out + l * p.fft_size);
out + l * p.fft_size,
map_dmrs_ptr,
map_data_dmrs_ptr);
}
}

View File

@@ -828,6 +828,47 @@ static inline void rotate_cpx_vector(const c16_t *const x, const c16_t *const al
// log2_amp - increase the output amplitude by a factor 2^log2_amp (default is 0)
// WARNING: log2_amp>0 can cause overflow!!
#ifdef __aarch64__
if (output_shift == 15) { // allows specific NEON instruction
int16x8_t ar = (int16x8_t)vdupq_n_s16(alpha->r);
int16x8_t ai = (int16x8_t)vdupq_n_s16(alpha->i);
int16x8_t *y_128 = (int16x8_t *)y;
int16x8_t *x_128 = (int16x8_t *)x;
for (uint32_t i = 0; i < (N >> 2); i++) {
// Split interleaved -> separate real/imag
int16x8_t br = vuzp1q_s16(x_128[i], x_128[i]);
int16x8_t bi = vuzp2q_s16(x_128[i], x_128[i]);
// Start with the two “diagonal” products using high-half, doubling, sat:
// x = round( (2*ar*br) / 2^16 ), y = round( (2*ar*bi) / 2^16 )
int16x8_t real = vqdmulhq_s16(ar, br);
int16x8_t imag = vqdmulhq_s16(ar, bi);
// real -= round( (2*ai*bi) / 2^16 )
real = vqrdmlshq_s16(real, ai, bi);
// imag += round( (2*ai*br) / 2^16 )
imag = vqrdmlahq_s16(imag, ai, br);
// Re-interleave [real, imag]
int16x8x2_t z = vzipq_s16(real, imag);
y_128[i] = z.val[0];
/*
printf("y : (%d %d) (%d %d) (%d %d) (%d %d)\n",
vgetq_lane_s16(y_128[i],0),
vgetq_lane_s16(y_128[i],1),
vgetq_lane_s16(y_128[i],2),
vgetq_lane_s16(y_128[i],3),
vgetq_lane_s16(y_128[i],4),
vgetq_lane_s16(y_128[i],5),
vgetq_lane_s16(y_128[i],6),
vgetq_lane_s16(y_128[i],7));*/
}
} else {
#endif
uint32_t i; // loop counter
simd_q15_t *y_128, alpha_128;
@@ -859,7 +900,10 @@ static inline void rotate_cpx_vector(const c16_t *const x, const c16_t *const al
shift));
// print_ints("y_128[0]=", &y_128[0]);
}
#if defined(__x86__) || defined(__x86_64__)
#ifdef __aarch64__
}
#endif //__aarch64__
#if defined(__x86_64__) || defined(__i386__)
}
#endif
}

View File

@@ -62,6 +62,9 @@ typedef struct {
uint8_t *b;
/// Pointers to transport block segments
uint8_t **c;
#ifdef ENABLE_CUDA
uint8_t *c_dev;
#endif
/// Frame where current HARQ round was sent
uint32_t frame;
/// Interleaver outputs
@@ -504,9 +507,11 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t dlsch_resource_mapping_stats;
time_stats_t dlsch_precoding_stats;
time_stats_t tinput;
time_stats_t tinput_memcpy;
time_stats_t tprep;
time_stats_t tparity;
time_stats_t toutput;
time_stats_t tconcat;
time_stats_t dlsch_rate_matching_stats;
time_stats_t dlsch_interleaving_stats;
@@ -556,6 +561,7 @@ typedef struct PHY_VARS_gNB_s {
int L1_tx_thread_core;
struct processingData_L1tx *msgDataTx;
void *scopeData;
int use_gpu;
} PHY_VARS_gNB;
struct puschSymbolReqId {

View File

@@ -336,6 +336,7 @@ typedef struct {
/// Top-level PHY Data Structure for UE
typedef struct PHY_VARS_NR_UE_s {
openair0_config_t openair0_cfg[MAX_CARDS];
/// \brief Module ID indicator for this instance
uint8_t Mod_id;
/// \brief Component carrier ID for this PHY instance

View File

@@ -553,6 +553,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
dlschCfg->dlDmrsScramblingId,
dlschCfg->BWPStart,
dlschCfg->dmrsConfigType,
dlschCfg->n_dmrs_cdm_groups,
dlschCfg->rb_offset,
ue->frame_parms.first_carrier_offset + (dlschCfg->BWPStart + dlschCfg->start_rb) * 12,
dlschCfg->number_rbs,

View File

@@ -227,7 +227,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
sym = (sym == 0) ? 5 : sym + 1;
}
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false);
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false, ue->openair0_cfg);
LOG_D(NR_PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);

View File

@@ -516,7 +516,7 @@ int main(int argc, char **argv)
bzero(output, sizeof(output));
if (input_fd == NULL) {
msgDataTx.num_pdsch_slot = 1;
nr_dlsch_encoding(gNB, &msgDataTx, frame, slot, frame_parms, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
nr_dlsch_encoding(gNB, &msgDataTx, frame, slot, frame_parms, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
}
for (SNR = snr0; SNR < snr1 && !stop; SNR += snr_step) {

View File

@@ -182,6 +182,7 @@ extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of dlsim */
int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1, g_pmi = 0;
void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
{
NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.connected_ue_list[0];
@@ -296,8 +297,9 @@ void validate_input_pmi(nfapi_nr_config_request_scf_t *gNB_config,
num_antenna_ports, pmi_pdu->num_ant_ports, pmi);
}
configmodule_interface_t *uniqCfg = NULL;
extern uint32_t use_gpu;
int main(int argc, char **argv)
{
stop = false;
@@ -393,7 +395,7 @@ int main(int argc, char **argv)
FILE *scg_fd=NULL;
while ((c = getopt(argc, argv, "--:O:f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:H:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:")) != -1) {
while ((c = getopt(argc, argv, "--:O:f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:H:M:N:F:GR:d:PQI:L:a:b:e:m:w:T:U:q:X:Y:Z:")) != -1) {
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
@@ -513,7 +515,10 @@ int main(int argc, char **argv)
print_perf=1;
cpu_meas_enabled = 1;
break;
case 'Q':
use_gpu=1;
break;
case 'I':
max_ldpc_iterations = atoi(optarg);
break;
@@ -924,8 +929,7 @@ printf("%d\n", slot);
init_nr_ue_transport(UE);
nr_l2_init_ue(1);
UE_mac = get_mac_inst(0);
UE_mac = nr_l2_init_ue(0);
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
UE->if_inst = nr_ue_if_module_init(0);
@@ -1033,12 +1037,15 @@ printf("%d\n", slot);
reset_meas(&gNB->dlsch_rate_matching_stats);
reset_meas(&gNB->dlsch_segmentation_stats);
reset_meas(&gNB->dlsch_modulation_stats);
reset_meas(&gNB->dlsch_precoding_stats);
reset_meas(&gNB->dlsch_encoding_stats);
reset_meas(&gNB->dci_generation_stats);
reset_meas(&gNB->tinput);
reset_meas(&gNB->tinput_memcpy);
reset_meas(&gNB->tprep);
reset_meas(&gNB->tparity);
reset_meas(&gNB->toutput);
reset_meas(&gNB->tconcat);
reset_meas(&gNB->phase_comp_stats);
uint32_t errors_scrambling[16] = {0};
@@ -1337,12 +1344,19 @@ printf("%d\n", slot);
printStatIndent2(&gNB->dci_generation_stats, "DCI encoding time");
printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");
printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time");
gNB->tinput.trials = gNB->dlsch_encoding_stats.trials;
printStatIndent3(&gNB->tinput,"DLSCH LDPC input processing time");
printStatIndent3(&gNB->tprep,"DLSCH LDPC input preparation time");
gNB->tinput_memcpy.trials = gNB->dlsch_encoding_stats.trials;
printStatIndent3(&gNB->tinput_memcpy,"DLSCH LDPC input memcpy time");
gNB->tparity.trials = gNB->dlsch_encoding_stats.trials;
printStatIndent3(&gNB->tparity,"DLSCH LDPC parity generation time");
gNB->toutput.trials = gNB->dlsch_encoding_stats.trials;
printStatIndent3(&gNB->toutput,"DLSCH LDPC output generation time");
gNB->dlsch_rate_matching_stats.trials = gNB->dlsch_encoding_stats.trials;
printStatIndent3(&gNB->dlsch_rate_matching_stats,"DLSCH Rate Matching time");
gNB->dlsch_interleaving_stats.trials = gNB->dlsch_encoding_stats.trials;
printStatIndent3(&gNB->dlsch_interleaving_stats, "DLSCH Interleaving time");
printStatIndent3(&gNB->tconcat, "DLSCH Segment Concatenation time");
printStatIndent2(&gNB->dlsch_modulation_stats,"DLSCH modulation time");
printStatIndent2(&gNB->dlsch_scrambling_stats, "DLSCH scrambling time");
printStatIndent2(&gNB->dlsch_precoding_stats,"DLSCH Mapping/Precoding time");

View File

@@ -32,6 +32,7 @@
// Define signal handler to attempt graceful termination
bool stop = false;
uint32_t use_gpu=0;
void sigint_handler(int arg)
{

Some files were not shown because too many files have changed in this diff Show More