Compare commits

...

103 Commits

Author SHA1 Message Date
Raymond Knopp
59404cc5e8 removed buffer read overflow (harmless but flagged by ASAN) 2025-01-31 21:37:52 +01:00
Raymond Knopp
73fa7d416a Merge remote-tracking branch 'origin/ldpc_enc_avx512' into rk_integration1224 2025-01-30 20:41:37 +01:00
Raymond Knopp
59123ce85d aarch64 testing and corrections 2025-01-30 09:27:26 +00:00
Raymond Knopp
4b3c3c2dac fixes after testing with AVX2 2025-01-30 06:21:40 +01:00
Raymond Knopp
c380dc4fce bit-packing done in nrLDPC_coding_segment_encoder.c now instead of nr_scrambling. Interestingly, it improves performance significantly too. Tested for AVX512 only for now 2025-01-29 22:32:03 +01:00
Raymond Knopp
40873d264d small fix after resolving conflicts during merge with develop 2025-01-21 21:15:39 +01:00
Raymond Knopp
d8291147b2 Merge remote-tracking branch 'origin/develop' into ldpc_enc_avx512 2025-01-21 15:54:09 +01:00
Raymond Knopp
5dc22f219a fix after ASAN test in CI (stack array size) 2025-01-03 17:12:11 +01:00
Raymond Knopp
f1a4e69386 better 128-bit implementation in rotate_cpx_vector 2025-01-03 08:14:07 +00:00
Raymond Knopp
367675c29b Merge branch 'ldpc_enc_avx512' into rk_integration1224 2025-01-03 08:17:02 +01:00
Raymond Knopp
540da76f1c Merge branch 'ldpc_enc_avx512' of https://gitlab.eurecom.fr/oai/openairinterface5g into ldpc_enc_avx512 2025-01-03 08:07:44 +01:00
Raymond Knopp
4340c229b1 logging 2025-01-03 07:50:48 +01:00
Raymond Knopp
5d2c881b91 3GPP Rate-matching/interleaving on 8-segment blocks, deinterleaving at output of multi-segment processing 2025-01-03 06:37:36 +00:00
Raymond Knopp
ad0d02f922 Merge branch 'ldpc_enc_avx512' into rk_integration1224 2024-12-30 07:25:42 +00:00
Raymond Knopp
a06f80e0bd fix for AVX2 in nr_ldpc_encoder_optim8segmulti.c 2024-12-29 19:06:25 +01:00
Raymond Knopp
6bb8bf62a3 neoverse-V2 fix 2024-12-29 14:54:59 +00:00
Jason
059501fa4b fixes for Neoverse selection in CMakeLists.txt 2024-12-29 14:44:21 +00:00
Raymond Knopp
c85bf0c1b6 changes to select neoverse-n1/n2 in CMakeLists.txt 2024-12-29 12:26:47 +00:00
Raymond Knopp
57677629ac modifications for aarch64 (mm_movemask_epi8 in scrambling) 2024-12-29 12:17:00 +00:00
Raymond Knopp
ead75c20fb changes for neoverse-v2 2024-12-29 09:50:02 +00:00
Raymond Knopp
58ea54f842 fix tali condition for 256-QAM with 128-bit SIMD 2024-12-21 21:38:09 +01:00
Raymond Knopp
c9536b6fa0 Merge branch 'ldpc_enc_avx512' of https://gitlab.eurecom.fr/oai/openairinterface5g into ldpc_enc_avx512 2024-12-21 18:28:04 +01:00
Raymond Knopp
c84a30650d fix build on aarch64 2024-12-21 17:26:50 +00:00
Raymond Knopp
b7f664dcfa fix after rebase 2024-12-18 09:34:37 +01:00
Raymond Knopp
e2cde7e679 Merge remote-tracking branch 'origin/develop' into ldpc_enc_avx512 2024-12-17 22:46:02 +01:00
Raymond Knopp
dd33d2af0f alignment issues in new rate-matching implementation in CI (with ASAN UBsan) 2024-12-17 18:04:02 +01:00
Raymond Knopp
4b76076d23 __AVX512BW__ -> __AVX512VBMI__ in nr_rate_matching.c 2024-12-16 17:04:28 +01:00
Raymond Knopp
018c79017f some AVX512F -> AVX512BW for permutex2var 2024-12-16 15:36:25 +01:00
Raymond Knopp
654c56b4c8 put back AVX512 in ldpc_encode_parity 2024-12-16 10:20:13 +01:00
Raymond Knopp
37421b91e9 removed used of AVX512 in ldpc_encode_parity 2024-12-16 09:52:00 +01:00
Raymond Knopp
c4bf2d5c1a timing measuremens for interleaving/rate matching 2024-12-16 01:29:04 +01:00
Raymond Knopp
cb465b4d56 AVX512 modifications for LDPC encoding: interleaving, ZC384 BG1, output formatting for encoder, segmentation (memcpy) 2024-12-16 01:09:38 +01:00
Raymond Knopp
966325c5b0 Merge branch 'resource_mapping_optim' into rk_integration1224 2024-12-16 00:51:33 +01:00
Raymond Knopp
20d665cc6b Merge branch 'develop' into resource_mapping_optim 2024-12-16 00:41:25 +01:00
Raymond Knopp
ed8c668ab4 another bugfix for AVX512 2024-12-16 00:22:55 +01:00
Raymond Knopp
4d51c51fd2 bugfix for AVX512 LDPC encoder optimization 2024-12-16 00:18:02 +01:00
Raymond Knopp
e3abcc9d27 AVX512 LDPC encoder optimizations for Zc=384 BG=1 2024-12-16 00:02:47 +01:00
Raymond Knopp
2676c43173 AVX512 fix for LDPC encoder 2024-12-15 21:04:50 +01:00
Raymond Knopp
435bf0aae6 AVX512 for output processing for LDPC encoder 2024-12-15 20:38:14 +01:00
Raymond Knopp
85f7c96925 memcpy in nr_segmentation.c 2024-12-15 19:03:59 +01:00
Raymond Knopp
a0a6e78d20 intermediate commit 3 2024-12-15 18:59:14 +01:00
Raymond Knopp
54cb5c0a93 intermediate commit 2 2024-12-15 18:41:46 +01:00
Raymond Knopp
e2ee18d92e intermediate commit 2024-12-15 18:16:52 +01:00
Raymond Knopp
ede36f272c simd optimizations for LDPC interleaving 2024-12-15 18:03:50 +01:00
Raymond Knopp
baff396b59 testing with "gather" 2024-12-04 14:48:14 +01:00
Raymond Knopp
f9799c4991 corrections for 4-layer transmission (CI tests) 2024-12-01 23:49:05 +01:00
Jason
13559a8144 fix for unaligned reads with aarch64 2024-12-01 20:59:52 +00:00
Jason
0ed7b9165e unaligned reads in nr_dlsch.c for aarch64 2024-12-01 20:57:35 +00:00
Raymond Knopp
3999e1f292 fix for 256-bit unaligned reads in nr_dlsch.c 2024-12-01 21:03:17 +01:00
Raymond Knopp
ec615c8435 unaligned reads in tx_layers array in resource mapping 2024-12-01 20:28:13 +01:00
Raymond Knopp
1e68a0ff0c fixed issues with new resource mapping with PTRS formats 2024-12-01 18:19:31 +01:00
Raymond Knopp
99182533e8 check for alignment in nr_dlsch.c 2024-12-01 10:13:19 +01:00
Raymond Knopp
149e53ce05 removal of "clang" warning 2024-11-28 11:27:35 +01:00
Raymond Knopp
9f94daa251 Merge branch 'resource_mapping_optim' of https://gitlab.eurecom.fr/oai/openairinterface5g into resource_mapping_optim 2024-11-28 09:17:34 +01:00
Raymond Knopp
5285267770 _mmX_xor_siY(a,a) -> _mmX_setzero_siY() to avoid warnings with clang 2024-11-28 09:16:34 +01:00
Jason
03a18d24aa yet another error, this type aarch64. hopefully the last 2024-11-27 19:53:33 +00:00
Raymond Knopp
64393a9d2d Merge branch 'resource_mapping_optim' of https://gitlab.eurecom.fr/oai/openairinterface5g into resource_mapping_optim 2024-11-27 19:45:00 +01:00
Raymond Knopp
9c10743748 avx2 build fix 2024-11-27 19:44:44 +01:00
Jason
9248a80d03 fixed for aarch64 build 2024-11-27 15:46:45 +00:00
Raymond Knopp
456e80f4ca compilation issues for multi-platforms 2024-11-27 15:18:40 +01:00
Raymond Knopp
cc8450628d removal of warning 2024-11-27 14:30:39 +01:00
Raymond Knopp
b44bd9319e removed incomplete optimization for LDPC encoder for AARCH64 2024-11-26 14:42:45 +01:00
Raymond Knopp
06d34836d0 Merge branch 'resource_mapping_optim' of https://gitlab.eurecom.fr/oai/openairinterface5g into resource_mapping_optim 2024-11-26 14:29:56 +01:00
Raymond Knopp
74225f2d88 fixes for ARM 2024-11-26 14:29:32 +01:00
Jason
0e70590958 fixes for ARM 2024-11-25 21:33:26 +00:00
Raymond Knopp
fd1276c535 clang-formta 2024-11-25 22:16:25 +01:00
Karim Boutiba
99f089b9af case statements on stupix 2024-11-25 21:47:50 +01:00
Raymond Knopp
ffc3ff0b57 fixed AVX512 issues 2024-11-25 21:37:15 +01:00
Raymond Knopp
166c519011 temporary 2024-11-25 19:33:21 +01:00
Raymond Knopp
41e215bc1a AVX512 additions for "resource mapping" in TX DLSCH procedures 2024-11-25 14:59:10 +01:00
Jason
7f407ee19d changes for __aarch64__ 2024-11-24 14:28:46 +00:00
Raymond Knopp
1a6c69893c Merge branch 'resource_mapping_optim' of https://gitlab.eurecom.fr/oai/openairinterface5g into resource_mapping_optim 2024-11-24 07:37:44 +01:00
Raymond Knopp
68b99dd81f commit before merge 2024-11-23 21:41:26 +01:00
Raymond Knopp
2f42628a20 bug fixes for 3-layer DL 2024-11-23 21:35:30 +01:00
Raymond Knopp
942648f628 Merge remote-tracking branch 'origin/develop' into resource_mapping_optim 2024-11-23 09:47:02 +01:00
Raymond Knopp
a163d8c609 Merge remote-tracking branch 'origin/develop' into resource_mapping_optim 2024-11-23 09:44:04 +01:00
Raymond Knopp
afe610d97c Merge branch 'resource_mapping_optim' of https://gitlab.eurecom.fr/oai/openairinterface5g into resource_mapping_optim 2024-11-23 09:18:27 +01:00
Raymond Knopp
8601a5e446 commit before merge 2024-11-23 09:18:07 +01:00
Raymond Knopp
392438cf50 bugfix for 3/4 layers 2024-11-23 09:15:16 +01:00
Raymond Knopp
ac4b540001 dmrs_offset in new mapping 2024-11-23 01:09:19 +01:00
Raymond Knopp
aee48ccaaf debugging 3 2024-11-22 23:35:37 +01:00
Raymond Knopp
7edb74ae62 debugging3 2024-11-22 23:23:43 +01:00
Raymond Knopp
771e1c674c debugging2 2024-11-22 23:22:31 +01:00
Raymond Knopp
41d7570b82 debuggin 2024-11-22 23:20:57 +01:00
Raymond Knopp
f79ca60ea4 Merge branch 'resource_mapping_optim' of https://gitlab.eurecom.fr/oai/openairinterface5g into resource_mapping_optim 2024-11-22 11:25:23 +01:00
Raymond Knopp
fd03d288f9 debugging of 3-layer resource mapping 2024-11-22 09:21:25 +01:00
Raymond Knopp
2a28e2fd82 Merge branch 'resource_mapping_optim' of https://gitlab.eurecom.fr/oai/openairinterface5g into resource_mapping_optim 2024-11-20 21:04:50 +01:00
Raymond Knopp
5f05a3bf66 merged all layers in nr_layer_mapping() instead of running each
individually
2024-11-20 15:44:54 +01:00
Raymond Knopp
84e87248dd Merge remote-tracking branch 'origin/develop' into resource_mapping_optim 2024-11-19 20:13:06 +01:00
Raymond Knopp
afd6cc6ade SIMD processing for nr_layer_mapping 2024-11-19 18:52:17 +01:00
Raymond Knopp
9a278e8d2d Merge remote-tracking branch 'origin/develop' into resource_mapping_optim 2024-11-17 23:07:20 +01:00
Karim Boutiba
29a324c37d Merge remote-tracking branch 'origin/fix-4layers-nr_dlsim' into resource_mapping_optim 2024-11-04 20:54:29 +01:00
Karim Boutiba
ed102689ed Merge remote-tracking branch 'origin/fix-4layers-nr_dlsim' into resource_mapping_optim 2024-11-04 20:53:58 +01:00
Laurent THOMAS
1a214beaa5 change the alignment of OAI mutli-dim arrays from 16 to 32 bytes 2024-11-04 16:07:26 +01:00
Laurent THOMAS
fd1a33d7f6 fix blocking bugs in command nr_dlsim -n100 -e27 -s35 -b 273 -R273 -x4 -y4 -z4
use a better complex vector multiplication function
2024-11-04 15:13:32 +01:00
Laurent THOMAS
2f65813a31 small fix of rotate vector unit test 2024-10-31 14:51:51 +01:00
Laurent THOMAS
5fc41e7681 add a optimzed complex vector multiplication function 2024-10-31 14:50:25 +01:00
Karim Boutiba
69ac466b4a resolved issue after merge with develop 2024-10-30 14:11:08 +01:00
Karim Boutiba
74adddd5b1 Merge remote-tracking branch 'origin/develop' into resource_mapping_optim 2024-10-30 12:18:39 +01:00
Karim Boutiba
10a7daede4 Merge branch 'resource_mapping_optim' of https://gitlab.eurecom.fr/oai/openairinterface5g into resource_mapping_optim 2024-10-17 07:36:03 +02:00
Raymond Knopp
3f5ff5b0ef dlsim memory allocations for 256QAM (fixes issue for large TBS) 2024-10-17 07:34:42 +02:00
Karim Boutiba
fda3db9ff3 dlsim memory allocations for 256QAM (fixes issue for large TBS) 2024-10-17 07:29:00 +02:00
Raymond Knopp
19e0d94685 testing avx2 for resource mapping 2024-10-11 11:32:07 +02:00
23 changed files with 3034 additions and 772 deletions

View File

@@ -146,9 +146,25 @@ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -DSIMDE_X86_SSSE3_NATIVE")
endif()
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mfloat-abi=hard -mfpu=neon -lgcc -lrt")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mfloat-abi=hard -mfpu=neon -lgcc -lrt")
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -lgcc -lrt")
execute_process(COMMAND
"lscpu"
OUTPUT_VARIABLE
CMAKE_NEOVERSE_INFO
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (CMAKE_NEOVERSE_INFO MATCHES "Neoverse-V1")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mcpu=neoverse-v1 -lgcc -lrt")
elseif (CMAKE_NEOVERSE_INFO MATCHES "Neoverse-V2")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mcpu=neoverse-v2 -ftree-vectorize -lgcc -lrt")
elseif (CMAKE_NEOVERSE_INFO MATCHES "Neoverse-N1")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mcpu=neoverse-n1 -lgcc -lrt")
elseif (CMAKE_NEOVERSE_INFO MATCHES "Neoverse-N2")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mcpu=neoverse-n2 -ftree-vectorize -lgcc -lrt")
else ()
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mcpu=native -lgcc -lrt")
endif()
else()
message(FATAL_ERROR "compile for CPU architecture ${CPUARCH}, CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}")
endif()

View File

@@ -66,98 +66,442 @@ static void ldpc8blocks_coding_segment(void *p)
// nrLDPC_encoder output is in "d"
// let's make this interface happy!
uint8_t tmp[8][68 * 384] __attribute__((aligned(32)));
uint8_t *d[impp->n_segments];
for (int rr = impp->macro_num * 8, i = 0; rr < impp->n_segments && rr < (impp->macro_num + 1) * 8; rr++, i++)
d[rr] = tmp[i];
uint8_t d[68 * 384]__attribute__((aligned(64)));
uint8_t *dp[2];
dp[0]=&d[0];
uint8_t *c[nrLDPC_TB_encoding_parameters->C];
unsigned int macro_segment, macro_segment_end;
macro_segment = 8*impp->macro_num;
macro_segment_end = (impp->n_segments > 8*(impp->macro_num+1)) ? 8*(impp->macro_num+1) : impp->n_segments;
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->macro_num * 8].ts_ldpc_encode);
ldpc_interface_segment.LDPCencoder(c, d, impp);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num * 8].ts_ldpc_encode);
c[r]=nrLDPC_TB_encoding_parameters->segments[r].c;
start_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num*8].ts_ldpc_encode);
ldpc_interface_segment.LDPCencoder(c, dp, impp);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num*8].ts_ldpc_encode);
// Compute where to place in output buffer that is concatenation of all segments
uint32_t r_offset = 0;
for (int i = 0; i < impp->macro_num * 8; i++)
r_offset += nrLDPC_TB_encoding_parameters->segments[i].E;
for (int rr = impp->macro_num * 8; rr < impp->n_segments && rr < (impp->macro_num + 1) * 8; rr++) {
if (impp->F > 0) {
// writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212
memset(&d[rr][impp->K - impp->F - 2 * impp->Zc], NR_NULL, impp->F);
}
if (impp->F>0) {
// writing into positions d[k-2Zc] as in clause 5.3.2 step 2) in 38.212
memset(&d[impp->K - impp->F - 2 * impp->Zc], NR_NULL, impp->F);
}
#ifdef DEBUG_LDPC_ENCODING
LOG_D(PHY, "rvidx in encoding = %d\n", rel15->rvIndex[0]);
LOG_D(PHY,"rvidx in encoding = %d\n", nrLDPC_TB_encoding_parameters->rv_index);
#endif
uint32_t E = nrLDPC_TB_encoding_parameters->segments[rr].E;
LOG_D(NR_PHY,
"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb "
const uint32_t E = nrLDPC_TB_encoding_parameters->segments[macro_segment].E;
uint32_t E2=E,E2_first_segment=macro_segment_end-macro_segment;
bool Eshift=false;
for (int s=macro_segment;s<macro_segment_end;s++)
if (nrLDPC_TB_encoding_parameters->segments[s].E != E) {
E2=nrLDPC_TB_encoding_parameters->segments[s].E;
Eshift=true;
E2_first_segment = s-macro_segment;
break;
}
LOG_D(NR_PHY,
"Rate Matching, Code segment %d...%d/%d (coded bits (G) %u, E %d, E2 %d Filler bits %d, Filler offset %d mod_order %d, nb_rb "
"%d,nrOfLayer %d)...\n",
rr,
impp->n_segments,
G,
E,
impp->F,
impp->K - impp->F - 2 * impp->Zc,
mod_order,
nb_rb,
nrLDPC_TB_encoding_parameters->nb_layers);
macro_segment,
macro_segment_end,
impp->n_segments,
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 %d...%d/%d (coded bits (G) %u, E %d, E2 %d Filler bits %d, Filler offset %d mod_order %d, nb_rb "
"%d,nrOfLayer %d)...\n",
macro_segment,
macro_segment_end,
impp->n_segments,
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 Tbslbrm = nrLDPC_TB_encoding_parameters->tbslbrm;
uint8_t e[E];
bzero(e, E);
start_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_rate_match);
uint8_t e[E]__attribute__((aligned(64)));
uint8_t f[E+64]__attribute__((aligned(64)));
uint8_t e2[E2]__attribute__((aligned(64)));
uint8_t f2[E2+64]__attribute__((aligned(64)));
bzero (e, E);
if (Eshift) bzero (e2,E2);
start_meas(&nrLDPC_TB_encoding_parameters->segments[macro_segment].ts_rate_match);
nr_rate_matching_ldpc(Tbslbrm,
impp->BG,
impp->Zc,
d,
e,
impp->n_segments,
impp->F,
impp->K - impp->F - 2 * impp->Zc,
nrLDPC_TB_encoding_parameters->rv_index,
E);
if (Eshift)
nr_rate_matching_ldpc(Tbslbrm,
impp->BG,
impp->Zc,
d[rr],
e,
d,
e2,
impp->n_segments,
impp->F,
impp->K - impp->F - 2 * impp->Zc,
nrLDPC_TB_encoding_parameters->rv_index,
E);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_rate_match);
if (impp->K - impp->F - 2 * impp->Zc > E) {
LOG_E(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);
E2);
LOG_E(NR_PHY,
"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, K %d, Filler bits %d, Filler offset %d mod_order %d, "
"nb_rb %d)...\n",
rr,
impp->n_segments,
G,
E,
impp->K,
impp->F,
impp->K - impp->F - 2 * impp->Zc,
mod_order,
nb_rb);
}
#ifdef DEBUG_LDPC_ENCODING
for (int i = 0; i < 16; i++)
printf("output ratematching e[%d]= %d r_offset %u\n", i, e[i], r_offset);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[macro_segment].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 %d...%d/%d (coded bits (G) %u, E %d, Kr %d, Filler bits %d, Filler offset %d mod_order %d, "
"nb_rb %d)...\n",
macro_segment,
macro_segment_end,
impp->n_segments,
G,
E,
impp->K,
impp->F,
impp->K - impp->F - 2 * impp->Zc,
mod_order,
nb_rb);
}
start_meas(&nrLDPC_TB_encoding_parameters->segments[macro_segment].ts_interleave);
nr_interleaving_ldpc(E,
mod_order,
e,
f);
if (Eshift)
nr_interleaving_ldpc(E2,
mod_order,
e2,
f2);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[macro_segment].ts_interleave);
if(impp->toutput != NULL) start_meas(impp->toutput);
/*
for (int i=0;i<16;i++)
for (int s=0;s<macro_segment_end-macro_segment;s++)
printf("i %d: segment %d : f[%d] %d\n",i,macro_segment+s,i,(f[i]>>s)&1);
*/
// information part and puncture columns
uint32_t Eoffset=0;
for (int s=0; s<macro_segment; s++)
Eoffset += (nrLDPC_TB_encoding_parameters->segments[s].E);
#ifdef __AVX512F__
uint64_t *output_p = (uint64_t*)impp->output;
int i=0;
__m512i bitperm[8];
uint32_t Eoffset2[8];
uint32_t Eoffset2_bit[8];
bitperm[0] = _mm512_set1_epi64(0x3830282018100800);
__m512i inc = _mm512_set1_epi8(0x1);
Eoffset2[0] = Eoffset>>6;
Eoffset2_bit[0] = Eoffset&63;
//printf("E2_first_segment %d,Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E2_first_segment,Eoffset,Eoffset2[0],Eoffset2_bit[0]);
for (int n=1;n<E2_first_segment;n++) {
bitperm[n] = _mm512_add_epi8(bitperm[n-1],inc);
Eoffset += E;
Eoffset2[n] = Eoffset>>6;
Eoffset2_bit[n] = Eoffset&63;
//printf("E %d : n %d, Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E,n,Eoffset,Eoffset2[n],Eoffset2_bit[n]);
}
if (Eshift) {
bitperm[E2_first_segment] = _mm512_add_epi8(bitperm[E2_first_segment-1],inc);
Eoffset += E;
Eoffset2[E2_first_segment] = Eoffset>>6;
Eoffset2_bit[E2_first_segment] = Eoffset &63;
//printf("E2 %d : Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E2,Eoffset,Eoffset2[E2_first_segment],Eoffset2_bit[E2_first_segment]);
}
for (int n=E2_first_segment+1;n<macro_segment_end-macro_segment;n++) {
bitperm[n] = _mm512_add_epi8(bitperm[n-1],inc);
Eoffset+=E2;
Eoffset2[n] = Eoffset>>6;
Eoffset2_bit[n] = Eoffset&63;
//printf("E2 %d (macro_segment_end %d, macro_segment %d) : n %d, Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E2,macro_segment_end,macro_segment,n,Eoffset,Eoffset2[n],Eoffset2_bit[n]);
}
int i2=0;
__m64 tmp;
for (i=0;i<E2;i+=64,i2++) {
if (i<E) {
for (int j=0; j < E2_first_segment; j++) {
#ifdef DEBUG_BIT_INTERLEAVE
printf("segment %d : qword %d, first bit %d last bit %d\n",j,
Eoffset2[j]+(i>>6),
(Eoffset2_bit[j] + i)&63,
(i<=(E-64)) ? 63 : (Eoffset2_bit[j] + E-1)&63);
if (Eoffset2_bit[j] > 0)
printf("segment %d : qword %d, first bit %d last bit %d\n",j,
1+Eoffset2[j]+(i>>6),
0,
((Eoffset2_bit[j] + i)&63) - 1);
#endif
// Note: Here and below for AVX2, we are using the 64-bit SIMD instruction
// instead of C >>/<< because when the Eoffset2_bit is 64 or 0, the <<
// and >> operations are undefined and in fact don't give "0" which is
// what we want here. The SIMD version do give 0 when the shift is 64
tmp = (__m64)_mm512_bitshuffle_epi64_mask(((__m512i *)f)[i2],bitperm[j]);
*(__m64*)(output_p + Eoffset2[j]) = _mm_or_si64(*(__m64*)(output_p + Eoffset2[j]),_mm_slli_si64(tmp,Eoffset2_bit[j]));
*(__m64*)(output_p + Eoffset2[j]+1) = _mm_or_si64(*(__m64*)(output_p + Eoffset2[j]+1),_mm_srli_si64(tmp,(64-Eoffset2_bit[j])));
#ifdef DEBUG_BIT_INTERLEAVE
if (j<=1) {
printf("pos : %d, i2 %d, j %d\n",(int)(output_p + Eoffset2[j]-(uint64_t*)impp->output),i2,j);
printf("i : %x.%x.%x.%x.%x.%x.%x.%x\n",
((uint8_t*)(output_p + Eoffset2[j]))[0],
((uint8_t*)(output_p + Eoffset2[j]))[1],
((uint8_t*)(output_p + Eoffset2[j]))[2],
((uint8_t*)(output_p + Eoffset2[j]))[3],
((uint8_t*)(output_p + Eoffset2[j]))[4],
((uint8_t*)(output_p + Eoffset2[j]))[5],
((uint8_t*)(output_p + Eoffset2[j]))[6],
((uint8_t*)(output_p + Eoffset2[j]))[7]);
printf("i+1 : %x.%x.%x.%x.%x.%x.%x.%x\n",
((uint8_t*)(output_p + Eoffset2[j]+1))[0],
((uint8_t*)(output_p + Eoffset2[j]+1))[1],
((uint8_t*)(output_p + Eoffset2[j]+1))[2],
((uint8_t*)(output_p + Eoffset2[j]+1))[3],
((uint8_t*)(output_p + Eoffset2[j]+1))[4],
((uint8_t*)(output_p + Eoffset2[j]+1))[5],
((uint8_t*)(output_p + Eoffset2[j]+1))[6],
((uint8_t*)(output_p + Eoffset2[j]+1))[7]);
printf("%x.%x.%x.%x.%x.%x.%x.%x\n",
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),0)<<(0-j))&1)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),1)<<(1-j))&2)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),2)<<(2-j))&4)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),3)<<(3-j))&8)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),4)<<(4-j))&16)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),5)<<(5-j))&32)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),6)<<(6-j))&64)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),7)<<(7-j))&128),
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),8)<<(0-j))&1)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),9)<<(1-j))&2)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),10)<<(2-j))&4)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),11)<<(3-j))&8)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),12)<<(4-j))&16)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),13)<<(5-j))&32)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),14)<<(6-j))&64)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),15)<<(7-j))&128),
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),16)<<(0-j))&1)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),17)<<(1-j))&2)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),18)<<(2-j))&4)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),19)<<(3-j))&8)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),20)<<(4-j))&16)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),21)<<(5-j))&32)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),22)<<(6-j))&64)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),23)<<(7-j))&128),
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),24)<<(0-j))&1)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),25)<<(1-j))&2)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),26)<<(2-j))&4)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),27)<<(3-j))&8)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),28)<<(4-j))&16)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),29)<<(5-j))&32)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),30)<<(6-j))&64)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],0),31)<<(7-j))&128),
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),0)<<(0-j))&1)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),1)<<(1-j))&2)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),2)<<(2-j))&4)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),3)<<(3-j))&8)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),4)<<(4-j))&16)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),5)<<(5-j))&32)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),6)<<(6-j))&64)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),7)<<(7-j))&128),
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),8)<<(0-j))&1)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),9)<<(1-j))&2)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),10)<<(2-j))&4)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),11)<<(3-j))&8)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),12)<<(4-j))&16)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),13)<<(5-j))&32)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),14)<<(6-j))&64)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),15)<<(7-j))&128),
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),16)<<(0-j))&1)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),17)<<(1-j))&2)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),18)<<(2-j))&4)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),19)<<(3-j))&8)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),20)<<(4-j))&16)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),21)<<(5-j))&32)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),22)<<(6-j))&64)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),23)<<(7-j))&128),
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),24)<<(0-j))&1)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),25)<<(1-j))&2)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),26)<<(2-j))&4)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),27)<<(3-j))&8)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),28)<<(4-j))&16)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),29)<<(5-j))&32)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),30)<<(6-j))&64)+
((_mm256_extract_epi8(_mm512_extracti32x8_epi32(((__m512i *)f)[i2],1),31)<<(7-j))&128));
}
#endif
start_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_interleave);
nr_interleaving_ldpc(E, mod_order, e, impp->output + r_offset);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_interleave);
#ifdef DEBUG_LDPC_ENCODING
for (int i = 0; i < 16; i++)
printf("output interleaving f[%d]= %d r_offset %u\n", i, impp->output[i + r_offset], r_offset);
if (r == impp->n_segments - 1)
write_output("enc_output.m", "enc", impp->output, G, 1, 4);
} //for (int j=0;
} // if (i < E)
for (int j=E2_first_segment; j < macro_segment_end-macro_segment; j++) {
#ifdef DEBUG_BIT_INTERLEAVE
printf("segment %d : qword %d, first bit %d last bit %d\n",j,
Eoffset2[j]+(i>>6),
(Eoffset2_bit[j] + i)&63,
(i<=(E-64)) ? 63 : (Eoffset2_bit[j] + E-1)&63);
if (Eoffset2_bit[j] > 0)
printf("segment %d : qword %d, first bit %d last bit %d\n",j,
1+Eoffset2[j]+(i>>6),
0,
((Eoffset2_bit[j] + i)&63) - 1);
#endif
r_offset += E;
tmp = (__m64)_mm512_bitshuffle_epi64_mask(((__m512i *)f2)[i2],bitperm[j]);
*(__m64*)(output_p + Eoffset2[j]) = _mm_or_si64(*(__m64*)(output_p + Eoffset2[j]),
_mm_slli_si64(tmp,Eoffset2_bit[j]));
*(__m64*)(output_p + Eoffset2[j]+1) = _mm_or_si64(*(__m64*)(output_p + Eoffset2[j]+1),_mm_srli_si64(tmp,(64-Eoffset2_bit[j])));
}
output_p++;
}
#elif defined(__aarch64__)
uint16_t *output_p = (uint16_t*)impp->output;
int i=0;
uint32_t Eoffset2[8];
uint32_t Eoffset2_bit[8];
Eoffset2[0] = Eoffset>>4;
Eoffset2_bit[0] = Eoffset&15;
//printf("E2_first_segment %d,Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E2_first_segment,Eoffset,Eoffset2[0],Eoffset2_bit[0]);
for (int n=1;n<E2_first_segment;n++) {
Eoffset += E;
Eoffset2[n] = Eoffset>>4;
Eoffset2_bit[n] = Eoffset&15;
//printf("E %d : n %d, Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E,n,Eoffset,Eoffset2[n],Eoffset2_bit[n]);
}
if (Eshift) {
Eoffset += E;
Eoffset2[E2_first_segment] = Eoffset>>4;
Eoffset2_bit[E2_first_segment] = Eoffset &15;
//printf("E2 %d : Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E2,Eoffset,Eoffset2[E2_first_segment],Eoffset2_bit[E2_first_segment]);
}
for (int n=E2_first_segment+1;n<macro_segment_end-macro_segment;n++) {
Eoffset+=E2;
Eoffset2[n] = Eoffset>>4;
Eoffset2_bit[n] = Eoffset&15;
//printf("E2 %d (macro_segment_end %d, macro_segment %d) : n %d, Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E2,macro_segment_end,macro_segment,n,Eoffset,Eoffset2[n],Eoffset2_bit[n]);
}
int i2=0;
const int8_t __attribute__ ((aligned (16))) ucShift[8][16] = {
{0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7}, // segment 0
{-1,0,1,2,3,4,5,6,-1,0,1,2,3,4,5,6}, // segment 1
{-2,-1,0,1,2,3,4,5,-2,-1,0,1,2,3,4,5}, // segment 2
{-3,-2,-1,0,1,2,3,4,-3,-2,-1,0,1,2,3,4}, // segment 3
{-4,-3,-2,-1,0,1,2,3,-4,-3,-2,-1,0,1,2,3}, // segment 4
{-5,-4,-3,-2,-1,0,1,2,-5,-4,-3,-2,-1,0,1,2}, // segment 5
{-6,-5,-4,-3,-2,-1,0,1,-6,-5,-4,-3,-2,-1,0,1}, // segment 6
{-7,-6,-5,-4,-3,-2,-1,0,-7,-6,-5,-4,-3,-2,-1,0}}; // segment 7
const uint8_t __attribute__ ((aligned (16))) masks[16] =
{0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};
int8x16_t vshift[8];
for (int n=0;n<8;n++) vshift[n] = vld1q_s8(ucShift[n]);
uint8x16_t vmask = vld1q_u8(masks);
int32_t tmp;
uint8x16_t cshift;
for (i=0;i<E2;i+=16,i2++) {
if (i<E) {
for (int j=0; j < E2_first_segment; j++) {
cshift = vandq_u8(vshlq_u8(((uint8x16_t*)f)[i2],vshift[j]),vmask);
tmp = (int)vaddv_u8(vget_low_u8(cshift));
tmp += (int)(vaddv_u8(vget_high_u8(cshift))<<8);
*(output_p + Eoffset2[j]) |= (uint16_t)(tmp<<Eoffset2_bit[j]);
*(output_p + Eoffset2[j]+1) |= (uint16_t)(tmp>>(16-Eoffset2_bit[j]));
}
}
for (int j=E2_first_segment; j < macro_segment_end-macro_segment; j++) {
cshift = vandq_u8(vshlq_u8(((uint8x16_t*)f2)[i2],vshift[j]),vmask);
tmp = (int)vaddv_u8(vget_low_u8(cshift));
tmp += (int)(vaddv_u8(vget_high_u8(cshift))<<8);
*(output_p + Eoffset2[j]) |= (uint16_t)(tmp<<Eoffset2_bit[j]);
*(output_p + Eoffset2[j]+1) |= (uint16_t)(tmp>>(16-Eoffset2_bit[j]));
}
output_p++;
}
#else
uint32_t *output_p = (uint32_t*)impp->output;
int i=0;
uint32_t Eoffset2[8];
uint32_t Eoffset2_bit[8];
Eoffset2[0] = Eoffset>>5;
Eoffset2_bit[0] = Eoffset&31;
//printf("E2_first_segment %d,Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E2_first_segment,Eoffset,Eoffset2[0],Eoffset2_bit[0]);
for (int n=1;n<E2_first_segment;n++) {
Eoffset += E;
Eoffset2[n] = Eoffset>>5;
Eoffset2_bit[n] = Eoffset&31;
//printf("E %d : n %d, Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E,n,Eoffset,Eoffset2[n],Eoffset2_bit[n]);
}
if (Eshift) {
Eoffset += E;
Eoffset2[E2_first_segment] = Eoffset>>5;
Eoffset2_bit[E2_first_segment] = Eoffset &31;
//printf("E2 %d : Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E2,Eoffset,Eoffset2[E2_first_segment],Eoffset2_bit[E2_first_segment]);
}
for (int n=E2_first_segment+1;n<macro_segment_end-macro_segment;n++) {
Eoffset+=E2;
Eoffset2[n] = Eoffset>>5;
Eoffset2_bit[n] = Eoffset&31;
//printf("E2 %d (macro_segment_end %d, macro_segment %d) : n %d, Eoffset %d, Eoffset2 %d, Eoffset2_bit %d\n",E2,macro_segment_end,macro_segment,n,Eoffset,Eoffset2[n],Eoffset2_bit[n]);
}
int i2=0;
int tmp;
__m64 tmp64,tmp64b,tmp64c;
for (i=0;i<E2;i+=32,i2++) {
if (i<E) {
for (int j=0; j < E2_first_segment; j++) {
// Note: Here and below, we are using the 64-bit SIMD instruction
// instead of C >>/<< because when the Eoffset2_bit is 64 or 0, the <<
// and >> operations are undefined and in fact don't give "0" which is
// what we want here. The SIMD version do give 0 when the shift is 64
tmp = _mm256_movemask_epi8(_mm256_slli_epi16(((__m256i *)f)[i2],7-j));
tmp64=_mm_set1_pi32(tmp);
tmp64b = _mm_or_si64(*(__m64*)(output_p + Eoffset2[j]),_mm_slli_pi32(tmp64,Eoffset2_bit[j]));
tmp64c = _mm_or_si64(*(__m64*)(output_p + Eoffset2[j]),_mm_srli_pi32(tmp64,(32-Eoffset2_bit[j])));
*(output_p + Eoffset2[j]) = _m_to_int(tmp64b);
*(output_p + Eoffset2[j]+1) = _m_to_int(_mm_srli_si64(tmp64c,32));
}
}
for (int j=E2_first_segment; j < macro_segment_end-macro_segment; j++) {
tmp = _mm256_movemask_epi8(_mm256_slli_epi16(((__m256i *)f2)[i2],7-j));
tmp64=_mm_set1_pi32(tmp);
tmp64b = _mm_or_si64(*(__m64*)(output_p + Eoffset2[j]),_mm_slli_pi32(tmp64,Eoffset2_bit[j]));
tmp64c = _mm_or_si64(*(__m64*)(output_p + Eoffset2[j]),_mm_srli_pi32(tmp64,(32-Eoffset2_bit[j])));
*(output_p + Eoffset2[j]) = _m_to_int(tmp64b);
*(output_p + Eoffset2[j]+1) = _m_to_int(_mm_srli_si64(tmp64c,32));
}
output_p++;
}
#endif
if(impp->toutput != NULL) stop_meas(impp->toutput);
/*
printf("E %d (mod16 %d) F %d\n",E,E&15,impp->F);
for (int i=0;i<16;i++)
for (int s=0;s<macro_segment_end-macro_segment;s++)
printf("i %d: segment %d : output[%d] %d\n",i,macro_segment+s,i,output_offset[i+s*E]);
*/
// Task running in // completed
completed_task_ans(impp->ans);
}
@@ -180,7 +524,7 @@ static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_
NR_DL_gNB_HARQ_t harq;
impp.harq = &harq;
impp.BG = nrLDPC_TB_encoding_parameters->BG;
impp.output = nrLDPC_TB_encoding_parameters->segments->output;
impp.output = nrLDPC_TB_encoding_parameters->segments->output;
impp.K = nrLDPC_TB_encoding_parameters->K;
impp.F = nrLDPC_TB_encoding_parameters->F;
@@ -205,6 +549,7 @@ static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_
int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters)
{
int 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];
size_t n_seg = (nrLDPC_TB_encoding_parameters->C / 8 + ((nrLDPC_TB_encoding_parameters->C & 7) == 0 ? 0 : 1));

View File

@@ -36,43 +36,138 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e, uint8_t *f)
memset(f, 0, E * sizeof(uint8_t));
uint8_t *e0, *e1, *e2, *e3, *e4, *e5, *e6, *e7;
uint8_t *fp;
#if 0 // def __WASAVX2__
simde__m256i tmp0,tmp1,tmp2,tmp0b,tmp1b,tmp3,tmp4,tmp5;
simde__m256i *e0_256,*e1_256,*e2_256,*e3_256,*e4_256,*e5_256,*e6_256,*e7_256;
int j,k;
#if 1 //def __WASAVX2__
#ifdef __AVX512VBMI__
__m512i tmp0,tmp1,tmp2,tmp3,tmp4,tmp5;
__m512i *e0_512,*e1_512,*e2_512,*e3_512,*e4_512,*e5_512,*e6_512,*e7_512;
__m512i *f_512=(__m512i *)f;
#else
simde__m128i tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7;
simde__m128i *e0_128,*e1_128,*e2_128,*e3_128,*e4_128,*e5_128,*e6_128,*e7_128;
simde__m256i *f_256=(simde__m256i *)f;
uint8_t *fp2;
simde__m128i *f_128=(simde__m128i *)f;
#endif
switch(Qm) {
case 2:
e0=e;
e1=e0+EQm;
e0_256=(simde__m256i *)e0;
e1_256=(simde__m256i *)e1;
for (int k=0,j=0;j<EQm>>5;j++,k+=2) {
f_256[k] = simde_mm256_unpacklo_epi8(e0_256[j],e1_256[j]);
f_256[k+1] = simde_mm256_unpackhi_epi8(e0_256[j],e1_256[j]);
#ifdef __AVX512VBMI__
e0_512=(__m512i *)e0;
e1_512=(__m512i *)e1;
__m512i p8a = _mm512_set_epi8(95,31,94,30,93,29,92,28,91,27,90,26,89,25,88,24,87,23,86,22,85,21,84,20,83,19,82,18,81,17,80,16,79,15,78,14,77,13,76,12,75,11,74,10,73,9,72,8,71,7,70,6,69,5,68,4,67,3,66,2,65,1,64,0);
__m512i p8b = _mm512_set_epi8(127,63,126,62,125,61,124,60,123,59,122,58,121,57,120,56,119,55,118,54,117,53,116,52,115,51,114,50,113,49,112,48,111,47,110,46,109,45,108,44,107,43,106,42,105,41,104,40,103,39,102,38,101,37,100,36,99,35,98,34,97,33,96,32);
__m512i e0j,e1j;
for (k=0,j=0;j<EQm>>6;j++,k+=2) {
e0j = _mm512_loadu_si512(e0_512+j);
e1j = _mm512_loadu_si512(e1_512+j);
_mm512_storeu_si512(f_512+k,_mm512_permutex2var_epi8(e0j,p8a,e1j)); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
_mm512_storeu_si512(f_512+k+1,_mm512_permutex2var_epi8(e0j,p8b,e1j));
}
if ((j<<6) != EQm) {
int k2=k<<6;
fp = &f[k2];
for (int j2=(j<<6) ; j2< EQm ; j2++) {
*fp++ = e0[j2];
*fp++ = e1[j2];
}
}
#else
e0_128=(simde__m128i *)e0;
e1_128=(simde__m128i *)e1;
simde__m128i e0j,e1j;
for (k=0,j=0;j<EQm>>4;j++,k+=2) {
e0j=simde_mm_loadu_si128(e0_128+j);
e1j=simde_mm_loadu_si128(e1_128+j);
simde_mm_storeu_si128(f_128+k,simde_mm_unpacklo_epi8(e0j,e1j));
simde_mm_storeu_si128(f_128+k+1,simde_mm_unpackhi_epi8(e0j,e1j));
}
if ((j<<4) != EQm) {
int k2=k<<4;
fp = &f[k2];
for (int j2=(j<<4) ; j2< EQm ; j2++) {
*fp++ = e0[j2];
*fp++ = e1[j2];
}
}
#endif
break;
case 4:
e0=e;
e1=e0+EQm;
e2=e1+EQm;
e3=e2+EQm;
e0_256=(simde__m256i *)e0;
e1_256=(simde__m256i *)e1;
e2_256=(simde__m256i *)e2;
e3_256=(simde__m256i *)e3;
for (int k=0,j=0;j<EQm>>5;j++,k+=4) {
tmp0 = simde_mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
tmp1 = simde_mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15)
f_256[k] = simde_mm256_unpacklo_epi8(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
f_256[k+1] = simde_mm256_unpackhi_epi8(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15)
tmp0 = simde_mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31)
tmp1 = simde_mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31)
f_256[k+2] = simde_mm256_unpacklo_epi8(tmp0,tmp1);
f_256[k+3] = simde_mm256_unpackhi_epi8(tmp0,tmp1);
#ifdef __AVX512VBMI__
e0_512=(__m512i *)e0;
e1_512=(__m512i *)e1;
e2_512=(__m512i *)e2;
e3_512=(__m512i *)e3;
p8a = _mm512_set_epi8(95,31,94,30,93,29,92,28,91,27,90,26,89,25,88,24,87,23,86,22,85,21,84,20,83,19,82,18,81,17,80,16,79,15,78,14,77,13,76,12,75,11,74,10,73,9,72,8,71,7,70,6,69,5,68,4,67,3,66,2,65,1,64,0);
p8b = _mm512_set_epi8(127,63,126,62,125,61,124,60,123,59,122,58,121,57,120,56,119,55,118,54,117,53,116,52,115,51,114,50,113,49,112,48,111,47,110,46,109,45,108,44,107,43,106,42,105,41,104,40,103,39,102,38,101,37,100,36,99,35,98,34,97,33,96,32);
__m512i p16a = _mm512_set_epi16(47,15,46,14,45,13,44,12,43,11,42,10,41,9,40,8,39,7,38,6,37,5,36,4,35,3,34,2,33,1,32,0);
__m512i p16b = _mm512_set_epi16(63,31,62,30,61,29,60,28,59,27,58,26,57,25,56,24,55,23,54,22,53,21,52,20,51,19,50,18,49,17,48,16);
__m512i p32a = _mm512_set_epi32(23,7,22,6,21,5,20,4,19,3,18,2,17,1,16,0);
__m512i p32b = _mm512_set_epi32(31,15,30,14,29,13,28,12,27,11,26,10,25,9,24,8);
__m512i e2j,e3j;
for (k=0,j=0;j<EQm>>6;j++,k+=4) {
e0j = _mm512_loadu_si512(e0_512+j);
e1j = _mm512_loadu_si512(e1_512+j);
e2j = _mm512_loadu_si512(e2_512+j);
e3j = _mm512_loadu_si512(e3_512+j);
tmp0 = _mm512_permutex2var_epi8(e0j,p8a,e1j); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
tmp1 = _mm512_permutex2var_epi8(e2j,p8a,e3j); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15)
_mm512_storeu_si512(f_512+k,_mm512_permutex2var_epi16(tmp0,p16a,tmp1)); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
_mm512_storeu_si512(f_512+k+1,_mm512_permutex2var_epi16(tmp0,p16b,tmp1));
tmp0 = _mm512_permutex2var_epi8(e0j,p8b,e1j); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
tmp1 = _mm512_permutex2var_epi8(e2j,p8b,e3j); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15)
_mm512_storeu_si512(f_512+k+2,_mm512_permutex2var_epi16(tmp0,p16a,tmp1)); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
_mm512_storeu_si512(f_512+k+3,_mm512_permutex2var_epi16(tmp0,p16b,tmp1));
}
if ((j<<6) != EQm) {
int k2=k<<6;
fp = &f[k2];
for (int j2=(j<<6) ; j2< EQm ; j2++) {
*fp++ = e0[j2];
*fp++ = e1[j2];
*fp++ = e2[j2];
*fp++ = e3[j2];
}
}
#else
e0_128=(simde__m128i *)e0;
e1_128=(simde__m128i *)e1;
e2_128=(simde__m128i *)e2;
e3_128=(simde__m128i *)e3;
simde__m128i e2j,e3j;
for (k=0,j=0;j<EQm>>4;j++,k+=4) {
e0j = simde_mm_loadu_si128(e0_128+j);
e1j = simde_mm_loadu_si128(e1_128+j);
e2j = simde_mm_loadu_si128(e2_128+j);
e3j = simde_mm_loadu_si128(e3_128+j);
tmp0 = simde_mm_unpacklo_epi8(e0j,e1j); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+7) e1(i+7)
tmp1 = simde_mm_unpacklo_epi8(e2j,e3j); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+7) e3(i+7)
simde_mm_storeu_si128(f_128+k,simde_mm_unpacklo_epi16(tmp0,tmp1)); // e0(i) e1(i) e2(i) e3(i) ... e0(i+3) e1(i+3) e2(i+3) e3(i+3)
simde_mm_storeu_si128(f_128+k+1,simde_mm_unpackhi_epi16(tmp0,tmp1)); // e0(i+4) e1(i+4) e2(i+4) e3(i+4) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
tmp0 = simde_mm_unpackhi_epi8(e0j,e1j); // e0(i+8) e1(i+8) e0(i+9) e1(i+9) .... e0(i+15) e1(i+15)
tmp1 = simde_mm_unpackhi_epi8(e2j,e3j); // e2(i+8) e3(i+9) e2(i+10) e3(i+10) .... e2(i+31) e3(i+31)
simde_mm_storeu_si128(f_128+k+2,simde_mm_unpacklo_epi16(tmp0,tmp1));
simde_mm_storeu_si128(f_128+k+3,simde_mm_unpackhi_epi16(tmp0,tmp1));
}
if ((j<<4) != EQm) {
int k2=k<<4;
fp = &f[k2];
for (int j2=(j<<4) ; j2< EQm ; j2++) {
*fp++ = e0[j2];
*fp++ = e1[j2];
*fp++ = e2[j2];
*fp++ = e3[j2];
}
}
#endif
break;
case 6:
e0=e;
@@ -81,95 +176,77 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e, uint8_t *f)
e3=e2+EQm;
e4=e3+EQm;
e5=e4+EQm;
e0_256=(simde__m256i *)e0;
e1_256=(simde__m256i *)e1;
e2_256=(simde__m256i *)e2;
e3_256=(simde__m256i *)e3;
e4_256=(simde__m256i *)e4;
e5_256=(simde__m256i *)e5;
#ifdef __AVX512VBMI__
e0_512=(__m512i *)e0;
e1_512=(__m512i *)e1;
e2_512=(__m512i *)e2;
e3_512=(__m512i *)e3;
e4_512=(__m512i *)e4;
e5_512=(__m512i *)e5;
__m512i e4j,e5j;
p8a = _mm512_set_epi8(95,31,94,30,93,29,92,28,91,27,90,26,89,25,88,24,87,23,86,22,85,21,84,20,83,19,82,18,81,17,80,16,79,15,78,14,77,13,76,12,75,11,74,10,73,9,72,8,71,7,70,6,69,5,68,4,67,3,66,2,65,1,64,0);
p8b = _mm512_set_epi8(127,63,126,62,125,61,124,60,123,59,122,58,121,57,120,56,119,55,118,54,117,53,116,52,115,51,114,50,113,49,112,48,111,47,110,46,109,45,108,44,107,43,106,42,105,41,104,40,103,39,102,38,101,37,100,36,99,35,98,34,97,33,96,32);
for (int j=0,k=0;j<EQm>>5;j++,k+=192) {
fp = f+k;
fp2 = fp+96;
p16a = _mm512_set_epi16(47,15,46,14,45,13,44,12,43,11,42,10,41,9,40,8,39,7,38,6,37,5,36,4,35,3,34,2,33,1,32,0);
p16b = _mm512_set_epi16(63,31,62,30,61,29,60,28,59,27,58,26,57,25,56,24,55,23,54,22,53,21,52,20,51,19,50,18,49,17,48,16);
tmp0 = simde_mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
tmp1 = simde_mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15)
tmp0b = simde_mm256_unpacklo_epi16(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
tmp1b = simde_mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15)
tmp0 = simde_mm256_unpacklo_epi8(e4_256[j],e5_256[j]); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+15) e5(i+15)
*((uint32_t*)fp) = simde_mm256_extract_epi32(tmp0b,0);
*((uint16_t*)(fp+4)) = simde_mm256_extract_epi16(tmp0,0);
*((uint32_t*)(fp+6)) = simde_mm256_extract_epi32(tmp0b,1);
*((uint16_t*)(fp+10)) = simde_mm256_extract_epi16(tmp0,1);
*((uint32_t*)(fp+12)) = simde_mm256_extract_epi32(tmp0b,2);
*((uint16_t*)(fp+16)) = simde_mm256_extract_epi16(tmp0,2);
*((uint32_t*)(fp+18)) = simde_mm256_extract_epi32(tmp0b,3);
*((uint16_t*)(fp+22)) = simde_mm256_extract_epi16(tmp0,3);
*((uint32_t*)(fp+24)) = simde_mm256_extract_epi32(tmp0b,4);
*((uint16_t*)(fp+26)) = simde_mm256_extract_epi16(tmp0,4);
*((uint32_t*)(fp+30)) = simde_mm256_extract_epi32(tmp0b,5);
*((uint16_t*)(fp+34)) = simde_mm256_extract_epi16(tmp0,5);
*((uint32_t*)(fp+36)) = simde_mm256_extract_epi32(tmp0,6);
*((uint16_t*)(fp+40)) = simde_mm256_extract_epi16(tmp0,6);
*((uint32_t*)(fp+42)) = simde_mm256_extract_epi32(tmp0b,7);
*((uint16_t*)(fp+46)) = simde_mm256_extract_epi16(tmp0,7);
__m512i p16c = _mm512_set_epi16(21,20,41,19,18,40,17,16,39,15,14,38,13,12,37,11,10,36,9,8,35,7,6,34,5,4,33,3,2,32,1,0);
__m512i p16d = _mm512_set_epi16(10,52,9,8,51,7,6,50,5,4,49,3,2,48,1,0,47,31,30,46,29,28,45,27,26,44,25,24,43,23,22,42);
__m512i p16d2 = _mm512_set_epi16(32+10,30,32+9,32+8,27,32+7,32+6,24,32+5,32+4,21,32+3,32+2,18,32+1,32+0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
__m512i p16e = _mm512_set_epi16(63,31,30,62,29,28,61,27,26,60,25,24,59,23,22,58,21,20,57,19,18,56,17,16,55,15,14,54,13,12,53,11);
*((uint32_t*)(fp+48)) = simde_mm256_extract_epi32(tmp1b,0);
*((uint16_t*)(fp+52)) = simde_mm256_extract_epi16(tmp0,8);
*((uint32_t*)(fp+56)) = simde_mm256_extract_epi32(tmp1b,1);
*((uint16_t*)(fp+60)) = simde_mm256_extract_epi16(tmp0,9);
*((uint32_t*)(fp+62)) = simde_mm256_extract_epi32(tmp1b,2);
*((uint16_t*)(fp+66)) = simde_mm256_extract_epi16(tmp0,10);
*((uint32_t*)(fp+68)) = simde_mm256_extract_epi32(tmp1b,3);
*((uint16_t*)(fp+72)) = simde_mm256_extract_epi16(tmp0,11);
*((uint32_t*)(fp+74)) = simde_mm256_extract_epi32(tmp1b,4);
*((uint16_t*)(fp+76)) = simde_mm256_extract_epi16(tmp0,12);
*((uint32_t*)(fp+80)) = simde_mm256_extract_epi32(tmp1b,5);
*((uint16_t*)(fp+82)) = simde_mm256_extract_epi16(tmp0,13);
*((uint32_t*)(fp+86)) = simde_mm256_extract_epi32(tmp1b,6);
*((uint16_t*)(fp+90)) = simde_mm256_extract_epi16(tmp0,14);
*((uint32_t*)(fp+92)) = simde_mm256_extract_epi32(tmp1b,7);
*((uint16_t*)(fp+94)) = simde_mm256_extract_epi16(tmp0,15);
for (j=0,k=0;j<EQm>>6;j++,k+=6) {
e0j = _mm512_loadu_si512(e0_512+j);
e1j = _mm512_loadu_si512(e1_512+j);
e2j = _mm512_loadu_si512(e2_512+j);
e3j = _mm512_loadu_si512(e3_512+j);
e4j = _mm512_loadu_si512(e4_512+j);
e5j = _mm512_loadu_si512(e5_512+j);
tmp0 = _mm512_permutex2var_epi8(e0j,p8a,e1j); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+31) e1(i+31)
tmp1 = _mm512_permutex2var_epi8(e2j,p8a,e3j); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+31) e3(i+31)
tmp2 = _mm512_permutex2var_epi8(e4j,p8a,e5j); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+31) e5(i+31)
tmp3 = _mm512_permutex2var_epi16(tmp0,p16a,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15)
tmp4 = _mm512_permutex2var_epi16(tmp0,p16b,tmp1); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31)
_mm512_storeu_si512(f_512+k,_mm512_permutex2var_epi16(tmp3,p16c,tmp2)); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) ... e0(i+9) e1(i+9) e2(i+9) e3(i+9) e4(i+9) e5(i+9) e0(i+10) e1(i+10)
tmp5 = _mm512_permutex2var_epi16(tmp3,p16d,tmp2); // e2(i+10) e3(i+10) e4(i+10) e5(i+10) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) e4(i+15) e5(i+15) x x x x e4(i+16) e5(i+16) x x x x .... e4(i+20) e5(i+20) x x
_mm512_storeu_si512(f_512+k+1,_mm512_permutex2var_epi16(tmp5,p16d2,tmp4)); // e2(i+10) e3(i+10) e4(i+10) e5(i+10) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) e4(i+15) e5(i+15) e0(i+16) e1(i+16) e2(i+16) e3(i+16) e4(i+16) e5(i+16) e0(i+20) e1(i+20) e2(i+20) e3(i+20) e4(i+20) e5(i+20) e0(i+21) e1(i+21)
_mm512_storeu_si512(f_512+k+2,_mm512_permutex2var_epi16(tmp4,p16e,tmp2)); // e2(i+21) e3(i+21) e4(i+21) e5(i+21) .... e0(i+31) e1(i+31) e2(i+31) e3(i+31) e4(i+31) e5(i+31)
tmp0 = simde_mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31)
tmp1 = simde_mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31)
tmp0b = simde_mm256_unpacklo_epi16(tmp0,tmp1); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) ... e0(i+23) e1(i+23) e2(i+23) e3(i+23)
tmp1b = simde_mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31)
tmp0 = simde_mm256_unpackhi_epi8(e4_256[j],e5_256[j]); // e4(i+16) e5(i+16) e4(i+17) e5(i+17) .... e4(i+31) e5(i+31)
*((uint32_t*)fp2) = simde_mm256_extract_epi32(tmp0b,0);
*((uint16_t*)(fp2+4)) = simde_mm256_extract_epi16(tmp0,0);
*((uint32_t*)(fp2+6)) = simde_mm256_extract_epi32(tmp0b,1);
*((uint16_t*)(fp2+10)) = simde_mm256_extract_epi16(tmp0,1);
*((uint32_t*)(fp2+12)) = simde_mm256_extract_epi32(tmp0b,2);
*((uint16_t*)(fp2+16)) = simde_mm256_extract_epi16(tmp0,2);
*((uint32_t*)(fp2+18)) = simde_mm256_extract_epi32(tmp0b,3);
*((uint16_t*)(fp2+22)) = simde_mm256_extract_epi16(tmp0,3);
*((uint32_t*)(fp2+24)) = simde_mm256_extract_epi32(tmp0b,4);
*((uint16_t*)(fp2+26)) = simde_mm256_extract_epi16(tmp0,4);
*((uint32_t*)(fp2+30)) = simde_mm256_extract_epi32(tmp0b,5);
*((uint16_t*)(fp2+34)) = simde_mm256_extract_epi16(tmp0,5);
*((uint32_t*)(fp2+36)) = simde_mm256_extract_epi32(tmp0,6);
*((uint16_t*)(fp2+40)) = simde_mm256_extract_epi16(tmp0,6);
*((uint32_t*)(fp2+42)) = simde_mm256_extract_epi32(tmp0b,7);
*((uint16_t*)(fp2+46)) = simde_mm256_extract_epi16(tmp0,7);
tmp0 = _mm512_permutex2var_epi8(e0j,p8b,e1j); // e0(i+32) e1(i+32) e0(i+32) e1(i+32) .... e0(i+63) e1(i+63)
tmp1 = _mm512_permutex2var_epi8(e2j,p8b,e3j); // e2(i+32) e3(i+32) e2(i+32) e3(i+32) .... e2(i+63) e3(i+63)
tmp2 = _mm512_permutex2var_epi8(e4j,p8b,e5j); // e4(i+32) e5(i+32) e4(i+32) e5(i+32) .... e4(i+63) e5(i+63)
tmp3 = _mm512_permutex2var_epi16(tmp0,p16a,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15)
tmp4 = _mm512_permutex2var_epi16(tmp0,p16b,tmp1); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31)
*((uint32_t*)(fp2+48)) = simde_mm256_extract_epi32(tmp1b,0);
*((uint16_t*)(fp2+52)) = simde_mm256_extract_epi16(tmp0,8);
*((uint32_t*)(fp2+56)) = simde_mm256_extract_epi32(tmp1b,1);
*((uint16_t*)(fp2+60)) = simde_mm256_extract_epi16(tmp0,9);
*((uint32_t*)(fp2+62)) = simde_mm256_extract_epi32(tmp1b,2);
*((uint16_t*)(fp2+66)) = simde_mm256_extract_epi16(tmp0,10);
*((uint32_t*)(fp2+68)) = simde_mm256_extract_epi32(tmp1b,3);
*((uint16_t*)(fp2+72)) = simde_mm256_extract_epi16(tmp0,11);
*((uint32_t*)(fp2+74)) = simde_mm256_extract_epi32(tmp1b,4);
*((uint16_t*)(fp2+76)) = simde_mm256_extract_epi16(tmp0,12);
*((uint32_t*)(fp2+80)) = simde_mm256_extract_epi32(tmp1b,5);
*((uint16_t*)(fp2+82)) = simde_mm256_extract_epi16(tmp0,13);
*((uint32_t*)(fp2+86)) = simde_mm256_extract_epi32(tmp1b,6);
*((uint16_t*)(fp2+90)) = simde_mm256_extract_epi16(tmp0,14);
*((uint32_t*)(fp2+92)) = simde_mm256_extract_epi32(tmp1b,7);
*((uint16_t*)(fp2+94)) = simde_mm256_extract_epi16(tmp0,15);
_mm512_storeu_si512(f_512+k+3,_mm512_permutex2var_epi16(tmp3,p16c,tmp2)); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) ... e0(i+9) e1(i+9) e2(i+9) e3(i+9) e4(i+9) e5(i+9) e0(i+10) e1(i+10)
tmp5 = _mm512_permutex2var_epi16(tmp3,p16d,tmp2); // e2(i+10) e3(i+10) e4(i+10) e5(i+10) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) e4(i+15) e5(i+15) x x x x e4(i+16) e5(i+16) x x x x .... e4(i+20) e5(i+20) x x
_mm512_storeu_si512(f_512+k+4,_mm512_permutex2var_epi16(tmp5,p16d2,tmp4)); // e2(i+10) e3(i+10) e4(i+10) e5(i+10) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) e4(i+15) e5(i+15) e0(i+16) e1(i+16) e2(i+16) e3(i+16) e4(i+16) e5(i+16) e0(i+20) e1(i+20) e2(i+20) e3(i+20) e4(i+20) e5(i+20) e0(i+21) e1(i+21)
_mm512_storeu_si512(f_512+k+5,_mm512_permutex2var_epi16(tmp4,p16e,tmp2)); // e2(i+21) e3(i+21) e4(i+21) e5(i+21) .... e0(i+31) e1(i+31) e2(i+31) e3(i+31) e4(i+31) e5(i+31)
}
if ((j<<6) != EQm) {
int k2=k<<6;
fp = &f[k2];
for (int j2=(j<<6) ; j2< EQm ; j2++) {
*fp++ = e0[j2];
*fp++ = e1[j2];
*fp++ = e2[j2];
*fp++ = e3[j2];
*fp++ = e4[j2];
*fp++ = e5[j2];
}
}
#else
fp = f;
for (int j = 0; j< EQm; j++){
*fp++ = e0[j];
*fp++ = e1[j];
*fp++ = e2[j];
*fp++ = e3[j];
*fp++ = e4[j];
*fp++ = e5[j];
}
#endif
break;
case 8:
e0=e;
@@ -181,43 +258,137 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e, uint8_t *f)
e6=e5+EQm;
e7=e6+EQm;
e0_256=(simde__m256i *)e0;
e1_256=(simde__m256i *)e1;
e2_256=(simde__m256i *)e2;
e3_256=(simde__m256i *)e3;
e4_256=(simde__m256i *)e4;
e5_256=(simde__m256i *)e5;
e6_256=(simde__m256i *)e6;
e7_256=(simde__m256i *)e7;
for (int k=0,j=0;j<EQm>>5;j++,k+=8) {
tmp0 = simde_mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
tmp1 = simde_mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15)
tmp2 = simde_mm256_unpacklo_epi8(e4_256[j],e5_256[j]); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+15) e5(i+15)
tmp3 = simde_mm256_unpacklo_epi8(e6_256[j],e7_256[j]); // e6(i) e7(i) e6(i+1) e7(i+1) .... e6(i+15) e7(i+15)
tmp4 = simde_mm256_unpacklo_epi16(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
tmp5 = simde_mm256_unpacklo_epi16(tmp2,tmp3); // e4(i) e5(i) e6(i) e7(i) ... e4(i+7) e5(i+7) e6(i+7) e7(i+7)
f_256[k] = simde_mm256_unpacklo_epi16(tmp4,tmp5); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) e6(i) e7(i)... e0(i+3) e1(i+3) e2(i+3) e3(i+3) e4(i+3) e5(i+3) e6(i+3) e7(i+3))
f_256[k+1] = simde_mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+4) e1(i+4) e2(i+4) e3(i+4) e4(i+4) e5(i+4) e6(i+4) e7(i+4)... e0(i+7) e1(i+7) e2(i+7) e3(i+7) e4(i+7) e5(i+7) e6(i+7) e7(i+7))
#ifdef __AVX512VBMI__
e0_512=(__m512i *)e0;
e1_512=(__m512i *)e1;
e2_512=(__m512i *)e2;
e3_512=(__m512i *)e3;
e4_512=(__m512i *)e4;
e5_512=(__m512i *)e5;
e6_512=(__m512i *)e6;
e7_512=(__m512i *)e7;
__m512i e6j,e7j;
p8a = _mm512_set_epi8(95,31,94,30,93,29,92,28,91,27,90,26,89,25,88,24,87,23,86,22,85,21,84,20,83,19,82,18,81,17,80,16,79,15,78,14,77,13,76,12,75,11,74,10,73,9,72,8,71,7,70,6,69,5,68,4,67,3,66,2,65,1,64,0);
p8b = _mm512_set_epi8(127,63,126,62,125,61,124,60,123,59,122,58,121,57,120,56,119,55,118,54,117,53,116,52,115,51,114,50,113,49,112,48,111,47,110,46,109,45,108,44,107,43,106,42,105,41,104,40,103,39,102,38,101,37,100,36,99,35,98,34,97,33,96,32);
tmp4 = simde_mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15)
tmp5 = simde_mm256_unpackhi_epi16(tmp2,tmp3); // e4(i+8) e5(i+8) e6(i+8) e7(i+8) ... e4(i+15) e5(i+15) e6(i+15) e7(i+15)
f_256[k+2] = simde_mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) e4(i+8) e5(i+8) e6(i+8) e7(i+8)... e0(i+11) e1(i+11) e2(i+11) e3(i+11) e4(i+11) e5(i+11) e6(i+11) e7(i+11))
f_256[k+3] = simde_mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+12) e1(i+12) e2(i+12) e3(i+12) e4(i+12) e5(i+12) e6(i+12) e7(i+12)... e0(i+15) e1(i+15) e2(i+15) e3(i+15) e4(i+15) e5(i+15) e6(i+15) e7(i+15))
p16a = _mm512_set_epi16(47,15,46,14,45,13,44,12,43,11,42,10,41,9,40,8,39,7,38,6,37,5,36,4,35,3,34,2,33,1,32,0);
p16b = _mm512_set_epi16(63,31,62,30,61,29,60,28,59,27,58,26,57,25,56,24,55,23,54,22,53,21,52,20,51,19,50,18,49,17,48,16);
tmp0 = simde_mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31)
tmp1 = simde_mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31)
tmp2 = simde_mm256_unpackhi_epi8(e4_256[j],e5_256[j]); // e4(i+16) e5(i+16) e4(i+17) e5(i+17) .... e4(i+31) e5(i+31)
tmp3 = simde_mm256_unpackhi_epi8(e6_256[j],e7_256[j]); // e6(i+16) e7(i+16) e6(i+17) e7(i+17) .... e6(i+31) e7(i+31)
tmp4 = simde_mm256_unpacklo_epi16(tmp0,tmp1); // e0(i+!6) e1(i+16) e2(i+16) e3(i+16) ... e0(i+23) e1(i+23) e2(i+23) e3(i+23)
tmp5 = simde_mm256_unpacklo_epi16(tmp2,tmp3); // e4(i+16) e5(i+16) e6(i+16) e7(i+16) ... e4(i+23) e5(i+23) e6(i+23) e7(i+23)
f_256[k+4] = simde_mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) e4(i+16) e5(i+16) e6(i+16) e7(i+16)... e0(i+19) e1(i+19) e2(i+19) e3(i+19) e4(i+19) e5(i+19) e6(i+19) e7(i+19))
f_256[k+5] = simde_mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+20) e1(i+20) e2(i+20) e3(i+20) e4(i+20) e5(i+20) e6(i+20) e7(i+20)... e0(i+23) e1(i+23) e2(i+23) e3(i+23) e4(i+23) e5(i+23) e6(i+23) e7(i+23))
p32a = _mm512_set_epi32(23,7,22,6,21,5,20,4,19,3,18,2,17,1,16,0);
p32b = _mm512_set_epi32(31,15,30,14,29,13,28,12,27,11,26,10,25,9,24,8);
for (k=0,j=0;j<EQm>>6;j++,k+=8) {
e0j = _mm512_loadu_si512(e0_512+j);
e1j = _mm512_loadu_si512(e1_512+j);
e2j = _mm512_loadu_si512(e2_512+j);
e3j = _mm512_loadu_si512(e3_512+j);
e4j = _mm512_loadu_si512(e4_512+j);
e5j = _mm512_loadu_si512(e5_512+j);
e6j = _mm512_loadu_si512(e6_512+j);
e7j = _mm512_loadu_si512(e7_512+j);
tmp0 = _mm512_permutex2var_epi8(e0j,p8a,e1j); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
tmp1 = _mm512_permutex2var_epi8(e2j,p8a,e3j); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15)
tmp2 = _mm512_permutex2var_epi8(e4j,p8a,e5j); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+15) e5(i+15)
tmp3 = _mm512_permutex2var_epi8(e6j,p8a,e7j); // e6(i) e7(i) e6(i+1) e7(i+1) .... e6(i+15) e7(i+15)
tmp4 = _mm512_permutex2var_epi16(tmp0,p16a,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
tmp5 = _mm512_permutex2var_epi16(tmp2,p16a,tmp3); // e4(i) e5(i) e6(i) e7(i) ... e4(i+7) e5(i+7) e6(i+7) e7(i+7)
_mm512_storeu_si512(f_512+k,_mm512_permutex2var_epi32(tmp4,p32a,tmp5)); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) e6(i) e7(i)... e0(i+3) e1(i+3) e2(i+3) e3(i+3) e4(i+3) e5(i+3) e6(i+3) e7(i+3))
_mm512_storeu_si512(f_512+k+1,_mm512_permutex2var_epi32(tmp4,p32b,tmp5)); // e0(i+4) e1(i+4) e2(i+4) e3(i+4) e4(i+4) e5(i+4) e6(i+4) e7(i+4)... e0(i+7) e1(i+7) e2(i+7) e3(i+7) e4(i+7) e5(i+7) e6(i+7) e7(i+7))
tmp4 = simde_mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31)
tmp5 = simde_mm256_unpackhi_epi16(tmp2,tmp3); // e4(i+24) e5(i+24) e6(i+24) e7(i+24) ... e4(i+31) e5(i+31) e6(i+31) e7(i+31)
f_256[k+6] = simde_mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) e4(i+24) e5(i+24) e6(i+24) e7(i+24)... e0(i+27) e1(i+27) e2(i+27) e3(i+27) e4(i+27) e5(i+27) e6(i+27) e7(i+27))
f_256[k+7] = simde_mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+28) e1(i+28) e2(i+28) e3(i+28) e4(i+28) e5(i+28) e6(i+28) e7(i+28)... e0(i+31) e1(i+31) e2(i+31) e3(i+31) e4(i+31) e5(i+31) e6(i+31) e7(i+31))
tmp4 = _mm512_permutex2var_epi16(tmp0,p16b,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15)
tmp5 = _mm512_permutex2var_epi16(tmp2,p16b,tmp3); // e4(i+8) e5(i+8) e6(i+8) e7(i+8) ... e4(i+15) e5(i+15) e6(i+15) e7(i+15)
_mm512_storeu_si512(f_512+k+2,_mm512_permutex2var_epi32(tmp4,p32a,tmp5)); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) e4(i+8) e5(i+8) e6(i+8) e7(i+8)... e0(i+11) e1(i+11) e2(i+11) e3(i+11) e4(i+11) e5(i+11) e6(i+11) e7(i+11))
_mm512_storeu_si512(f_512+k+3,_mm512_permutex2var_epi32(tmp4,p32b,tmp5)); // e0(i+12) e1(i+12) e2(i+12) e3(i+12) e4(i+12) e5(i+12) e6(i+12) e7(i+12)... e0(i+15) e1(i+15) e2(i+15) e3(i+15) e4(i+15) e5(i+15) e6(i+15) e7(i+15))
tmp0 = _mm512_permutex2var_epi8(e0j,p8b,e1j); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31)
tmp1 = _mm512_permutex2var_epi8(e2j,p8b,e3j); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31)
tmp2 = _mm512_permutex2var_epi8(e4j,p8b,e5j); // e4(i+16) e5(i+16) e4(i+17) e5(i+17) .... e4(i+31) e5(i+31)
tmp3 = _mm512_permutex2var_epi8(e6j,p8b,e7j); // e6(i+16) e7(i+16) e6(i+17) e7(i+17) .... e6(i+31) e7(i+31)
tmp4 = _mm512_permutex2var_epi16(tmp0,p16a,tmp1); // e0(i+!6) e1(i+16) e2(i+16) e3(i+16) ... e0(i+23) e1(i+23) e2(i+23) e3(i+23)
tmp5 = _mm512_permutex2var_epi16(tmp2,p16a,tmp3); // e4(i+16) e5(i+16) e6(i+16) e7(i+16) ... e4(i+23) e5(i+23) e6(i+23) e7(i+23)
_mm512_storeu_si512(f_512+k+4,_mm512_permutex2var_epi32(tmp4,p32a,tmp5)); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) e4(i+16) e5(i+16) e6(i+16) e7(i+16)... e0(i+19) e1(i+19) e2(i+19) e3(i+19) e4(i+19) e5(i+19) e6(i+19) e7(i+19))
_mm512_storeu_si512(f_512+k+5,_mm512_permutex2var_epi32(tmp4,p32b,tmp5)); // e0(i+20) e1(i+20) e2(i+20) e3(i+20) e4(i+20) e5(i+20) e6(i+20) e7(i+20)... e0(i+23) e1(i+23) e2(i+23) e3(i+23) e4(i+23) e5(i+23) e6(i+23) e7(i+23))
tmp4 = _mm512_permutex2var_epi16(tmp0,p16b,tmp1); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31)
tmp5 = _mm512_permutex2var_epi16(tmp2,p16b,tmp3); // e4(i+24) e5(i+24) e6(i+24) e7(i+24) ... e4(i+31) e5(i+31) e6(i+31) e7(i+31)
_mm512_storeu_si512(f_512+k+6,_mm512_permutex2var_epi32(tmp4,p32a,tmp5)); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) e4(i+24) e5(i+24) e6(i+24) e7(i+24)... e0(i+27) e1(i+27) e2(i+27) e3(i+27) e4(i+27) e5(i+27) e6(i+27) e7(i+27))
_mm512_storeu_si512(f_512+k+7,_mm512_permutex2var_epi32(tmp4,p32b,tmp5)); // e0(i+28) e1(i+28) e2(i+28) e3(i+28) e4(i+28) e5(i+28) e6(i+28) e7(i+28)... e0(i+31) e1(i+31) e2(i+31) e3(i+31) e4(i+31) e5(i+31) e6(i+31) e7(i+31))
}
if ((j<<6) != EQm) {
int k2=k<<6;
fp=&f[k2];
for (int j2=(j<<6) ; j2< EQm ; j2++) {
*fp++ = e0[j2];
*fp++ = e1[j2];
*fp++ = e2[j2];
*fp++ = e3[j2];
*fp++ = e4[j2];
*fp++ = e5[j2];
*fp++ = e6[j2];
*fp++ = e7[j2];
}
}
#else
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 e4j,e5j,e6j,e7j;
for (k=0,j=0;j<EQm>>4;j++,k+=8) {
e0j = simde_mm_loadu_si128(e0_128+j);
e1j = simde_mm_loadu_si128(e1_128+j);
e2j = simde_mm_loadu_si128(e2_128+j);
e3j = simde_mm_loadu_si128(e3_128+j);
e4j = simde_mm_loadu_si128(e4_128+j);
e5j = simde_mm_loadu_si128(e5_128+j);
e6j = simde_mm_loadu_si128(e6_128+j);
e7j = simde_mm_loadu_si128(e7_128+j);
tmp0 = simde_mm_unpacklo_epi8(e0j,e1j); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+7) e1(i+7)
tmp1 = simde_mm_unpacklo_epi8(e2j,e3j); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+7) e3(i+7)
tmp2 = simde_mm_unpacklo_epi16(tmp0,tmp1);// e0(i) e1(i) e2(i) e3(i) e0(i+1) e1(i+1) e2(i+1) e3(i+1) ... e0(i+3) e1(i+3) e2(i+3) e3(i+3)
tmp3 = simde_mm_unpackhi_epi16(tmp0,tmp1);// e0(i+4) e1(i+4) e2(i+4) e3(i+4) e0(i+5) e1(i+5) e2(i+5) e3(i+5) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
tmp4 = simde_mm_unpacklo_epi8(e4j,e5j); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+7) e5(i+7)
tmp5 = simde_mm_unpacklo_epi8(e6j,e7j); // e6(i) e7(i) e6(i+1) e7(i+1) .... e6(i+7) e7(i+7)
tmp6 = simde_mm_unpacklo_epi16(tmp4,tmp5);// e4(i) e5(i) e6(i) e7(i) e4(i+1) e5(i+1) e6(i+1) e7(i+1) ... e4(i+3) e5(i+3) e6(i+) e7(i+3)
tmp7 = simde_mm_unpackhi_epi16(tmp4,tmp5);// e4(i+4) e5(i+4) e6(i+4) e7(i+4) e4(i+5) e5(i+5) e6(i+5) e7(i+5) ... e4(i+7) e5(i+7) e6(i+7) e7(i+7)
simde_mm_storeu_si128(f_128+k,simde_mm_unpacklo_epi32(tmp2,tmp6)); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) e6(i) e7(i) e0(i+1) ... e7(i+1)
simde_mm_storeu_si128(f_128+k+1,simde_mm_unpackhi_epi32(tmp2,tmp6)); // e0(i+2) e1(i+2) e2(i+2) e3(i+2) e4(i+2) e5(i+2) e6(i+2) e7(i+2) e0(i+3) e1(i+3) ... e7(i+3)
simde_mm_storeu_si128(f_128+k+2,simde_mm_unpacklo_epi32(tmp3,tmp7)); // e0(i+4) e1(i+4) e2(i+4) e3(i+4) e4(i+4) e5(i+4) e6(i+4) e7+4(i) e0(i+5) ... e7(i+5)
simde_mm_storeu_si128(f_128+k+3,simde_mm_unpackhi_epi32(tmp3,tmp7)); // e0(i+6) e1(i+6) e2(i+6) e3(i+6) e4(i+6) e5(i+6) e6(i+6) e7(i+6) e0(i+7) e0(i+7) ... e7(i+7)
tmp0 = simde_mm_unpackhi_epi8(e0j,e1j); // e0(i+8) e1(i+8) e0(i+9) e1(i+9) .... e0(i+15) e1(i+15)
tmp1 = simde_mm_unpackhi_epi8(e2j,e3j); // e2(i+8) e3(i+8) e2(i+9) e3(i+9) .... e2(i+15) e3(i+15)
tmp2 = simde_mm_unpacklo_epi16(tmp0,tmp1);// e0(i) e1(i) e2(i) e3(i) e0(i+1) e1(i+1) e2(i+1) e3(i+1) ... e0(i+3) e1(i+3) e2(i+3) e3(i+3)
tmp3 = simde_mm_unpackhi_epi16(tmp0,tmp1);// e0(i+4) e1(i+4) e2(i+4) e3(i+4) e0(i+5) e1(i+5) e2(i+5) e3(i+5) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
tmp4 = simde_mm_unpackhi_epi8(e4j,e5j); // e4(i+8) e5(i+8) e4(i+9) e5(i+9) .... e4(i+15) e515i+7)
tmp5 = simde_mm_unpackhi_epi8(e6j,e7j); // e6(i+8) e7(i+8) e6(i+9) e7(i+9) .... e6(i+15) e7(i+15)
tmp6 = simde_mm_unpacklo_epi16(tmp4,tmp5);// e4(i) e5(i) e6(i) e7(i) e4(i+1) e5(i+1) e6(i+1) e7(i+1) ... e4(i+3) e5(i+3) e6(i+) e7(i+3)
tmp7 = simde_mm_unpackhi_epi16(tmp4,tmp5);// e4(i+4) e5(i+4) e6(i+4) e7(i+4) e4(i+5) e5(i+5) e6(i+5) e7(i+5) ... e4(i+7) e5(i+7) e6(i+7) e7(i+7)
simde_mm_storeu_si128(f_128+k+4,simde_mm_unpacklo_epi32(tmp2,tmp6)); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) e6(i) e7(i) e0(i+1) ... e7(i+1)
simde_mm_storeu_si128(f_128+k+5,simde_mm_unpackhi_epi32(tmp2,tmp6)); // e0(i+2) e1(i+2) e2(i+2) e3(i+2) e4(i+2) e5(i+2) e6(i+2) e7(i+2) e0(i+3) e1(i+3) ... e7(i+3)
simde_mm_storeu_si128(f_128+k+6,simde_mm_unpacklo_epi32(tmp3,tmp7)); // e0(i+4) e1(i+4) e2(i+4) e3(i+4) e4(i+4) e5(i+4) e6(i+4) e7+4(i) e0(i+5) ... e7(i+5)
simde_mm_storeu_si128(f_128+k+7,simde_mm_unpackhi_epi32(tmp3,tmp7)); // e0(i+6) e1(i+6) e2(i+6) e3(i+6) e4(i+6) e5(i+6) e6(i+6) e7(i+6) e0(i+7) e0(i+7) ... e7(i+7)
}
if ((j<<4) != EQm) {
int k2=k<<4;
fp=&f[k2];
for (int j2=(j<<4) ; j2< EQm ; j2++) {
*fp++ = e0[j2];
*fp++ = e1[j2];
*fp++ = e2[j2];
*fp++ = e3[j2];
*fp++ = e4[j2];
*fp++ = e5[j2];
*fp++ = e6[j2];
*fp++ = e7[j2];
}
}
#endif
break;
default: AssertFatal(1==0,"Should be here!\n");
}

View File

@@ -126,7 +126,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((simde__m128i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>4)+lut_idxCnProcG3[j][0]*2);
// sgn = simde_mm_sign_epi8(ones, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(ones, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(ones, ymm0);\n");
// min = simde_mm_abs_epi8(ymm0);
fprintf(fd," min = simde_mm_abs_epi8(ymm0);\n");
@@ -138,7 +138,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
fprintf(fd," min = simde_mm_min_epu8(min, simde_mm_abs_epi8(ymm0));\n");
// sgn = simde_mm_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(sgn, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(sgn, ymm0);\n");
// Store result
// min = simde_mm_min_epu8(min, maxLLR); // 128 in epi8 is -127
#ifndef DROP_MAXLLR
@@ -146,7 +146,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
#endif
// *p_cnProcBufResBit = simde_mm_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = simde_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[0]>>4)+(j*bitOffsetInGroup));
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = oai_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[0]>>4)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
@@ -185,7 +185,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((simde__m128i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>4)+lut_idxCnProcG4[j][0]*2);
// sgn = simde_mm_sign_epi8(ones, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(ones, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(ones, ymm0);\n");
// min = simde_mm_abs_epi8(ymm0);
fprintf(fd," min = simde_mm_abs_epi8(ymm0);\n");
@@ -199,7 +199,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
fprintf(fd," min = simde_mm_min_epu8(min, simde_mm_abs_epi8(ymm0));\n");
// sgn = simde_mm_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(sgn, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(sgn, ymm0);\n");
}
// Store result
@@ -209,7 +209,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
#endif
// *p_cnProcBufResBit = simde_mm_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = simde_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[1]>>4)+(j*bitOffsetInGroup));
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = oai_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[1]>>4)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
@@ -252,7 +252,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((simde__m128i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>4)+lut_idxCnProcG5[j][0]*2);
// sgn = simde_mm_sign_epi8(ones, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(ones, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(ones, ymm0);\n");
// min = simde_mm_abs_epi8(ymm0);
fprintf(fd," min = simde_mm_abs_epi8(ymm0);\n");
@@ -266,7 +266,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
fprintf(fd," min = simde_mm_min_epu8(min, simde_mm_abs_epi8(ymm0));\n");
// sgn = simde_mm_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(sgn, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(sgn, ymm0);\n");
}
// Store result
@@ -276,7 +276,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
#endif
// *p_cnProcBufResBit = simde_mm_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = simde_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[2]>>4)+(j*bitOffsetInGroup));
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = oai_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[2]>>4)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
@@ -319,7 +319,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((simde__m128i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>4)+lut_idxCnProcG6[j][0]*2);
// sgn = simde_mm_sign_epi8(ones, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(ones, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(ones, ymm0);\n");
// min = simde_mm_abs_epi8(ymm0);
fprintf(fd," min = simde_mm_abs_epi8(ymm0);\n");
@@ -333,7 +333,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
fprintf(fd," min = simde_mm_min_epu8(min, simde_mm_abs_epi8(ymm0));\n");
// sgn = simde_mm_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(sgn, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(sgn, ymm0);\n");
}
// Store result
@@ -343,7 +343,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
#endif
// *p_cnProcBufResBit = simde_mm_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = simde_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[3]>>4)+(j*bitOffsetInGroup));
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = oai_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[3]>>4)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
@@ -389,7 +389,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((simde__m128i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>4)+lut_idxCnProcG7[j][0]*2);
// sgn = simde_mm_sign_epi8(ones, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(ones, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(ones, ymm0);\n");
// min = simde_mm_abs_epi8(ymm0);
fprintf(fd," min = simde_mm_abs_epi8(ymm0);\n");
@@ -403,7 +403,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
fprintf(fd," min = simde_mm_min_epu8(min, simde_mm_abs_epi8(ymm0));\n");
// sgn = simde_mm_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(sgn, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(sgn, ymm0);\n");
}
// Store result
@@ -413,7 +413,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
#endif
// *p_cnProcBufResBit = simde_mm_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = simde_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[4]>>4)+(j*bitOffsetInGroup));
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = oai_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[4]>>4)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
@@ -460,7 +460,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((simde__m128i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>4)+lut_idxCnProcG8[j][0]*2);
// sgn = simde_mm_sign_epi8(ones, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(ones, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(ones, ymm0);\n");
// min = simde_mm_abs_epi8(ymm0);
fprintf(fd," min = simde_mm_abs_epi8(ymm0);\n");
@@ -474,7 +474,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
fprintf(fd," min = simde_mm_min_epu8(min, simde_mm_abs_epi8(ymm0));\n");
// sgn = simde_mm_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(sgn, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(sgn, ymm0);\n");
}
// Store result
@@ -484,7 +484,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
#endif
// *p_cnProcBufResBit = simde_mm_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = simde_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[5]>>4)+(j*bitOffsetInGroup));
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = oai_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[5]>>4)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
@@ -531,7 +531,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((simde__m128i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>4)+lut_idxCnProcG9[j][0]*2);
// sgn = simde_mm_sign_epi8(ones, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(ones, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(ones, ymm0);\n");
// min = simde_mm_abs_epi8(ymm0);
fprintf(fd," min = simde_mm_abs_epi8(ymm0);\n");
@@ -545,7 +545,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
fprintf(fd," min = simde_mm_min_epu8(min, simde_mm_abs_epi8(ymm0));\n");
// sgn = simde_mm_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(sgn, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(sgn, ymm0);\n");
}
// Store result
@@ -555,7 +555,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
#endif
// *p_cnProcBufResBit = simde_mm_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = simde_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[6]>>4)+(j*bitOffsetInGroup));
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = oai_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[6]>>4)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
@@ -603,7 +603,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((simde__m128i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>4)+lut_idxCnProcG10[j][0]*2);
// sgn = simde_mm_sign_epi8(ones, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(ones, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(ones, ymm0);\n");
// min = simde_mm_abs_epi8(ymm0);
fprintf(fd," min = simde_mm_abs_epi8(ymm0);\n");
@@ -617,7 +617,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
fprintf(fd," min = simde_mm_min_epu8(min, simde_mm_abs_epi8(ymm0));\n");
// sgn = simde_mm_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(sgn, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(sgn, ymm0);\n");
}
// Store result
@@ -627,7 +627,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
#endif
// *p_cnProcBufResBit = simde_mm_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = simde_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[7]>>4)+(j*bitOffsetInGroup));
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = oai_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[7]>>4)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
@@ -678,7 +678,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((simde__m128i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>4)+lut_idxCnProcG19[j][0]*2);
// sgn = simde_mm_sign_epi8(ones, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(ones, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(ones, ymm0);\n");
// min = simde_mm_abs_epi8(ymm0);
fprintf(fd," min = simde_mm_abs_epi8(ymm0);\n");
@@ -692,7 +692,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
fprintf(fd," min = simde_mm_min_epu8(min, simde_mm_abs_epi8(ymm0));\n");
// sgn = simde_mm_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = simde_mm_sign_epi8(sgn, ymm0);\n");
fprintf(fd," sgn = oai_mm_sign_epi8(sgn, ymm0);\n");
}
// Store result
@@ -702,7 +702,7 @@ void nrLDPC_cnProc_BG1_generator_128(const char* dir, int R)
#endif
// *p_cnProcBufResBit = simde_mm_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = simde_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[8]>>4)+(j*bitOffsetInGroup));
fprintf(fd," ((simde__m128i*)cnProcBufRes)[%d+i] = oai_mm_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[8]>>4)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}

View File

@@ -0,0 +1,151 @@
#include "PHY/sse_intrin.h"
// generated code for Zc=384, byte encoding
static inline void ldpc384_byte(uint8_t *c,uint8_t *d) {
__m512i *csimd=(__m512i *)c,*dsimd=(__m512i *)d;
__m512i *c2,*d2;
int i2;
for (i2=0; i2<6; i2++) {
c2=&csimd[i2];
d2=&dsimd[i2];
//row: 0
d2[0]=_mm512_xor_si512(c2[13468],_mm512_xor_si512(c2[3169],_mm512_xor_si512(c2[3435],_mm512_xor_si512(c2[5284],_mm512_xor_si512(c2[5028],_mm512_xor_si512(c2[15327],_mm512_xor_si512(c2[6085],_mm512_xor_si512(c2[13224],_mm512_xor_si512(c2[3193],_mm512_xor_si512(c2[2141],_mm512_xor_si512(c2[12977],_mm512_xor_si512(c2[2413],_mm512_xor_si512(c2[36],_mm512_xor_si512(c2[8500],_mm512_xor_si512(c2[3221],_mm512_xor_si512(c2[5068],_mm512_xor_si512(c2[14054],_mm512_xor_si512(c2[4286],_mm512_xor_si512(c2[64],_mm512_xor_si512(c2[6411],_mm512_xor_si512(c2[8786],_mm512_xor_si512(c2[1923],_mm512_xor_si512(c2[2993],_mm512_xor_si512(c2[2992],_mm512_xor_si512(c2[6686],_mm512_xor_si512(c2[3005],_mm512_xor_si512(c2[8546],_mm512_xor_si512(c2[14880],_mm512_xor_si512(c2[16216],_mm512_xor_si512(c2[13310],_mm512_xor_si512(c2[16740],_mm512_xor_si512(c2[8572],_mm512_xor_si512(c2[386],_mm512_xor_si512(c2[1178],_mm512_xor_si512(c2[12013],_mm512_xor_si512(c2[10432],_mm512_xor_si512(c2[13072],_mm512_xor_si512(c2[4632],_mm512_xor_si512(c2[5957],_mm512_xor_si512(c2[10443],_mm512_xor_si512(c2[9929],_mm512_xor_si512(c2[2271],_mm512_xor_si512(c2[5705],_mm512_xor_si512(c2[6771],_mm512_xor_si512(c2[6505],_mm512_xor_si512(c2[5451],_mm512_xor_si512(c2[6255],_mm512_xor_si512(c2[9421],_mm512_xor_si512(c2[14172],_mm512_xor_si512(c2[11281],_mm512_xor_si512(c2[9173],_mm512_xor_si512(c2[12868],_mm512_xor_si512(c2[13405],_mm512_xor_si512(c2[998],_mm512_xor_si512(c2[11824],_mm512_xor_si512(c2[13419],_mm512_xor_si512(c2[12891],_mm512_xor_si512(c2[4180],_mm512_xor_si512(c2[13958],_mm512_xor_si512(c2[3137],_mm512_xor_si512(c2[3663],_mm512_xor_si512(c2[2885],_mm512_xor_si512(c2[3672],_mm512_xor_si512(c2[10536],_mm512_xor_si512(c2[7121],_mm512_xor_si512(c2[12925],c2[10025]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 1
d2[6]=_mm512_xor_si512(c2[13468],_mm512_xor_si512(c2[13732],_mm512_xor_si512(c2[3433],_mm512_xor_si512(c2[3699],_mm512_xor_si512(c2[5548],_mm512_xor_si512(c2[5028],_mm512_xor_si512(c2[5292],_mm512_xor_si512(c2[15591],_mm512_xor_si512(c2[6349],_mm512_xor_si512(c2[13224],_mm512_xor_si512(c2[13488],_mm512_xor_si512(c2[3457],_mm512_xor_si512(c2[2405],_mm512_xor_si512(c2[12977],_mm512_xor_si512(c2[13241],_mm512_xor_si512(c2[2677],_mm512_xor_si512(c2[300],_mm512_xor_si512(c2[8764],_mm512_xor_si512(c2[3485],_mm512_xor_si512(c2[5332],_mm512_xor_si512(c2[14054],_mm512_xor_si512(c2[14318],_mm512_xor_si512(c2[4550],_mm512_xor_si512(c2[328],_mm512_xor_si512(c2[6411],_mm512_xor_si512(c2[6675],_mm512_xor_si512(c2[9050],_mm512_xor_si512(c2[2187],_mm512_xor_si512(c2[3257],_mm512_xor_si512(c2[3256],_mm512_xor_si512(c2[6950],_mm512_xor_si512(c2[3269],_mm512_xor_si512(c2[8810],_mm512_xor_si512(c2[15144],_mm512_xor_si512(c2[16216],_mm512_xor_si512(c2[16480],_mm512_xor_si512(c2[13574],_mm512_xor_si512(c2[109],_mm512_xor_si512(c2[8572],_mm512_xor_si512(c2[8836],_mm512_xor_si512(c2[650],_mm512_xor_si512(c2[1442],_mm512_xor_si512(c2[12013],_mm512_xor_si512(c2[12277],_mm512_xor_si512(c2[10696],_mm512_xor_si512(c2[13336],_mm512_xor_si512(c2[4632],_mm512_xor_si512(c2[4896],_mm512_xor_si512(c2[6221],_mm512_xor_si512(c2[10707],_mm512_xor_si512(c2[9929],_mm512_xor_si512(c2[10193],_mm512_xor_si512(c2[2535],_mm512_xor_si512(c2[5969],_mm512_xor_si512(c2[7035],_mm512_xor_si512(c2[6769],_mm512_xor_si512(c2[5715],_mm512_xor_si512(c2[6255],_mm512_xor_si512(c2[6519],_mm512_xor_si512(c2[9685],_mm512_xor_si512(c2[14436],_mm512_xor_si512(c2[11281],_mm512_xor_si512(c2[11545],_mm512_xor_si512(c2[9437],_mm512_xor_si512(c2[13132],_mm512_xor_si512(c2[13669],_mm512_xor_si512(c2[1262],_mm512_xor_si512(c2[12088],_mm512_xor_si512(c2[13419],_mm512_xor_si512(c2[13683],_mm512_xor_si512(c2[13155],_mm512_xor_si512(c2[4444],_mm512_xor_si512(c2[13958],_mm512_xor_si512(c2[14222],_mm512_xor_si512(c2[3401],_mm512_xor_si512(c2[3927],_mm512_xor_si512(c2[2885],_mm512_xor_si512(c2[3149],_mm512_xor_si512(c2[3936],_mm512_xor_si512(c2[10800],_mm512_xor_si512(c2[7121],_mm512_xor_si512(c2[7385],_mm512_xor_si512(c2[13189],c2[10289])))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 2
d2[12]=_mm512_xor_si512(c2[13732],_mm512_xor_si512(c2[3433],_mm512_xor_si512(c2[3435],_mm512_xor_si512(c2[3699],_mm512_xor_si512(c2[5284],_mm512_xor_si512(c2[5548],_mm512_xor_si512(c2[5292],_mm512_xor_si512(c2[15327],_mm512_xor_si512(c2[15591],_mm512_xor_si512(c2[6085],_mm512_xor_si512(c2[6349],_mm512_xor_si512(c2[13488],_mm512_xor_si512(c2[3457],_mm512_xor_si512(c2[2141],_mm512_xor_si512(c2[2405],_mm512_xor_si512(c2[13241],_mm512_xor_si512(c2[2677],_mm512_xor_si512(c2[36],_mm512_xor_si512(c2[300],_mm512_xor_si512(c2[8764],_mm512_xor_si512(c2[3221],_mm512_xor_si512(c2[3485],_mm512_xor_si512(c2[5068],_mm512_xor_si512(c2[5332],_mm512_xor_si512(c2[14318],_mm512_xor_si512(c2[4550],_mm512_xor_si512(c2[64],_mm512_xor_si512(c2[328],_mm512_xor_si512(c2[6675],_mm512_xor_si512(c2[8786],_mm512_xor_si512(c2[9050],_mm512_xor_si512(c2[1923],_mm512_xor_si512(c2[2187],_mm512_xor_si512(c2[3257],_mm512_xor_si512(c2[2992],_mm512_xor_si512(c2[3256],_mm512_xor_si512(c2[6686],_mm512_xor_si512(c2[6950],_mm512_xor_si512(c2[3269],_mm512_xor_si512(c2[8546],_mm512_xor_si512(c2[8810],_mm512_xor_si512(c2[14880],_mm512_xor_si512(c2[15144],_mm512_xor_si512(c2[16480],_mm512_xor_si512(c2[13574],_mm512_xor_si512(c2[16740],_mm512_xor_si512(c2[109],_mm512_xor_si512(c2[8836],_mm512_xor_si512(c2[386],_mm512_xor_si512(c2[650],_mm512_xor_si512(c2[1178],_mm512_xor_si512(c2[1442],_mm512_xor_si512(c2[12277],_mm512_xor_si512(c2[10696],_mm512_xor_si512(c2[13072],_mm512_xor_si512(c2[13336],_mm512_xor_si512(c2[4896],_mm512_xor_si512(c2[6221],_mm512_xor_si512(c2[10443],_mm512_xor_si512(c2[10707],_mm512_xor_si512(c2[10193],_mm512_xor_si512(c2[2271],_mm512_xor_si512(c2[2535],_mm512_xor_si512(c2[5705],_mm512_xor_si512(c2[5969],_mm512_xor_si512(c2[7035],_mm512_xor_si512(c2[6505],_mm512_xor_si512(c2[6769],_mm512_xor_si512(c2[5451],_mm512_xor_si512(c2[5715],_mm512_xor_si512(c2[6519],_mm512_xor_si512(c2[9685],_mm512_xor_si512(c2[14172],_mm512_xor_si512(c2[14436],_mm512_xor_si512(c2[11545],_mm512_xor_si512(c2[9437],_mm512_xor_si512(c2[12868],_mm512_xor_si512(c2[13132],_mm512_xor_si512(c2[13669],_mm512_xor_si512(c2[998],_mm512_xor_si512(c2[1262],_mm512_xor_si512(c2[11824],_mm512_xor_si512(c2[12088],_mm512_xor_si512(c2[13683],_mm512_xor_si512(c2[12891],_mm512_xor_si512(c2[13155],_mm512_xor_si512(c2[4180],_mm512_xor_si512(c2[4444],_mm512_xor_si512(c2[14222],_mm512_xor_si512(c2[3401],_mm512_xor_si512(c2[3663],_mm512_xor_si512(c2[3927],_mm512_xor_si512(c2[3149],_mm512_xor_si512(c2[3672],_mm512_xor_si512(c2[3936],_mm512_xor_si512(c2[10536],_mm512_xor_si512(c2[10800],_mm512_xor_si512(c2[7385],_mm512_xor_si512(c2[13189],_mm512_xor_si512(c2[10025],c2[10289]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 3
d2[18]=_mm512_xor_si512(c2[13732],_mm512_xor_si512(c2[3433],_mm512_xor_si512(c2[3699],_mm512_xor_si512(c2[5284],_mm512_xor_si512(c2[5548],_mm512_xor_si512(c2[5292],_mm512_xor_si512(c2[15591],_mm512_xor_si512(c2[6085],_mm512_xor_si512(c2[6349],_mm512_xor_si512(c2[13488],_mm512_xor_si512(c2[3457],_mm512_xor_si512(c2[2405],_mm512_xor_si512(c2[13241],_mm512_xor_si512(c2[2677],_mm512_xor_si512(c2[36],_mm512_xor_si512(c2[300],_mm512_xor_si512(c2[8764],_mm512_xor_si512(c2[3485],_mm512_xor_si512(c2[5068],_mm512_xor_si512(c2[5332],_mm512_xor_si512(c2[14318],_mm512_xor_si512(c2[4550],_mm512_xor_si512(c2[328],_mm512_xor_si512(c2[6675],_mm512_xor_si512(c2[9050],_mm512_xor_si512(c2[1923],_mm512_xor_si512(c2[2187],_mm512_xor_si512(c2[3257],_mm512_xor_si512(c2[3256],_mm512_xor_si512(c2[6686],_mm512_xor_si512(c2[6950],_mm512_xor_si512(c2[3269],_mm512_xor_si512(c2[8810],_mm512_xor_si512(c2[14880],_mm512_xor_si512(c2[15144],_mm512_xor_si512(c2[16480],_mm512_xor_si512(c2[13574],_mm512_xor_si512(c2[109],_mm512_xor_si512(c2[8836],_mm512_xor_si512(c2[650],_mm512_xor_si512(c2[1178],_mm512_xor_si512(c2[1442],_mm512_xor_si512(c2[12277],_mm512_xor_si512(c2[10696],_mm512_xor_si512(c2[13072],_mm512_xor_si512(c2[13336],_mm512_xor_si512(c2[4896],_mm512_xor_si512(c2[6221],_mm512_xor_si512(c2[10443],_mm512_xor_si512(c2[10707],_mm512_xor_si512(c2[10193],_mm512_xor_si512(c2[2535],_mm512_xor_si512(c2[5705],_mm512_xor_si512(c2[5969],_mm512_xor_si512(c2[7035],_mm512_xor_si512(c2[6769],_mm512_xor_si512(c2[5451],_mm512_xor_si512(c2[5715],_mm512_xor_si512(c2[6519],_mm512_xor_si512(c2[9685],_mm512_xor_si512(c2[14436],_mm512_xor_si512(c2[11545],_mm512_xor_si512(c2[9437],_mm512_xor_si512(c2[12868],_mm512_xor_si512(c2[13132],_mm512_xor_si512(c2[13669],_mm512_xor_si512(c2[1262],_mm512_xor_si512(c2[11824],_mm512_xor_si512(c2[12088],_mm512_xor_si512(c2[13683],_mm512_xor_si512(c2[13155],_mm512_xor_si512(c2[4180],_mm512_xor_si512(c2[4444],_mm512_xor_si512(c2[14222],_mm512_xor_si512(c2[3401],_mm512_xor_si512(c2[3927],_mm512_xor_si512(c2[3149],_mm512_xor_si512(c2[3936],_mm512_xor_si512(c2[10536],_mm512_xor_si512(c2[10800],_mm512_xor_si512(c2[7385],_mm512_xor_si512(c2[13189],_mm512_xor_si512(c2[10025],c2[10289])))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 4
d2[24]=_mm512_xor_si512(c2[3173],c2[14006]);
//row: 5
d2[30]=_mm512_xor_si512(c2[4225],_mm512_xor_si512(c2[10827],_mm512_xor_si512(c2[11093],_mm512_xor_si512(c2[12936],_mm512_xor_si512(c2[795],_mm512_xor_si512(c2[12686],_mm512_xor_si512(c2[6084],_mm512_xor_si512(c2[13743],_mm512_xor_si512(c2[3708],_mm512_xor_si512(c2[3987],_mm512_xor_si512(c2[10851],_mm512_xor_si512(c2[9793],_mm512_xor_si512(c2[3734],_mm512_xor_si512(c2[10071],_mm512_xor_si512(c2[7694],_mm512_xor_si512(c2[13501],_mm512_xor_si512(c2[16152],_mm512_xor_si512(c2[10873],_mm512_xor_si512(c2[12720],_mm512_xor_si512(c2[4817],_mm512_xor_si512(c2[11944],_mm512_xor_si512(c2[7716],_mm512_xor_si512(c2[14069],_mm512_xor_si512(c2[16444],_mm512_xor_si512(c2[9581],_mm512_xor_si512(c2[10645],_mm512_xor_si512(c2[10644],_mm512_xor_si512(c2[14344],_mm512_xor_si512(c2[10657],_mm512_xor_si512(c2[16204],_mm512_xor_si512(c2[5643],_mm512_xor_si512(c2[6973],_mm512_xor_si512(c2[4073],_mm512_xor_si512(c2[7503],_mm512_xor_si512(c2[16224],_mm512_xor_si512(c2[8044],_mm512_xor_si512(c2[8836],_mm512_xor_si512(c2[2776],_mm512_xor_si512(c2[1189],_mm512_xor_si512(c2[3829],_mm512_xor_si512(c2[12290],_mm512_xor_si512(c2[13609],_mm512_xor_si512(c2[1200],_mm512_xor_si512(c2[10178],_mm512_xor_si512(c2[686],_mm512_xor_si512(c2[9929],_mm512_xor_si512(c2[13357],_mm512_xor_si512(c2[14429],_mm512_xor_si512(c2[14163],_mm512_xor_si512(c2[13109],_mm512_xor_si512(c2[13913],_mm512_xor_si512(c2[184],_mm512_xor_si512(c2[4935],_mm512_xor_si512(c2[2044],_mm512_xor_si512(c2[16825],_mm512_xor_si512(c2[3625],_mm512_xor_si512(c2[13131],_mm512_xor_si512(c2[4168],_mm512_xor_si512(c2[8656],_mm512_xor_si512(c2[2581],_mm512_xor_si512(c2[4176],_mm512_xor_si512(c2[3648],_mm512_xor_si512(c2[11832],_mm512_xor_si512(c2[4721],_mm512_xor_si512(c2[10789],_mm512_xor_si512(c2[11321],_mm512_xor_si512(c2[10537],_mm512_xor_si512(c2[11330],_mm512_xor_si512(c2[1299],_mm512_xor_si512(c2[14773],_mm512_xor_si512(c2[3688],_mm512_xor_si512(c2[782],c2[13716]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 6
d2[36]=_mm512_xor_si512(c2[5812],_mm512_xor_si512(c2[340],_mm512_xor_si512(c2[384],_mm512_xor_si512(c2[8321],_mm512_xor_si512(c2[7549],_mm512_xor_si512(c2[16311],_mm512_xor_si512(c2[4968],c2[8955])))))));
//row: 7
d2[42]=_mm512_xor_si512(c2[2376],_mm512_xor_si512(c2[16380],_mm512_xor_si512(c2[15892],_mm512_xor_si512(c2[3521],_mm512_xor_si512(c2[9076],c2[13369])))));
//row: 8
d2[48]=_mm512_xor_si512(c2[14261],_mm512_xor_si512(c2[7921],_mm512_xor_si512(c2[3962],_mm512_xor_si512(c2[14523],_mm512_xor_si512(c2[4228],_mm512_xor_si512(c2[14525],_mm512_xor_si512(c2[14789],_mm512_xor_si512(c2[6077],_mm512_xor_si512(c2[16368],_mm512_xor_si512(c2[16632],_mm512_xor_si512(c2[13468],_mm512_xor_si512(c2[5821],_mm512_xor_si512(c2[16382],_mm512_xor_si512(c2[16120],_mm512_xor_si512(c2[9516],_mm512_xor_si512(c2[9780],_mm512_xor_si512(c2[6878],_mm512_xor_si512(c2[280],_mm512_xor_si512(c2[544],_mm512_xor_si512(c2[13478],_mm512_xor_si512(c2[14017],_mm512_xor_si512(c2[7683],_mm512_xor_si512(c2[3986],_mm512_xor_si512(c2[14547],_mm512_xor_si512(c2[2928],_mm512_xor_si512(c2[13225],_mm512_xor_si512(c2[13489],_mm512_xor_si512(c2[13764],_mm512_xor_si512(c2[7430],_mm512_xor_si512(c2[3206],_mm512_xor_si512(c2[13767],_mm512_xor_si512(c2[829],_mm512_xor_si512(c2[11126],_mm512_xor_si512(c2[11390],_mm512_xor_si512(c2[9806],_mm512_xor_si512(c2[9293],_mm512_xor_si512(c2[2953],_mm512_xor_si512(c2[4008],_mm512_xor_si512(c2[14305],_mm512_xor_si512(c2[14569],_mm512_xor_si512(c2[5861],_mm512_xor_si512(c2[16152],_mm512_xor_si512(c2[16416],_mm512_xor_si512(c2[14847],_mm512_xor_si512(c2[8513],_mm512_xor_si512(c2[5079],_mm512_xor_si512(c2[15640],_mm512_xor_si512(c2[857],_mm512_xor_si512(c2[11148],_mm512_xor_si512(c2[11412],_mm512_xor_si512(c2[7204],_mm512_xor_si512(c2[864],_mm512_xor_si512(c2[9579],_mm512_xor_si512(c2[2981],_mm512_xor_si512(c2[3245],_mm512_xor_si512(c2[2716],_mm512_xor_si512(c2[13013],_mm512_xor_si512(c2[13277],_mm512_xor_si512(c2[3780],_mm512_xor_si512(c2[14341],_mm512_xor_si512(c2[3785],_mm512_xor_si512(c2[14076],_mm512_xor_si512(c2[14340],_mm512_xor_si512(c2[7479],_mm512_xor_si512(c2[881],_mm512_xor_si512(c2[1145],_mm512_xor_si512(c2[3792],_mm512_xor_si512(c2[14353],_mm512_xor_si512(c2[9339],_mm512_xor_si512(c2[2741],_mm512_xor_si512(c2[3005],_mm512_xor_si512(c2[15673],_mm512_xor_si512(c2[9075],_mm512_xor_si512(c2[9339],_mm512_xor_si512(c2[108],_mm512_xor_si512(c2[10669],_mm512_xor_si512(c2[14103],_mm512_xor_si512(c2[7769],_mm512_xor_si512(c2[638],_mm512_xor_si512(c2[10935],_mm512_xor_si512(c2[11199],_mm512_xor_si512(c2[9365],_mm512_xor_si512(c2[3025],_mm512_xor_si512(c2[1179],_mm512_xor_si512(c2[11476],_mm512_xor_si512(c2[11740],_mm512_xor_si512(c2[1971],_mm512_xor_si512(c2[12268],_mm512_xor_si512(c2[12532],_mm512_xor_si512(c2[12806],_mm512_xor_si512(c2[6472],_mm512_xor_si512(c2[11225],_mm512_xor_si512(c2[4885],_mm512_xor_si512(c2[13865],_mm512_xor_si512(c2[7261],_mm512_xor_si512(c2[7525],_mm512_xor_si512(c2[5425],_mm512_xor_si512(c2[15986],_mm512_xor_si512(c2[6744],_mm512_xor_si512(c2[410],_mm512_xor_si512(c2[11236],_mm512_xor_si512(c2[4632],_mm512_xor_si512(c2[4896],_mm512_xor_si512(c2[4896],_mm512_xor_si512(c2[10716],_mm512_xor_si512(c2[4382],_mm512_xor_si512(c2[3064],_mm512_xor_si512(c2[13361],_mm512_xor_si512(c2[13625],_mm512_xor_si512(c2[6492],_mm512_xor_si512(c2[16789],_mm512_xor_si512(c2[158],_mm512_xor_si512(c2[7564],_mm512_xor_si512(c2[1224],_mm512_xor_si512(c2[7298],_mm512_xor_si512(c2[700],_mm512_xor_si512(c2[964],_mm512_xor_si512(c2[6244],_mm512_xor_si512(c2[16541],_mm512_xor_si512(c2[16805],_mm512_xor_si512(c2[7048],_mm512_xor_si512(c2[708],_mm512_xor_si512(c2[10214],_mm512_xor_si512(c2[3880],_mm512_xor_si512(c2[14965],_mm512_xor_si512(c2[8367],_mm512_xor_si512(c2[8631],_mm512_xor_si512(c2[12074],_mm512_xor_si512(c2[5740],_mm512_xor_si512(c2[9960],_mm512_xor_si512(c2[3626],_mm512_xor_si512(c2[13661],_mm512_xor_si512(c2[7057],_mm512_xor_si512(c2[7321],_mm512_xor_si512(c2[10488],_mm512_xor_si512(c2[14198],_mm512_xor_si512(c2[7864],_mm512_xor_si512(c2[1791],_mm512_xor_si512(c2[12088],_mm512_xor_si512(c2[12352],_mm512_xor_si512(c2[12617],_mm512_xor_si512(c2[6013],_mm512_xor_si512(c2[6277],_mm512_xor_si512(c2[14212],_mm512_xor_si512(c2[7872],_mm512_xor_si512(c2[13684],_mm512_xor_si512(c2[7080],_mm512_xor_si512(c2[7344],_mm512_xor_si512(c2[4973],_mm512_xor_si512(c2[15264],_mm512_xor_si512(c2[15528],_mm512_xor_si512(c2[14751],_mm512_xor_si512(c2[8417],_mm512_xor_si512(c2[3924],_mm512_xor_si512(c2[14485],_mm512_xor_si512(c2[4456],_mm512_xor_si512(c2[14753],_mm512_xor_si512(c2[15017],_mm512_xor_si512(c2[8679],_mm512_xor_si512(c2[3672],_mm512_xor_si512(c2[14233],_mm512_xor_si512(c2[4465],_mm512_xor_si512(c2[14762],_mm512_xor_si512(c2[15026],_mm512_xor_si512(c2[11329],_mm512_xor_si512(c2[4731],_mm512_xor_si512(c2[4995],_mm512_xor_si512(c2[7908],_mm512_xor_si512(c2[1574],_mm512_xor_si512(c2[13718],_mm512_xor_si512(c2[7384],_mm512_xor_si512(c2[10812],_mm512_xor_si512(c2[4214],_mm512_xor_si512(c2[4478],c2[12929]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 9
d2[54]=_mm512_xor_si512(c2[12149],_mm512_xor_si512(c2[10575],_mm512_xor_si512(c2[389],_mm512_xor_si512(c2[1454],_mm512_xor_si512(c2[15204],_mm512_xor_si512(c2[12616],_mm512_xor_si512(c2[16848],c2[4993])))))));
//row: 10
d2[60]=_mm512_xor_si512(c2[9781],_mm512_xor_si512(c2[5045],_mm512_xor_si512(c2[4804],_mm512_xor_si512(c2[12493],_mm512_xor_si512(c2[16733],c2[9149])))));
//row: 11
d2[66]=_mm512_xor_si512(c2[268],_mm512_xor_si512(c2[10032],_mm512_xor_si512(c2[10296],_mm512_xor_si512(c2[6864],_mm512_xor_si512(c2[3],_mm512_xor_si512(c2[7130],_mm512_xor_si512(c2[269],_mm512_xor_si512(c2[8979],_mm512_xor_si512(c2[2112],_mm512_xor_si512(c2[12672],_mm512_xor_si512(c2[8729],_mm512_xor_si512(c2[1598],_mm512_xor_si512(c2[1862],_mm512_xor_si512(c2[2127],_mm512_xor_si512(c2[12161],_mm512_xor_si512(c2[9780],_mm512_xor_si512(c2[2919],_mm512_xor_si512(c2[10045],_mm512_xor_si512(c2[24],_mm512_xor_si512(c2[9794],_mm512_xor_si512(c2[10058],_mm512_xor_si512(c2[6888],_mm512_xor_si512(c2[27],_mm512_xor_si512(c2[5836],_mm512_xor_si512(c2[15864],_mm512_xor_si512(c2[16672],_mm512_xor_si512(c2[9541],_mm512_xor_si512(c2[9805],_mm512_xor_si512(c2[6108],_mm512_xor_si512(c2[16142],_mm512_xor_si512(c2[3737],_mm512_xor_si512(c2[13765],_mm512_xor_si512(c2[12195],_mm512_xor_si512(c2[5328],_mm512_xor_si512(c2[6916],_mm512_xor_si512(c2[49],_mm512_xor_si512(c2[8763],_mm512_xor_si512(c2[1896],_mm512_xor_si512(c2[854],_mm512_xor_si512(c2[10624],_mm512_xor_si512(c2[10888],_mm512_xor_si512(c2[7981],_mm512_xor_si512(c2[1120],_mm512_xor_si512(c2[3759],_mm512_xor_si512(c2[13793],_mm512_xor_si512(c2[10106],_mm512_xor_si512(c2[2981],_mm512_xor_si512(c2[3245],_mm512_xor_si512(c2[12481],_mm512_xor_si512(c2[5620],_mm512_xor_si512(c2[5618],_mm512_xor_si512(c2[15652],_mm512_xor_si512(c2[6688],_mm512_xor_si512(c2[16716],_mm512_xor_si512(c2[6687],_mm512_xor_si512(c2[16721],_mm512_xor_si512(c2[10381],_mm512_xor_si512(c2[3520],_mm512_xor_si512(c2[6700],_mm512_xor_si512(c2[16728],_mm512_xor_si512(c2[12241],_mm512_xor_si512(c2[5380],_mm512_xor_si512(c2[1680],_mm512_xor_si512(c2[11714],_mm512_xor_si512(c2[3016],_mm512_xor_si512(c2[12780],_mm512_xor_si512(c2[13044],_mm512_xor_si512(c2[110],_mm512_xor_si512(c2[10144],_mm512_xor_si512(c2[3540],_mm512_xor_si512(c2[13574],_mm512_xor_si512(c2[12267],_mm512_xor_si512(c2[5136],_mm512_xor_si512(c2[5400],_mm512_xor_si512(c2[4081],_mm512_xor_si512(c2[14115],_mm512_xor_si512(c2[4873],_mm512_xor_si512(c2[14907],_mm512_xor_si512(c2[15708],_mm512_xor_si512(c2[8583],_mm512_xor_si512(c2[8847],_mm512_xor_si512(c2[14127],_mm512_xor_si512(c2[7260],_mm512_xor_si512(c2[16767],_mm512_xor_si512(c2[9900],_mm512_xor_si512(c2[8333],_mm512_xor_si512(c2[1202],_mm512_xor_si512(c2[1466],_mm512_xor_si512(c2[9652],_mm512_xor_si512(c2[2785],_mm512_xor_si512(c2[14138],_mm512_xor_si512(c2[7277],_mm512_xor_si512(c2[2256],_mm512_xor_si512(c2[13624],_mm512_xor_si512(c2[6493],_mm512_xor_si512(c2[6757],_mm512_xor_si512(c2[5966],_mm512_xor_si512(c2[16000],_mm512_xor_si512(c2[9400],_mm512_xor_si512(c2[2533],_mm512_xor_si512(c2[10466],_mm512_xor_si512(c2[3605],_mm512_xor_si512(c2[10200],_mm512_xor_si512(c2[3339],_mm512_xor_si512(c2[9146],_mm512_xor_si512(c2[2285],_mm512_xor_si512(c2[9950],_mm512_xor_si512(c2[2825],_mm512_xor_si512(c2[3089],_mm512_xor_si512(c2[13116],_mm512_xor_si512(c2[6255],_mm512_xor_si512(c2[972],_mm512_xor_si512(c2[11006],_mm512_xor_si512(c2[14976],_mm512_xor_si512(c2[7851],_mm512_xor_si512(c2[8115],_mm512_xor_si512(c2[12868],_mm512_xor_si512(c2[6001],_mm512_xor_si512(c2[16563],_mm512_xor_si512(c2[9696],_mm512_xor_si512(c2[12600],_mm512_xor_si512(c2[205],_mm512_xor_si512(c2[10239],_mm512_xor_si512(c2[4693],_mm512_xor_si512(c2[14727],_mm512_xor_si512(c2[15519],_mm512_xor_si512(c2[8652],_mm512_xor_si512(c2[219],_mm512_xor_si512(c2[9989],_mm512_xor_si512(c2[10253],_mm512_xor_si512(c2[16586],_mm512_xor_si512(c2[9725],_mm512_xor_si512(c2[7875],_mm512_xor_si512(c2[1008],_mm512_xor_si512(c2[758],_mm512_xor_si512(c2[10528],_mm512_xor_si512(c2[10792],_mm512_xor_si512(c2[6832],_mm512_xor_si512(c2[16860],_mm512_xor_si512(c2[7358],_mm512_xor_si512(c2[497],_mm512_xor_si512(c2[6580],_mm512_xor_si512(c2[16344],_mm512_xor_si512(c2[16608],_mm512_xor_si512(c2[7373],_mm512_xor_si512(c2[506],_mm512_xor_si512(c2[14237],_mm512_xor_si512(c2[7370],_mm512_xor_si512(c2[10816],_mm512_xor_si512(c2[3685],_mm512_xor_si512(c2[3949],_mm512_xor_si512(c2[16620],_mm512_xor_si512(c2[9759],_mm512_xor_si512(c2[13720],_mm512_xor_si512(c2[6853],c2[16094])))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 12
d2[72]=_mm512_xor_si512(c2[3433],_mm512_xor_si512(c2[15326],_mm512_xor_si512(c2[12266],_mm512_xor_si512(c2[10695],_mm512_xor_si512(c2[13356],c2[2857])))));
//row: 13
d2[78]=_mm512_xor_si512(c2[9772],_mm512_xor_si512(c2[10036],_mm512_xor_si512(c2[16632],_mm512_xor_si512(c2[3],_mm512_xor_si512(c2[1852],_mm512_xor_si512(c2[15052],_mm512_xor_si512(c2[1332],_mm512_xor_si512(c2[1596],_mm512_xor_si512(c2[11895],_mm512_xor_si512(c2[2653],_mm512_xor_si512(c2[9528],_mm512_xor_si512(c2[9792],_mm512_xor_si512(c2[16656],_mm512_xor_si512(c2[15604],_mm512_xor_si512(c2[9281],_mm512_xor_si512(c2[9545],_mm512_xor_si512(c2[15876],_mm512_xor_si512(c2[13505],_mm512_xor_si512(c2[12974],_mm512_xor_si512(c2[5068],_mm512_xor_si512(c2[16684],_mm512_xor_si512(c2[1636],_mm512_xor_si512(c2[10358],_mm512_xor_si512(c2[10622],_mm512_xor_si512(c2[854],_mm512_xor_si512(c2[13527],_mm512_xor_si512(c2[2715],_mm512_xor_si512(c2[2979],_mm512_xor_si512(c2[5354],_mm512_xor_si512(c2[15386],_mm512_xor_si512(c2[16456],_mm512_xor_si512(c2[16455],_mm512_xor_si512(c2[3254],_mm512_xor_si512(c2[2728],_mm512_xor_si512(c2[16468],_mm512_xor_si512(c2[5114],_mm512_xor_si512(c2[11448],_mm512_xor_si512(c2[12520],_mm512_xor_si512(c2[12784],_mm512_xor_si512(c2[9878],_mm512_xor_si512(c2[13308],_mm512_xor_si512(c2[4876],_mm512_xor_si512(c2[5140],_mm512_xor_si512(c2[13849],_mm512_xor_si512(c2[14641],_mm512_xor_si512(c2[8317],_mm512_xor_si512(c2[8581],_mm512_xor_si512(c2[7000],_mm512_xor_si512(c2[9640],_mm512_xor_si512(c2[936],_mm512_xor_si512(c2[1200],_mm512_xor_si512(c2[2525],_mm512_xor_si512(c2[7011],_mm512_xor_si512(c2[6233],_mm512_xor_si512(c2[6497],_mm512_xor_si512(c2[15734],_mm512_xor_si512(c2[2273],_mm512_xor_si512(c2[3339],_mm512_xor_si512(c2[3073],_mm512_xor_si512(c2[2019],_mm512_xor_si512(c2[2559],_mm512_xor_si512(c2[2823],_mm512_xor_si512(c2[5989],_mm512_xor_si512(c2[10740],_mm512_xor_si512(c2[7585],_mm512_xor_si512(c2[7849],_mm512_xor_si512(c2[5741],_mm512_xor_si512(c2[9436],_mm512_xor_si512(c2[9973],_mm512_xor_si512(c2[14461],_mm512_xor_si512(c2[8392],_mm512_xor_si512(c2[9723],_mm512_xor_si512(c2[9987],_mm512_xor_si512(c2[9459],_mm512_xor_si512(c2[748],_mm512_xor_si512(c2[10262],_mm512_xor_si512(c2[10526],_mm512_xor_si512(c2[16600],_mm512_xor_si512(c2[231],_mm512_xor_si512(c2[16084],_mm512_xor_si512(c2[16348],_mm512_xor_si512(c2[240],_mm512_xor_si512(c2[7104],_mm512_xor_si512(c2[13705],_mm512_xor_si512(c2[3425],_mm512_xor_si512(c2[3689],_mm512_xor_si512(c2[9493],c2[6593])))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 14
d2[84]=_mm512_xor_si512(c2[3698],_mm512_xor_si512(c2[14931],_mm512_xor_si512(c2[2558],_mm512_xor_si512(c2[6793],_mm512_xor_si512(c2[7337],c2[3420])))));
//row: 15
d2[90]=_mm512_xor_si512(c2[267],_mm512_xor_si512(c2[6869],_mm512_xor_si512(c2[7129],_mm512_xor_si512(c2[8714],_mm512_xor_si512(c2[8978],_mm512_xor_si512(c2[12939],_mm512_xor_si512(c2[8728],_mm512_xor_si512(c2[2126],_mm512_xor_si512(c2[9521],_mm512_xor_si512(c2[9785],_mm512_xor_si512(c2[540],_mm512_xor_si512(c2[29],_mm512_xor_si512(c2[6893],_mm512_xor_si512(c2[5835],_mm512_xor_si512(c2[16671],_mm512_xor_si512(c2[6113],_mm512_xor_si512(c2[3472],_mm512_xor_si512(c2[3736],_mm512_xor_si512(c2[12194],_mm512_xor_si512(c2[6915],_mm512_xor_si512(c2[8498],_mm512_xor_si512(c2[8762],_mm512_xor_si512(c2[853],_mm512_xor_si512(c2[7980],_mm512_xor_si512(c2[3758],_mm512_xor_si512(c2[10105],_mm512_xor_si512(c2[12480],_mm512_xor_si512(c2[5353],_mm512_xor_si512(c2[5617],_mm512_xor_si512(c2[6687],_mm512_xor_si512(c2[6686],_mm512_xor_si512(c2[10116],_mm512_xor_si512(c2[10380],_mm512_xor_si512(c2[6699],_mm512_xor_si512(c2[12240],_mm512_xor_si512(c2[1421],_mm512_xor_si512(c2[1685],_mm512_xor_si512(c2[3015],_mm512_xor_si512(c2[109],_mm512_xor_si512(c2[3545],_mm512_xor_si512(c2[12266],_mm512_xor_si512(c2[4080],_mm512_xor_si512(c2[4608],_mm512_xor_si512(c2[4872],_mm512_xor_si512(c2[4875],_mm512_xor_si512(c2[15713],_mm512_xor_si512(c2[14126],_mm512_xor_si512(c2[16502],_mm512_xor_si512(c2[16766],_mm512_xor_si512(c2[8332],_mm512_xor_si512(c2[9651],_mm512_xor_si512(c2[13873],_mm512_xor_si512(c2[14137],_mm512_xor_si512(c2[13623],_mm512_xor_si512(c2[5965],_mm512_xor_si512(c2[9135],_mm512_xor_si512(c2[9399],_mm512_xor_si512(c2[16528],_mm512_xor_si512(c2[10465],_mm512_xor_si512(c2[10205],_mm512_xor_si512(c2[8881],_mm512_xor_si512(c2[9145],_mm512_xor_si512(c2[9949],_mm512_xor_si512(c2[13121],_mm512_xor_si512(c2[977],_mm512_xor_si512(c2[14981],_mm512_xor_si512(c2[12867],_mm512_xor_si512(c2[16298],_mm512_xor_si512(c2[16562],_mm512_xor_si512(c2[204],_mm512_xor_si512(c2[4692],_mm512_xor_si512(c2[15254],_mm512_xor_si512(c2[15518],_mm512_xor_si512(c2[218],_mm512_xor_si512(c2[16585],_mm512_xor_si512(c2[7610],_mm512_xor_si512(c2[7874],_mm512_xor_si512(c2[14736],_mm512_xor_si512(c2[757],_mm512_xor_si512(c2[6831],_mm512_xor_si512(c2[7357],_mm512_xor_si512(c2[6579],_mm512_xor_si512(c2[7372],_mm512_xor_si512(c2[13972],_mm512_xor_si512(c2[14236],_mm512_xor_si512(c2[10815],_mm512_xor_si512(c2[16625],_mm512_xor_si512(c2[13455],c2[13719]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 16
d2[96]=_mm512_xor_si512(c2[11621],_mm512_xor_si512(c2[1322],_mm512_xor_si512(c2[1588],_mm512_xor_si512(c2[3437],_mm512_xor_si512(c2[3181],_mm512_xor_si512(c2[13480],_mm512_xor_si512(c2[4238],_mm512_xor_si512(c2[3444],_mm512_xor_si512(c2[11377],_mm512_xor_si512(c2[1346],_mm512_xor_si512(c2[288],_mm512_xor_si512(c2[11124],_mm512_xor_si512(c2[566],_mm512_xor_si512(c2[15084],_mm512_xor_si512(c2[4793],_mm512_xor_si512(c2[6653],_mm512_xor_si512(c2[1368],_mm512_xor_si512(c2[3221],_mm512_xor_si512(c2[12207],_mm512_xor_si512(c2[2439],_mm512_xor_si512(c2[15112],_mm512_xor_si512(c2[4564],_mm512_xor_si512(c2[6939],_mm512_xor_si512(c2[76],_mm512_xor_si512(c2[1140],_mm512_xor_si512(c2[1145],_mm512_xor_si512(c2[4839],_mm512_xor_si512(c2[1152],_mm512_xor_si512(c2[6699],_mm512_xor_si512(c2[13033],_mm512_xor_si512(c2[14369],_mm512_xor_si512(c2[11463],_mm512_xor_si512(c2[14893],_mm512_xor_si512(c2[6725],_mm512_xor_si512(c2[15434],_mm512_xor_si512(c2[16226],_mm512_xor_si512(c2[10166],_mm512_xor_si512(c2[8585],_mm512_xor_si512(c2[11225],_mm512_xor_si512(c2[15180],_mm512_xor_si512(c2[2785],_mm512_xor_si512(c2[4104],_mm512_xor_si512(c2[8596],_mm512_xor_si512(c2[8076],_mm512_xor_si512(c2[424],_mm512_xor_si512(c2[3852],_mm512_xor_si512(c2[4924],_mm512_xor_si512(c2[4658],_mm512_xor_si512(c2[3604],_mm512_xor_si512(c2[4408],_mm512_xor_si512(c2[7574],_mm512_xor_si512(c2[12325],_mm512_xor_si512(c2[9434],_mm512_xor_si512(c2[7320],_mm512_xor_si512(c2[11021],_mm512_xor_si512(c2[11558],_mm512_xor_si512(c2[16046],_mm512_xor_si512(c2[9977],_mm512_xor_si512(c2[11572],_mm512_xor_si512(c2[11044],_mm512_xor_si512(c2[2333],_mm512_xor_si512(c2[12111],_mm512_xor_si512(c2[1284],_mm512_xor_si512(c2[1816],_mm512_xor_si512(c2[1032],_mm512_xor_si512(c2[1825],_mm512_xor_si512(c2[8689],_mm512_xor_si512(c2[8956],_mm512_xor_si512(c2[5268],_mm512_xor_si512(c2[11078],c2[8172]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 17
d2[102]=_mm512_xor_si512(c2[1060],_mm512_xor_si512(c2[12580],_mm512_xor_si512(c2[4681],_mm512_xor_si512(c2[10241],c2[14777]))));
//row: 18
d2[108]=_mm512_xor_si512(c2[542],_mm512_xor_si512(c2[9386],_mm512_xor_si512(c2[6496],_mm512_xor_si512(c2[1274],c2[1284]))));
//row: 19
d2[114]=_mm512_xor_si512(c2[4490],_mm512_xor_si512(c2[5559],_mm512_xor_si512(c2[6425],_mm512_xor_si512(c2[13299],c2[1443]))));
//row: 20
d2[120]=_mm512_xor_si512(c2[12149],_mm512_xor_si512(c2[1850],_mm512_xor_si512(c2[2116],_mm512_xor_si512(c2[3965],_mm512_xor_si512(c2[15578],_mm512_xor_si512(c2[3709],_mm512_xor_si512(c2[14008],_mm512_xor_si512(c2[4766],_mm512_xor_si512(c2[11905],_mm512_xor_si512(c2[1874],_mm512_xor_si512(c2[816],_mm512_xor_si512(c2[11652],_mm512_xor_si512(c2[1094],_mm512_xor_si512(c2[15612],_mm512_xor_si512(c2[3735],_mm512_xor_si512(c2[7181],_mm512_xor_si512(c2[1896],_mm512_xor_si512(c2[3749],_mm512_xor_si512(c2[12735],_mm512_xor_si512(c2[2967],_mm512_xor_si512(c2[15640],_mm512_xor_si512(c2[5092],_mm512_xor_si512(c2[7467],_mm512_xor_si512(c2[604],_mm512_xor_si512(c2[1668],_mm512_xor_si512(c2[1673],_mm512_xor_si512(c2[5367],_mm512_xor_si512(c2[1680],_mm512_xor_si512(c2[7227],_mm512_xor_si512(c2[13561],_mm512_xor_si512(c2[14897],_mm512_xor_si512(c2[11991],_mm512_xor_si512(c2[15421],_mm512_xor_si512(c2[2224],_mm512_xor_si512(c2[7253],_mm512_xor_si512(c2[15962],_mm512_xor_si512(c2[16754],_mm512_xor_si512(c2[10694],_mm512_xor_si512(c2[9113],_mm512_xor_si512(c2[11753],_mm512_xor_si512(c2[5681],_mm512_xor_si512(c2[3313],_mm512_xor_si512(c2[4632],_mm512_xor_si512(c2[9124],_mm512_xor_si512(c2[8604],_mm512_xor_si512(c2[952],_mm512_xor_si512(c2[4380],_mm512_xor_si512(c2[5452],_mm512_xor_si512(c2[5186],_mm512_xor_si512(c2[4132],_mm512_xor_si512(c2[4936],_mm512_xor_si512(c2[8102],_mm512_xor_si512(c2[12853],_mm512_xor_si512(c2[9962],_mm512_xor_si512(c2[7848],_mm512_xor_si512(c2[11549],_mm512_xor_si512(c2[12086],_mm512_xor_si512(c2[16574],_mm512_xor_si512(c2[10505],_mm512_xor_si512(c2[12100],_mm512_xor_si512(c2[11572],_mm512_xor_si512(c2[2861],_mm512_xor_si512(c2[12639],_mm512_xor_si512(c2[1812],_mm512_xor_si512(c2[2344],_mm512_xor_si512(c2[1560],_mm512_xor_si512(c2[2353],_mm512_xor_si512(c2[9217],_mm512_xor_si512(c2[5796],_mm512_xor_si512(c2[11606],c2[8700]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 21
d2[126]=_mm512_xor_si512(c2[3447],_mm512_xor_si512(c2[10093],_mm512_xor_si512(c2[2309],_mm512_xor_si512(c2[5787],c2[8965]))));
//row: 22
d2[132]=_mm512_xor_si512(c2[7920],_mm512_xor_si512(c2[3048],_mm512_xor_si512(c2[10983],c2[6012])));
//row: 23
d2[138]=_mm512_xor_si512(c2[6348],_mm512_xor_si512(c2[6625],_mm512_xor_si512(c2[16224],c2[7344])));
//row: 24
d2[144]=_mm512_xor_si512(c2[7658],_mm512_xor_si512(c2[14260],_mm512_xor_si512(c2[14520],_mm512_xor_si512(c2[16369],_mm512_xor_si512(c2[11092],_mm512_xor_si512(c2[16119],_mm512_xor_si512(c2[9517],_mm512_xor_si512(c2[281],_mm512_xor_si512(c2[7420],_mm512_xor_si512(c2[14284],_mm512_xor_si512(c2[13226],_mm512_xor_si512(c2[7167],_mm512_xor_si512(c2[13504],_mm512_xor_si512(c2[11127],_mm512_xor_si512(c2[7958],_mm512_xor_si512(c2[2690],_mm512_xor_si512(c2[14306],_mm512_xor_si512(c2[16153],_mm512_xor_si512(c2[11403],_mm512_xor_si512(c2[8244],_mm512_xor_si512(c2[15377],_mm512_xor_si512(c2[11149],_mm512_xor_si512(c2[601],_mm512_xor_si512(c2[2976],_mm512_xor_si512(c2[13008],_mm512_xor_si512(c2[14078],_mm512_xor_si512(c2[14077],_mm512_xor_si512(c2[876],_mm512_xor_si512(c2[14090],_mm512_xor_si512(c2[2736],_mm512_xor_si512(c2[9076],_mm512_xor_si512(c2[10406],_mm512_xor_si512(c2[7500],_mm512_xor_si512(c2[10936],_mm512_xor_si512(c2[2762],_mm512_xor_si512(c2[11477],_mm512_xor_si512(c2[12269],_mm512_xor_si512(c2[6209],_mm512_xor_si512(c2[4622],_mm512_xor_si512(c2[7262],_mm512_xor_si512(c2[5153],_mm512_xor_si512(c2[15723],_mm512_xor_si512(c2[147],_mm512_xor_si512(c2[4633],_mm512_xor_si512(c2[4119],_mm512_xor_si512(c2[13356],_mm512_xor_si512(c2[16790],_mm512_xor_si512(c2[961],_mm512_xor_si512(c2[701],_mm512_xor_si512(c2[16536],_mm512_xor_si512(c2[445],_mm512_xor_si512(c2[3617],_mm512_xor_si512(c2[8368],_mm512_xor_si512(c2[5477],_mm512_xor_si512(c2[3363],_mm512_xor_si512(c2[7058],_mm512_xor_si512(c2[7601],_mm512_xor_si512(c2[12089],_mm512_xor_si512(c2[6014],_mm512_xor_si512(c2[7609],_mm512_xor_si512(c2[7081],_mm512_xor_si512(c2[15265],_mm512_xor_si512(c2[8148],_mm512_xor_si512(c2[14222],_mm512_xor_si512(c2[14748],_mm512_xor_si512(c2[13970],_mm512_xor_si512(c2[14763],_mm512_xor_si512(c2[4732],_mm512_xor_si512(c2[1311],_mm512_xor_si512(c2[7121],c2[4215]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 25
d2[150]=_mm512_xor_si512(c2[2125],_mm512_xor_si512(c2[4560],_mm512_xor_si512(c2[16721],c2[14956])));
//row: 26
d2[156]=_mm512_xor_si512(c2[1849],_mm512_xor_si512(c2[4513],_mm512_xor_si512(c2[3217],c2[2294])));
//row: 27
d2[162]=_mm512_xor_si512(c2[543],_mm512_xor_si512(c2[603],c2[9865]));
//row: 28
d2[168]=_mm512_xor_si512(c2[7923],_mm512_xor_si512(c2[5064],_mm512_xor_si512(c2[13959],c2[5008])));
//row: 29
d2[174]=_mm512_xor_si512(c2[528],_mm512_xor_si512(c2[7130],_mm512_xor_si512(c2[7396],_mm512_xor_si512(c2[8981],_mm512_xor_si512(c2[9245],_mm512_xor_si512(c2[8989],_mm512_xor_si512(c2[2393],_mm512_xor_si512(c2[9782],_mm512_xor_si512(c2[10046],_mm512_xor_si512(c2[15855],_mm512_xor_si512(c2[290],_mm512_xor_si512(c2[7154],_mm512_xor_si512(c2[6096],_mm512_xor_si512(c2[37],_mm512_xor_si512(c2[6374],_mm512_xor_si512(c2[3733],_mm512_xor_si512(c2[3997],_mm512_xor_si512(c2[12461],_mm512_xor_si512(c2[7176],_mm512_xor_si512(c2[8765],_mm512_xor_si512(c2[9029],_mm512_xor_si512(c2[1120],_mm512_xor_si512(c2[8247],_mm512_xor_si512(c2[4025],_mm512_xor_si512(c2[10372],_mm512_xor_si512(c2[12747],_mm512_xor_si512(c2[5620],_mm512_xor_si512(c2[5884],_mm512_xor_si512(c2[6948],_mm512_xor_si512(c2[6953],_mm512_xor_si512(c2[10383],_mm512_xor_si512(c2[10647],_mm512_xor_si512(c2[6960],_mm512_xor_si512(c2[12507],_mm512_xor_si512(c2[1682],_mm512_xor_si512(c2[1946],_mm512_xor_si512(c2[3276],_mm512_xor_si512(c2[376],_mm512_xor_si512(c2[3806],_mm512_xor_si512(c2[12533],_mm512_xor_si512(c2[4347],_mm512_xor_si512(c2[4875],_mm512_xor_si512(c2[5139],_mm512_xor_si512(c2[15974],_mm512_xor_si512(c2[14393],_mm512_xor_si512(c2[16769],_mm512_xor_si512(c2[132],_mm512_xor_si512(c2[8593],_mm512_xor_si512(c2[9912],_mm512_xor_si512(c2[14140],_mm512_xor_si512(c2[14404],_mm512_xor_si512(c2[13884],_mm512_xor_si512(c2[6232],_mm512_xor_si512(c2[9396],_mm512_xor_si512(c2[9660],_mm512_xor_si512(c2[10732],_mm512_xor_si512(c2[10466],_mm512_xor_si512(c2[9148],_mm512_xor_si512(c2[9412],_mm512_xor_si512(c2[1488],_mm512_xor_si512(c2[10216],_mm512_xor_si512(c2[13382],_mm512_xor_si512(c2[1238],_mm512_xor_si512(c2[15242],_mm512_xor_si512(c2[13128],_mm512_xor_si512(c2[16565],_mm512_xor_si512(c2[16829],_mm512_xor_si512(c2[471],_mm512_xor_si512(c2[4959],_mm512_xor_si512(c2[15521],_mm512_xor_si512(c2[15785],_mm512_xor_si512(c2[485],_mm512_xor_si512(c2[16852],_mm512_xor_si512(c2[7877],_mm512_xor_si512(c2[8141],_mm512_xor_si512(c2[5234],_mm512_xor_si512(c2[1024],_mm512_xor_si512(c2[7092],_mm512_xor_si512(c2[7624],_mm512_xor_si512(c2[6840],_mm512_xor_si512(c2[7633],_mm512_xor_si512(c2[14233],_mm512_xor_si512(c2[14497],_mm512_xor_si512(c2[11076],_mm512_xor_si512(c2[16886],_mm512_xor_si512(c2[13716],c2[13980]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 30
d2[180]=_mm512_xor_si512(c2[3696],_mm512_xor_si512(c2[10298],_mm512_xor_si512(c2[10300],_mm512_xor_si512(c2[10564],_mm512_xor_si512(c2[12149],_mm512_xor_si512(c2[12413],_mm512_xor_si512(c2[8186],_mm512_xor_si512(c2[12157],_mm512_xor_si512(c2[5297],_mm512_xor_si512(c2[5561],_mm512_xor_si512(c2[12950],_mm512_xor_si512(c2[13214],_mm512_xor_si512(c2[3458],_mm512_xor_si512(c2[10322],_mm512_xor_si512(c2[9000],_mm512_xor_si512(c2[9264],_mm512_xor_si512(c2[3205],_mm512_xor_si512(c2[9542],_mm512_xor_si512(c2[6901],_mm512_xor_si512(c2[7165],_mm512_xor_si512(c2[15629],_mm512_xor_si512(c2[10080],_mm512_xor_si512(c2[10344],_mm512_xor_si512(c2[11933],_mm512_xor_si512(c2[12197],_mm512_xor_si512(c2[4288],_mm512_xor_si512(c2[11415],_mm512_xor_si512(c2[6929],_mm512_xor_si512(c2[7193],_mm512_xor_si512(c2[13540],_mm512_xor_si512(c2[15651],_mm512_xor_si512(c2[15915],_mm512_xor_si512(c2[8788],_mm512_xor_si512(c2[9052],_mm512_xor_si512(c2[10116],_mm512_xor_si512(c2[9857],_mm512_xor_si512(c2[10121],_mm512_xor_si512(c2[13551],_mm512_xor_si512(c2[13815],_mm512_xor_si512(c2[10128],_mm512_xor_si512(c2[15411],_mm512_xor_si512(c2[15675],_mm512_xor_si512(c2[4850],_mm512_xor_si512(c2[5114],_mm512_xor_si512(c2[6444],_mm512_xor_si512(c2[3544],_mm512_xor_si512(c2[6710],_mm512_xor_si512(c2[6974],_mm512_xor_si512(c2[15701],_mm512_xor_si512(c2[7251],_mm512_xor_si512(c2[7515],_mm512_xor_si512(c2[8043],_mm512_xor_si512(c2[8307],_mm512_xor_si512(c2[9891],_mm512_xor_si512(c2[2247],_mm512_xor_si512(c2[660],_mm512_xor_si512(c2[3036],_mm512_xor_si512(c2[3300],_mm512_xor_si512(c2[11761],_mm512_xor_si512(c2[13080],_mm512_xor_si512(c2[413],_mm512_xor_si512(c2[677],_mm512_xor_si512(c2[157],_mm512_xor_si512(c2[9136],_mm512_xor_si512(c2[9400],_mm512_xor_si512(c2[12564],_mm512_xor_si512(c2[12828],_mm512_xor_si512(c2[1216],_mm512_xor_si512(c2[13900],_mm512_xor_si512(c2[13370],_mm512_xor_si512(c2[13634],_mm512_xor_si512(c2[12316],_mm512_xor_si512(c2[12580],_mm512_xor_si512(c2[13384],_mm512_xor_si512(c2[16550],_mm512_xor_si512(c2[4142],_mm512_xor_si512(c2[4406],_mm512_xor_si512(c2[1515],_mm512_xor_si512(c2[16296],_mm512_xor_si512(c2[2832],_mm512_xor_si512(c2[3096],_mm512_xor_si512(c2[3639],_mm512_xor_si512(c2[7863],_mm512_xor_si512(c2[8127],_mm512_xor_si512(c2[1788],_mm512_xor_si512(c2[2052],_mm512_xor_si512(c2[3653],_mm512_xor_si512(c2[2861],_mm512_xor_si512(c2[3125],_mm512_xor_si512(c2[11045],_mm512_xor_si512(c2[11309],_mm512_xor_si512(c2[4192],_mm512_xor_si512(c2[10260],_mm512_xor_si512(c2[10528],_mm512_xor_si512(c2[10792],_mm512_xor_si512(c2[10008],_mm512_xor_si512(c2[10537],_mm512_xor_si512(c2[10801],_mm512_xor_si512(c2[506],_mm512_xor_si512(c2[770],_mm512_xor_si512(c2[14244],_mm512_xor_si512(c2[3159],_mm512_xor_si512(c2[16884],c2[253])))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 31
d2[186]=_mm512_xor_si512(c2[13994],_mm512_xor_si512(c2[13730],_mm512_xor_si512(c2[3701],_mm512_xor_si512(c2[3437],_mm512_xor_si512(c2[3961],_mm512_xor_si512(c2[3697],_mm512_xor_si512(c2[5810],_mm512_xor_si512(c2[5282],_mm512_xor_si512(c2[5546],_mm512_xor_si512(c2[5560],_mm512_xor_si512(c2[5296],_mm512_xor_si512(c2[15853],_mm512_xor_si512(c2[15589],_mm512_xor_si512(c2[6617],_mm512_xor_si512(c2[6089],_mm512_xor_si512(c2[6353],_mm512_xor_si512(c2[9517],_mm512_xor_si512(c2[13756],_mm512_xor_si512(c2[13492],_mm512_xor_si512(c2[3725],_mm512_xor_si512(c2[3461],_mm512_xor_si512(c2[2667],_mm512_xor_si512(c2[2403],_mm512_xor_si512(c2[13503],_mm512_xor_si512(c2[13239],_mm512_xor_si512(c2[2945],_mm512_xor_si512(c2[2681],_mm512_xor_si512(c2[568],_mm512_xor_si512(c2[40],_mm512_xor_si512(c2[304],_mm512_xor_si512(c2[9026],_mm512_xor_si512(c2[8762],_mm512_xor_si512(c2[3747],_mm512_xor_si512(c2[3483],_mm512_xor_si512(c2[5594],_mm512_xor_si512(c2[5066],_mm512_xor_si512(c2[5330],_mm512_xor_si512(c2[14580],_mm512_xor_si512(c2[14316],_mm512_xor_si512(c2[4812],_mm512_xor_si512(c2[4548],_mm512_xor_si512(c2[590],_mm512_xor_si512(c2[326],_mm512_xor_si512(c2[6937],_mm512_xor_si512(c2[6673],_mm512_xor_si512(c2[9312],_mm512_xor_si512(c2[9048],_mm512_xor_si512(c2[2449],_mm512_xor_si512(c2[1921],_mm512_xor_si512(c2[2185],_mm512_xor_si512(c2[3519],_mm512_xor_si512(c2[3255],_mm512_xor_si512(c2[3518],_mm512_xor_si512(c2[3254],_mm512_xor_si512(c2[7212],_mm512_xor_si512(c2[6684],_mm512_xor_si512(c2[6948],_mm512_xor_si512(c2[6159],_mm512_xor_si512(c2[3531],_mm512_xor_si512(c2[3267],_mm512_xor_si512(c2[9072],_mm512_xor_si512(c2[8808],_mm512_xor_si512(c2[15412],_mm512_xor_si512(c2[14884],_mm512_xor_si512(c2[15148],_mm512_xor_si512(c2[16742],_mm512_xor_si512(c2[16478],_mm512_xor_si512(c2[13836],_mm512_xor_si512(c2[13572],_mm512_xor_si512(c2[377],_mm512_xor_si512(c2[113],_mm512_xor_si512(c2[9098],_mm512_xor_si512(c2[8834],_mm512_xor_si512(c2[912],_mm512_xor_si512(c2[648],_mm512_xor_si512(c2[1704],_mm512_xor_si512(c2[1176],_mm512_xor_si512(c2[1440],_mm512_xor_si512(c2[12545],_mm512_xor_si512(c2[12281],_mm512_xor_si512(c2[10958],_mm512_xor_si512(c2[10694],_mm512_xor_si512(c2[13598],_mm512_xor_si512(c2[13070],_mm512_xor_si512(c2[13334],_mm512_xor_si512(c2[5164],_mm512_xor_si512(c2[4900],_mm512_xor_si512(c2[6483],_mm512_xor_si512(c2[6219],_mm512_xor_si512(c2[10969],_mm512_xor_si512(c2[10441],_mm512_xor_si512(c2[10705],_mm512_xor_si512(c2[10455],_mm512_xor_si512(c2[10191],_mm512_xor_si512(c2[2797],_mm512_xor_si512(c2[2533],_mm512_xor_si512(c2[6231],_mm512_xor_si512(c2[5703],_mm512_xor_si512(c2[5967],_mm512_xor_si512(c2[7297],_mm512_xor_si512(c2[7033],_mm512_xor_si512(c2[7037],_mm512_xor_si512(c2[6773],_mm512_xor_si512(c2[5977],_mm512_xor_si512(c2[5449],_mm512_xor_si512(c2[5713],_mm512_xor_si512(c2[6781],_mm512_xor_si512(c2[6517],_mm512_xor_si512(c2[9953],_mm512_xor_si512(c2[9689],_mm512_xor_si512(c2[14704],_mm512_xor_si512(c2[14440],_mm512_xor_si512(c2[11813],_mm512_xor_si512(c2[11549],_mm512_xor_si512(c2[9699],_mm512_xor_si512(c2[9435],_mm512_xor_si512(c2[13394],_mm512_xor_si512(c2[12866],_mm512_xor_si512(c2[13130],_mm512_xor_si512(c2[13937],_mm512_xor_si512(c2[13673],_mm512_xor_si512(c2[1524],_mm512_xor_si512(c2[1260],_mm512_xor_si512(c2[12350],_mm512_xor_si512(c2[11822],_mm512_xor_si512(c2[12086],_mm512_xor_si512(c2[13945],_mm512_xor_si512(c2[13681],_mm512_xor_si512(c2[13417],_mm512_xor_si512(c2[13153],_mm512_xor_si512(c2[4706],_mm512_xor_si512(c2[4178],_mm512_xor_si512(c2[4442],_mm512_xor_si512(c2[14484],_mm512_xor_si512(c2[14220],_mm512_xor_si512(c2[3663],_mm512_xor_si512(c2[3399],_mm512_xor_si512(c2[4189],_mm512_xor_si512(c2[3925],_mm512_xor_si512(c2[3411],_mm512_xor_si512(c2[3147],_mm512_xor_si512(c2[4204],_mm512_xor_si512(c2[3940],_mm512_xor_si512(c2[11068],_mm512_xor_si512(c2[10540],_mm512_xor_si512(c2[10804],_mm512_xor_si512(c2[7647],_mm512_xor_si512(c2[7383],_mm512_xor_si512(c2[13457],_mm512_xor_si512(c2[13193],_mm512_xor_si512(c2[10551],_mm512_xor_si512(c2[10023],c2[10287]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 32
d2[192]=_mm512_xor_si512(c2[5019],_mm512_xor_si512(c2[11621],_mm512_xor_si512(c2[11617],_mm512_xor_si512(c2[11881],_mm512_xor_si512(c2[13466],_mm512_xor_si512(c2[13730],_mm512_xor_si512(c2[10033],_mm512_xor_si512(c2[13480],_mm512_xor_si512(c2[6614],_mm512_xor_si512(c2[6878],_mm512_xor_si512(c2[14273],_mm512_xor_si512(c2[14537],_mm512_xor_si512(c2[4781],_mm512_xor_si512(c2[11645],_mm512_xor_si512(c2[10323],_mm512_xor_si512(c2[10587],_mm512_xor_si512(c2[4528],_mm512_xor_si512(c2[10865],_mm512_xor_si512(c2[8224],_mm512_xor_si512(c2[8488],_mm512_xor_si512(c2[51],_mm512_xor_si512(c2[11403],_mm512_xor_si512(c2[11667],_mm512_xor_si512(c2[13250],_mm512_xor_si512(c2[13514],_mm512_xor_si512(c2[5605],_mm512_xor_si512(c2[12732],_mm512_xor_si512(c2[8246],_mm512_xor_si512(c2[8510],_mm512_xor_si512(c2[14857],_mm512_xor_si512(c2[73],_mm512_xor_si512(c2[337],_mm512_xor_si512(c2[10105],_mm512_xor_si512(c2[10369],_mm512_xor_si512(c2[11439],_mm512_xor_si512(c2[11174],_mm512_xor_si512(c2[11438],_mm512_xor_si512(c2[14868],_mm512_xor_si512(c2[15132],_mm512_xor_si512(c2[11451],_mm512_xor_si512(c2[16728],_mm512_xor_si512(c2[97],_mm512_xor_si512(c2[6173],_mm512_xor_si512(c2[6437],_mm512_xor_si512(c2[7767],_mm512_xor_si512(c2[4861],_mm512_xor_si512(c2[8033],_mm512_xor_si512(c2[8297],_mm512_xor_si512(c2[123],_mm512_xor_si512(c2[8568],_mm512_xor_si512(c2[8832],_mm512_xor_si512(c2[9360],_mm512_xor_si512(c2[9624],_mm512_xor_si512(c2[3564],_mm512_xor_si512(c2[1983],_mm512_xor_si512(c2[4359],_mm512_xor_si512(c2[4623],_mm512_xor_si512(c2[13084],_mm512_xor_si512(c2[14403],_mm512_xor_si512(c2[1730],_mm512_xor_si512(c2[1994],_mm512_xor_si512(c2[2523],_mm512_xor_si512(c2[1480],_mm512_xor_si512(c2[10453],_mm512_xor_si512(c2[10717],_mm512_xor_si512(c2[13887],_mm512_xor_si512(c2[14151],_mm512_xor_si512(c2[15217],_mm512_xor_si512(c2[14693],_mm512_xor_si512(c2[14957],_mm512_xor_si512(c2[13633],_mm512_xor_si512(c2[13897],_mm512_xor_si512(c2[12578],_mm512_xor_si512(c2[14701],_mm512_xor_si512(c2[972],_mm512_xor_si512(c2[5465],_mm512_xor_si512(c2[5729],_mm512_xor_si512(c2[2832],_mm512_xor_si512(c2[724],_mm512_xor_si512(c2[4155],_mm512_xor_si512(c2[4419],_mm512_xor_si512(c2[4956],_mm512_xor_si512(c2[9180],_mm512_xor_si512(c2[9444],_mm512_xor_si512(c2[3111],_mm512_xor_si512(c2[3375],_mm512_xor_si512(c2[4970],_mm512_xor_si512(c2[4178],_mm512_xor_si512(c2[4442],_mm512_xor_si512(c2[12362],_mm512_xor_si512(c2[12626],_mm512_xor_si512(c2[5509],_mm512_xor_si512(c2[11583],_mm512_xor_si512(c2[11845],_mm512_xor_si512(c2[12109],_mm512_xor_si512(c2[11331],_mm512_xor_si512(c2[11860],_mm512_xor_si512(c2[12124],_mm512_xor_si512(c2[1829],_mm512_xor_si512(c2[2093],_mm512_xor_si512(c2[15567],_mm512_xor_si512(c2[4476],_mm512_xor_si512(c2[1312],c2[1576])))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 33
d2[198]=_mm512_xor_si512(c2[809],_mm512_xor_si512(c2[2136],_mm512_xor_si512(c2[10961],c2[11077])));
//row: 34
d2[204]=_mm512_xor_si512(c2[10035],_mm512_xor_si512(c2[5366],_mm512_xor_si512(c2[2823],c2[14992])));
//row: 35
d2[210]=_mm512_xor_si512(c2[16106],_mm512_xor_si512(c2[5813],_mm512_xor_si512(c2[6073],_mm512_xor_si512(c2[7922],_mm512_xor_si512(c2[7672],_mm512_xor_si512(c2[1070],_mm512_xor_si512(c2[8729],_mm512_xor_si512(c2[17],_mm512_xor_si512(c2[15868],_mm512_xor_si512(c2[5837],_mm512_xor_si512(c2[4779],_mm512_xor_si512(c2[15615],_mm512_xor_si512(c2[5057],_mm512_xor_si512(c2[2680],_mm512_xor_si512(c2[11138],_mm512_xor_si512(c2[5859],_mm512_xor_si512(c2[7706],_mm512_xor_si512(c2[16692],_mm512_xor_si512(c2[6924],_mm512_xor_si512(c2[2702],_mm512_xor_si512(c2[9049],_mm512_xor_si512(c2[11424],_mm512_xor_si512(c2[4561],_mm512_xor_si512(c2[4037],_mm512_xor_si512(c2[5631],_mm512_xor_si512(c2[5630],_mm512_xor_si512(c2[9324],_mm512_xor_si512(c2[5643],_mm512_xor_si512(c2[11184],_mm512_xor_si512(c2[629],_mm512_xor_si512(c2[1959],_mm512_xor_si512(c2[15948],_mm512_xor_si512(c2[2489],_mm512_xor_si512(c2[11210],_mm512_xor_si512(c2[3024],_mm512_xor_si512(c2[3816],_mm512_xor_si512(c2[14657],_mm512_xor_si512(c2[13070],_mm512_xor_si512(c2[15710],_mm512_xor_si512(c2[7276],_mm512_xor_si512(c2[8595],_mm512_xor_si512(c2[13081],_mm512_xor_si512(c2[672],_mm512_xor_si512(c2[12567],_mm512_xor_si512(c2[4909],_mm512_xor_si512(c2[8343],_mm512_xor_si512(c2[9409],_mm512_xor_si512(c2[9149],_mm512_xor_si512(c2[8089],_mm512_xor_si512(c2[8893],_mm512_xor_si512(c2[12065],_mm512_xor_si512(c2[16816],_mm512_xor_si512(c2[13925],_mm512_xor_si512(c2[11811],_mm512_xor_si512(c2[15506],_mm512_xor_si512(c2[16049],_mm512_xor_si512(c2[3636],_mm512_xor_si512(c2[14462],_mm512_xor_si512(c2[16057],_mm512_xor_si512(c2[15529],_mm512_xor_si512(c2[6818],_mm512_xor_si512(c2[16596],_mm512_xor_si512(c2[5775],_mm512_xor_si512(c2[6301],_mm512_xor_si512(c2[5523],_mm512_xor_si512(c2[6316],_mm512_xor_si512(c2[13180],_mm512_xor_si512(c2[9759],_mm512_xor_si512(c2[15569],c2[12663])))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 36
d2[216]=_mm512_xor_si512(c2[4755],_mm512_xor_si512(c2[15220],_mm512_xor_si512(c2[11008],c2[5760])));
//row: 37
d2[222]=_mm512_xor_si512(c2[10032],_mm512_xor_si512(c2[10296],_mm512_xor_si512(c2[3],_mm512_xor_si512(c2[269],_mm512_xor_si512(c2[2112],_mm512_xor_si512(c2[1598],_mm512_xor_si512(c2[1862],_mm512_xor_si512(c2[12161],_mm512_xor_si512(c2[2919],_mm512_xor_si512(c2[3448],_mm512_xor_si512(c2[9794],_mm512_xor_si512(c2[10058],_mm512_xor_si512(c2[27],_mm512_xor_si512(c2[15864],_mm512_xor_si512(c2[9541],_mm512_xor_si512(c2[9805],_mm512_xor_si512(c2[16142],_mm512_xor_si512(c2[13765],_mm512_xor_si512(c2[5328],_mm512_xor_si512(c2[49],_mm512_xor_si512(c2[1896],_mm512_xor_si512(c2[10624],_mm512_xor_si512(c2[10888],_mm512_xor_si512(c2[1120],_mm512_xor_si512(c2[13793],_mm512_xor_si512(c2[2981],_mm512_xor_si512(c2[3245],_mm512_xor_si512(c2[5620],_mm512_xor_si512(c2[15652],_mm512_xor_si512(c2[16716],_mm512_xor_si512(c2[16721],_mm512_xor_si512(c2[3520],_mm512_xor_si512(c2[16728],_mm512_xor_si512(c2[5380],_mm512_xor_si512(c2[11714],_mm512_xor_si512(c2[12780],_mm512_xor_si512(c2[13044],_mm512_xor_si512(c2[10144],_mm512_xor_si512(c2[13574],_mm512_xor_si512(c2[5136],_mm512_xor_si512(c2[5400],_mm512_xor_si512(c2[14115],_mm512_xor_si512(c2[14907],_mm512_xor_si512(c2[8583],_mm512_xor_si512(c2[8847],_mm512_xor_si512(c2[7260],_mm512_xor_si512(c2[9900],_mm512_xor_si512(c2[1202],_mm512_xor_si512(c2[1466],_mm512_xor_si512(c2[2785],_mm512_xor_si512(c2[7277],_mm512_xor_si512(c2[6493],_mm512_xor_si512(c2[6757],_mm512_xor_si512(c2[16000],_mm512_xor_si512(c2[2533],_mm512_xor_si512(c2[4909],_mm512_xor_si512(c2[3605],_mm512_xor_si512(c2[3339],_mm512_xor_si512(c2[2285],_mm512_xor_si512(c2[2825],_mm512_xor_si512(c2[3089],_mm512_xor_si512(c2[6255],_mm512_xor_si512(c2[11006],_mm512_xor_si512(c2[7851],_mm512_xor_si512(c2[8115],_mm512_xor_si512(c2[6001],_mm512_xor_si512(c2[9696],_mm512_xor_si512(c2[10239],_mm512_xor_si512(c2[14727],_mm512_xor_si512(c2[8652],_mm512_xor_si512(c2[9989],_mm512_xor_si512(c2[10253],_mm512_xor_si512(c2[9725],_mm512_xor_si512(c2[1008],_mm512_xor_si512(c2[10528],_mm512_xor_si512(c2[10792],_mm512_xor_si512(c2[16860],_mm512_xor_si512(c2[497],_mm512_xor_si512(c2[16344],_mm512_xor_si512(c2[16608],_mm512_xor_si512(c2[506],_mm512_xor_si512(c2[7370],_mm512_xor_si512(c2[3685],_mm512_xor_si512(c2[3949],_mm512_xor_si512(c2[9759],c2[6853])))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 38
d2[228]=_mm512_xor_si512(c2[15050],_mm512_xor_si512(c2[13046],_mm512_xor_si512(c2[8836],c2[5955])));
//row: 39
d2[234]=_mm512_xor_si512(c2[544],_mm512_xor_si512(c2[7693],_mm512_xor_si512(c2[6953],c2[11056])));
//row: 40
d2[240]=_mm512_xor_si512(c2[12410],_mm512_xor_si512(c2[9864],c2[14992]));
//row: 41
d2[246]=_mm512_xor_si512(c2[13740],_mm512_xor_si512(c2[15352],_mm512_xor_si512(c2[3014],c2[8668])));
//row: 42
d2[252]=_mm512_xor_si512(c2[3698],_mm512_xor_si512(c2[10300],_mm512_xor_si512(c2[10296],_mm512_xor_si512(c2[10560],_mm512_xor_si512(c2[12145],_mm512_xor_si512(c2[12409],_mm512_xor_si512(c2[12937],_mm512_xor_si512(c2[12159],_mm512_xor_si512(c2[5293],_mm512_xor_si512(c2[5557],_mm512_xor_si512(c2[12952],_mm512_xor_si512(c2[13216],_mm512_xor_si512(c2[3460],_mm512_xor_si512(c2[10324],_mm512_xor_si512(c2[9002],_mm512_xor_si512(c2[9266],_mm512_xor_si512(c2[3207],_mm512_xor_si512(c2[9544],_mm512_xor_si512(c2[6903],_mm512_xor_si512(c2[7167],_mm512_xor_si512(c2[15625],_mm512_xor_si512(c2[10082],_mm512_xor_si512(c2[10346],_mm512_xor_si512(c2[11929],_mm512_xor_si512(c2[12193],_mm512_xor_si512(c2[3744],_mm512_xor_si512(c2[4284],_mm512_xor_si512(c2[11417],_mm512_xor_si512(c2[6925],_mm512_xor_si512(c2[7189],_mm512_xor_si512(c2[13536],_mm512_xor_si512(c2[15653],_mm512_xor_si512(c2[15917],_mm512_xor_si512(c2[8784],_mm512_xor_si512(c2[9048],_mm512_xor_si512(c2[10118],_mm512_xor_si512(c2[9853],_mm512_xor_si512(c2[10117],_mm512_xor_si512(c2[13553],_mm512_xor_si512(c2[13817],_mm512_xor_si512(c2[10130],_mm512_xor_si512(c2[15413],_mm512_xor_si512(c2[15677],_mm512_xor_si512(c2[4852],_mm512_xor_si512(c2[5116],_mm512_xor_si512(c2[6446],_mm512_xor_si512(c2[3540],_mm512_xor_si512(c2[6712],_mm512_xor_si512(c2[6976],_mm512_xor_si512(c2[15697],_mm512_xor_si512(c2[7253],_mm512_xor_si512(c2[7517],_mm512_xor_si512(c2[8045],_mm512_xor_si512(c2[8309],_mm512_xor_si512(c2[2249],_mm512_xor_si512(c2[662],_mm512_xor_si512(c2[3038],_mm512_xor_si512(c2[3302],_mm512_xor_si512(c2[11763],_mm512_xor_si512(c2[13082],_mm512_xor_si512(c2[409],_mm512_xor_si512(c2[673],_mm512_xor_si512(c2[159],_mm512_xor_si512(c2[9132],_mm512_xor_si512(c2[9396],_mm512_xor_si512(c2[12566],_mm512_xor_si512(c2[12830],_mm512_xor_si512(c2[13896],_mm512_xor_si512(c2[13372],_mm512_xor_si512(c2[13636],_mm512_xor_si512(c2[12312],_mm512_xor_si512(c2[12576],_mm512_xor_si512(c2[13380],_mm512_xor_si512(c2[16552],_mm512_xor_si512(c2[4144],_mm512_xor_si512(c2[4408],_mm512_xor_si512(c2[1517],_mm512_xor_si512(c2[16298],_mm512_xor_si512(c2[2834],_mm512_xor_si512(c2[3098],_mm512_xor_si512(c2[3641],_mm512_xor_si512(c2[7865],_mm512_xor_si512(c2[8129],_mm512_xor_si512(c2[1790],_mm512_xor_si512(c2[2054],_mm512_xor_si512(c2[3649],_mm512_xor_si512(c2[2857],_mm512_xor_si512(c2[3121],_mm512_xor_si512(c2[11041],_mm512_xor_si512(c2[11305],_mm512_xor_si512(c2[4188],_mm512_xor_si512(c2[10262],_mm512_xor_si512(c2[10524],_mm512_xor_si512(c2[10788],_mm512_xor_si512(c2[10010],_mm512_xor_si512(c2[10539],_mm512_xor_si512(c2[10803],_mm512_xor_si512(c2[508],_mm512_xor_si512(c2[772],_mm512_xor_si512(c2[14246],_mm512_xor_si512(c2[3161],_mm512_xor_si512(c2[16886],c2[255]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 43
d2[258]=_mm512_xor_si512(c2[7393],_mm512_xor_si512(c2[13995],_mm512_xor_si512(c2[14261],_mm512_xor_si512(c2[15840],_mm512_xor_si512(c2[16104],_mm512_xor_si512(c2[15854],_mm512_xor_si512(c2[9252],_mm512_xor_si512(c2[16647],_mm512_xor_si512(c2[16],_mm512_xor_si512(c2[12949],_mm512_xor_si512(c2[7155],_mm512_xor_si512(c2[14019],_mm512_xor_si512(c2[12961],_mm512_xor_si512(c2[6902],_mm512_xor_si512(c2[13239],_mm512_xor_si512(c2[10598],_mm512_xor_si512(c2[10862],_mm512_xor_si512(c2[2425],_mm512_xor_si512(c2[14041],_mm512_xor_si512(c2[15624],_mm512_xor_si512(c2[15888],_mm512_xor_si512(c2[7985],_mm512_xor_si512(c2[15112],_mm512_xor_si512(c2[10884],_mm512_xor_si512(c2[336],_mm512_xor_si512(c2[2717],_mm512_xor_si512(c2[12485],_mm512_xor_si512(c2[12749],_mm512_xor_si512(c2[13813],_mm512_xor_si512(c2[13812],_mm512_xor_si512(c2[353],_mm512_xor_si512(c2[617],_mm512_xor_si512(c2[13825],_mm512_xor_si512(c2[2477],_mm512_xor_si512(c2[8547],_mm512_xor_si512(c2[8811],_mm512_xor_si512(c2[10141],_mm512_xor_si512(c2[7241],_mm512_xor_si512(c2[10671],_mm512_xor_si512(c2[2497],_mm512_xor_si512(c2[11212],_mm512_xor_si512(c2[11740],_mm512_xor_si512(c2[12004],_mm512_xor_si512(c2[5944],_mm512_xor_si512(c2[4357],_mm512_xor_si512(c2[6733],_mm512_xor_si512(c2[6997],_mm512_xor_si512(c2[15458],_mm512_xor_si512(c2[16777],_mm512_xor_si512(c2[4104],_mm512_xor_si512(c2[4368],_mm512_xor_si512(c2[3854],_mm512_xor_si512(c2[13097],_mm512_xor_si512(c2[16261],_mm512_xor_si512(c2[16525],_mm512_xor_si512(c2[696],_mm512_xor_si512(c2[436],_mm512_xor_si512(c2[16013],_mm512_xor_si512(c2[16277],_mm512_xor_si512(c2[180],_mm512_xor_si512(c2[3352],_mm512_xor_si512(c2[8103],_mm512_xor_si512(c2[5212],_mm512_xor_si512(c2[3098],_mm512_xor_si512(c2[6529],_mm512_xor_si512(c2[6793],_mm512_xor_si512(c2[1250],_mm512_xor_si512(c2[7336],_mm512_xor_si512(c2[11824],_mm512_xor_si512(c2[5485],_mm512_xor_si512(c2[5749],_mm512_xor_si512(c2[7344],_mm512_xor_si512(c2[6816],_mm512_xor_si512(c2[14736],_mm512_xor_si512(c2[15000],_mm512_xor_si512(c2[13417],_mm512_xor_si512(c2[7889],_mm512_xor_si512(c2[13957],_mm512_xor_si512(c2[14489],_mm512_xor_si512(c2[13705],_mm512_xor_si512(c2[14498],_mm512_xor_si512(c2[4203],_mm512_xor_si512(c2[4467],_mm512_xor_si512(c2[1046],_mm512_xor_si512(c2[6856],_mm512_xor_si512(c2[3686],c2[3950]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 44
d2[264]=_mm512_xor_si512(c2[1323],_mm512_xor_si512(c2[7925],_mm512_xor_si512(c2[8185],_mm512_xor_si512(c2[10034],_mm512_xor_si512(c2[4225],_mm512_xor_si512(c2[9784],_mm512_xor_si512(c2[3182],_mm512_xor_si512(c2[10841],_mm512_xor_si512(c2[1085],_mm512_xor_si512(c2[7949],_mm512_xor_si512(c2[6891],_mm512_xor_si512(c2[832],_mm512_xor_si512(c2[7169],_mm512_xor_si512(c2[4792],_mm512_xor_si512(c2[13250],_mm512_xor_si512(c2[7971],_mm512_xor_si512(c2[9818],_mm512_xor_si512(c2[1909],_mm512_xor_si512(c2[9036],_mm512_xor_si512(c2[4814],_mm512_xor_si512(c2[11161],_mm512_xor_si512(c2[13536],_mm512_xor_si512(c2[6673],_mm512_xor_si512(c2[7743],_mm512_xor_si512(c2[7742],_mm512_xor_si512(c2[11436],_mm512_xor_si512(c2[3781],_mm512_xor_si512(c2[7755],_mm512_xor_si512(c2[13296],_mm512_xor_si512(c2[2741],_mm512_xor_si512(c2[4071],_mm512_xor_si512(c2[1165],_mm512_xor_si512(c2[4601],_mm512_xor_si512(c2[9350],_mm512_xor_si512(c2[13322],_mm512_xor_si512(c2[5136],_mm512_xor_si512(c2[5928],_mm512_xor_si512(c2[16769],_mm512_xor_si512(c2[15182],_mm512_xor_si512(c2[927],_mm512_xor_si512(c2[9388],_mm512_xor_si512(c2[10707],_mm512_xor_si512(c2[15193],_mm512_xor_si512(c2[14679],_mm512_xor_si512(c2[7021],_mm512_xor_si512(c2[10455],_mm512_xor_si512(c2[11521],_mm512_xor_si512(c2[11261],_mm512_xor_si512(c2[10201],_mm512_xor_si512(c2[11005],_mm512_xor_si512(c2[14177],_mm512_xor_si512(c2[2033],_mm512_xor_si512(c2[16037],_mm512_xor_si512(c2[13923],_mm512_xor_si512(c2[723],_mm512_xor_si512(c2[1260],_mm512_xor_si512(c2[5748],_mm512_xor_si512(c2[16574],_mm512_xor_si512(c2[1274],_mm512_xor_si512(c2[746],_mm512_xor_si512(c2[8930],_mm512_xor_si512(c2[1813],_mm512_xor_si512(c2[7887],_mm512_xor_si512(c2[8413],_mm512_xor_si512(c2[7635],_mm512_xor_si512(c2[8428],_mm512_xor_si512(c2[15292],_mm512_xor_si512(c2[11871],_mm512_xor_si512(c2[780],c2[14775])))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
//row: 45
d2[270]=_mm512_xor_si512(c2[1862],_mm512_xor_si512(c2[5618],c2[4080]));
}
}

View File

@@ -37,7 +37,11 @@
#include "common/utils/LOG/log.h"
#ifdef __AVX512F__
#include "ldpc384_simd512_byte.c"
#else
#include "ldpc384_byte.c"
#endif
#include "ldpc384_byte_128.c"
#include "ldpc352_byte.c"
#include "ldpc352_byte_128.c"
@@ -87,7 +91,7 @@
static void encode_parity_check_part_optim(uint8_t *cc, uint8_t *d, short BG,short Zc,short Kb, int simd_size, int ncols)
{
unsigned char c[2 * 22 * Zc * simd_size] __attribute__((aligned(32))); //double size matrix of c
unsigned char c[2 * 22 * Zc * simd_size] __attribute__((aligned(64))); //double size matrix of c
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));
@@ -95,7 +99,6 @@ static void encode_parity_check_part_optim(uint8_t *cc, uint8_t *d, short BG,sho
for (int i1 = 1; i1 < simd_size; i1++) {
memcpy(&c[(2 * ncols * Zc * i1)], &c[i1], (2 * ncols * Zc * sizeof(unsigned char)) - i1);
}
if (BG == 1) {
switch (Zc) {
case 176:

View File

@@ -114,7 +114,13 @@ int LDPCencoder(unsigned char **inputArray, unsigned char **outputArray, encoder
fprintf(fd,"#include \"PHY/sse_intrin.h\"\n");
fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n");
if (gen_code == 1 && (Zc&31)==0) {
if (gen_code == 1 && (Zc&63)==0) {
shift=6;
mask=63;
strcpy(data_type,"__m512i");
strcpy(xor_command,"_mm512_xor_si512");
}
else if (gen_code == 1 && (Zc&31)==0) {
shift=5; // AVX2 - 256-bit SIMD
mask=31;
strcpy(data_type,"simde__m256i");

View File

@@ -79,10 +79,13 @@ int LDPCencoder(uint8_t **test_input, uint8_t **channel_input, encoder_implempar
#endif
if ((Zc&31) > 0) simd_size = 16;
#ifdef __AVX512F__
else if ((BG==1) && (Zc==384)) simd_size=64;
#endif
else simd_size = 32;
uint8_t c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
uint8_t d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
uint8_t c[22*Zc] __attribute__((aligned(64))); //padded input, unpacked, max size
uint8_t d[46*Zc] __attribute__((aligned(64))); //coded parity part output, unpacked, max size
// calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;

View File

@@ -97,10 +97,13 @@ int LDPCencoder(uint8_t **test_input, uint8_t **channel_input, encoder_implempar
AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
if ((Zc&31) > 0) simd_size = 16;
else simd_size = 32;
#ifdef __AVX512F__
else if ((BG==1) && (Zc==384)) simd_size = 64;
#endif
else simd_size = 32;
unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
unsigned char c[22*Zc] __attribute__((aligned(64))); //padded input, unpacked, max size
unsigned char d[46*Zc] __attribute__((aligned(64))); //coded parity part output, unpacked, max size
// calculate number of punctured bits
@@ -131,6 +134,7 @@ int LDPCencoder(uint8_t **test_input, uint8_t **channel_input, encoder_implempar
((simde__m256i *)c)[i] = c256;
}
for (i=(block_length>>5)<<5;i<block_length;i++) {
for (j=0; j<impp->n_segments; j++) {
@@ -164,6 +168,36 @@ int LDPCencoder(uint8_t **test_input, uint8_t **channel_input, encoder_implempar
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
*/
#ifdef __AVX512F__
uint32_t l1 = (block_length-(2*Zc));
uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit);
if ((((2*Zc)&63) == 0) && (((block_length-(2*Zc))&63) == 0)) {
__m512i *c512p = (__m512i *)&c[2*Zc];
__m512i *d512p = (__m512i *)&d[0];
__m512i mask0 = _mm512_set1_epi8(0x1);
for (i=0;i<l1>>6;i++)
for (j=0;j<impp->n_segments;j++)
((__m512i *)channel_input[j])[i] = _mm512_and_si512(_mm512_srai_epi16(c512p[i],j),mask0);
for (i1=0;i1<l2>>6;i1++,i++)
for (j=0;j<impp->n_segments;j++)
((__m512i *)channel_input[j])[i] = _mm512_and_si512(_mm512_srai_epi16(d512p[i1],j),mask0);
}
else if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) {
__m256i *c256p = (__m256i *)&c[2*Zc];
__m256i *d256p = (__m256i *)&d[0];
__m256i mask0 = _mm256_set1_epi8(0x1);
for (i=0;i<l1>>6;i++)
for (j=0;j<impp->n_segments;j++)
((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),mask0);
for (i1=0;i1<l2>>6;i1++,i++)
for (j=0;j<impp->n_segments;j++)
((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),mask0);
}
#else
if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) {
//AssertFatal(((2*Zc)&31) == 0,"2*Zc needs to be a multiple of 32 for now\n");
//AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n");
@@ -181,6 +215,7 @@ int LDPCencoder(uint8_t **test_input, uint8_t **channel_input, encoder_implempar
for (i1=0;i1<l2;i1++,i++)
for (j=0;j<impp->n_segments;j++) ((simde__m256i *)channel_input[j])[i] = simde_mm256_and_si256(simde_mm256_srai_epi16(d256p[i1],j),masks[0]);
}
#endif
else {
#ifdef DEBUG_LDPC
LOG_W(PHY,"using non-optimized version\n");
@@ -194,6 +229,7 @@ int LDPCencoder(uint8_t **test_input, uint8_t **channel_input, encoder_implempar
channel_input[j][block_length-2*Zc+i] = (d[i]>>j)&1;
}
if(impp->toutput != NULL) stop_meas(impp->toutput);
return 0;
}

View File

@@ -65,7 +65,22 @@ int LDPCencoder(uint8_t **input, uint8_t **output, encoder_implemparams_t *impp)
macro_segment_end = (impp->n_segments > 8*(impp->macro_num+1)) ? 8*(impp->macro_num+1) : impp->n_segments;
///printf("macro_segment: %d\n", macro_segment);
///printf("macro_segment_end: %d\n", macro_segment_end );
#ifdef __aarch64__
simde__m128i shufmask = simde_mm_set_epi64x(0x0101010101010101, 0x0000000000000000);
simde__m128i andmask = simde_mm_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats.
simde__m128i zero128 = simde_mm_setzero_si128();
simde__m128i masks[8];
register simde__m128i c128;
masks[0] = simde_mm_set1_epi8(0x1);
masks[1] = simde_mm_set1_epi8(0x2);
masks[2] = simde_mm_set1_epi8(0x4);
masks[3] = simde_mm_set1_epi8(0x8);
masks[4] = simde_mm_set1_epi8(0x10);
masks[5] = simde_mm_set1_epi8(0x20);
masks[6] = simde_mm_set1_epi8(0x40);
masks[7] = simde_mm_set1_epi8(0x80);
#else
simde__m256i shufmask = simde_mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
simde__m256i andmask = simde_mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats.
simde__m256i zero256 = simde_mm256_setzero_si256();
@@ -79,7 +94,7 @@ int LDPCencoder(uint8_t **input, uint8_t **output, encoder_implemparams_t *impp)
masks[5] = simde_mm256_set1_epi8(0x20);
masks[6] = simde_mm256_set1_epi8(0x40);
masks[7] = simde_mm256_set1_epi8(0x80);
#endif
//determine number of bits in codeword
@@ -103,10 +118,12 @@ int LDPCencoder(uint8_t **input, uint8_t **output, encoder_implemparams_t *impp)
AssertFatal(Zc > 0, "no valid Zc found for block length %d\n", block_length);
if ((Zc&31) > 0) simd_size = 16;
else
simd_size = 32;
unsigned char cc[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
unsigned char dd[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
#ifdef __AVX512F__
else if ((BG==1) && Zc==384) simd_size =64;
#endif
else simd_size=32;
unsigned char cc[22*Zc] __attribute__((aligned(64))); //padded input, unpacked, max size
unsigned char dd[46*Zc] __attribute__((aligned(64))); //coded parity part output, unpacked, max size
// calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
@@ -118,6 +135,7 @@ int LDPCencoder(uint8_t **input, uint8_t **output, encoder_implemparams_t *impp)
memset(dd,0,sizeof(unsigned char) * nrows * Zc);
if(impp->tinput != NULL) start_meas(impp->tinput);
//interleave up to 8 transport-block segements at a time
#if 0
for (i=0; i<block_length; i++) {
//for (j=0; j<n_segments; j++) {
@@ -128,6 +146,25 @@ int LDPCencoder(uint8_t **input, uint8_t **output, encoder_implemparams_t *impp)
c[i] |= (temp << (j-macro_segment));
}
}
#elif defined(__aarch64__)
for (int i=0; i<block_length>>4; i++) {
c128 = simde_mm_and_si128(simde_mm_cmpeq_epi8(simde_mm_andnot_si128(simde_mm_shuffle_epi8(simde_mm_set1_epi16(((uint16_t*)input[macro_segment])[i]), shufmask),andmask),zero128),masks[0]);
//for (j=1; j<n_segments; j++) {
for (int j=macro_segment+1; j < macro_segment_end; j++) {
c128 = simde_mm_or_si128(simde_mm_and_si128(simde_mm_cmpeq_epi8(simde_mm_andnot_si128(simde_mm_shuffle_epi8(simde_mm_set1_epi32(((uint16_t*)input[j])[i]), shufmask),andmask),zero128),masks[j-macro_segment]),c128);
}
((simde__m128i *)cc)[i] = c128;
}
for (int i=(block_length>>4)<<4;i<block_length;i++) {
//for (j=0; j<n_segments; j++) {
for (int j=macro_segment; j < macro_segment_end; j++) {
temp = (input[j][i/8]&(128>>(i&7)))>>(7-(i&7));
//printf("c(%d,%d)=%d\n",j,i,temp);
cc[i] |= (temp << (j-macro_segment));
}
}
#else
for (int i=0; i<block_length>>5; i++) {
c256 = simde_mm256_and_si256(simde_mm256_cmpeq_epi8(simde_mm256_andnot_si256(simde_mm256_shuffle_epi8(simde_mm256_set1_epi32(((uint32_t*)input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
@@ -166,48 +203,8 @@ int LDPCencoder(uint8_t **input, uint8_t **output, encoder_implemparams_t *impp)
return(-1);
}
}
if(impp->toutput != NULL) start_meas(impp->toutput);
// information part and puncture columns
/*
memcpy(&output[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
memcpy(&output[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
*/
if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) {
//AssertFatal(((2*Zc)&31) == 0,"2*Zc needs to be a multiple of 32 for now\n");
//AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n");
uint32_t l1 = (block_length-(2*Zc))>>5;
uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
simde__m256i *c256p = (simde__m256i *)&cc[2*Zc];
simde__m256i *d256p = (simde__m256i *)&dd[0];
// if (((block_length-(2*Zc))&31)>0) l1++;
for (int i=0;i<l1;i++)
//for (j=0;j<n_segments;j++) ((simde__m256i *)output[j])[i] = simde_mm256_and_si256(simde_mm256_srai_epi16(c256p[i],j),masks[0]);
for (int j=macro_segment; j < macro_segment_end; j++) ((simde__m256i *)output[j])[i] = simde_mm256_and_si256(simde_mm256_srai_epi16(c256p[i],j-macro_segment),masks[0]);
// if ((((nrows-no_punctured_columns) * Zc-removed_bit)&31)>0) l2++;
for (int i1=0, i=l1;i1<l2;i1++,i++)
//for (j=0;j<n_segments;j++) ((simde__m256i *)output[j])[i] = simde_mm256_and_si256(simde_mm256_srai_epi16(d256p[i1],j),masks[0]);
for (int j=macro_segment; j < macro_segment_end; j++) ((simde__m256i *)output[j])[i] = simde_mm256_and_si256(simde_mm256_srai_epi16(d256p[i1],j-macro_segment),masks[0]);
}
else {
#ifdef DEBUG_LDPC
LOG_W(PHY,"using non-optimized version\n");
#endif
// do non-SIMD version
for (int i=0;i<(block_length-2*Zc);i++)
//for (j=0; j<n_segments; j++)
for (int j=macro_segment; j < macro_segment_end; j++)
output[j][i] = (cc[2*Zc+i]>>(j-macro_segment))&1;
for (int i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
//for (j=0; j<n_segments; j++)
for (int j=macro_segment; j < macro_segment_end; j++)
output[j][block_length-2*Zc+i] = (dd[i]>>(j-macro_segment))&1;
}
if(impp->toutput != NULL) stop_meas(impp->toutput);
memcpy(output[0],&cc[2*Zc],(block_length-(2*Zc)));
memcpy(output[0]+block_length-(2*Zc),dd,((nrows-no_punctured_columns) * Zc-removed_bit));
return 0;
}

View File

@@ -151,13 +151,8 @@ else
for (r=0; r<*C; r++) {
k = 0;
while (k<((Kprime - L)>>3)) {
output_buffers[r][k] = input_buffer[s];
//printf("encoding segment %d : byte %d (%d) => %d\n",r,k,(Kprime-L)>>3,input_buffer[s]);
k++;
s++;
}
memcpy(output_buffers[r],input_buffer+s,(Kprime-L)>>3);
s+=(Kprime-L)>>3;
if (*C > 1) { // add CRC
crc = crc24b(output_buffers[r],Kprime-L)>>8;

View File

@@ -24,8 +24,10 @@
#include "executables/softmodem-common.h"
// #define DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // TODO: For debug, to be removed if want to merge to develop
//Table 6.3.1.5-1 Precoding Matrix W 1 layer 2 antenna ports 'n' = -1 and 'o' = -j
//#define DEBUG_LAYER_MAPPING
#define USE_NEON
//#define USE_GATHER
// Table 6.3.1.5-1 Precoding Matrix W 1 layer 2 antenna ports 'n' = -1 and 'o' = -j
const char nr_W_1l_2p[6][2][1] = {
{{'1'}, {'0'}}, // pmi 0
{{'0'}, {'1'}},
@@ -35,7 +37,7 @@ const char nr_W_1l_2p[6][2][1] = {
{{'1'}, {'o'}} // pmi 5
};
//Table 6.3.1.5-3 Precoding Matrix W 1 layer 4 antenna ports 'n' = -1 and 'o' = -j
// Table 6.3.1.5-3 Precoding Matrix W 1 layer 4 antenna ports 'n' = -1 and 'o' = -j
const char nr_W_1l_4p[28][4][1] = {
{{'1'}, {'0'}, {'0'}, {'0'}}, // pmi 0
{{'0'}, {'1'}, {'0'}, {'0'}},
@@ -68,14 +70,14 @@ const char nr_W_1l_4p[28][4][1] = {
{{'1'}, {'o'}, {'o'}, {'n'}} // pmi 27
};
//Table 6.3.1.5-4 Precoding Matrix W 2 antenna ports layers 2 'n' = -1 and 'o' = -j
// Table 6.3.1.5-4 Precoding Matrix W 2 antenna ports layers 2 'n' = -1 and 'o' = -j
const char nr_W_2l_2p[3][2][2] = {
{{'1', '0'}, {'0', '1'}}, // pmi 0
{{'1', '1'}, {'1', 'n'}},
{{'1', '1'}, {'j', 'o'}} // pmi 2
};
//Table 6.3.1.5-5 Precoding Matrix W 2 layers 4 antenna ports 'n' = -1 and 'o' = -j
// Table 6.3.1.5-5 Precoding Matrix W 2 layers 4 antenna ports 'n' = -1 and 'o' = -j
const char nr_W_2l_4p[22][4][2] = {
{{'1', '0'}, {'0', '1'}, {'0', '0'}, {'0', '0'}}, // pmi 0
{{'1', '0'}, {'0', '0'}, {'0', '1'}, {'0', '0'}}, {{'1', '0'}, {'0', '0'}, {'0', '0'}, {'0', '1'}},
@@ -94,7 +96,7 @@ const char nr_W_2l_4p[22][4][2] = {
{{'1', '1'}, {'o', 'o'}, {'1', 'n'}, {'o', 'j'}}, {{'1', '1'}, {'o', 'o'}, {'j', 'o'}, {'1', 'n'}} // pmi 21
};
//Table 6.3.1.5-6 Precoding Matrix W 3 layers 4 antenna ports 'n' = -1 and 'o' = -j
// Table 6.3.1.5-6 Precoding Matrix W 3 layers 4 antenna ports 'n' = -1 and 'o' = -j
const char nr_W_3l_4p[7][4][3] = {{{'1', '0', '0'}, {'0', '1', '0'}, {'0', '0', '1'}, {'0', '0', '0'}}, // pmi 0
{{'1', '0', '0'}, {'0', '1', '0'}, {'1', '0', '0'}, {'0', '0', '1'}},
{{'1', '0', '0'}, {'0', '1', '0'}, {'n', '0', '0'}, {'0', '0', '1'}},
@@ -103,7 +105,7 @@ const char nr_W_3l_4p[7][4][3] = {{{'1', '0', '0'}, {'0', '1', '0'}, {'0', '0',
{{'1', '1', '1'}, {'n', '1', 'n'}, {'1', '1', 'n'}, {'n', '1', '1'}},
{{'1', '1', '1'}, {'n', '1', 'n'}, {'j', 'j', 'o'}, {'o', 'j', 'j'}}};
//Table 6.3.1.5-7 Precoding Matrix W 4 layers 4 antenna ports 'n' = -1 and 'o' = -j
// Table 6.3.1.5-7 Precoding Matrix W 4 layers 4 antenna ports 'n' = -1 and 'o' = -j
const char nr_W_4l_4p[5][4][4] = {
{{'1', '0', '0', '0'}, {'0', '1', '0', '0'}, {'0', '0', '1', '0'}, {'0', '0', '0', '1'}}, // pmi 0
{{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'1', 'n', '0', '0'}, {'0', '0', '1', 'n'}},
@@ -112,137 +114,133 @@ const char nr_W_4l_4p[5][4][4] = {
{{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}} // pmi 4
};
void nr_modulation(const uint32_t *in,
uint32_t length,
uint16_t mod_order,
int16_t *out)
void nr_modulation(const uint32_t *in, uint32_t length, uint16_t mod_order, int16_t *out)
{
uint16_t mask = ((1<<mod_order)-1);
int32_t* nr_mod_table32;
int32_t* out32 = (int32_t*) out;
uint16_t mask = ((1 << mod_order) - 1);
int32_t *nr_mod_table32;
int32_t *out32 = (int32_t *)out;
const uint8_t *in_bytes = (const uint8_t *)in;
const uint64_t *in64 = (const uint64_t *)in;
int64_t* out64 = (int64_t*) out;
uint32_t i=0;
int64_t *out64 = (int64_t *)out;
uint32_t i = 0;
#if defined(__SSE2__)
simde__m128i *nr_mod_table128;
simde__m128i *out128;
#endif
LOG_D(PHY,"nr_modulation: length %d, mod_order %d\n",length,mod_order);
LOG_D(PHY, "nr_modulation: length %d, mod_order %d\n", length, mod_order);
switch (mod_order) {
#if defined(__SSE2__)
case 2:
nr_mod_table128 = (simde__m128i *)nr_qpsk_byte_mod_table;
out128 = (simde__m128i *)out;
for (i=0; i<length/8; i++)
out128[i] = nr_mod_table128[in_bytes[i]];
// the bits that are left out
i = i*8/2;
nr_mod_table32 = (int32_t*) nr_qpsk_mod_table;
while (i<length/2) {
const int idx = ((in_bytes[(i * 2) / 8] >> ((i * 2) & 0x7)) & mask);
out32[i] = nr_mod_table32[idx];
i++;
}
return;
case 2:
nr_mod_table128 = (simde__m128i *)nr_qpsk_byte_mod_table;
out128 = (simde__m128i *)out;
for (i = 0; i < length / 8; i++)
out128[i] = nr_mod_table128[in_bytes[i]];
// the bits that are left out
i = i * 8 / 2;
nr_mod_table32 = (int32_t *)nr_qpsk_mod_table;
while (i < length / 2) {
const int idx = ((in_bytes[(i * 2) / 8] >> ((i * 2) & 0x7)) & mask);
out32[i] = nr_mod_table32[idx];
i++;
}
return;
#else
case 2:
nr_mod_table32 = (int32_t*) nr_qpsk_mod_table;
for (i=0; i<length/mod_order; i++) {
const int idx = ((in[i * 2 / 32] >> ((i * 2) & 0x1f)) & mask);
out32[i] = nr_mod_table32[idx];
}
return;
case 2:
nr_mod_table32 = (int32_t *)nr_qpsk_mod_table;
for (i = 0; i < length / mod_order; i++) {
const int idx = ((in[i * 2 / 32] >> ((i * 2) & 0x1f)) & mask);
out32[i] = nr_mod_table32[idx];
}
return;
#endif
case 4:
out64 = (int64_t*) out;
for (i=0; i<length/8; i++)
out64[i] = nr_16qam_byte_mod_table[in_bytes[i]];
// the bits that are left out
i = i*8/4;
while (i<length/4) {
const int idx = ((in_bytes[(i * 4) / 8] >> ((i * 4) & 0x7)) & mask);
out32[i] = nr_16qam_mod_table[idx];
i++;
}
return;
case 6:
if (length > (3*64))
for (i = 0; i < length - 3 * 64; i += 3 * 64) {
uint64_t x = *in64++;
uint64_t x1 = x & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x >> 12) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x >> 24) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x >> 36) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x >> 48) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
uint64_t x2 = (x >> 60);
x = *in64++;
x2 |= x<<4;
x1 = x2 & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 12) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 24) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 36) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 48) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x2 = ((x>>56)&0xf0) | (x2>>60);
x = *in64++;
x2 |= x<<8;
x1 = x2 & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 12) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 24) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 36) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 48) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x2 = ((x>>52)&0xff0) | (x2>>60);
*out64++ = nr_64qam_mod_table[x2];
case 4:
out64 = (int64_t *)out;
for (i = 0; i < length / 8; i++)
out64[i] = nr_16qam_byte_mod_table[in_bytes[i]];
// the bits that are left out
i = i * 8 / 4;
while (i < length / 4) {
const int idx = ((in_bytes[(i * 4) / 8] >> ((i * 4) & 0x7)) & mask);
out32[i] = nr_16qam_mod_table[idx];
i++;
}
while (i + 24 <= length) {
uint32_t xx = 0;
memcpy(&xx, in_bytes + i / 8, 3);
uint64_t x1 = xx & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (xx >> 12) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
i += 24;
}
if (i != length) {
uint32_t xx = 0;
memcpy(&xx, in_bytes + i / 8, 2);
uint64_t x1 = xx & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
}
return;
return;
case 8:
nr_mod_table32 = (int32_t*) nr_256qam_mod_table;
for (i=0; i<length/8; i++)
out32[i] = nr_mod_table32[in_bytes[i]];
return;
case 6:
if (length > (3 * 64))
for (i = 0; i < length - 3 * 64; i += 3 * 64) {
uint64_t x = *in64++;
uint64_t x1 = x & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x >> 12) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x >> 24) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x >> 36) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x >> 48) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
uint64_t x2 = (x >> 60);
x = *in64++;
x2 |= x << 4;
x1 = x2 & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 12) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 24) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 36) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 48) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x2 = ((x >> 56) & 0xf0) | (x2 >> 60);
x = *in64++;
x2 |= x << 8;
x1 = x2 & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 12) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 24) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 36) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (x2 >> 48) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x2 = ((x >> 52) & 0xff0) | (x2 >> 60);
*out64++ = nr_64qam_mod_table[x2];
}
default:
break;
while (i + 24 <= length) {
uint32_t xx = 0;
memcpy(&xx, in_bytes + i / 8, 3);
uint64_t x1 = xx & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
x1 = (xx >> 12) & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
i += 24;
}
if (i != length) {
uint32_t xx = 0;
memcpy(&xx, in_bytes + i / 8, 2);
uint64_t x1 = xx & 0xfff;
*out64++ = nr_64qam_mod_table[x1];
}
return;
case 8:
nr_mod_table32 = (int32_t *)nr_256qam_mod_table;
for (i = 0; i < length / 8; i++)
out32[i] = nr_mod_table32[in_bytes[i]];
return;
default:
break;
}
AssertFatal(false,"Invalid or unsupported modulation order %d\n",mod_order);
AssertFatal(false, "Invalid or unsupported modulation order %d\n", mod_order);
}
void nr_layer_mapping(int nbCodes,
@@ -251,36 +249,296 @@ void nr_layer_mapping(int nbCodes,
uint8_t n_layers,
int layerSz,
uint32_t n_symbs,
c16_t tx_layer[layerSz],
int layer)
c16_t tx_layers[][layerSz])
{
LOG_D(PHY,"Doing layer mapping for %d layers, %d symbols\n",n_layers,n_symbs);
LOG_D(PHY, "Doing layer mapping for %d layers, %d symbols\n", n_layers, n_symbs);
switch (n_layers) {
case 1:
memcpy(tx_layer, mod_symbs[0], n_symbs * sizeof(**mod_symbs));
memcpy(tx_layers[0], mod_symbs[0], n_symbs * sizeof(**mod_symbs));
break;
case 2:
case 3:
case 4:
for (int i = 0; i < n_symbs / n_layers; i++) {
const c16_t *base = mod_symbs[0] + n_layers * i;
tx_layer[i] = base[layer];
}
break;
case 2: {
#if defined(__AVX512BW__)
int i=0;
__m512i perm2a = _mm512_set_epi32(30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0);
__m512i perm2b = _mm512_set_epi32(31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1);
#ifndef USE_GATHER
__m512i a, b;
int j;
for (i = 0, j = 0; i < n_symbs >> 4; i += 2, j++) {
a = ((__m512i *)mod_symbs[0])[i];
b = ((__m512i *)mod_symbs[0])[i + 1];
((__m512i *)tx_layers[0])[j] = _mm512_permutex2var_epi32(a, perm2a, b);
((__m512i *)tx_layers[1])[j] = _mm512_permutex2var_epi32(a, perm2b, b);
}
if (i << 4 != n_symbs) {
for (int i2 = ((n_symbs >> 4) << 4); i2 < n_symbs; i2 += 2) {
tx_layers[0][i2 >> 1] = mod_symbs[0][i2];
tx_layers[1][i2 >> 1] = mod_symbs[0][i2 + 1];
}
}
#else
for (i=0; i <n_symbs; i+=32) {
*(__m512i *)(tx_layers[0]+i/2)=_mm512_i32gather_epi32(perm2a, mod_symbs[0]+i, 4);
*(__m512i *)(tx_layers[1]+i/2)=_mm512_i32gather_epi32(perm2b, mod_symbs[0]+i, 4);
}
for (; i < n_symbs; i += 2) {
tx_layers[0][i >> 1] = mod_symbs[0][i];
tx_layers[1][i >> 1] = mod_symbs[0][i + 1];
}
#endif
#elif defined(__aarch64__)
int i;
#ifdef USE_NEON
// SIMDe doesn't handle this properly, gcc up to 14.2 neither
uint8_t const perm0[16] = {0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15};
uint8x16_t perm = vld1q_u8(perm0);
uint8x16_t d;
for (i = 0; i < n_symbs >> 2; i++) {
d = vqtbl1q_u8(((uint8x16_t *)mod_symbs[0])[i], perm);
((int64_t *)tx_layers[0])[i] = vgetq_lane_u64((uint64x2_t)d, 0);
((int64_t *)tx_layers[1])[i] = vgetq_lane_u64((uint64x2_t)d, 1);
}
if (i << 2 != n_symbs) {
for (int i2 = ((n_symbs >> 3) << 3); i2 < n_symbs; i2 += 2) {
tx_layers[0][i2 >> 1] = mod_symbs[0][i2];
tx_layers[1][i2 >> 1] = mod_symbs[0][i2 + 1];
}
}
#else
for (i = 0; i < n_symbs; i += 2) {
tx_layers[0][i >> 1] = mod_symbs[0][i];
tx_layers[1][i >> 1] = mod_symbs[0][i + 1];
}
#endif
#else
int i;
simde__m256i perm2 = simde_mm256_set_epi32(7, 5, 3, 1, 6, 4, 2, 0);
simde__m256i d;
for (i = 0; i < n_symbs >> 3; i++) {
d = simde_mm256_permutevar8x32_epi32(((simde__m256i *)mod_symbs[0])[i], perm2);
((simde__m128i *)tx_layers[0])[i] = simde_mm256_extractf128_si256(d, 0);
((simde__m128i *)tx_layers[1])[i] = simde_mm256_extractf128_si256(d, 1);
}
if (i << 3 != n_symbs) {
for (int i2 = ((n_symbs >> 3) << 3); i2 < n_symbs; i2 += 2) {
tx_layers[0][i2 >> 1] = mod_symbs[0][i2];
tx_layers[1][i2 >> 1] = mod_symbs[0][i2 + 1];
}
}
#endif
} break;
case 3: {
#if defined(__AVX512BW__)
__m512i i0, i1, i2, d0;
__m512i perm3_0 =
_mm512_set_epi32(13 + 16, 10 + 16, 7 + 16, 4 + 16, 1 + 16, 14 + 16, 11 + 16, 8 + 16, 5 + 16, 2 + 16, 15, 12, 9, 6, 3, 0);
__m512i perm3_0b = _mm512_set_epi32(13 + 16, 10 + 16, 7 + 16, 4 + 16, 1 + 16, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
__m512i perm3_1 = _mm512_set_epi32(14 + 16,
11 + 16,
8 + 16,
5 + 16,
2 + 16,
15 + 16,
12 + 16,
9 + 16,
6 + 16,
3 + 16,
0 + 16,
13,
10,
7,
4,
1);
__m512i perm3_1b = _mm512_set_epi32(14 + 16, 11 + 16, 8 + 16, 5 + 16, 2 + 16, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
__m512i perm3_2 = _mm512_set_epi32(15 + 16,
12 + 16,
9 + 16,
6 + 16,
3 + 16,
0 + 16,
13 + 16,
10 + 16,
7 + 16,
4 + 16,
1 + 16,
14,
11,
8,
5,
2);
__m512i perm3_2b = _mm512_set_epi32(15 + 16, 12 + 16, 9 + 16, 6 + 16, 3 + 16, 0 + 16, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
int i,n;
for (i = 0, n = 0; i < n_symbs >> 4; i += 3, n++) {
i0 = ((__m512i *)mod_symbs[0])[i];
i1 = ((__m512i *)mod_symbs[0])[i + 1];
i2 = ((__m512i *)mod_symbs[0])[i + 2];
d0 = _mm512_permutex2var_epi32(i0, perm3_0, i1);
((__m512i *)tx_layers[0])[n] = _mm512_permutex2var_epi32(d0, perm3_0b, i2); // 11000000
d0 = _mm512_permutex2var_epi32(i0, perm3_1, i1);
((__m512i *)tx_layers[1])[n] = _mm512_permutex2var_epi32(d0, perm3_1b, i2); // 11000000
d0 = _mm512_permutex2var_epi32(i0, perm3_2, i1);
((__m512i *)tx_layers[2])[n] = _mm512_permutex2var_epi32(d0, perm3_2b, i2); // 11000000
}
#elif defined(__aarch64__)
for (int i = 0; i < n_symbs; i += 3) {
tx_layers[0][i / 3] = mod_symbs[0][i];
tx_layers[1][i / 3] = mod_symbs[0][i + 1];
tx_layers[2][i / 3] = mod_symbs[0][i + 2];
}
#else
simde__m256i i0, i1, i2, d0, d1, d2, d3;
simde__m256i perm3_0 = simde_mm256_set_epi32(5, 2, 7, 4, 1, 6, 3, 0);
simde__m256i perm3_1 = simde_mm256_set_epi32(6, 3, 0, 5, 2, 7, 4, 1);
simde__m256i perm3_2 = simde_mm256_set_epi32(7, 4, 1, 6, 3, 0, 5, 2);
int i,n;
for (i = 0, n = 0; i < n_symbs >> 3; i += 3, n++) {
i0 = ((simde__m256i *)mod_symbs[0])[i];
i1 = ((simde__m256i *)mod_symbs[0])[i + 1];
i2 = ((simde__m256i *)mod_symbs[0])[i + 2];
d0 = simde_mm256_permutevar8x32_epi32(i0, perm3_0);
d1 = simde_mm256_permutevar8x32_epi32(i1, perm3_0);
d2 = simde_mm256_permutevar8x32_epi32(i2, perm3_0);
d3 = simde_mm256_blend_epi32(d0, d1, 0x38); // 00111000
((simde__m256i *)tx_layers[0])[n] = simde_mm256_blend_epi32(d3, d2, 0xc0); // 11000000
d0 = simde_mm256_permutevar8x32_epi32(i0, perm3_1);
d1 = simde_mm256_permutevar8x32_epi32(i1, perm3_1);
d2 = simde_mm256_permutevar8x32_epi32(i2, perm3_1);
d3 = simde_mm256_blend_epi32(d0, d1, 0x18); // 00011000
((simde__m256i *)tx_layers[1])[n] = simde_mm256_blend_epi32(d3, d2, 0xe0); // 11100000
d0 = simde_mm256_permutevar8x32_epi32(i0, perm3_2);
d1 = simde_mm256_permutevar8x32_epi32(i1, perm3_2);
d2 = simde_mm256_permutevar8x32_epi32(i2, perm3_2);
d3 = simde_mm256_blend_epi32(d0, d1, 0x1c); // 00011100
((simde__m256i *)tx_layers[2])[n] = simde_mm256_blend_epi32(d3, d2, 0xe0); // 11100000
#ifdef DEBUG_LAYER_MAPPING
printf("\nsymb %d/%d\n", i << 3, n_symbs);
printf(" layer 0:\t");
for (int j = 0; j < 8 * 6; j += 6) {
printf("%d %d ", ((int16_t *)&mod_symbs[0][i << 3])[j], ((int16_t *)&mod_symbs[0][i << 3])[j + 1]);
}
printf("\n layer 1:\t");
for (int j = 2; j < 8 * 6; j += 6) {
printf("%d %d ", ((int16_t *)&mod_symbs[0][i << 3])[j], ((int16_t *)&mod_symbs[0][i << 3])[j + 1]);
}
printf("\n layer 2:\t");
for (int j = 4; j < 8 * 6; j += 6) {
printf("%d %d ", ((int16_t *)&mod_symbs[0][i << 3])[j], ((int16_t *)&mod_symbs[0][i << 3])[j + 1]);
}
printf("\n Mapping layer 0:\t");
for (int j = 0; j < 16; j++) {
printf("%d ", ((int16_t *)&tx_layers[0][n << 3])[j]);
}
printf("\n Mapping layer 1:\t");
for (int j = 0; j < 16; j++) {
printf("%d ", ((int16_t *)&tx_layers[1][n << 3])[j]);
}
printf("\n Mapping layer 2:\t");
for (int j = 0; j < 16; j++) {
printf("%d ", ((int16_t *)&tx_layers[2][n << 3])[j]);
}
#endif
}
if (i << 3 != n_symbs) {
for (int i2 = ((n_symbs >> 3) << 3); i2 < n_symbs; i2 += 3) {
tx_layers[0][i2 / 3] = mod_symbs[0][i2];
tx_layers[1][i2 / 3] = mod_symbs[0][i2 + 1];
tx_layers[2][i2 / 3] = mod_symbs[0][i2 + 2];
}
}
#endif
} break;
case 4: {
#if defined(__AVX512BW__)
__m512i perm4 = _mm512_set_epi32(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0);
__m512i e;
int i;
for (i = 0; i < n_symbs >> 4; i++) {
e = _mm512_permutexvar_epi32(perm4, ((__m512i *)mod_symbs[0])[i]);
((__m128i *)tx_layers[0])[i] = _mm512_extracti64x2_epi64(e, 0);
((__m128i *)tx_layers[1])[i] = _mm512_extracti64x2_epi64(e, 1);
((__m128i *)tx_layers[2])[i] = _mm512_extracti64x2_epi64(e, 2);
((__m128i *)tx_layers[3])[i] = _mm512_extracti64x2_epi64(e, 3);
}
if (i << 4 != n_symbs) {
for (int i2 = ((n_symbs >> 4) << 4); i2 < n_symbs; i2 += 4) {
tx_layers[0][i2 >> 2] = mod_symbs[0][i2];
tx_layers[1][i2 >> 2] = mod_symbs[0][i2 + 1];
tx_layers[2][i2 >> 2] = mod_symbs[0][i2 + 2];
tx_layers[3][i2 >> 2] = mod_symbs[0][i2 + 3];
}
}
#elif defined(__aarch64__)
int i;
#ifdef USE_NEON
// SIMDe doesn't handle this properly, gcc up to 14.2 neither
uint32x4_t d4;
for (i = 0; i < n_symbs >> 2; i++) {
d4 = ((uint32x4_t *)mod_symbs[0])[i];
((uint32_t *)tx_layers[0])[i] = vgetq_lane_u32(d4, 0);
((uint32_t *)tx_layers[1])[i] = vgetq_lane_u32(d4, 1);
((uint32_t *)tx_layers[2])[i] = vgetq_lane_u32(d4, 0);
((uint32_t *)tx_layers[3])[i] = vgetq_lane_u32(d4, 1);
}
if (i << 2 != n_symbs) {
for (int i2 = ((n_symbs >> 2) << 2); i2 < n_symbs; i2 += 4) {
tx_layers[0][i2 >> 2] = mod_symbs[0][i2];
tx_layers[1][i2 >> 2] = mod_symbs[0][i2 + 1];
tx_layers[0][i2 >> 2] = mod_symbs[0][i2];
tx_layers[1][i2 >> 2] = mod_symbs[0][i2 + 1];
}
}
#else
for (int i = 0; i < n_symbs; i += 4) {
tx_layers[0][i >> 2] = mod_symbs[0][i];
tx_layers[1][i >> 2] = mod_symbs[0][i + 1];
tx_layers[2][i >> 2] = mod_symbs[0][i + 2];
tx_layers[3][i >> 2] = mod_symbs[0][i + 3];
}
#endif
#else
simde__m256i perm4 = simde_mm256_set_epi32(7, 3, 6, 2, 5, 1, 4, 0);
simde__m256i e;
int i;
for (i = 0; i < n_symbs >> 3; i++) {
e = simde_mm256_permutevar8x32_epi32(((simde__m256i *)mod_symbs[0])[i], perm4);
((uint64_t *)tx_layers[0])[i] = simde_mm256_extract_epi64(e, 0);
((uint64_t *)tx_layers[1])[i] = simde_mm256_extract_epi64(e, 1);
((uint64_t *)tx_layers[2])[i] = simde_mm256_extract_epi64(e, 2);
((uint64_t *)tx_layers[3])[i] = simde_mm256_extract_epi64(e, 3);
}
if (i << 3 != n_symbs) {
for (int i2 = ((n_symbs >> 3) << 3); i2 < n_symbs; i2 += 3) {
tx_layers[0][i2 >> 1] = mod_symbs[0][i2];
tx_layers[1][i2 >> 1] = mod_symbs[0][i2 + 1];
tx_layers[2][i2 >> 1] = mod_symbs[0][i2 + 2];
tx_layers[3][i2 >> 1] = mod_symbs[0][i2 + 2];
}
}
#endif
} break;
case 5:
if (layer < 2)
for (int i = 0; i < n_symbs; i += 2) {
case 6:
case 7:
case 8:
/*
// Layer 0,1
for (int i = 0; i < n_symbs; i += 2) {
const int txIdx = i / 2;
tx_layer[txIdx] = mod_symbs[0][i + layer];
}
tx_layer[0][txIdx] = mod_symbs[0][i];
tx_layer[1][txIdx] = mod_symbs[0][i + 1];
}
// layers 2,3,4
else
for (int i = 0; i < n_symbs; i += 3) {
const int txIdx = i / 3;
tx_layer[txIdx] = mod_symbs[1][i + layer];
tx_layer[2][txIdx] = mod_symbs[1][i + 2];
tx_layer[3][txIdx] = mod_symbs[1][i + 3];
tx_layer[4][txIdx] = mod_symbs[1][i + 4];
}
break;
@@ -288,7 +546,12 @@ void nr_layer_mapping(int nbCodes,
for (int q=0; q<2; q++)
for (int i = 0; i < n_symbs; i += 3) {
const int txIdx = i / 3;
tx_layer[txIdx] = mod_symbs[q][i + layer];
tx_layer[0][txIdx] = mod_symbs[q][i + layer];
tx_layer[1][txIdx] = mod_symbs[q][i + layer];
tx_layer[2][txIdx] = mod_symbs[q][i + layer];
tx_layer[3][txIdx] = mod_symbs[q][i + layer];
tx_layer[4][txIdx] = mod_symbs[q][i + layer];
tx_layer[5][txIdx] = mod_symbs[q][i + layer];
}
break;
@@ -312,7 +575,7 @@ void nr_layer_mapping(int nbCodes,
tx_layer[txIdx] = mod_symbs[q][i + layer];
}
break;
*/
default:
AssertFatal(0, "Invalid number of layers %d\n", n_layers);
}
@@ -337,7 +600,7 @@ void nr_dft(c16_t *z, c16_t *d, uint32_t Msc_PUSCH)
simde__m128i norm128;
if ((Msc_PUSCH % 1536) > 0) {
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip += 4) {
dft_in0[ip] = d[i];
}
}
@@ -357,19 +620,18 @@ void nr_dft(c16_t *z, c16_t *d, uint32_t Msc_PUSCH)
}
if ((Msc_PUSCH % 1536) > 0) {
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip += 4)
z[i] = dft_out0[ip];
}
}
void perform_symbol_rotation(NR_DL_FRAME_PARMS *fp, double f0, c16_t *symbol_rotation)
{
const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10;
const double Tc=(1/480e3/4096);
const double Nu=2048*64*(1/(float)(1<<fp->numerology_index));
const double Ncp0=16*64 + (144*64*(1/(float)(1<<fp->numerology_index)));
const double Ncp1=(144*64*(1/(float)(1<<fp->numerology_index)));
const int nsymb = fp->symbols_per_slot * fp->slots_per_frame / 10;
const double Tc = (1 / 480e3 / 4096);
const double Nu = 2048 * 64 * (1 / (float)(1 << fp->numerology_index));
const double Ncp0 = 16 * 64 + (144 * 64 * (1 / (float)(1 << fp->numerology_index)));
const double Ncp1 = (144 * 64 * (1 / (float)(1 << fp->numerology_index)));
LOG_D(PHY, "Doing symbol rotation calculation for TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb);
@@ -430,7 +692,9 @@ void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp)
fp->timeshift_symbol_rotation[i].i = (int16_t)round(exp_im * 32767);
if (i < 10)
LOG_D(PHY,"Timeshift symbol rotation %d => (%d,%d) %f\n",i,
LOG_D(PHY,
"Timeshift symbol rotation %d => (%d,%d) %f\n",
i,
fp->timeshift_symbol_rotation[i].r,
fp->timeshift_symbol_rotation[i].i,
poff);
@@ -441,13 +705,13 @@ c16_t nr_layer_precoder(int sz, c16_t datatx_F_precoding[][sz], const char *prec
{
c16_t precodatatx_F = {0};
for (int al = 0; al<n_layers; al++) {
for (int al = 0; al < n_layers; al++) {
c16_t antenna = datatx_F_precoding[al][re_offset];
switch (prec_matrix[al]) {
case '0': //multiply by zero
case '0': // multiply by zero
break;
case '1': //multiply by 1
case '1': // multiply by 1
precodatatx_F = c16add(precodatatx_F, antenna);
break;
@@ -492,15 +756,15 @@ c16_t nr_layer_precoder_cm(int n_layers,
}
void nr_layer_precoder_simd(const int n_layers,
const int n_symbols,
const int symSz,
const c16_t txdataF_res_mapped[n_layers][n_symbols][symSz],
const int ant,
const nfapi_nr_pm_pdu_t *pmi_pdu,
const int symbol,
const int sc_offset,
const int re_cnt,
c16_t *txdataF_precoded)
const int n_symbols,
const int symSz,
const c16_t txdataF_res_mapped[n_layers][n_symbols][symSz],
const int ant,
const nfapi_nr_pm_pdu_t *pmi_pdu,
const int symbol,
const int sc_offset,
const int re_cnt,
c16_t *txdataF_precoded)
{
uint32_t sc = sc_offset;
c16_t prec_weight = {0};
@@ -510,22 +774,25 @@ void nr_layer_precoder_simd(const int n_layers,
// 256 SIMD: Do 8 RE in one iteration, 3 iterations for 2 RB
#ifdef __AVX2__
const uint32_t re_cnt_align8 = re_cnt & ~7;
for(; sc < sc_offset + (re_cnt_align8); sc += sizeof(simde__m256i) / sizeof(prec_weight)) {
for (; sc < sc_offset + (re_cnt_align8); sc += sizeof(simde__m256i) / sizeof(prec_weight)) {
// Matrix multiplication for 4 elements of the result (sizeof(simde__m256i) / sizeof(*prec_matrix) = 8)
simde__m256i y = simde_mm256_set1_epi16(0); // Y = W[0]*X[0] + W[1]*X[1] + ... + W[nrOfLayers-1]*X[nrOfLayers-1]
for(int nl = 0; nl < n_layers; nl++) {
for (int nl = 0; nl < n_layers; nl++) {
prec_weight.r = pmi_pdu->weights[nl][ant].precoder_weight_Re;
prec_weight.i = pmi_pdu->weights[nl][ant].precoder_weight_Im;
const simde__m256i x = simde_mm256_loadu_epi32(&txdataF_res_mapped[nl][symbol][sc]);
// Rearrange precoding matrix weight to match complex multiplication and broadcast it to match SIMD size
const simde__m256i w_c = simde_mm256_set1_epi32(c16toI32(c16conj(prec_weight))); // broadcast conjugate of w
const simde__m256i w_s = simde_mm256_set1_epi32(c16toI32(c16swap(prec_weight))); // broadcast swapped real and img of w
const simde__m256i w_c = simde_mm256_set1_epi32(c16toI32(c16conj(prec_weight))); // broadcast conjugate of w
const simde__m256i w_s = simde_mm256_set1_epi32(c16toI32(c16swap(prec_weight))); // broadcast swapped real and img of w
// Multiplication and shift
const simde__m256i reals = simde_mm256_srai_epi32(simde_mm256_madd_epi16(x, w_c), 15); // (int32_t) .r = (x.r * w.r - x.i * w.i) >> 15
const simde__m256i imags = simde_mm256_slli_epi32(simde_mm256_madd_epi16(x, w_s), 1); // (int32_t) .i = (x.r * w.i + x.i * w.r) << 1, since higher 16 bit of each 32 bit is taken by blend_epi16
const simde__m256i reals =
simde_mm256_srai_epi32(simde_mm256_madd_epi16(x, w_c), 15); // (int32_t) .r = (x.r * w.r - x.i * w.i) >> 15
const simde__m256i imags = simde_mm256_slli_epi32(
simde_mm256_madd_epi16(x, w_s),
1); // (int32_t) .i = (x.r * w.i + x.i * w.r) << 1, since higher 16 bit of each 32 bit is taken by blend_epi16
// Re-arrange to match c16_t format
const simde__m256i produ = simde_mm256_blend_epi16(reals, imags, 0xAA);
@@ -540,43 +807,40 @@ void nr_layer_precoder_simd(const int n_layers,
// 128 SIMD: Do 4 RE in one iteration, 3 iterations for 1 RB
const uint32_t re_cnt_align4 = re_cnt & ~3;
for(; sc < sc_offset+re_cnt_align4; sc += sizeof(simde__m128i) / sizeof(prec_weight)) {
#ifdef DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // Get result with trivial solution, TODO: To be removed
c16_t y_triv[4];
for(int i = 0; i < 4; i++)
y_triv[i] = nr_layer_precoder_cm(n_layers,
NR_SYMBOLS_PER_SLOT,
symSz,
txdataF_res_mapped,
ant,
pmi_pdu,
symbol,
sc + i);
memcpy(&txdataF_precoded[sc], y_triv, sizeof(y_triv));
#endif
for (; sc < sc_offset + re_cnt_align4; sc += sizeof(simde__m128i) / sizeof(prec_weight)) {
#ifdef DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // Get result with trivial solution, TODO: To be removed
c16_t y_triv[4];
for (int i = 0; i < 4; i++)
y_triv[i] = nr_layer_precoder_cm(n_layers, NR_SYMBOLS_PER_SLOT, symSz, txdataF_res_mapped, ant, pmi_pdu, symbol, sc + i);
memcpy(&txdataF_precoded[sc], y_triv, sizeof(y_triv));
#endif
// Matrix multiplication for 4 elements of the result (sizeof(simde__m128i) / sizeof(c16_t) = 4)
simde__m128i y = simde_mm_set1_epi16(0); // Y = W[0]*X[0] + W[1]*X[1] + ... + W[nrOfLayers-1]*X[nrOfLayers-1]
for(int nl = 0; nl < n_layers; nl++) {
for (int nl = 0; nl < n_layers; nl++) {
prec_weight.r = pmi_pdu->weights[nl][ant].precoder_weight_Re;
prec_weight.i = pmi_pdu->weights[nl][ant].precoder_weight_Im;
const simde__m128i x = simde_mm_loadu_epi32(&txdataF_res_mapped[nl][symbol][sc]);
// Rearrange precoding matrix weight to match complex multiplication and broadcast it to match SIMD size
const simde__m128i w_c = simde_mm_set1_epi32(c16toI32(c16conj(prec_weight))); // broadcast conjugate of w
const simde__m128i w_s = simde_mm_set1_epi32(c16toI32(c16swap(prec_weight))); // broadcast swapped real and img of w
const simde__m128i w_c = simde_mm_set1_epi32(c16toI32(c16conj(prec_weight))); // broadcast conjugate of w
const simde__m128i w_s = simde_mm_set1_epi32(c16toI32(c16swap(prec_weight))); // broadcast swapped real and img of w
// Multiplication and shift
const simde__m128i reals = simde_mm_srai_epi32(simde_mm_madd_epi16(x, w_c), 15); // (int32_t) .r = (x.r * w.r - x.i * w.i) >> 15
const simde__m128i imags = simde_mm_slli_epi32(simde_mm_madd_epi16(x, w_s), 1); // (int32_t) .i = (x.r * w.i + x.i * w.r) << 1, since higher 16 bit of each 32 bit is taken by blend_epi16
const simde__m128i reals =
simde_mm_srai_epi32(simde_mm_madd_epi16(x, w_c), 15); // (int32_t) .r = (x.r * w.r - x.i * w.i) >> 15
const simde__m128i imags = simde_mm_slli_epi32(
simde_mm_madd_epi16(x, w_s),
1); // (int32_t) .i = (x.r * w.i + x.i * w.r) << 1, since higher 16 bit of each 32 bit is taken by blend_epi16
/* Re-arrange to match c16_t format
bit index: 0 | 16 | 32 | 48 | 64 | 80 | 96 | 112
reals = {R0.r[15..30] | R0.r[31] (0)*15 | R1.r[15..30] | R1.r[31] (0)*15 | R2.r[15..30] | R2.r[31] (0)*15 | R3.r[15..30] | R3.r[31] (0)*15}
imags = {0 R0.i[0..14]| R0.i[15..30] | 0 R1.i[0..14]| R1.i[15..30] | 0 R2.i[0..14]| R2.i[15..30] | 0 R3.i[0..14]| R3.i[15..30] }
16b from {reals | imags | reals | imags | reals | imags | reals | imags }
produ = {R0.r[15..30] | R0.i[15..30] | R1.r[15..30] | R1.i[15..30] | R2.r[15..30] | R2.i[15..30] | R3.r[15..30] | R3.i[15..30] }
bit index: 0 | 16 | 32 | 48 | 64 | 80 | 96 |
112 reals = {R0.r[15..30] | R0.r[31] (0)*15 | R1.r[15..30] | R1.r[31] (0)*15 | R2.r[15..30] | R2.r[31] (0)*15 |
R3.r[15..30] | R3.r[31] (0)*15} imags = {0 R0.i[0..14]| R0.i[15..30] | 0 R1.i[0..14]| R1.i[15..30] | 0 R2.i[0..14]|
R2.i[15..30] | 0 R3.i[0..14]| R3.i[15..30] } 16b from {reals | imags | reals | imags | reals
| imags | reals | imags } produ = {R0.r[15..30] | R0.i[15..30] | R1.r[15..30] | R1.i[15..30]
| R2.r[15..30] | R2.i[15..30] | R3.r[15..30] | R3.i[15..30] }
*/
const simde__m128i produ = simde_mm_blend_epi16(reals, imags, 0xAA);
@@ -586,30 +850,30 @@ void nr_layer_precoder_simd(const int n_layers,
// Store the result to txdataF
simde_mm_storeu_si128(&txdataF_precoded[sc], y);
#ifdef DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // Print simd and trivial result, TODO: To be removed
c16_t *y_simd = (c16_t*) &y;
printf("debug_to_be_removed re_cnt=%d, sc=%u, y_simd=(%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d)\n",
re_cnt,
sc,
y_simd[0].r,
y_simd[0].i,
y_simd[1].r,
y_simd[1].i,
y_simd[2].r,
y_simd[2].i,
y_simd[3].r,
y_simd[3].i);
printf("debug_to_be_removed re_cnt=%d, sc=%u, y_triv=(%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d)\n",
re_cnt,
sc,
y_triv[0].r,
y_triv[0].i,
y_triv[1].r,
y_triv[1].i,
y_triv[2].r,
y_triv[2].i,
y_triv[3].r,
y_triv[3].i);
#endif
#ifdef DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // Print simd and trivial result, TODO: To be removed
c16_t *y_simd = (c16_t *)&y;
printf("debug_to_be_removed re_cnt=%d, sc=%u, y_simd=(%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d)\n",
re_cnt,
sc,
y_simd[0].r,
y_simd[0].i,
y_simd[1].r,
y_simd[1].i,
y_simd[2].r,
y_simd[2].i,
y_simd[3].r,
y_simd[3].i);
printf("debug_to_be_removed re_cnt=%d, sc=%u, y_triv=(%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d), (%+4d,%+4d)\n",
re_cnt,
sc,
y_triv[0].r,
y_triv[0].i,
y_triv[1].r,
y_triv[1].i,
y_triv[2].r,
y_triv[2].i,
y_triv[3].r,
y_triv[3].i);
#endif
}
}

View File

@@ -60,8 +60,7 @@ void nr_layer_mapping(int nbCodes,
uint8_t n_layers,
int layerSz,
uint32_t n_symbs,
c16_t tx_layers[layerSz],
int l);
c16_t tx_layers[][layerSz]);
/*! \brief Perform NR layer mapping. TS 38.211 V15.4.0 subclause 7.3.1.3
@param[in] ulsch_ue, double Pointer to NR_UE_ULSCH_t struct

View File

@@ -248,9 +248,11 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_off
{
PHY_VARS_gNB *gNB = msgTx->gNB;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
start_meas(&gNB->dci_generation_stats);
for (int i = 0; i < msgTx->num_ul_pdcch; i++)
nr_generate_dci(msgTx->gNB, &msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
for (int i = 0; i < msgTx->num_dl_pdcch; i++)
nr_generate_dci(msgTx->gNB, &msgTx->pdcch_pdu[i].pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
stop_meas(&gNB->dci_generation_stats);
}

File diff suppressed because it is too large Load Diff

View File

@@ -33,12 +33,33 @@ void nr_codeword_scrambling(uint8_t *in,
{
const int roundedSz = (size + 31) / 32;
uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz);
for (int i = 0; i < roundedSz; i++)
out[i] = ((uint32_t*)in)[i] ^ seq[i];
#if 0
//#elif __AVX2__
for (int i = 0; i < roundedSz; i++) {
simde__m256i c = ((simde__m256i*)in)[i];
uint32_t in32 = simde_mm256_movemask_epi8(simde_mm256_slli_epi16(c, 7));
__m256i c = ((__m256i*)in)[i];
uint32_t in32 = _mm256_movemask_epi8(_mm256_slli_epi16(c, 7));
out[i] = in32 ^ seq[i];
DEBUG_SCRAMBLING(LOG_D(PHY, "in[%d] %x => %x\n", i, in32, out[i]));
}
//#elif defined (__aarch64__)
const int8_t __attribute__ ((aligned (16))) ucShift[] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7};
int8x16_t vshift = vld1q_s8(ucShift);
uint8x16_t *c = (uint8x16_t*)in;
uint8x16_t cshift;
uint32_t in32;
for (int i = 0; i < roundedSz; i++) {
cshift = vshlq_u8(*c++, vshift);
in32 = vaddv_u8(vget_low_u8(cshift));
in32 += (vaddv_u8(vget_high_u8(cshift)) << 8);
cshift = vshlq_u8(*c++, vshift);
in32 += (vaddv_u8(vget_low_u8(cshift)) << 16);
in32 += (vaddv_u8(vget_high_u8(cshift)) << 24);
out[i] = in32 ^ seq[i];
DEBUG_SCRAMBLING(LOG_D(PHY, "in[%d] %x => %x\n", i, in32, out[i]));
}
#endif
}
void nr_codeword_unscrambling(int16_t* llr, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI)

View File

@@ -156,9 +156,8 @@ void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y,
// log2_amp - increase the output amplitude by a factor 2^log2_amp (default is 0)
// WARNING: log2_amp>0 can cause overflow!!
uint32_t i; // loop counter
#if 0
simd_q15_t *y_128,alpha_128;
int32_t *xd=(int32_t *)x;
@@ -194,6 +193,39 @@ void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y,
);
//print_ints("y_128[0]=", &y_128[0]);
}
#else
const c16_t for_re = {alpha->r, -alpha->i};
const simde__m128i alpha_for_real = simde_mm_set1_epi32(*(uint32_t *)&for_re);
const c16_t for_im = {alpha->i, alpha->r};
const simde__m128i alpha_for_im = simde_mm_set1_epi32(*(uint32_t *)&for_im);
const simde__m128i perm_mask = simde_mm_set_epi8( 15,
14,
7,
6,
13,
12,
5,
4,
11,
10,
3,
2,
9,
8,
1,
0);
simde__m128i *xd = (simde__m128i *)x;
const simde__m128i *end = xd + N / 8;
for (simde__m128i *yd = (simde__m128i *)y; xd < end; yd++, xd++) {
const simde__m128i y128 = simde_mm_lddqu_si128(xd);
const simde__m128i xre = simde_mm_srai_epi32(simde_mm_madd_epi16(y128, alpha_for_real), output_shift);
const simde__m128i xim = simde_mm_srai_epi32(simde_mm_madd_epi16(y128, alpha_for_im), output_shift);
// a bit faster than unpacklo+unpackhi+packs
const simde__m128i tmp = simde_mm_packs_epi32(xre, xim);
simde_mm_storeu_si128(yd, simde_mm_shuffle_epi8(tmp, perm_mask));
}
#endif
#if defined(__x86__) || defined(__x86_64__)
}
#endif

View File

@@ -521,6 +521,8 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t dlsch_interleaving_stats;
time_stats_t dlsch_segmentation_stats;
time_stats_t dci_generation_stats;
time_stats_t phase_comp_stats;
time_stats_t rx_pusch_stats;
time_stats_t rx_pusch_init_stats;
time_stats_t rx_pusch_symbol_processing_stats;

View File

@@ -55,6 +55,8 @@
/* x86 processors */
#define oai_mm_sign_epi8(a,b) simde_mm_sign_epi8(a,b)
#if defined(__AVX512BW__) || defined(__AVX512F__)
#include <immintrin.h>
#endif
@@ -66,6 +68,7 @@
#include <simde/x86/clmul.h>
#include <simde/arm/neon.h>
#define oai_mm_sign_epi8(a,b) (simde__m128i)vbslq_s8(vcltzq_s8((int8x16_t) (b)), vnegq_s8((int8x16_t) (a)), (int8x16_t)(a))
#endif // x86_64 || i386
#include <stdbool.h>
#include "assertions.h"

View File

@@ -286,6 +286,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
//apply the OFDM symbol rotation here
if (gNB->phase_comp) {
start_meas(&gNB->phase_comp_stats);
for(int i = 0; i < gNB->common_vars.num_beams_period; ++i) {
for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) {
apply_nr_rotation_TX(fp,
@@ -300,6 +301,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
T_INT(aa), T_BUFFER(&gNB->common_vars.txdataF[aa][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t)));
}
}
stop_meas(&gNB->phase_comp_stats);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 0);

View File

@@ -511,7 +511,7 @@ int main(int argc, char **argv)
//printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32));
// generate signal
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS] __attribute__((aligned(32)));
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS] __attribute__((aligned(64)));
bzero(output,rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
if (input_fd == NULL) {
msgDataTx.num_pdsch_slot = 1;
@@ -532,12 +532,12 @@ int main(int argc, char **argv)
//if (i<16)
// printf("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]);
if (output[i] == 0)
if ((output[i]&1) == 0)
modulated_input[i] = 1.0; ///sqrt(2); //QPSK
else
modulated_input[i] = -1.0; ///sqrt(2);
//if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]);
//if (i<16) printf("modulated_input[%d] = %f (%d)\n",i,modulated_input[i],output[i]);
//SNR =10;
SNR_lin = pow(10, SNR / 10.0);
sigma = 1.0 / sqrt(2 * SNR_lin);

View File

@@ -962,10 +962,12 @@ int main(int argc, char **argv)
reset_meas(&gNB->dlsch_segmentation_stats);
reset_meas(&gNB->dlsch_modulation_stats);
reset_meas(&gNB->dlsch_encoding_stats);
reset_meas(&gNB->dci_generation_stats);
reset_meas(&gNB->tinput);
reset_meas(&gNB->tprep);
reset_meas(&gNB->tparity);
reset_meas(&gNB->toutput);
reset_meas(&gNB->phase_comp_stats);
uint32_t errors_scrambling[16] = {0};
int n_errors[16] = {0};
@@ -1263,6 +1265,7 @@ int main(int argc, char **argv)
UE->dl_harq_processes[0][slot].C,
msgDataTx->dlsch[0][0].harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0] << 3);
printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx");
printStatIndent2(&gNB->dci_generation_stats,"DCI encoding time");
printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");
printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time");
printStatIndent3(&gNB->tinput,"DLSCH LDPC input processing time");
@@ -1275,6 +1278,7 @@ int main(int argc, char **argv)
printStatIndent2(&gNB->dlsch_scrambling_stats, "DLSCH scrambling time");
printStatIndent2(&gNB->dlsch_resource_mapping_stats, "DLSCH Resource Mapping time");
printStatIndent2(&gNB->dlsch_precoding_stats,"DLSCH Layer Precoding time");
if (gNB->phase_comp) printStatIndent2(&gNB->phase_comp_stats,"Phase Compensation");
printf("\nUE function statistics (per %d us slot)\n", 1000 >> *scc->ssbSubcarrierSpacing);
for (int i = RX_PDSCH_STATS; i <= DLSCH_PROCEDURES_STATS; i++) {

View File

@@ -239,6 +239,7 @@ int main(int argc, char *argv[])
int threadCnt=0;
int max_ldpc_iterations = 5;
int num_antennas_per_thread = 1;
char gNBthreads[128]="n";
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) {
exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
}
@@ -250,7 +251,7 @@ int main(int argc, char *argv[])
InitSinLUT();
int c;
while ((c = getopt(argc, argv, "--:O:a:b:c:d:ef:g:h:i:k:m:n:p:q:r:s:t:u:v:w:y:z:A:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:E:X:")) != -1) {
while ((c = getopt(argc, argv, "--:O:a:b:c:d:ef:g:h:i:k:m:n:p:q:r:s:t:u:v:w:y:z:A:C:F:G:H:I:M:N:PQR:S:T:U:L:ZW:E:X:Y:")) != -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' */
@@ -384,6 +385,11 @@ int main(int argc, char *argv[])
threadCnt = atoi(optarg);
break;
case 'Y':
strncpy(gNBthreads,optarg, sizeof(gNBthreads)-1);
gNBthreads[sizeof(gNBthreads)-1]=0;
break;
case 'u':
mu = atoi(optarg);
break;
@@ -589,7 +595,9 @@ int main(int argc, char *argv[])
gNB->RU_list[0] = calloc(1, sizeof(**gNB->RU_list));
gNB->RU_list[0]->rfdevice.openair0_cfg = openair0_cfg;
initFloatingCoresTpool(threadCnt, &gNB->threadPool, false, "gNB-tpool");
if (gNBthreads[0]=='n') initFloatingCoresTpool(threadCnt, &gNB->threadPool, false, "gNB-tpool");
else initNamedTpool(gNBthreads, &gNB->threadPool, true, "gNB-tpool");
initNotifiedFIFO(&gNB->respDecode);
initNotifiedFIFO(&gNB->respPuschSymb);