From 6d9ceaa712033dc4f28050886be43572df7c2b68 Mon Sep 17 00:00:00 2001 From: Sy Date: Fri, 29 May 2020 13:51:38 +0200 Subject: [PATCH] Test for AVX512 --- .../generator_avx512/cnProc_gen_BG1_avx512.c | 171 +- .../cnProc_gen_BG1_avx512.c.save | 742 -------- .../generator_avx512/cnProc_gen_BG1_avx512.o | Bin 34248 -> 0 bytes .../cnProc_gen_BG1_avx512.save11 | 706 ------- .../generator_avx512/cnProc_gen_BG2_avx512.o | Bin 28832 -> 0 bytes .../generator_avx512/cnProc_gen_avx512 | Bin 199680 -> 199640 bytes .../nrLDPC_tools/generator_avx512/main.o | Bin 206816 -> 0 bytes .../nrLDPC_cnProc_BG1_Z104_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z10_13_AVX512.c | 1522 +++++++-------- .../nrLDPC_cnProc_BG1_Z112_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z11_13_AVX512.c | 1522 +++++++-------- .../nrLDPC_cnProc_BG1_Z120_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z128_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z12_13_AVX512.c | 1522 +++++++-------- .../nrLDPC_cnProc_BG1_Z13_13_AVX512.c | 1534 +++++++-------- .../nrLDPC_cnProc_BG1_Z144_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z14_13_AVX512.c | 1534 +++++++-------- .../nrLDPC_cnProc_BG1_Z15_13_AVX512.c | 1534 +++++++-------- .../nrLDPC_cnProc_BG1_Z160_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z16_13_AVX512.c | 1534 +++++++-------- .../nrLDPC_cnProc_BG1_Z176_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z18_13_AVX512.c | 1534 +++++++-------- .../nrLDPC_cnProc_BG1_Z192_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z208_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z20_13_AVX512.c | 1556 ++++++++-------- .../nrLDPC_cnProc_BG1_Z224_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z22_13_AVX512.c | 1556 ++++++++-------- .../nrLDPC_cnProc_BG1_Z240_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z24_13_AVX512.c | 1556 ++++++++-------- .../nrLDPC_cnProc_BG1_Z256_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z26_13_AVX512.c | 1594 ++++++++-------- .../nrLDPC_cnProc_BG1_Z288_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z28_13_AVX512.c | 1594 ++++++++-------- .../nrLDPC_cnProc_BG1_Z2_13_AVX512.c | 1512 +++++++-------- .../nrLDPC_cnProc_BG1_Z30_13_AVX512.c | 1594 ++++++++-------- .../nrLDPC_cnProc_BG1_Z320_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z32_13_AVX512.c | 1594 ++++++++-------- .../nrLDPC_cnProc_BG1_Z352_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z36_13_AVX512.c | 1594 ++++++++-------- .../nrLDPC_cnProc_BG1_Z384_13_AVX512.c | 1652 ++++++++--------- .../nrLDPC_cnProc_BG1_Z3_13_AVX512.c | 1512 +++++++-------- .../nrLDPC_cnProc_BG1_Z40_13_AVX512.c | 1594 ++++++++-------- .../nrLDPC_cnProc_BG1_Z44_13_AVX512.c | 1594 ++++++++-------- .../nrLDPC_cnProc_BG1_Z48_13_AVX512.c | 1594 ++++++++-------- .../nrLDPC_cnProc_BG1_Z4_13_AVX512.c | 1512 +++++++-------- .../nrLDPC_cnProc_BG1_Z52_13_AVX512.c | 1628 ++++++++-------- .../nrLDPC_cnProc_BG1_Z56_13_AVX512.c | 1628 ++++++++-------- .../nrLDPC_cnProc_BG1_Z5_13_AVX512.c | 1512 +++++++-------- .../nrLDPC_cnProc_BG1_Z60_13_AVX512.c | 1628 ++++++++-------- .../nrLDPC_cnProc_BG1_Z64_13_AVX512.c | 1628 ++++++++-------- .../nrLDPC_cnProc_BG1_Z6_13_AVX512.c | 1522 +++++++-------- .../nrLDPC_cnProc_BG1_Z72_13_AVX512.c | 1628 ++++++++-------- .../nrLDPC_cnProc_BG1_Z7_13_AVX512.c | 1522 +++++++-------- .../nrLDPC_cnProc_BG1_Z80_13_AVX512.c | 1628 ++++++++-------- .../nrLDPC_cnProc_BG1_Z88_13_AVX512.c | 1628 ++++++++-------- .../nrLDPC_cnProc_BG1_Z8_13_AVX512.c | 1522 +++++++-------- .../nrLDPC_cnProc_BG1_Z96_13_AVX512.c | 1628 ++++++++-------- .../nrLDPC_cnProc_BG1_Z9_13_AVX512.c | 1522 +++++++-------- 58 files changed, 40728 insertions(+), 42139 deletions(-) delete mode 100644 openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.c.save delete mode 100644 openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.o delete mode 100644 openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.save11 delete mode 100644 openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG2_avx512.o delete mode 100644 openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/main.o diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.c index 277cea73cf..b4962d7a80 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.c +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.c @@ -69,8 +69,8 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Offsets are in units of bitOffsetInGroup (1*384/64)=6 // Offsets are in units of bitOffsetInGroup (1*384/64)=6 - const uint8_t lut_idxCnProcG3[3][2] = {{6,12}, {0,12}, {0,6}}; - + // const uint8_t lut_idxCnProcG3[3][2] = {{6,12}, {0,12}, {0,6}}; + const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}}; fprintf(fd," __m512i zmm0, min, sgn,ones,maxLLR;\n"); fprintf(fd," ones = _mm512_set1_epi8((char)1);\n"); @@ -80,10 +80,10 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) { // Number of groups of 64 CNs for parallel processing // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[0]*Z + 63)>>31; + M = (lut_numCnInCnGroups[0]*Z + 31)>>7; // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX)>>31; + bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX)>>7; // Set pointers to start of group 3 @@ -104,7 +104,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," for (int i=0;i<%d;i+=2) {\n",M); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>31)+lut_idxCnProcG3[j][0]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>7)+lut_idxCnProcG3[j][0]); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -112,7 +112,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // 32 CNs of second BN // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>31)+lut_idxCnProcG3[j][1]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>7)+lut_idxCnProcG3[j][1]); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -125,11 +125,11 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[0]>>31)+(j*bitOffsetInGroup)); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[0]>>7)+(j*bitOffsetInGroup)); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>31)+lut_idxCnProcG3[j][0]+1); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>7)+lut_idxCnProcG3[j][0]+1); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -137,7 +137,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // 32 CNs of second BN // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>31)+lut_idxCnProcG3[j][1]+1); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>7)+lut_idxCnProcG3[j][1]+1); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -150,7 +150,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[0]>>31)+(j*bitOffsetInGroup)+1); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[0]>>7)+(j*bitOffsetInGroup)+1); fprintf(fd," }\n"); } @@ -160,16 +160,17 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Process group with 4 BNs fprintf(fd,"//Process group with 4 BNs\n"); // Offset is 5*384/64 = 30 - const uint8_t lut_idxCnProcG4[4][3] = {{30,60,90}, {0,60,90}, {0,30,90}, {0,30,60}}; + // const uint8_t lut_idxCnProcG4[4][3] = {{30,60,90}, {0,60,90}, {0,30,90}, {0,30,60}}; + const uint8_t lut_idxCnProcG4[4][3] = {{60,120,180}, {0,120,180}, {0,60,180}, {0,60,120}}; if (lut_numCnInCnGroups[1] > 0) { // Number of groups of 64 CNs for parallel processing // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[1]*Z + 63)>>31; + M = (lut_numCnInCnGroups[1]*Z + 31)>>7; // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX)>>31; + bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX)>>7; // Set pointers to start of group 4 @@ -188,7 +189,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," for (int i=0;i<%d;i++) {\n",M); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>31)+lut_idxCnProcG4[j][0]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>7)+lut_idxCnProcG4[j][0]); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -198,7 +199,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Loop over BNs for (k=1; k<3; k++) { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>31)+lut_idxCnProcG4[j][k]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>7)+lut_idxCnProcG4[j][k]); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -212,7 +213,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[1]>>31)+(j*bitOffsetInGroup)); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[1]>>7)+(j*bitOffsetInGroup)); fprintf(fd," }\n"); } } @@ -222,18 +223,21 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Process group with 5 BNs fprintf(fd,"//Process group with 5 BNs\n"); // Offset is 18*384/64 = 216 - const uint16_t lut_idxCnProcG5[5][4] = {{108,216,324,432}, {0,216,324,432}, - {0,108,324,432}, {0,108,216,432}, {0,108,216,324}}; + //const uint16_t lut_idxCnProcG5[5][4] = {{108,216,324,432}, {0,216,324,432}, + // {0,108,324,432}, {0,108,216,432}, {0,108,216,324}}; + const uint16_t lut_idxCnProcG5[5][4] = {{216,432,648,864}, {0,432,648,864}, + {0,216,648,864}, {0,216,432,864}, {0,216,432,648}}; + if (lut_numCnInCnGroups[2] > 0) { // Number of groups of 64 CNs for parallel processing // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[2]*Z + 63)>>31; + M = (lut_numCnInCnGroups[2]*Z + 31)>>7; // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX)>>31; + bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX)>>7; // Set pointers to start of group 4 @@ -253,7 +257,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," for (int i=0;i<%d;i++) {\n",M); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>31)+lut_idxCnProcG5[j][0]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>7)+lut_idxCnProcG5[j][0]); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -263,7 +267,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Loop over BNs for (k=1; k<4; k++) { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>31)+lut_idxCnProcG5[j][k]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>7)+lut_idxCnProcG5[j][k]); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -277,7 +281,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[2]>>31)+(j*bitOffsetInGroup)); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[2]>>7)+(j*bitOffsetInGroup)); fprintf(fd," }\n"); } } @@ -286,19 +290,21 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Process group with 6 BNs fprintf(fd,"//Process group with 6 BNs\n"); // Offset is 8*384/64 = 48 - const uint16_t lut_idxCnProcG6[6][5] = {{48,96,144,192,240}, {0,96,144,192,240}, + /* const uint16_t lut_idxCnProcG6[6][5] = {{48,96,144,192,240}, {0,96,144,192,240}, {0,48,144,192,240}, {0,48,96,192,240}, - {0,48,96,144,240}, {0,48,96,144,192}}; - + {0,48,96,144,240}, {0,48,96,144,192}};*/ + const uint16_t lut_idxCnProcG6[6][5] = {{96,192,288,384,480}, {0,192,288,384,480}, + {0,96,288,384,480}, {0,96,192,384,480}, + {0,96,192,288,480}, {0,96,192,288,384}}; if (lut_numCnInCnGroups[3] > 0) { // Number of groups of 64 CNs for parallel processing // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[3]*Z + 63)>>31; + M = (lut_numCnInCnGroups[3]*Z + 31)>>7; // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX)>>31; + bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX)>>7; // Set pointers to start of group 4 @@ -318,7 +324,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," for (int i=0;i<%d;i++) {\n",M); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>31)+lut_idxCnProcG6[j][0]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>7)+lut_idxCnProcG6[j][0]); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -328,7 +334,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Loop over BNs for (k=1; k<5; k++) { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>31)+lut_idxCnProcG6[j][k]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>7)+lut_idxCnProcG6[j][k]); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -342,7 +348,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[3]>>31)+(j*bitOffsetInGroup)); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[3]>>7)+(j*bitOffsetInGroup)); fprintf(fd," }\n"); } } @@ -352,20 +358,25 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Process group with 7 BNs fprintf(fd,"//Process group with 7 BNs\n"); // Offset is 5*384/64 = 30 - const uint16_t lut_idxCnProcG7[7][6] = {{30,60,90,120,150,180}, {0,60,90,120,150,180}, + /* const uint16_t lut_idxCnProcG7[7][6] = {{30,60,90,120,150,180}, {0,60,90,120,150,180}, {0,30,90,120,150,180}, {0,30,60,120,150,180}, {0,30,60,90,150,180}, {0,30,60,90,120,180}, - {0,30,60,90,120,150}}; + {0,30,60,90,120,150}};*/ + const uint16_t lut_idxCnProcG7[7][6] = {{60,120,180,240,300,360}, {0,120,180,240,300,360}, + {0,60,180,240,300,360}, {0,60,120,240,300,360}, + {0,60,120,180,300,360}, {0,60,120,180,240,360}, + {0,60,120,180,240,300}}; + if (lut_numCnInCnGroups[4] > 0) { // Number of groups of 64 CNs for parallel processing // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[4]*Z + 63)>>31; + M = (lut_numCnInCnGroups[4]*Z + 31)>>7; // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX)>>31; + bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX)>>7; // Set pointers to start of group 4 @@ -385,7 +396,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," for (int i=0;i<%d;i++) {\n",M); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>31)+lut_idxCnProcG7[j][0]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>7)+lut_idxCnProcG7[j][0]); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -395,7 +406,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Loop over BNs for (k=1; k<6; k++) { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>31)+lut_idxCnProcG7[j][k]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>7)+lut_idxCnProcG7[j][k]); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -409,7 +420,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[4]>>31)+(j*bitOffsetInGroup)); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[4]>>7)+(j*bitOffsetInGroup)); fprintf(fd," }\n"); } } @@ -419,10 +430,15 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Process group with 8 BNs fprintf(fd,"//Process group with 8 BNs\n"); // Offset is 2*384/64 = 12 - const uint8_t lut_idxCnProcG8[8][7] = {{12,24,36,48,56,72,84}, {0,24,36,48,56,72,84}, + /* const uint8_t lut_idxCnProcG8[8][7] = {{12,24,36,48,56,72,84}, {0,24,36,48,56,72,84}, {0,12,36,48,56,72,84}, {0,12,24,48,56,72,84}, {0,12,24,36,56,72,84}, {0,12,24,36,48,72,84}, - {0,12,24,36,48,56,84}, {0,12,24,36,48,120,72}}; + {0,12,24,36,48,56,84}, {0,12,24,36,48,120,72}};*/ + + const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168}, + {0,24,72,96,120,144,168}, {0,24,48,96,120,144,168}, + {0,24,48,72,120,144,168}, {0,24,48,72,96,144,168}, + {0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}}; @@ -430,10 +446,10 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) { // Number of groups of 64 CNs for parallel processing // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[5]*Z + 63)>>31; + M = (lut_numCnInCnGroups[5]*Z + 31)>>7; // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX)>>31; + bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX)>>7; // Set pointers to start of group 4 @@ -453,7 +469,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," for (int i=0;i<%d;i++) {\n",M); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>31)+lut_idxCnProcG8[j][0]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>7)+lut_idxCnProcG8[j][0]); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -463,7 +479,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Loop over BNs for (k=1; k<7; k++) { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>31)+lut_idxCnProcG8[j][k]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>7)+lut_idxCnProcG8[j][k]); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -477,7 +493,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[5]>>31)+(j*bitOffsetInGroup)); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[5]>>7)+(j*bitOffsetInGroup)); fprintf(fd," }\n"); } } @@ -486,23 +502,27 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Process group with 9 BNs fprintf(fd,"//Process group with 9 BNs\n"); // Offset is 2*384/64 = 12 - const uint8_t lut_idxCnProcG9[9][8] = {{12,24,36,48,60,72,84,96}, {0,24,36,48,60,72,84,96}, + /*const uint8_t lut_idxCnProcG9[9][8] = {{12,24,36,48,60,72,84,96}, {0,24,36,48,60,72,84,96}, {0,12,36,48,60,72,84,96}, {0,12,24,48,60,72,84,96}, {0,12,24,36,60,72,84,96}, {0,12,24,36,48,72,84,96}, {0,12,24,36,48,60,84,96}, {0,12,24,36,48,60,72,96}, - {0,12,24,36,48,60,72,84}}; - + {0,12,24,36,48,60,72,84}};*/ + const uint8_t lut_idxCnProcG9[9][8] = {{24,48,72,96,120,144,168,192}, {0,48,72,96,120,144,168,192}, + {0,24,72,96,120,144,168,192}, {0,24,48,96,120,144,168,192}, + {0,24,48,72,120,144,168,192}, {0,24,48,72,96,144,168,192}, + {0,24,48,72,96,120,168,192}, {0,24,48,72,96,120,144,192}, + {0,24,48,72,96,120,144,168}}; if (lut_numCnInCnGroups[6] > 0) { // Number of groups of 64 CNs for parallel processing // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[6]*Z + 63)>>31; + M = (lut_numCnInCnGroups[6]*Z + 31)>>7; // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX)>>31; + bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX)>>7; // Set pointers to start of group 9 @@ -522,7 +542,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," for (int i=0;i<%d;i++) {\n",M); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>31)+lut_idxCnProcG9[j][0]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>7)+lut_idxCnProcG9[j][0]); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -532,7 +552,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Loop over BNs for (k=1; k<8; k++) { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>31)+lut_idxCnProcG9[j][k]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>7)+lut_idxCnProcG9[j][k]); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -546,7 +566,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[6]>>31)+(j*bitOffsetInGroup)); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[6]>>7)+(j*bitOffsetInGroup)); fprintf(fd," }\n"); } } @@ -555,11 +575,17 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Process group with 10 BNs fprintf(fd,"//Process group with 10 BNs\n"); // Offset is 1*384/64 = 6 - const uint8_t lut_idxCnProcG10[10][9] = {{6,12,18,24,30,36,42,48,54}, {0,12,18,24,30,36,42,48,54}, + /* const uint8_t lut_idxCnProcG10[10][9] = {{6,12,18,24,30,36,42,48,54}, {0,12,18,24,30,36,42,48,54}, {0,6,18,24,30,36,42,48,54}, {0,6,12,24,30,36,42,48,54}, {0,6,12,18,30,36,42,48,54}, {0,6,12,18,24,36,42,48,54}, {0,6,12,18,24,30,42,48,54}, {0,6,12,18,24,30,36,48,54}, - {0,6,12,18,24,30,36,42,54}, {0,6,12,36,24,30,36,42,48}}; + {0,6,12,18,24,30,36,42,54}, {0,6,12,36,24,30,36,42,48}};*/ + + const uint8_t lut_idxCnProcG10[10][9] = {{12,24,36,48,60,72,84,96,108}, {0,24,36,48,60,72,84,96,108}, + {0,12,36,48,60,72,84,96,108}, {0,12,24,48,60,72,84,96,108}, + {0,12,24,36,60,72,84,96,108}, {0,12,24,36,48,72,84,96,108}, + {0,12,24,36,48,60,84,96,108}, {0,12,24,36,48,60,72,96,108}, + {0,12,24,36,48,60,72,84,108}, {0,12,24,36,48,60,72,84,96}}; @@ -569,10 +595,10 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) { // Number of groups of 64 CNs for parallel processing // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[7]*Z + 63)>>31; + M = (lut_numCnInCnGroups[7]*Z + 31)>>7; // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX)>>31; + bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX)>>7; // Set pointers to start of group 10 @@ -592,7 +618,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," for (int i=0;i<%d;i++) {\n",M); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>31)+lut_idxCnProcG10[j][0]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>7)+lut_idxCnProcG10[j][0]); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -602,7 +628,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Loop over BNs for (k=1; k<9; k++) { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>31)+lut_idxCnProcG10[j][k]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>7)+lut_idxCnProcG10[j][k]); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -616,7 +642,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[7]>>31)+(j*bitOffsetInGroup)); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[7]>>7)+(j*bitOffsetInGroup)); fprintf(fd," }\n"); } } @@ -626,7 +652,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Process group with 19 BNs fprintf(fd,"//Process group with 19 BNs\n"); // Offset is 4*384/64 = 24 - const uint16_t lut_idxCnProcG19[19][18] = {{24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, + /* const uint16_t lut_idxCnProcG19[19][18] = {{24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,24,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,24,48,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,24,48,72,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,24,48,72,96,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,24,48,72,96,120,168,192,216,240,264,288,312,336,360,384,408,432}, {0,24,48,72,96,120,144,192,216,240,264,288,312,336,360,384,408,432}, @@ -635,17 +661,28 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) {0,24,48,72,96,120,144,168,192,216,240,264,312,336,360,384,408,432}, {0,24,48,72,96,120,144,168,192,216,240,264,288,336,360,384,408,432}, {0,24,48,72,96,120,144,168,192,216,240,264,288,312,360,384,408,432}, {0,24,48,72,96,120,144,168,192,216,240,264,288,312,336,384,408,432}, {0,24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,408,432}, {0,24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,432}, - {0,24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408}}; + {0,24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408}};*/ + +const uint16_t lut_idxCnProcG19[19][18] = {{48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, + {0,48,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, + {0,48,96,144,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,288,336,384,432,480,528,576,624,672,720,768,816,864}, + {0,48,96,144,192,240,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,384,432,480,528,576,624,672,720,768,816,864}, + {0,48,96,144,192,240,288,336,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,480,528,576,624,672,720,768,816,864}, + {0,48,96,144,192,240,288,336,384,432,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,576,624,672,720,768,816,864}, + {0,48,96,144,192,240,288,336,384,432,480,528,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,672,720,768,816,864}, + {0,48,96,144,192,240,288,336,384,432,480,528,576,624,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,768,816,864}, + {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,864}, + {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816}}; if (lut_numCnInCnGroups[8] > 0) { // Number of groups of 64 CNs for parallel processing // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[8]*Z + 63)>>31; + M = (lut_numCnInCnGroups[8]*Z + 31)>>7; // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX)>>31; + bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX)>>7; // Set pointers to start of group 19 @@ -665,7 +702,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," for (int i=0;i<%d;i++) {\n",M); // Abs and sign of 64 CNs (first BN) // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>31)+lut_idxCnProcG19[j][0]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>7)+lut_idxCnProcG19[j][0]); // sgn = _mm512_sign_epi16(ones, zmm0); fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); // min = _mm512_abs_epi8(zmm0); @@ -675,7 +712,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) // Loop over BNs for (k=1; k<18; k++) { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>31)+lut_idxCnProcG19[j][k]); + fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>7)+lut_idxCnProcG19[j][k]); // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); @@ -689,7 +726,7 @@ void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[8]>>31)+(j*bitOffsetInGroup)); + fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[8]>>7)+(j*bitOffsetInGroup)); fprintf(fd," }\n"); } } diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.c.save b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.c.save deleted file mode 100644 index 08c651c03b..0000000000 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.c.save +++ /dev/null @@ -1,742 +0,0 @@ -#include -#include -#include "../../nrLDPCdecoder_defs.h" -#include "../../nrLDPC_types.h" -#include "../../nrLDPC_bnProc.h" - -void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) -{ - const char *ratestr[3]={"13","23","89"}; - - if (R<0 || R>2) {printf("Illegal R %d\n",R); abort();} - - - // system("mkdir -p ../ldpc_gen_files"); - - char fname[50]; - sprintf(fname,"../ldpc_gen_files/nrLDPC_cnProc_BG1_Z%d_%s_AVX512.c",Z,ratestr[R]); - FILE *fd=fopen(fname,"w"); - if (fd == NULL) {printf("Cannot create \n");abort();} - - fprintf(fd,"#include \n"); - fprintf(fd,"#include \n"); - fprintf(fd, "#include \"../include/avx512fintrin.h\"\n"); - - fprintf(fd, "__m512i _mm512_sign_epi16(__m512i a, __m512i b){ \n"); /* Emulate _mm512_sign_epi16() with instructions that exist in the AVX-512 instruction set */ - fprintf(fd, "b = _mm512_min_epi16(b, _mm512_set1_epi16(1)); \n" ); - fprintf(fd, "b = _mm512_max_epi16(b, _mm512_set1_epi16(-1)); \n" ); - fprintf(fd, " a = _mm512_mullo_epi16(a, b);\n"); - fprintf(fd, "return a;\n"); - fprintf(fd, "}\n" ); - - - fprintf(fd,"void nrLDPC_cnProc_BG1_Z%d_%s_AVX512(int8_t* cnProcBuf,int8_t* cnProcBufRes) {\n",Z,ratestr[R]); - - const uint8_t* lut_numCnInCnGroups; - const uint32_t* lut_startAddrCnGroups = lut_startAddrCnGroups_BG1; - - if (R==0) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R13; - else if (R==1) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R23; - else if (R==2) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R89; - else { printf("aborting, illegal R %d\n",R); fclose(fd);abort();} - - //__m512i* p_cnProcBuf; - //__m512i* p_cnProcBufRes; - - // Number of CNs in Groups - uint32_t M; - uint32_t j; - uint32_t k; - // Offset to each bit within a group in terms of 64 Byte - uint32_t bitOffsetInGroup; - - //__m512i zmm0, min, sgn; - //__m512i* p_cnProcBufResBit; - - // const __m512i* p_ones = (__m512i*) ones256_epi8; - // const __m512i* p_maxLLR = (__m512i*) maxLLR256_epi8; - - // LUT with offsets for bits that need to be processed - // 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc. - // Offsets are in units of bitOffsetInGroup (1*384/64) - // const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}}; - - // ===================================================================== - // Process group with 3 BNs - fprintf(fd,"//Process group with 3 BNs\n"); - // LUT with offsets for bits that need to be processed - // 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc. - // Offsets are in units of bitOffsetInGroup (1*384/64)=6 - // Offsets are in units of bitOffsetInGroup (1*384/64)=6 - - // const uint8_t lut_idxCnProcG3[3][2] = {{6,12}, {0,12}, {0,6}}; - const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}}; - - fprintf(fd," __m512i zmm0, min, sgn,ones,maxLLR;\n"); - fprintf(fd," ones = _mm512_set1_epi8((char)1);\n"); - fprintf(fd," maxLLR = _mm512_set1_epi8((char)127);\n"); - - if (lut_numCnInCnGroups[0] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[0]*Z + 31)>>5; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX)>>5; - - - // Set pointers to start of group 3 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[0]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[0]]; - - // Loop over every BN - - for (j=0; j<3; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i>5)+lut_idxCnProcG3[j][0]); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - // 32 CNs of second BN - // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][1]); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[0]>>5)+(j*bitOffsetInGroup)); - - // Abs and sign of 64 CNs (first BN) - // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][0]+1); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - // 32 CNs of second BN - // zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i]; - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][1]+1); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[0]>>5)+(j*bitOffsetInGroup)+1); - - fprintf(fd," }\n"); - } - } - - // ===================================================================== - // Process group with 4 BNs - fprintf(fd,"//Process group with 4 BNs\n"); - // Offset is 5*384/64 = 30 - // const uint8_t lut_idxCnProcG4[4][3] = {{30,60,90}, {0,60,90}, {0,30,90}, {0,30,60}}; - const uint8_t lut_idxCnProcG4[4][3] = {{60,120,180}, {0,120,180}, {0,60,180}, {0,60,120}}; - - if (lut_numCnInCnGroups[1] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[1]*Z + 31)>>5; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX)>>5; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - for (j=0; j<4; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i>5)+lut_idxCnProcG4[j][0]); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - - // Loop over BNs - for (k=1; k<3; k++) - { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>5)+lut_idxCnProcG4[j][k]); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - } - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[1]>>5)+(j*bitOffsetInGroup)); - fprintf(fd," }\n"); - } - } - - - // ===================================================================== - // Process group with 5 BNs - fprintf(fd,"//Process group with 5 BNs\n"); - // Offset is 18*384/64 = 216 - //const uint16_t lut_idxCnProcG5[5][4] = {{108,216,324,432}, {0,216,324,432}, - // {0,108,324,432}, {0,108,216,432}, {0,108,216,324}}; - - - const uint16_t lut_idxCnProcG5[5][4] = {{216,432,648,864}, {0,432,648,864}, - {0,216,648,864}, {0,216,432,864}, {0,216,432,648}}; - - if (lut_numCnInCnGroups[2] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[2]*Z + 31)>>5; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX)>>5; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<5; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i>5)+lut_idxCnProcG5[j][0]); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - - // Loop over BNs - for (k=1; k<4; k++) - { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>5)+lut_idxCnProcG5[j][k]); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - } - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[2]>>5)+(j*bitOffsetInGroup)); - fprintf(fd," }\n"); - } - } - - // ===================================================================== - // Process group with 6 BNs - fprintf(fd,"//Process group with 6 BNs\n"); - // Offset is 8*384/64 = 48 - /* const uint16_t lut_idxCnProcG6[6][5] = {{48,96,144,192,240}, {0,96,144,192,240}, - {0,48,144,192,240}, {0,48,96,192,240}, - {0,48,96,144,240}, {0,48,96,144,192}};*/ - - const uint16_t lut_idxCnProcG6[6][5] = {{96,192,288,384,480}, {0,192,288,384,480}, - {0,96,288,384,480}, {0,96,192,384,480}, - {0,96,192,288,480}, {0,96,192,288,384}}; - if (lut_numCnInCnGroups[3] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[3]*Z + 31)>>5; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX)>>5; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<6; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i>5)+lut_idxCnProcG6[j][0]); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - - // Loop over BNs - for (k=1; k<5; k++) - { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>5)+lut_idxCnProcG6[j][k]); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - } - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[3]>>5)+(j*bitOffsetInGroup)); - fprintf(fd," }\n"); - } - } - - - // ===================================================================== - // Process group with 7 BNs - fprintf(fd,"//Process group with 7 BNs\n"); - // Offset is 5*384/64 = 30 - /* const uint16_t lut_idxCnProcG7[7][6] = {{30,60,90,120,150,180}, {0,60,90,120,150,180}, - {0,30,90,120,150,180}, {0,30,60,120,150,180}, - {0,30,60,90,150,180}, {0,30,60,90,120,180}, - {0,30,60,90,120,150}};*/ - - - const uint16_t lut_idxCnProcG7[7][6] = {{60,120,180,240,300,360}, {0,120,180,240,300,360}, - {0,60,180,240,300,360}, {0,60,120,240,300,360}, - {0,60,120,180,300,360}, {0,60,120,180,240,360}, - {0,60,120,180,240,300}}; - - if (lut_numCnInCnGroups[4] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[4]*Z + 31)>>5; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX)>>5; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<7; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i>5)+lut_idxCnProcG7[j][0]); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - - // Loop over BNs - for (k=1; k<6; k++) - { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>5)+lut_idxCnProcG7[j][k]); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - } - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[4]>>5)+(j*bitOffsetInGroup)); - fprintf(fd," }\n"); - } - } - - - // ===================================================================== - // Process group with 8 BNs - fprintf(fd,"//Process group with 8 BNs\n"); - // Offset is 2*384/64 = 12 - /* const uint8_t lut_idxCnProcG8[8][7] = {{12,24,36,48,56,72,84}, {0,24,36,48,56,72,84}, - {0,12,36,48,56,72,84}, {0,12,24,48,56,72,84}, - {0,12,24,36,56,72,84}, {0,12,24,36,48,72,84}, - {0,12,24,36,48,56,84}, {0,12,24,36,48,120,72}};*/ - - const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168}, - {0,24,72,96,120,144,168}, {0,24,48,96,120,144,168}, - {0,24,48,72,120,144,168}, {0,24,48,72,96,144,168}, - {0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}}; - - - - if (lut_numCnInCnGroups[5] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[5]*Z + 31)>>5; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX)>>5; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<8; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i>5)+lut_idxCnProcG8[j][0]); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - - // Loop over BNs - for (k=1; k<7; k++) - { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>5)+lut_idxCnProcG8[j][k]); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - } - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[5]>>5)+(j*bitOffsetInGroup)); - fprintf(fd," }\n"); - } - } - - // ===================================================================== - // Process group with 9 BNs - fprintf(fd,"//Process group with 9 BNs\n"); - // Offset is 2*384/64 = 12 - /*const uint8_t lut_idxCnProcG9[9][8] = {{12,24,36,48,60,72,84,96}, {0,24,36,48,60,72,84,96}, - {0,12,36,48,60,72,84,96}, {0,12,24,48,60,72,84,96}, - {0,12,24,36,60,72,84,96}, {0,12,24,36,48,72,84,96}, - {0,12,24,36,48,60,84,96}, {0,12,24,36,48,60,72,96}, - {0,12,24,36,48,60,72,84}};*/ - - const uint8_t lut_idxCnProcG9[9][8] = {{24,48,72,96,120,144,168,192}, {0,48,72,96,120,144,168,192}, - {0,24,72,96,120,144,168,192}, {0,24,48,96,120,144,168,192}, - {0,24,48,72,120,144,168,192}, {0,24,48,72,96,144,168,192}, - {0,24,48,72,96,120,168,192}, {0,24,48,72,96,120,144,192}, - {0,24,48,72,96,120,144,168}}; - - - if (lut_numCnInCnGroups[6] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[6]*Z + 31)>>5; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX)>>5; - - - // Set pointers to start of group 9 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<9; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i>5)+lut_idxCnProcG9[j][0]); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - - // Loop over BNs - for (k=1; k<8; k++) - { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>5)+lut_idxCnProcG9[j][k]); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - } - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[6]>>5)+(j*bitOffsetInGroup)); - fprintf(fd," }\n"); - } - } - - // ===================================================================== - // Process group with 10 BNs - fprintf(fd,"//Process group with 10 BNs\n"); - // Offset is 1*384/64 = 6 - /* const uint8_t lut_idxCnProcG10[10][9] = {{6,12,18,24,30,36,42,48,54}, {0,12,18,24,30,36,42,48,54}, - {0,6,18,24,30,36,42,48,54}, {0,6,12,24,30,36,42,48,54}, - {0,6,12,18,30,36,42,48,54}, {0,6,12,18,24,36,42,48,54}, - {0,6,12,18,24,30,42,48,54}, {0,6,12,18,24,30,36,48,54}, - {0,6,12,18,24,30,36,42,54}, {0,6,12,36,24,30,36,42,48}};*/ - - const uint8_t lut_idxCnProcG10[10][9] = {{12,24,36,48,60,72,84,96,108}, {0,24,36,48,60,72,84,96,108}, - {0,12,36,48,60,72,84,96,108}, {0,12,24,48,60,72,84,96,108}, - {0,12,24,36,60,72,84,96,108}, {0,12,24,36,48,72,84,96,108}, - {0,12,24,36,48,60,84,96,108}, {0,12,24,36,48,60,72,96,108}, - {0,12,24,36,48,60,72,84,108}, {0,12,24,36,48,60,72,84,96}}; - - - - - - if (lut_numCnInCnGroups[7] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[7]*Z + 31)>>5; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX)>>5; - - - // Set pointers to start of group 10 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<10; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i>5)+lut_idxCnProcG10[j][0]); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - - // Loop over BNs - for (k=1; k<9; k++) - { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>5)+lut_idxCnProcG10[j][k]); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - } - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[7]>>5)+(j*bitOffsetInGroup)); - fprintf(fd," }\n"); - } - } - - - // ===================================================================== - // Process group with 19 BNs - fprintf(fd,"//Process group with 19 BNs\n"); - // Offset is 4*384/64 = 24 - /* const uint16_t lut_idxCnProcG19[19][18] = {{24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, - {0,24,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,24,48,96,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, - {0,24,48,72,120,144,168,192,216,240,264,288,312,336,360,384,408,432}, {0,24,48,72,96,144,168,192,216,240,264,288,312,336,360,384,408,432}, - {0,24,48,72,96,120,168,192,216,240,264,288,312,336,360,384,408,432}, {0,24,48,72,96,120,144,192,216,240,264,288,312,336,360,384,408,432}, - {0,24,48,72,96,120,144,168,216,240,264,288,312,336,360,384,408,432}, {0,24,48,72,96,120,144,168,192,240,264,288,312,336,360,384,408,432}, - {0,24,48,72,96,120,144,168,192,216,264,288,312,336,360,384,408,432}, {0,24,48,72,96,120,144,168,192,216,240,288,312,336,360,384,408,432}, - {0,24,48,72,96,120,144,168,192,216,240,264,312,336,360,384,408,432}, {0,24,48,72,96,120,144,168,192,216,240,264,288,336,360,384,408,432}, - {0,24,48,72,96,120,144,168,192,216,240,264,288,312,360,384,408,432}, {0,24,48,72,96,120,144,168,192,216,240,264,288,312,336,384,408,432}, - {0,24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,408,432}, {0,24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,432}, - {0,24,48,72,96,120,144,168,192,216,240,264,288,312,336,360,384,408}};*/ - -const uint16_t lut_idxCnProcG19[19][18] = {{48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, - {0,48,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, - {0,48,96,144,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,288,336,384,432,480,528,576,624,672,720,768,816,864}, - {0,48,96,144,192,240,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,384,432,480,528,576,624,672,720,768,816,864}, - {0,48,96,144,192,240,288,336,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,480,528,576,624,672,720,768,816,864}, - {0,48,96,144,192,240,288,336,384,432,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,576,624,672,720,768,816,864}, - {0,48,96,144,192,240,288,336,384,432,480,528,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,672,720,768,816,864}, - {0,48,96,144,192,240,288,336,384,432,480,528,576,624,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,768,816,864}, - {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,864}, - {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816}}; - - - if (lut_numCnInCnGroups[8] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[8]*Z + 31)>>5; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX)>>5; - - - // Set pointers to start of group 19 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<19; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i>5)+lut_idxCnProcG19[j][0]); - // sgn = _mm512_sign_epi16(ones, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(ones, zmm0);\n"); - // min = _mm512_abs_epi8(zmm0); - fprintf(fd," min = _mm512_abs_epi8(zmm0);\n"); - - - // Loop over BNs - for (k=1; k<18; k++) - { - fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>5)+lut_idxCnProcG19[j][k]); - - // min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0)); - fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n"); - - // sgn = _mm512_sign_epi16(sgn, zmm0); - fprintf(fd," sgn = _mm512_sign_epi16(sgn, zmm0);\n"); - } - - // Store result - // min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127 - fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n"); - // *p_cnProcBufResBit = _mm512_sign_epi16(min, sgn); - // p_cnProcBufResBit++; - fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = _mm512_sign_epi16(min, sgn);\n",(lut_startAddrCnGroups[8]>>5)+(j*bitOffsetInGroup)); - fprintf(fd," }\n"); - } - } - - fprintf(fd,"}\n"); - fclose(fd); -}//end of the function nrLDPC_cnProc_BG1 - - - - - - diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.o b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.o deleted file mode 100644 index 9eef9df59f39881367b911233cd091768483e3ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34248 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 U-F})Lne6wo|GN!aQf>SH2ZU2Z#{d8T diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.save11 b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.save11 deleted file mode 100644 index 670a6ce59b..0000000000 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_BG1_avx512.save11 +++ /dev/null @@ -1,706 +0,0 @@ - -#include -#include -#include "../../nrLDPCdecoder_defs.h" -#include "../../nrLDPC_types.h" -#include "../../nrLDPC_bnProc.h" - -void nrLDPC_cnProc_BG1_generator_AVX512(uint16_t Z,int R) -{ - const char *ratestr[3]={"13","23","89"}; - - if (R<0 || R>2) {printf("Illegal R %d\n",R); abort();} - - - // system("mkdir -p ../ldpc_gen_files"); - - char fname[50]; - sprintf(fname,"../ldpc_gen_files/nrLDPC_cnProc_BG1_Z%d_%s_AVX512.c",Z,ratestr[R]); - FILE *fd=fopen(fname,"w"); - if (fd == NULL) {printf("Cannot create \n");abort();} - - fprintf(fd,"#include \n"); - fprintf(fd,"#include \n"); - fprintf(fd, "#include \"../include/avx512fintrin.h\"\n"); - - fprintf(fd, "__m512i _mm512_sign_epi16(__m512i a, __m512i b){ \n"); /* Emulate _mm512_sign_epi16() with instructions that exist in the AVX-512 instruction set */ - fprintf(fd, "b = _mm512_min_epi16(b, _mm512_set1_epi16(1)); \n" ); - fprintf(fd, "b = _mm512_max_epi16(b, _mm512_set1_epi16(-1)); \n" ); - fprintf(fd, " a = _mm512_mullo_epi16(a, b);\n"); - fprintf(fd, "return a;\n"); - fprintf(fd, "}\n" ); - - - fprintf(fd,"void nrLDPC_cnProc_BG1_Z%d_%s_AVX512(int8_t* cnProcBuf,int8_t* cnProcBufRes) {\n",Z,ratestr[R]); - - const uint8_t* lut_numCnInCnGroups; - const uint32_t* lut_startAddrCnGroups = lut_startAddrCnGroups_BG1; - - if (R==0) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R13; - else if (R==1) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R23; - else if (R==2) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R89; - else { printf("aborting, illegal R %d\n",R); fclose(fd);abort();} - - //__m512i* p_cnProcBuf; - //__m512i* p_cnProcBufRes; - - // Number of CNs in Groups - uint32_t M; - uint32_t j; - uint32_t k; - // Offset to each bit within a group in terms of 64 Byte - uint32_t bitOffsetInGroup; - - //__m512i zmm0, min, sgn; - //__m512i* p_cnProcBufResBit; - - // const __m512i* p_ones = (__m512i*) ones256_epi8; - // const __m512i* p_maxLLR = (__m512i*) maxLLR256_epi8; - - // LUT with offsets for bits that need to be processed - // 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc. - // Offsets are in units of bitOffsetInGroup (1*384/64) - // const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}}; - - // ===================================================================== - // Process group with 3 BNs - fprintf(fd,"//Process group with 3 BNs\n"); - // LUT with offsets for bits that need to be processed - // 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc. - // Offsets are in units of bitOffsetInGroup (1*384/64)=6 - // Offsets are in units of bitOffsetInGroup (1*384/64)=6 - - const uint8_t lut_idxCnProcG3[3][2] = {{6,12}, {0,12}, {0,6}}; - - - fprintf(fd," __m512i zmm0, min, sgn,ones,maxLLR;\n"); - fprintf(fd," ones = _mm512_set1_epi8((char)1);\n"); - fprintf(fd," maxLLR = _mm512_set1_epi8((char)127);\n"); - - if (lut_numCnInCnGroups[0] > 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[0]*Z ) ; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX) ; - - - // Set pointers to start of group 3 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[0]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[0]]; - - // Loop over every BN - - for (j=0; j<3; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[1]*Z ) ; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX) ; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - for (j=0; j<4; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[2]*Z ) ; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX) ; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<5; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[3]*Z ) ; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX) ; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<6; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[4]*Z ) ; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX) ; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<7; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[5]*Z ) ; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX) ; - - - // Set pointers to start of group 4 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<8; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[6]*Z ) ; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX) ; - - - // Set pointers to start of group 9 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<9; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[7]*Z ) ; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX) ; - - - // Set pointers to start of group 10 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<10; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; i 0) - { - // Number of groups of 64 CNs for parallel processing - // Ceil for values not divisible by 64 - M = (lut_numCnInCnGroups[8]*Z ) ; - - // Set the offset to each bit within a group in terms of 64 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX) ; - - - // Set pointers to start of group 19 - //p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]]; - //p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]]; - - // Loop over every BN - - for (j=0; j<19; j++) - { - // Set of results pointer to correct BN address - //p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - // for (i=0; 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 G{rBJU{b%C< diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_avx512 b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_avx512/cnProc_gen_avx512 index 92574a4fb21783f63806c058467fd54ed2f8c26e..87455423bd2ba8f7431a21f7a5e2e28576bd1aca 100755 GIT binary patch delta 23948 zcmeI4d303Ow(j??N~Ng^RDcQz5THVzKuAI_(iA-cLg)#i6rczy68fGhz$iVD01IiP zXrvP*D7_#>V`xMPh=3?iprW8cL`6iJ`^~-QJm=u`oN?cHf4ni?xQrol?cbc=Tx;*W z=313tE&t-^b1FKgnjXI;=_yNW=EFoZ2S-{+oJk=M^P#{a4+& zAwBH<0!z7am7?>rCp>)kFg`zfB8--wJ;}V9Y+m_bqH~KUjt(oo|4u}1V#AVpMDAQi zeC`K{@o4Qs>&L{7XgywG3jV%at!(c33ejkNS79*z?p*N|{Jp=3EBAWE-W?m|XAecb zvH96qFkADphryuB;U*km!jUE%1p~oo6OJ+ASQCze8Jj!5Qi?e$XH6Q_`AT*0x3ei5|be@UC=NR zc9WPM64Og!dP__nH1cXvug^%3SAzOW(6baoF$2+uO7k8-2;=r5msyLy#I_Xt*h7I2wLxM4}O*h8+## zZllpKf{UVI1jnFZ1Q$oc2zH@i1eZj^OPS-*FoH{?VFV|j5%N*$a%dURZZwSO3TOmL zRtXIwx(XUb>S|~h!O3VC!8On@f@`8-^pS>!5nKxmBe)J4MsPhejNk@nxb-OX(GV@a zp4%WO{xllc(eF-qqI_&#!E5LXA$oMl{k@4=}l?u?CH;)L4r~AvM;c zQG;%DBN~IKu?Y=hT<@Y`sPfP-RPUi-sJ5bEsJ5eFsCJ@ZsCJ`abh-zPtv>4GL$nN8 z5Di0i01ZQS2n|D)kA@*Tf`-xSF*FR-aWo9or)U_e0yGTODKre#X*3Mg88nQsor z9c95lFboEQ;V@%;`Pn02p%@7R#V8mkM#Dfc1_nKig@Ixm47wN(1Hl9s2qwZnFbM{N z$uJQ3V9=8v27)Ot5KM)EU>XbrufW9T`?9lPp?DPriq~M!({vapX23u(69$S|Fz8}7 z3o5?^hk+m$27(1J5G;g&U=a)iHU*oL`$Jr%+-2!e|5&Un ze^YG1bb5!srDx;s8}X%c7uK4~@3C2J<2@EbD)dtv2K|(PK|d}S^b-q%8!8Ed@x{Re z^Rwe&Fw9ag(3OUPt_%!x2{6!=g@LXd40PpTpmW1Omk5K~s{qp$@3A5*gq2_*tPBHT z6&MJs!a!IJ2Ers52$NyZZ*>^xYQR930s~!580b=Api6^+E*%ECS}@SnhQWC2z>LLv ztP2ZaJs1eyw z=(@r{*9```?l92xfPt^WMOX3vAVwABr-w~A*@t@<5(_}sGP zzR~S_FqQJN--ki(TVe3AVH*qvu^pyce)bL+jAbXxOZnNmU@+?4Fc|d*Fp%$ofqX9v zx0@{s;{8M`55p1_S-aFzEg` z4CJ4{U=*LiKz;%S@&XvhPr^Wc3I_7eU?4vYqhaQJ4h#Jm80gQ!U=-(Ip#K5}`tvZ* ze+dKqS1{0DfI;^cVIaQ*19=Dr^2;z7#T6LHzlMSQ8yLvHg@ODk4CKD=V4?pW2Ks9- z&|imv{s$P0;ztsHU^!H$(zYhcb0~qKZ!eA5{W*+o94D=Ql$gMDthrvK@gMmC82J#3P z$RlAOkAm^?#Eo!n*K#K%lqz!X?!$-9%?G9h|K+oBFuhW4pN27*sY4pln)ge?^*n2L zJ-*W1+@5JfA6G{;qN%;H(G2`ur!jwAo%ToL9e*^|*CqMVG_RJU1+_xWt!Lqm zF&2*{%M!2@STt*z)oa!MM=@#tgFMvRBYpY)rZaO$|9L<%?Ef@qi7C|n{f#|x|Nrjp z|Cxxo`}-&KXpH}FpWzGROw34n(yDe{eQmu zf0u}6h|G`w6jNX^=g{BAr2otP(?t8*pnr);v+n5df?g!Tr!~;D=(8O(?O|o2G?@*#^Hn z5(3+j_E7J(A#V0yq_DhF6U{l)v_*zT&h=4RJ$y8z5p&Uwtk_V~&V}7BgU=>WcfyeA z_x`|IRH!xD_oh=w)TqbMzEAC#sAZ{WKcIGeR8lRpA5z6eMO*tw>M`87$gsbWgo_B{qL=-86I?{;T`@+l z{SJQQ3v=k1xEN%&;lYI!(P_w8_78CDVa1G#k@oIS;G%?{189CZBXChxABv0V_Dsr9MW2AM9Q)nIxJcDs#l>R#DmO0D zjEjI>r@^Hg7whejbWzK=$g?}?qPCs_%})EZbX?TcRre9PtHv!n{;;Kyb?e|MhOMOg zimG1$XcaZJs3^Mm)pUoEQNO5#BlITaZiM6K+>A!x&Gc+IoVj(;Zf>^wtDi^cC4HIo z@sih*EM_k<*fto=;nmRGXf)3}scGS*`=g8Kt%xebf5o(jZ%L4jry5>{25a>w9d)Fe4(RG$e8l{)- zzQBn`P+GrE`cuu&E@R9Z=io7(UWu4yCgFsD-JEhV_>#mYJQ5Qu=n!feoyP$fH z)|0AND+AxSG#lv(#MciuS9F323k6s067WrV#SkQWxFZXmSBvB&3siag3hy!Y6nFMHe)~%!{)6#b?3eF1pBs0fAqZ1YB&w zpum`_fXhu768LKsz!fIcn(;Vu)C2Tq`Msh_8mm{+SF0{#@dyW~iDU+=wPfn30x}oW zT^LJ(M^zrDS1b7due#`tyC~ZzYp^+|+n@%FLuem0hfHa;gG`RP3=_Aj6$A%&L}JOp zO|>u;@rP96cs&-$>yOuyQ$DJPm}5nwG|dxb)mn1Qa#Tps<4iq5+o`$Z^)%n?qL?w& zUW5eWU|-xEEOpK#6XpxtizVEdY{KIL9bEvcoA8vti3fNf3a7nneiPnhskfjzM%INO_6zx~uyx8d49_cUpWE zXl?Fk!t(;>VZ(IxGGR#I3hW8aOcP!e*j0ToSx@z?qPl!~8=ej-xi!z;)l`?yn9w8e zGpftJCiDwTq`LH)Feva>s>^C>KI!2s;@&KEd~z!a*>7deYS57p&MCJYK3 zNOd`cbGGB0Z&S6s%sB;iG^%YVCly*qp;??%U@q0=FizT@la8di9L`Avo};=P!8rxG z$^nk#oC2psD9aR7+xt|Cqd83n&V4Qea15srSXOza;Hj;oN*rhUv?p2c1Hti}Md0#C zzzLj1;619gi6#sRyg_w2iF0=3oV6)(GUpWdax&GDkCO_WK~>=AqypEg`%_SuK~;4s zOkLG^DkjPMB!88YW^hk&6#-x4oC5Ev90+`SvB^7Um_DsD3%cXeopUB<5qOdYF^jVZ zY)GXz+k`=Z>!=jxaLz8Aa|e~;T+S)*MOAScN^vKZ;{1nLTd+lnZ&w;%t_l5JIm@*g zfD26M>Bg`=mEuAZYTX&yX`(OUoC1@mTomW*!I96Xlhg3%c16MW250HTzPU94mv9z= z0TuHK9^FGqw#@W-db3~-?TO1d%To*+Cjq|6Sp<%!0j@BizYj;Yq)H5M&Zimnq)J@L zIiF!T(boxd6(<#Xfa+^CC+*9j&ryA?;iO)M5sw4D#Yy`y+(?mYIj6u`REg_2XMc{o znW`#eqrR$B@onHV&$4q#1mH$aBk-8=X5*>d%z$r`>GKR^K^@u?-{CCJGu%l<_bz7< zxVSmsW)u1capX3t#5~S9n4ya%)fUeA0z+Fjs=D_$snB)=-{+(+a%gr5z^$D0C59`h z2)1$3Aq<16&8sNEb7~k&$quwd?&cn{IOLehdlfgIN|m^Wa}H-;ak|gFoO1-j^ESW_ zIg7v&r2+Su&_9wRuhEc#oO2YzE>xHMIp=7G`;w_J4{%bUC#WzFa?&vzI!z6EO;7Fq zDLuo(Pn0zF$Z_mDL4|q5gkFIUsW6Y4FevazD$HXhbdP7bTmAeR%FRR7bKLZW#FrWk z_=yQU6If87(x&6tt)WspVfwU*?AzWIu)u^~fjuemqzQup*HB@eGNF4C%ezrwer7_y zz}KlTPn$3#@F^cv=I18$OlJMdRGDW?7!Ww03iGT9H6KT&vVRLEFetFx zub=gx@y9J zKzl2|?@Xv=b7Vg%%65j-pj@E5M_1GX2G{KE$*Ap zFECaWn~mQx4WP<=X!<;JOhKu7H1RdvqyeElRp;4yZ11V`(k<-t&SlAWQJ_|)L7}^A zf`&15&*RwRRI4_oexVP;R1hOd`GD#(g1w#`);Q?#L^2HsU9a>xdTi!!DoHy#y|1$* zn`+X*G$?ctm0C1Y_k50R*&ehAQ@_v%H5BPn>QW&(+3Cq;$+=|E7^VTCyVMpMQ8NTN zi?h?afF+rEriN*_CIf=M9z= zmRI-Y>dAVfsya`vo-)1|f+|Vgr5tpJ3a_%{71~$%=HX78Q>|5%yvtY;Q4h2l(}2)i zwI7nqQdC~a?DQ^Y$yAy^)tLr`-lPJn!PNaG$3CPAOJV94`o2od(bFtiJ(SWy3@ zs;Z?&m#13uu3%~P6wumC{X)l4mDOPy5SmVFcwMGJp)b>ZSdVE)=o|EI>oe5?9t}6C zX{8=e*)?G71~zDcig{g+^ZSS8DSPxWn0E>VER+)lFFKo5k71OXFGO!S9!>%m3oJ^ z$o5SAt2_j?QsbyVIxr2a@(|QY{YG!@Nv6S79)emaR}0XNOhcp`Znc#hG|G>I@N4nrrKK`t*mj2 zORT_N#%^GPM$}bP7U-_HxZ3dcXRlYhAFE9Z^t2W+^Z*9xGce#NYe1aE(m|hR8WP%! zigplF_gd~|o+`f(D^MGnOD{+wab{DMz9@-==Ba*=WX9Uz9KufTI?i{MHp7=Ck z5(%B$9(0T(5?Ysvax7E#M$Rxm`H(&(oDz+fMB@C8p4D~A z+Yz9XC6UmQG$NlQ5_*V=(9hJpi8JJ=RD}^mH-vMlBob%0o}kktkVB6qq^e6ukMjCWp}ZQX#Kn5`7VBv%oGWQJ zb7&PRj(L(+=sYUA97&tUvBTB8#kkS>RAuuekvI=hqFhNN^a*tmk{0h#RV`$vcMIn$ zPaj|xNg|=CRAWjK3H@3ny`iVY1)qR(sUBX9YAoYDPBc!U%}Gc6QagXZ1_rZHQ2gj;FKY-E}SYK|~2 z2Ka5p84}!46<~xZsSY^bVP}pwN45Zcmua5Rr&aN#m{=$1g>7MH%r@?P2+hp*n5GHc zL^b$6(+r^#m47Lo&Nh0Y+t`^S&ec?k+nMGGtxQjH2h#$fo!y{2nHCBiN0Vk3)0pi% zz|X@$cQZ``HJ?uVG~f>yXGm}nm9`8c?9l+uz3j{pr-s?+{E%s$(7f)T`E(XJ&Kz;(Afq#%X`awt z*z%l*nHC7$nGSk{X`#^9nt>i=8ncr}m=XngjA zoSmT$SaO9*`3zJ49=Q!Q43f;ROT&4Nox#2ATt)BZ3#Q%=nGT`(cb=)XkLiuhpkFc# z2yLh?(TIkmz9IiDx#L*6cg%44!1?i#P)?7nU+%(SLtafRcILww`k}LpJUIl zvnur+!89b)rTnY#GJDe0j$)_x3zih6xnh?@LW5mE9g;|B2HkfwQ}=n!(1KQjB9d2V z+p3^NB`>JC>g=x!?3Bb3JYS`)#t5Ho3uiIO^d;wir8Q`A$t1LB9B2tiB(x(vNf%T1 zSDfKSJu-4{7S4|>^UC9lvi4$yLv7u0-+dpiP`m&6jBrE=EbA(m_c zXQE`f#QFD7rV5ft=wX@?6(y0-nRpP+N=)4$&hRuXQk5mI(EV=EDv}q}9AQnWo2rsn zg10NrTY79#6Nrh5_o$f2_+}IK{MI=H;(tN4OG$3>j(Nv}( zp-ojG`u1Hf2WPq@`kK@4O9ZVYiGPL` zC93QuOhZD?sHW?%iLmlm$n9N%`_ymvbu@%zUQcP+p^PrgC(~5pieLj3bi~2+K#FBCdWP<1=^me zR>(9e9JB+|fY3Em$4@f#{48(g2Hj0Z#vx$(Qz}-iSdVAcoGLeio$g=QIivz;XQn}+ zbJb-?GJmB??aEH=HBBT2v>6rZ(@Z^oa_l8_Z3BL5TeTUSUUs_g zv-1EIYConyp|e%9jd&WTY0?c~r}mH~J!^qJ%QPU=QXcdKFP76>2uqkkGfNzFuYODasifoj_k>8UQs%_$C$Z zbjDaI&FRuZ1>V63uT!R(>boMIEv zWla4-2UZ7N&NL+SX&dO9Og(X&;UU$}3Z?;2Of@Vgm(`NZ_=VLVD)d#BF<5}3tloIm z3|5ynW6_#J3D>YQB+jMuTHj*oF2#}zdirZ6kx)xl&~;1$LKmt|d04cfX@}S#iAr;# z%Xpj4jgm-cxOyFu%yBeLHnB4#&Q6r*9Z6J%6CG_0`mQ7r`co|EW~Kq5xeDKvk4>pf zmApj~C2*pL6Lo10x?K_pZ9#>+gK0qM zShX4HQ?^p&?vh01IMIuA6T2mm&09xF{%8c}X?BLhIhiW) zjK%!dQ+H)fUDZlPsqMY_b)BlI+Fu_2~jp#xRd+K*gJwiKDVSdllEA(1bRj>{JPeonYQ?Ii( zAl}|oia#(73bm?Y+wqXTr`honJGE*&q^VSjH<-GGK1Q49O{N~9$Eh+4nRDx%iAPj65%e}wx6qliY5vaCBeXcx;2ox3 zp)*wK4(yp1RjVB+#i42#t}+wpjog>clDV_0G)EptXF?OG6dy`wLc{2VYgYdM1BA9y zmykZCJUv|tI|JhUursKYX;A1_DsiVC+wur~ytT1YtIi_|5e;YR7TShBp+qqC2rbrF zjo+!K#;>MwwOf0%p+2A zC)1$N1GJ3ANZu6AyOC-5TFC6my; zwLwctBB5i5#xV^FZAB9-Uh<}L-b|{(Qj!GwOG>T#yBw5`>ZOhPNrLS9c23H`P`Xnm$Zq21^n8%W;zoOcX8kH;i0s5!#5iNFmd zu>?0&A&k%x)mr_&M^BB*c^pB_t)HR0C~LI_oNMEJ~ zD(*v=Le-W`S2YgC64OY%{h^+Ub?r-{%T@F~m?^3;nKbn>ndj7seV93YX)PIGEsgCF z>q2Ahak=`KVrr{%Llb0RxE z&DlADcDTvbL#9ONMYR(7^a<+Je!ZW*RMk14_p{uqq|^aCkz?xc0XT=MJ7nHaNe5w0 ztKJ6@nxOX3)m8NqnX{_gA-#26qsr)Gx%F5V47)jYJSbs-I04OO(Q&Foz>lVoKNly$B+i?#$kZS98@5C5DZv>MSf)`JEO3T>`}=*8EEoae2t;WwT5p|KMWY&6lY z_$B5D%^`Y`%OfE4W#i)_PyL-jAJUR>g(q@I=;r32-&!~0w?mjf8M0)Is|$S9S`42M zFbH6ydO|Ae2tFFzCC&HNKaGi5D9-Bi0Iu-}V>+|s7%gAdc?!9imJaWtjvmnmm?saU z^fFH#m=uXufS{jCQd<#!jktM;L6~{K0Xm`s39N6C$Nc(v z7=Qho4nwe>dlL@hP=m19cn;>F24Qok86FuCY08Z6rH7f{OOKpSF5FTSDI+!OZDi5x zZ>yAJI(;|0Cz;i1$}xOL;Z!}`+wk5LY+cOH%ue6Uwv9C5dVv>I5IW<#*|u>94MBnU z=)2jr2_`HQctN>7=I>_Prr=+r&_i;UW*8B^u}Yrmm*k<|- zL0j?BH??iEP1s8ymRR&qlD?^JTX5PC_{C>YF~@b6hrXL_TWtD*;-l|o+m@R!B#^$F zZChbNtt*c+M?HHSU%1A1v*#Vx>ATrGaf$C{Um-JCMSlWQN7W;9L3v^5yVhKoF4p(N)L9@ce8EBnRvEn05I0 zro|XX7Q`4w7Q~oG78Ii+3nHuP=?IO!T}&06*DL$z7=ozM`V?ZPa4S(|bjlb_#}Gs% z=rq5h=@^2jL^I|z#Uz1%|*v~ILhj~a53FQ$9Xua=$|7j$3@3^I2xzwAzUqXt#ack&A14- z=sXWcx^c1IMdx`qY8e-KE;`S{QCr^!%}&=fwfQT(v~iM$V`*{YBoD_*`nG5ZI?2Pa zikeypI?2Pan(i&K#4qZ%ukBG_{D5_*J#`VLJ>C`;Gf z^$NyyU{bZ+bI^v4|Nq~fvOdQ$_>o!yrdSrVN9~~rOTV(Dw0fCQfRstW{tOP!?Sv|u8%t3M3R+>58 z3?t{OJ!f?n?O>a>f*dTTC!asJfjmEC>j~#5caVb04F6&Q zV6`9F!JfEk$YlpxqZ?b&Mc%=#CK#7_yn`j_^^NPoNeRnn2OFw)F|KoXN87FsF|G?H zCTt@ALw&k&?Vp%%92;VBy{%=n0Rj^eW>LVB9o9?wFVSIdS(07q?hpC`eWjZBqyCg_ zjRpUbp>F=D_eOKBC02F(N$+i4Yq_gB{G^vtM}N|r*xs^Cx0X_$-q3qSCchcE)^Z0| zP$Z}sH*mPqT6N@x-Z#uzB=XH2NjLRZtvm8>={GB@1M$eV`Ia81j&HLRQ^8w$_>LR# zmUrxtse^_Nc`kLtI90x_rRI*M6)kTUkM8?Kr@q6V>-TKmtdYYP)w7gTbAGZERqiU5 zFy(1%vF%t{&(f)wI;mSLs;st_bk(|^B~7hrYk6$PS8XjV59n5v=&;t;7pqK%wJE+M O@dlaW>I;Xp>VE?T8w(s|@N?R4EkQ5}LtnH5J3u1 zS{2aHico+C1eAaZh=>JBBPs+@#0I$kx%Zss9K4=0?i=sJ`|vJf$Xx3;=YOuX_g-_a zN~G2q72{tTlUGysY)yI8QrbQ-tZ$2odj|cHHU7%yr(487VLg@Y!rZB5Z<^Wj!9?W8C65bhvHwn`{NyHO^h)^)?TPvC zB`2b_53L`PyQ1}Q<>~nQLd^>KXDi2`b*1t!{N26EO#HpSgfstIm400-7UqsbzNUq_ zIWYYSbDx93kfTgE+Js|FI2HziaV8vZ!U-mv2-7rwan&?)R*pI}tFu+><8Mbb8u6uS z>+mc=I>D?v|4(32EIF@w=)qv!XokyeiG_T0ATcE)L%=Ga~|w@44_ zMf*dM^bl6mpbI@&V>JG5S96(hp(A{5%3whTFEzr@$fHIC8bNAAp;1f?8yd#d#-L#Y zmqfz|jzz-=jzhx;cA{YfmqEi#@!M)<*GIz$Zit2v+!&2KEgEAqK`W@`_e%Ze z{fqjW`?oxm?%#>jIrzI@t=EnFS0TTA?QXt`G}G1hu(+u4IvV|`u@;R9)L4(k5^8Kj zqktN3qG8PIZ8Qwk7BmdiJ7^fH0yGTOb~FstPBaYFZZwQR_n^_wxQBbuGGswC4A}uR z4A}>07_ve%4B25cj8TuEVW^IwVW>Vq!%!8WVW>``VW>Vs!%&?g}G0`WESQQhUrz9I|K%AnV~Qc41+>91IlWVKCAJ7$_#fV2DXD5KM-FU%z%MlCQMABFE^$=+a@JbHhNF0RvrK80hN3V7~QXn&KHYfQ7Ij z41|qfAZ!c+;X^PGHi3cgVHgOT!eHEHFwixJfvyD%bRHP!TEalr3I@8?FwnJufvznK z=GzViI$wKO2s2?I>;MB{M;Hh@!9ds<2Er~d5O#&ZxZPl&%YuQfI}CI^V4&*>16?l| z=z7CI*9Qi=M__t!u}7fT=QpVGA6L&u4QTb;Ye3uFsD`U~<sBS^ygrp z{|W}fpNE0`YZ%BwFpyt>!7MJqK>iI30|WVQK3M2~ zhk^bN80i0mf&MNG^!H$(zYl|1XjpmB>oCw;U?8``KpqBz$Z#0QBVZtpG+`7Bq!#A1Oy(}Z4ix0Pgk;+PY0?ri;Xhp11K0oWuKu5iXt=+>Ll4FT|Mo8aHRg;K z<@;~9`o9MiYkz$le-{(=mq+&ZF|G$5Yog}+cTfMH&;H*fq7@?R<3Gg=`X)#5eHEl;bP5U*%gHHmQHVYZ#kL6@}O|zV7jJ`E0 zvR_*mJ!+;C#u7QZHcVLL00TzMGGO={y)-Q>EPU9rV;~66?*#RUaKtSbh7^`XbQo{i2>TR3i9SP7k`oMS7% zrH7R=I%8~IJD?M<=fE?;HWN22EJ4QrKFx1i)*HP<9k)$;-lkj8Nzw-(-3(jpNOUUb zBhi^->p>Z+>yr_dXFJghopgN`I!kT4TvY>gCaT^NQh^ znWIKi@RoWm9FC_Opxw%BPgFNY>t%dyEUobMB#S+Q4B;D$=G>ZSZZw+5yJ%WO*(WeW zOaY>b@n0z|@)8L$@w0P8IU-m?3vnZ@VPQ_p(sC24G4cT2tH_eLRala}Y4t^gmGWQ~ zBf>DpN|wg(MEIiU;m2Mtg)3-cG;el9GxG_et8w|!U5sYcR5ZIA%@N6(W_y{Map7TP zY{~j+Tp?@bQeg0lKG(r;*qb~$6!I5t;9ySzRO@s77B zCfSVHL@_C5%vOp?HDY3iW11zZ(8SC9&{C}!tEcD()FCqG)J>Q&%Teeha}Hq^(bhRF zJP6dZgbm6)PIs1h5p_{=jOkl1z5>;6oSssvMLGB;y2D9VB)$o_xRR4iSS;{o^)?B5 zpejmEpJ@nEJv`7KeE?^e&@J$=vW(Z8>u;)-<1vXzSVkom{AlRLSKwS9g*G*5W1;o2OdQQj*j(Tz>442m z*hZieJCdV?2|Eg$5eeuqVV1y`@p5ytG+`fsyR+2ADSCXZ`&n?dHl0t1a|X)M(Z+;B z1@=|0skm#)u_7JqOy3ys{ef-N(cXlU1YVB;%rv22U_FZLV8U4fpT#@D(b0qp1kS;m z#nH)xiv_Mz?@mRHtWsaWJly~#?#MDjwn)gkl&rf6w+k#&1+a$+_Xzy5H(*Z_9uW8i z-Y||{COj;#m&%!@J9`(=l=_&y&&2l-EwM*Tcvj$GY?zL|CJYID6MKRq+k}?|KCQl( zrlTf87OKm~P3RFAqPiSlLchSWRF_^81_k~|bvcl8w&$EFRF_Y1 zPJtCusV)a`QlY!3E}!J20=uiNK2+Nbs>H#ZCX;jDr`$t0i@+|b7y@6t6!?ajKCJ@_ z`eUDWJk41IwxPNl&RGN|P+g8NVNl=zs>^3MXGhNYJXPDXoKxVVMzxLPq(To-XbvY8 z7@)d*j+1ucq@AcPM{!btm#8jBb54P^s4mBFPJzoJm1R1r?M*7hah#?z=RQFtIG)o8 zETcTrao3hnB~CPbS{D|4OK=ir5m*ofIGM8ujHgvK#e_kD;Z%ZCIcHbS*^%Hh&M7cA zm1@byNreWe3jCZ@;68PCItp`_s_{HbXVv|AERrK6pT$YDc%(X1inBSVz*{O00^dv6 zQ3~MPPR-#RVn|3Y z@(oTpkl_xBT+2BHK0%eZj&nZ2k$hLpkyoRpJ)TIgDW~T2xy(=hFzaz*w$1)s7b-AB&j$^na zl?w9!Clz{*3iBW*9nYc5)HAd7^xl`~9v8&Oz0K( zBt@PuVNl>?D$J86bWLUXKq|~nP3RXmj|%fM6NUti@=;}eZc@)Q*0-g~JY~Xw!1+{| zr%kB&II?;tz%wTF3cOnj@Cy?L1^z;XdDet3Kg&N!RjuZt+$K^jo->^xamLdF`O1Wz z>8!|B{<*kohp805HhtRj>^n=FV#tJEffK6&UNB)$U>hpTizal@669%2s1+@Ufr<{<<=PIY>dhY(nW>hvcbVlK-I zY5%-sLchSpPQaf{7!sJ+iwgA@lX~W{emWKEZ4(9rzD;%ds|mIF9QiZV=^Yb#1-_$p z%-7Rv{Xuv1&wRWdqOGn4Ecl6*#a$En1y)w27T~u`{i!nVn?BDArXVSu7QUvNG$8a@ z)qR0px?eUubPGGZ3t4h68q~@(DD+Sr&@iU17diGrs?~6&exYT;RS+{uTTJyC$zD$$ zYbw+2iDDWMx=QIU=%usgQc2p_>0QK<{#288ra_@=sMKPZx)yV6vreETnEHh})kvgI zi+LDM2Rl9aEV+~l8p|{wG*4}%86_gf5ywvNODxHuJu;qYQ0Ui@piZW)mpL}O9B65# zexYxvN((WgN2wYU*y&lql5O;45}5{s)=>i?$^MfHuq->hiY1TIdMU>=C^WV$XnCft zr5qceK`Suz3(Zi+kv?%Jm0cxvdR}2kq)Yv|P*2r$RpUjyR@$Oc2&yW1U*#YN6-hP8 zD|DRly@)G)m};$tL)Yw2%s{HdEJY z92-*)G>xfW=n<8kr@Jks9BN=5UZ_zS2&${cRH9n*u4HNBG|+lX{X$1kmDOh&5E@1A z@CHnSLUU<9Y{)buG>4vTBc@uwLz}&(C6%@TH)iYtHt1I>c9CA%_a)U?6LxyV8E6Ii zFjK$K4ODeanFfSTNC9oeG$?c@y&jq~4GGO{2-*&t5V;T~gO7Fq;OtsZA!`W1onT%b) z^e5@I%2|vV-suQuM|OHwd&s9HeL!1eC#L?@9)eoZC@PT7OarSu1hu4N^yIoQ4X*YO z)RMk$1=^KqXtjr+mgJ5g7#$U z7g|hJ+KXvGXeBivU$3Pnsn^M@S4Bwct4>wfPtv~5V=k-$`lzH8+LMa3zoZp%c)9-OCq7O z)j&wHYg1J|!%puy&UcG8!)GOt(3@1GBPEg0v~bWIrmppzA*hbij9#Rw93_dwdAA+t zXh|gWZB=RsW;Bnga4b8$8#v!_+6%`?BBA4{D91}8p{=MWCopww(_*2kXeqB^8v8B} zT0rH#nyDMq+#hrBN!YQ5ah3#^Q?6yS`_N*0gPnQeJl-92Ez>PRe`^W4j%kt5eKDZx znHCGRHUZthG`4_ec$AjRMy761bB1+dfj2SElHf;G5oVay&JO2W?93Bqr`DivGu(W2SKG&ct}L9NvorJ_OLkEypJM9YBbT9`gCzTRlAK{@@O^ep zq-XO5Q}14;Gim*uWvcCCdZjz)mrMgfOR2AEMw8Ou{ED5SAWMQS(DO|F`9z zJLzeL*cm*)&P%lSU0~`x$aEZ4?nS2B2Tb#+a=&335c-CCaiv}>;b*Gc%k1_POudJhx@k#XW2$|`v^H&*-!lye9idtTuuxaI;QW!Dp(89Q zO^f0>Q~yz>@wA?9Fm)Ycx{%7Fm}yYxhx7`+$<+HX$9k!7e`2bAA`3N>=6#EC0GR$H z9Z)wg!?YQl;rxZ2q2ugaPs`ypQ-2ZDwJKv3?wN-^W8YzC@B}-bd<672rrwiGuhO&q zovHRI(*aqae=rRQougJFecGQ?ns?b5`iv!cRGRmg`afsdOSS{emTtv{r1A zNa(H}pms?lv;$pt3{%%x&d`tE1|=k~&;d0-OG;i)^R08H8n8nWOYnTyvj-{p}%$l#lMa-o>53>D|&&IXX-l78J?ksT|x2+ zT}ZEsijo)9youYp0#}m654eI?;Y^WC7dZcGYQ!6Qt?bL_ zI%>1ib&;LZ+kmEtMCdcLUg|In2;D|BooPsDXH|@`eR?H0GbGVBoc>fYXkAGpv{QA^ zdXh+JKGFJ2UEgws*0n$zNM50B!a*BKUQqMyT&9X?B#9+>jtZ>R-Fi=TVlCcM9jTNb zwoGk61+LLu!Jni?>7Y%S286B*18v6CbA@9oP-Qn~8WMV3wOEH&j)!iNhn=qPSaPNd zXiKI+q2ttaNV0EG>9%I4_B~5h)6#FlG$8akC2Gsm^8?3@Y6semX-H^Obpz>rQ>b(^ z+3C8@l5 znR;$>>@_OfK1@SGzgOKhU`9KsQv0&gb%!MhRD9V?gF|~}c8%y%3P^U2U3%x~!I+bZiXfX{sjj6}Z z89Ws0V;TT8XV{1;)z4Uq;oy_1m}Yp7D)V`E2E|#8KK{*M>MFsK#`QsGGW836l?pYN zX-McEs;^m0Jta9qSU1qwOaq|i47X9?&S8u0mRcTTEsleGsI0f~yQWXn z;J5W!zA~VWmpH~B&oNu6a$jZ|61sv)b_r9DlVdLtRZIgyr%)j;WvZ3t*bFMvc-_Iy*z+Tu+~z-eBrVVo3+O z`)ehU&_Afq*D(zUU8uTk!AmQgc8CpUeR&ZA}WCObpo%%ntb zNuqL`D9{e{ZAm0Fj7oSj(}2*83SZMNon~tU=T=Eno)eWS2l|dA68ea0xfL_&ireWZ zU}s32-_h%7nXqGO>IW{w4=0Ec1fa&oap(|pt~iJ&~oY~ z&FC0a>K=B6#95cN*!Lw-B~Fw`g}YZ02~DEH-N!T_^s*Z84rX+g9>IP|;n#4beIHR}ek3uKImSV+kRvjf z(7RNbN0|nMzC@LIjA=+{2dd1EC2tkZTaj+|Cz2P`e6f^k0(@K&OYoO!A7+>~pGxtB zWU9)U7EtA!luSbFD7^p=sHiENpRqF}&X=hYPg%_Wd+MqtiD=6`&D0}w5^cF>n0kfo zRU?r;Z2;Zvv+N9rvs6#eFPR2~zOJ^?jOtPWeZ@|#I*(n0Zu5DjE}`}5jr28BkI+rD z+l82Vg$_`awqZt>sS+=;Ga$~cREgg(4GMi%4TPlMinefGVy9MvXH=6a@iJ4F&}V5+ zy~5NZ^eHOLt4zH@wVJAE8~#m2osRHcV{bsbJ*gDGXBre*R+ZY0n{=O6$B*pPYVwp` zp;Elg)FreoZK5}rdW3#Mm08TxE3||1A$?jpmEuqA42aWBrFe^JQ0QH?pJp_OelGom zomvXdsD3i&ZKf`vt7y~wm8nOlooet7Q?JnHRr(I>nZKyEJ5Y-4)N|-%-=R{xD}$x- zV9jZb+>^nCmZncE_hm4l<>-NHR{r+^LI<-CYYi1LEA#9n{J+DD;*}-l>;v z^EG|E4QHoTi)ZvJ(Fmq4p^wup7|GNl^lDQzX{Vl^xSPt=X6@6Sc0s>*OD3rOJMoK; z=oENk*sIm%aeC2Pp#)Qp(4U;3B_)&4)AVc|OoKwdpq(yO@}_a#9aP(;BrmA>5_+dL zaGWHT;NvQ17haRSskohzsSan-OM#Y_OhQN011%$ogw7U1^5o1vQ_{c(@&PC9wpbQ0_gL;od56)|X5TIa4ZaYYilm(BJ5-+)xq;J>Lnm z5!0a1;dG6SC2u3n+m-IeLy{NNoZ5J9L{rW)t9aaB; zKF|_hO{oL8BNx=618~k#cgSo}DFUTz;E|KmF{K-C9@dRZ*guM2TkI(gtNw3=Ttb#>)YGiZi~t@C>u_fu%P zN^dN-$3(e zmU@c#Y~to224Us_2N;MBB(T0g9`ozxVf^)TIt;;j<~2BsLk+?f;69j#8ic(-&4{ST zC{t#9FFnlsUV7AGa^aGqNg1VCZzGFlJD}2z==9y}N60K!(~sag3L6^Y`|+dtQLuF> z-!mJ1H#>Zc3D*lOP(kR7?`DTjJZK1t#7E!F4xenoVu3#^=TZJ{cKCGs-zbcb+M^|A zgm0|VceBH1n9wcouo`+)Z(i$7EQs)VenXHcKKiD1_yQC56^K_XMkqty)DC~?Geh7P zUy_PFraL|K-R$tCrY|Ty`fhgk3KNC|+6k^Sq1KbjMAkpckj}tB)wOp1MUQLsj?$W{7G} zCQm*02`c}~ikQZS9m6&Higuv4DYO@;6`$a(M&Hd2Ke7r=5B`rzA92Qk9%JeenvCCp zgnz=+&oqXPEQqLN`57r9qb}l6l%Nv}BAXaZI69^sjv(s>^CQbuQtlg{(7 z$LmKhp9xMn&%>Ue`_b_`={OI2qE4@^=bdz%hdoK(fNV3IbexC1g1!r#IZisx!(Ltg z9ASA*I?lu1EL{(wx74}Ig`V5!1e|o9hdsmStas9R9`?FMXN!~0^RU;`_d&DMd0TBh zrb-L zBZf}$u(vYX6KkT~+Gv-c<2-EZNn7Fw(%3c_O*+oQw$W%FSJS@I%O=v%9Wmw7qY-DG zM?p_K5$92C`3eWnG*=5x>J6K$eFTSSL{G9|EiT&Pv+bj9>^!4eJgwZ|CpA588G4pQ zeQi_7S9LJ*Sr!eo<*9oo^^E>+6RbZQnJtSlZKtT$cDo_JHqCaKx`7i$w`iK}Hg&)F z!RQ92m5;!dqsQx!b{ac0wR{=s_tq;L{lL`nAFBDE>ff5%Qylh^f$%S`=)q8$wimzM zqCW?*l>a~2o^n3NYw(;}2IHZlL&9^+Eoe@ER6hRL9@wk|KCoE{EKt@{f8DIa_rPW) z@MrZ11bPoO{S?jxd0=~bj7LALHl6zG_9VUswkLtrmGd;dll8#%BtAMwBz%dv+XMtY zuvrOwV6zhVz-IM0PjDTIBYc&a)5S1qvD$N5chU}a^0cvo{ed}Q2dj1l#;>}O>7*u- zxu({@&<^&=nZNE}19%MVd0!y3o@z)YLwU&zQS)HZ=yZ|rgS>V5y{5wc;D#o&K!v{0 zQxhKC&<3)kKqa5W$I}OQFn0dm?O^{W8(6vj-NF8M2m61%gY8u(zWT=ww$a#C{;`AY zHoCHd9YOCOJ6M%}?qDs?>lr>{2dnqM4wgy(hR3={cCaZ2cVc2ht_UDqFv z3|ONrcdR;vmshi|8;-*3ILa(4up{M$KFg{iw^~XmSCS=S$L62(8`advhL$9CZ;K^* z$B{(K2R7S)4&4SkGjP=Kr$(v$w=wX72A1;Mt6E0JsZN;|w`$eU;#A{mAVHdpGYX1WfCwre1_ebx z1Q8^RMuQLsoabmz6HJVWc}`K2n8cTSN%ZCY|9jn2_f~aP-CM-(``+*Ova8NL=j?G! zd!4=4UT2>-?Ku3Px;)Q{kZ1d4<+~y_%O0FtKX9`xU2V&zWRtVwcE0t;J8$~sW#@fq z$DMThkxQ$^L$1s=puY_V*8``}^@3{=P8F-%s@U`>FZz~7fI^Y_oM@%Q`v{{G-jfB*VHfB)tg ze}D9%zd!kwzd!qHe}Dcfe}9?f{QiBPzrWh%??0X4@2~swFYWk^bo|9$Z{P8oo$s0O z+<`mpobcR>pEB;PU;3G+5fg6O@tgdnH~wbr^`HN^`M&Zwe_wg%Z^*L#xf~zn_($ql zhy?7%aT3P`!$?CfdF~?bpGN-v);z0kXl!b3X>FTS0wZtiYH6&i%c(jAYpEY{Z$got zGVwEOM)SDVhL-l0=JvMsac#|QZ5_=mvZn z*ib)QsH>|J!j`tC$*q8qwKV&iXT(RjsngmT8^MMdh69>l^DSJ9^kk@(y@;ILB!mw{ko|+zTB4!u6s&>%Wvr zZsK^dT4kd*HC$?c2W@ncvWR0d*RSFD7}sBn-2F7!-^TTY9G6C1#qZYsZP|9ch7IG^K2 zj(2iAO#E{kU+4G{N8>A?kNs&D2f_pli3bVStGSjJ_mfr;`sp;%ESt}<7YDo>C2Y?2 z>EAblO8p09JNggGcJ?0vt>E3Uq&N=ieDp}TWk zU@=xZRWpjqf ze>CyknVoA}MpwvYru@sZ1zaDJt>AY{COqe*)TLSEw{vXEzRmB$=CVrcc)<*8Vt|g48op%13DW`8VC%m1DM z{!c>t1plX%vyFH)f!;3vdnwfo1t#-5HvUI%QM1WEDK9nUA;Y$+p^$v}-$t3>za?wq ze;agD*5$wS3jR-kdbRSuC-J|N8hR-e{GU#pQ;De_g8#ixZE&c|<_(S*;ZFW9ru4!R z{}*M`pyQI7`M;8ZOYna_6zk)91(459G+`)HHLS??roE*M`_==+vTQ8_npWDM1zdBg zmJZ2RYe@HYN_Hgvw{hP(2L3DS^1p-Ur*-*ktgA`><$qr`ong_;l)opN0Uq;s9@fVH z#q=Eee<$U8q1`;-Zlb=$P;q7r`1{1oDA}E!PEaeE87j-_Rfx={krVf3jS}&YUlrX@c%MOpAY}9DDnT`>{TPST2APJS~H>k z6!<@bk~5Lty2OuK`9BkBoyc&%E}IM23jTLfM=knqE#sX&rXL0W_se~a z!KC5<+TID|$H4znz+peyJ|jD_M*i=l>|p*oRjHN#r)2NQ`l0>q?Ct^np9=qP8592> zW~_D_Z5I5$g}(Su_TK8~XOE=*|AXw=>}O1&&d(lC{Qm&`f2{mpT*3b>@S}Cm6mBF? z>X6){O8noQ_`f0b|JwQgw#5H);noC3yYm0e>`H37p1zc|7H0982#@~{tN~G<8E{qPRX|BtMk5mcXm+z%k1w`|8LKO|BlG3g`VsnFt`6* zkeyoUf7`RykBRwC(C?ZW``=61(!4MG8_E>)|53I&zcTwmjr8xq z$Z$Vxz8mNiHe>UsL1OCqrf`3!~=QZgMn<$U;<0{6p<=-?Z zD&-nJM_z(7QpliJiTz^qdsk)j^#azkqj=o|(Wxa71F)>z;w79l`DC_t)M(q(3 zkee1)aW;Q}iTMqYCtZ>@*5If=Y6u7{FSIciXkZ*vo(0u&=U?PEC1!3>gEMw#43Szu zVy>ty=Ho(bxoD-R-I75g+aF7?F6(se=zPO^oXt3|Y~)&q433AL(b=;3OpOwzh-W}# zN^#{#D6A6EhET?pwFi}K$+m^SR$fVPv|U*;W>LMg~`-5 zuATE4+fEKg|K=9Ym_Z54IO6I^7gF;%I(Lqw)F>-j48*mabm`DU2{9aNkjm|h+of+K z=MHMK?QzuIMyt(SnP!Z+8qx?)dxID`dzZ3e=1kmP(ZN|fn)z!>vC*5FQ{6cwoF^zN z@-yR37@W6R_LT&sQu;-m(oyLMeG>X6WK)R^?PqM{iCm@><+&sn?{ASWG>p08%F zXTBmY7q1{h?+tCH)C-Gop@WoqwT<-hPB@!t$oX+Ur7YmGQ8_+1px@WH-=`b7b2UVxbjA=_e)Z zFU6I;M63&aq~zPLY$0q`_7rilRckf>*uzl$uMNt6rFQJ(2rXHzH+or1N;9@HUFbs& z%CZo$AwQJ%(Es8QA@qM(+KZf}q#91z&9wH62a1W%US_RL z^i=oL8~VQ!Xso4$`qaS_NS~50^KAL4q)y)8uwWs#b%7nyE`>y(bGVOGeYsOf~Pkwu(cuPZj zqkT{<>9yKL=`lT?LWTY}RY@^6Qskbo%Dq?W%SewL)?+Kys=YGwuPs=&ZClS+gLNvy zp4DbPXO)1^b!r*M0&2q0k~w#+#QBs~Z-w?Xw<+p&HLQBc=XV|Ho`qQ5CY&+$aMTj( zV&(~5Auq-nCQ@2`>F7hq<)$=Iit3Qh77pv3z+wL?^uPUn5`ST_wa0cK>Gscw;35^& zH%dwL&rb5%$HhZkp}o=m`(M@nJ=BmR=Y{_7rrznu;&dQrC%(}C(}7)G(nU{DODWUZ zsHXsz{aMPk0^t;-Tlng@QuZ@)sU4;gr~dCrkgNYY$)nYOQfj-7-eiea5_%|9xmGZd zI?MXMiXF~3UFEFkIz#(AVK zpaw0QJ(N>Y=Mg_2>f2uEf4SR2{MhyXa%@ha{})rE{kPEni@2-Q{|kY;k9OA}3$yrL z!76S$8ZY$!bgnu{wU$EvFCl#jw*5v{7gllfvd%mM+x`+-naurUa<2ogWyJS^?aCyD zW8*;R|7Db4kL_6cPon;HP$|zgW*dNY9BqgGH<$Wi>nr;ub;dY%t5fVKJp#y?AB%-+7R|&(Wh=#3y9ve@9em zrSYT}^Cm)gvch|gbFN|gBtn@Be$^#5c^4%YwnRrQo` zI?8C`zBAS2jAjZcp(9?Y{&%&>=l@jdZsSV*KbyO`$m?9VtNxz_gi8Ai;wRJkLh?+a zZ#E-Qy`-!E7n0N7I-Sy!!B+j>jnp-eW}j6P^ird?O7;I7Qj{TAFPc-mW2OHFYR{4P zxwJi(Itu;27ucx(7XojF{O&~yONi@2l9zC(|5s3A3caJO|Cf`p0hw3-uc3VC|204< zh3A7^rT(AAom7bN|Hf2etnll^v@eA!*P1ra|1z|JJY5f@D+Vf^&t1lPiD5rz8eypZ zpAWS2fq8x@z0m4Qz;+R>?FWWs{cr0TZ7hODI(m&Qg#O<*Ju{C%22RK}v5wLXRS)N^ z{yz%$tR{Z-t9ASz`hOECq5qFSst+Wu`hP9DqVyXT=5eP&7 zZzb+kq#u%<24)MhvpIV48=67vt4N!ioy>76lDi9SdJZc`-Pu{Ge~*p+J*>F&QbQkW zSZitRe5kMlCqec9l}Y~}JV^f^1syMeVpl`C6M*4BxYNw4TN5$r|D&_lg3D0-e>y1# zp#P6Tdd^~X?0nqwE~eD}@a-J_{ww-louXcI1~D7x>i8|||7k!q9)7oQXz6m6*$Kv> z|4mi@&xEedLZ%_%dQg=0zt1~oW9FJgimS>#?P5HkmQ!cge$+KK>g%@H&EGW6h5nxh zr~8nYB^>JiK3ZRrbe$M1AaCgZRmk%k`rUN;=`3<|z^56Ms0V{C;0lkD82>LLM*Z)s zZ81G(7CpF={Em@adk_8JP0Cn9jQ||J#Az9=#E`w?TpBq)kF2^q|!apvIY`)S+$WkfL^* z!e~N0?09f&VFP_G&t47Y>i@0Cuj^<>Bjcg}PormLNa|j|QRx3Ok>*2@lhBP@-du956XG#CxRDrho zf9DAL|77xo{(lP)L^zw%&eFBx|BHckKGeRr6j$i~%c1k4?B-$h|J9^i{|fZ~1#tL$ zRtwL|&dh$FRmi84{y&HH%nw4fH^7slSW{I0-wmHG0Oo76ld^tRYD52@2nP!Ne<{+V z{y&`>A7VZDGGwM0|8GD)T~4{Z(4>#T@A=T@7~0zl9jg96gTF^P#v01w|7!aG4&c8v z>Hq8D{Ckm}FC$ax|A)cv#_Y}D_9F0K1l(^#5}R0qeT;SeFJ`aF?f~jLvYU{v8N`PE z|18peYWBYD`K13p0dB8M|36QEeV9J>Gkgcs|6j^Jko^?-ytbtOKTXei6V$vZJte*b zuPy=BzhjmCo5=qsvQLuwZFsN#|1dbI|DR?R_z56>XBz)Mmi-xh;E%G8Q1{1x@*A|G z{{J@pdf^&$#onYe(w|M$XJ{s} zwiFnq(R0 zt!eyF=>L<@g6q-yN7MRAoOjV$S^uwxD?P-$D(U|tfp%Zy{%}gHL+@;-zZ{aZiu!*G zoa>@r6#9QRdiG>w@ARbq4;|3|JJEb&4HJQ_J!#8cv}9TTpN#~Zm)#32q5p3o&&}|6 z8i#uN*6acBsnq{B)B7Hv2VaeBY-a>=TZR6=j=phrb{{E){@33j^#2<(|s8avG1zNugzldG*mMchk1O0UtJ`#7+FVz26pnX0-i(?Ht=|SJ1 z(4^dwcc$WBpr5^*eJc46IsX4-iuLECKzwKNBWJvn7yAF7Nh$RI`?&rM*jDQQM=VOn z^GA49V@mG$|4DfF5Ors%^$e~(myOTIKK}2{yRvEdj{LlAVy^x_J$L*c`u~?u>7|nX z|4;mDLjNzxTk*KrmcK;r{Cw7utN(wU{SwV`DSj-Avwuder{%kI_5bJSnSYW-6dSSy z`Q>=F6#D-=a5(gTd;SSt(&@}Q^GEqjh>qb$4L&VBQIAKrpH6?QgTuq=AAOoGPNRX# zlK$C&G!NE4S23dAfV^FU{y8}5pQA?AKi7i6Y;@^0za#zge&~K4dVV3Y*~N23{d4&U z`sZEvym=qqg11!)^vZ5ndgpB+!1Jw5x&BtIWORvx8~J&G26JI~R(pxQs<>-S6K=UL?X zk4X6fv^DifD0@H8;m5P9&_y3h^78~5UXGN|DviD?vSn>S27ESQ}BtH)W zXw+35;=wtJ=hqL=8X-RiH8&s>0H9nbTE_ z;#xaIu@+xXTKF(Ti`HN}2G>n3YaV0FH#9V)h)6M?xm=BE;>vZguyAOF3txkjCB+9s z`X~rj;I`-bnDw}d7#IX5uHYF8IOE#(3LGLmVoWszba7q&E&Ma|NNJ%4ZN6dU(bnmz znf_h@VX?C3YMS`inklY%Yh89_YtLXk`r+uWuFW{8sy$bmQgFp}e%sMv9INQzWfqvW zrxaTXYE-u2nw@{H3;P%Ao7SPfgX>>m(bgtlTD$?IMcTa9=i1(Q;Lz&ZQCW4m4!(yJ z1o!=w@^UtK8k7xg$j|UQ3CflwNDf%f;1D$x{156x4MAU9P(r*b=aTY4CrgBvhrHS| zxB@CyEL*IG>TeNz4QZ7NmJR5vCu)+0mX&hG3@87w9_IRi>!;?{H$-j^m48=J&E=nz z(5GM=N65c0xUMiX=p(O9$~Om<5znqp7^}>BHYjDTqy{{un_^56_N?0!CCA?>sr^pM z6!Pz^-nV9?v@0E2S7T*c`FC~F6FFwdK1) z+66S`i8i#@^rRGRUBk)0`L)ow24X2a6&fj_{A=%W?N3@vOKCIs_1g85kbl?y#*;_+ z-_yT93R_dG_=}qmht%rT<~m9t|I(?D|KPGcR-P4_aZmWINzI|Jfql@G0p-rKWnFz& zYlH^0R&#~?t1T=M@~=g9&-y2kuJj0**Fxh8xqMZ&)HlkZc)G@w5$m1nG{Rw7*UgL> zPX1lZwidbH&Eeat)A?&6-qrg~%F1Ee?oPR;P^`k6>{y-fJ)w|)Ww2Ot4*3tMY$wN_LHT#xYZ(~MVq~j@xP_Rh2^Veh`my+~ zifcW-jq3`P7WZ!G)Xg|-IyGn?o;8B}&&L8#mj7kUja;Ku{#_kXnzW88|H~Pt7xHf# z=3Ghr>r%=rVBC|xi@{3y-y1q=3vT3CPd%%lQ600)xxly*w6%21OEHb%6X#Dvf%Y=!K+QjwfFs|61CI2H(nb{ZHvs z!zrN?xSm2@Whmsolls+0S_JfR(l08!4J@IAxdxjL!{J5nW+E*pn~TWn*uIx~T^CjU z)e6eLlG_e7T+8#$x9;l6xq$pL$f^9hqB=CVg006y3v>Q%4p-Fn;;)JLNmzwC;aVSm z+S1pjT+07!>R-vML;2S~Amrb5^Pyn^bwv+elWhYQ<$wQ@{I6tIQpo>G>R8L&D)N`* ze=Qu&N>mwM{#QYZsgyba++2e?40^dTKb2N8=36bK3bhpDpJl999bJ@vi|+xt?xe4jf4$hI5<3woQU3K>Yv)%9?S;e2|77adk48P^vsw8X94s}N zUYa8(%Kw}smu2~%PD^vJTC~veV)BIi&nH*N|6J1bBnkOf76*q#tezDg_?ia)NkpFe$orN?lOY*-@;`EXv|4Rl}&fPBLd=q?YVYYcR^>3n< zOZaQTj;s9dq?Qx;J0CbN28s*e(pIQ*JhS1ols*!hP6LwHf|Ok}jQpQ~__+n%Uy|hiBxdZ&|J5Z7 z_6O?6v0mPnDs?f<9rp=R{r0Cr0v3TF`jtk|24z3FjW5U!e0OJ0r`I;e1DLV zk77|%{y&YZydJqZkUWL_{~;~DihrSpa!0WN7 z-^+aeBJ6ta&%Q=%9WjmBUjX^rXmfvXyBqu54PfwjESE12BmZi&W_Y|0lD-*9*#wX0 z1Ai-dHz)aDL*EPe*JEijvZVZPg{JjT(swPD|33bffy2i(i zkpFu)EC1SY%ktlr7xMp)SaI)!M{T+C|4_2~{%9EK%(9L7r+`-dAM*bnSiydj&B`x9 zI$H9_Y4z~@U$K8G|0n1FhWsCvUxgK^F8?)H^ySL`r;z`zC;9&@tql%7wF>#U7RkIO z$-Vtp zKAhy|Jk|>e`FRhVxD^S!5_{u^;PhIoUQ@v8BeeKjNq){8L4NYQ0ot#~kILrcE3y0C z#RgsGTmu3GC z^!Omwu0vQskUsYe(C2&5=a=+v``7!hA+JKdq|d!@_pa=((IdZ)eRF8ooMQt37U}a1 z-sOBY+YQVQXWwPzLi)7j_OI^z#JnZnng0Ul=j7*Mar>w2xcs}>G5Hmwzb?HaYm0cd2Pp>CRlac!WbV2YRooS`b?Y+4_((Hb#H0dMehLeY zb_7EMM`5!{5yS_i{yLKhSc=%lGxD$VE1}W)W8K2*wdG9-8=3cEy)u_qjT zkA=`DL{Qh6sPoUrVV%}!n_}ubvXzV*@eM+uiYh;9b3bednFAI6nvrn{yH^N?~)8CeCWK&Ip0; zf@tq4u&dreA&W|)SUVr{x}bsg5fd{Za}{aTYF948t`K!A<4U1WM@u0uVfiR*U~;VB z$LK9so3=p@%Q(kVHnceyf;OImdU9Iaq*yIMz7_JX-Ae0{@~?yx^6$)1?mMT~VkzYE zxt7q(=pyE&Vdqr-wOxb+YPT{+*v7=j8D+ff6LM9p4J~6~71b`{dqH|#DgXNUy0?(r z_YI|j-V>=`Y-*GL35=nn=tRo&FixM$ot$v|Q_s^;FI+=e{=0#ohc=xHRu2;ye}(){ zPZYQGOxh~s-&*vH?4(ZRe=6y|DOAi^sTDCS#vY4(*A9<$oPC)v8rJOk{Mf{4b)8*>S*^Vc*Hu)*b{|X@NN+Wo! zH8YY-`u>ahe?FWJ`9BaiHYfStHX=Gb)SL&L+d#+?s`Ym@&Ym?LZ- zkpI(@{GUV(4a^+Qfhw0Uvp+q_|CO}86KuM`@Mv18P5x&9iBDDKUpet=fe@PTko8rd{V=muu~ zTWRM4Xx|NoC&2;b|0rfw3(2Sap9!w#!=Ghvzm}l(gG)dStr)S+HKANgFu?D~l$|94<9nZOKnBNBAq5cxj^T#v*vsFv_f z?0f3}Crk4GRqigM#;@Tgx(g4rPL3P#N_jsVy?}fn|KEhywafnt*i{w*`8`;`?!@x- zC(!pg>ijJy81z%dUpfd z0#6pyC_l>o5#Xxjb{#z2l;mFzsj~c^l;r<(q;zlE@1nmS3bl@?h5Y0zaAJ4|+_ds>!|L57?lXf81m9O9{ zHCFk52B?0E^=^B9YW~;g|2yz=oPbx+PfPNz2lF#f{uwwuF0WnwPlb|waI-8wXO!gU zNGx!(N$bPb6Y_Hrm>dQs%Fnqq(!Z6QM*ywza~IT6ey)QjPhmyx!p?aqEuTamJPR(Y z#jdmwd)`B1l%F31|BvavN3+N9vV3m-O?dm^LHbkq`2e>6KY$~LV{=@O{jfIu`F$XJ z5L=b>d3WkxXP^rnrGNc#qR)dR`aBATKd+$Ak7=uxP|)Weq0ce-3)tW4vVHQdT>89} z9g$y(-}_1U{msqal&{TB$)(R(x&5mnucdx17Gar*E6WryMR}i~VK2~T5O+oHup1cX z+)3+`767jzgl)lDSl9=`Miu)IL=J0mEEu*cb7|uUi;*)NXTu(*xSDEi?fEf&bfw-m z_=_C~9ECU|b0lXFvUoqmF@Tr_ti`#&-`cIqcw3L_Vm=u7JA;gQURc@4Mn1>3g^f$- zY*~0Cgr9xxer9yF*E=4~wJY{)r~1yumf;?o34cnAS#TY6bpU>6{m6qteFad^d2`7e=d; zcsfhfQXu}t=*hRk++$Y!yGe1kXZ;+?_`720sLWks#XtNn95EOiXD_AHY)U)op3Qh- zAznh2uFAY1l{#|7!R~sN6Pp+JN6Ac zS5tH7TF;gHj2Hrc=bLRn5%~8KyC|i)+PRJs!XE$G#5a-0DEN1`1M9l(DVTJ0R3yW+n;yf~klHba4(1N;~ND+lmDnfCVq z|9yCe$WX@L9ZseK*?68F?sVdqD)?W)JA?S| z4gSZ2|Iy%oP{RLM@|~2@uP))gljr)|!T%E0z>XS%|BZ}|#Q*nrI=_yQ&~BapuP({| z^JwgIcs6%43Kaiu^8EP#W6PbTwW>OB{r!ahTUZau(V6dIMD++q8UN)#G*v0?V;Qui@wS-S+(Sd{O=(o=v;S`(i4u zSHZ=!x*h+4^Ar3>LW%3ZxZt1gpT~U*loS3>fZH9c{9T#K3;+CF_~+*P;j8==R;b41 z%XkB!J2%5OsQ;JL|5@t)DdV0QaQO}RN*DEij^0;U|39YskIakui|2$Iw79n7@?8RB z#GlZ}<&xefz*33w)kqb@Q$>BIy-EGz5jtL7TrGtCuxu+=yI5Kssoty>oVED`DxPU- zeJy~lQWVc1bBq+6Pll%TSFNk3pZ*>CXSMwIY35U+ zcuJ2@m}plYq_@!eWY;p_ctl!+*W<`#O$q*MUyCt~rS&ci{#UorR`NeQ$b5eKbk`$o zEc~B4Ff&e9A8XB9|ix_?~Xa-e{~y@6jKHrJGoXASOG{JxOL2_*3YQ#in=*~-_ zV@Cs`C5?8pmg{{yowE8%ITEt}SGNKAeu}w#Z+{%6wQdLhr=gXrmzVaAPJAD9EtFf$ z^HBaTL^2oE#DDjD2>xry>Z43Azw0^1!vEL@Pfj|%8c$hwB#7QI8vT6s>ZPmZa*vhC zoVD!BzuNfk{s#?|na|M#)b8ujo666lhHAlGNVJCJ&}|A&&t|x{F7bZ@wQ8LoJq+gm zevBL9J-jJ)GJajb|2IPw_a~^%|JPz`JOtatz4-l|jWy&6=zce2*o)!+ z4ax6nbPx*uKa7WsK545NcSisJApC!F^unZm2}?=v|BvDSUnc&4llO#!|KF%uej{3D zY8scWNc>+vz<)>3)%kxsR; zUyYUZmYVqg0Q`R)?Ou*YQknnHV;_7CD;IxWwf&=+tK5l2=))EKf0h};J&FH+QnmcT zJotZTz96sU|BM{Zw0u`yt%8lr3WENxNnVRrRnY$!XY9!p%%{|2zQxkUdqI{J(~K>W}-8f^XwpSS?J=FX1b2 zKSO`)&+IAS|82G^7yciPAV1~V#-8ML^ccZeMER}^hohRP!6*FC8HP_lN<8`u+n$IXtvV=gf={`xkI9}GNqj>iIjzuB`V{=S(d{;oYc*4h()?O`1} z0bDH}4u7F@d|6og27?g37mhx)K{~4%92}!KPWF8*@gItTe(>(M82G#E;*B&`^gdMx3Nt~yl|`u{q+EZ?*KAsle74hZV5g&Prw4zM8#-enj6m<_hM=j

Drxi5`WQhNT%+&^@4vvyJU)N*a5Tmog{4xM2M29f zTB8h>^O;tRE{xUcC0@qGcthG1^Y+5~*3v>6xrNZDgPPP@y(>ly)@bRFg7VWZAlnl@ z^Xf-w4e`dY^%iw%of9|PkxKr#_GcT?F1$J|;iy461g8tjpVm8uch0LAm%P%Rq1p=^GL9M9reqxE|`YeOjpFYZ*ZgVOFk$ zS9_gn_qG-D9_gz+Mme#8Rz^`Gz4mi3?eUb}yHc=lK7zjj)b@?u%&p@Oq}($C&m=s)RUPn|$H^@V#E6#6fE zt8|Drl;xBjxW2z0`p;dsz&+7s$UFo7ljGLs&V`}Yd80y|E3b}b5-wnQ^MCl z4-I#XE$csb$yTb|Jt9js>yhYJ=)dq-QFp09>=kkN8&7g2I(lU2nb1ATwks^fVULcU zt5#AT9f3$q`-T13`l4=ocWCs`V1*P`l2JG;AAPs1|KyOeX_~c}L#ZmBzQK2E^a-Kf zQHou&ag5V_IUb5UD0PhWx0i+f z^GyqV^D4wQF*lnsqN0< zlaNTi&>_51z!1Obvh?FS2TG4#`Fgj+_|G2NkjknDTt8C#`6k6oehdBAOG|-y*toUt z%RR9etp8m1Qrcn{i$edoL%wok>5<@@#T;G9nMGb9okxocxONZnh2S|GxLjj!O)baT z;4UbOX=@gFL;tz&sqa>3d5FFF-G9fOHr&(LxCLOfn9_Q!xF$3^Nrd|;&q@5X_L1OI zo4JdRXrGenVORtx5M^FQ3+RO?ThhD z^u4&)Ph8!i?(oY}_CfvgL;pFl@asJ0Q(uP;baluTCVOk>KmGiD3dehye(}P0_^e-j zqbHp2YnrE!!gN{s@r^32rJl9O`Akp;D7TZT!4Zi2PO*b2xQa(%RrGBFS3T7_?tP;a z+mA#4*&jNoL9e-ZlKIApJ9Ft*WPfzM+OH1jqh%>W{HDv&&m1`CzC(rnn+6}08NaNN z!5zyiiRoizwZRMEDJyh1|_X%I0C;D(k-$;JJcS_g@g!PFk3a6=*JfWg!qQ zBi3&NuR!9|fBMn2QbVEt7SqafN?U_pW$}wLlaNAp56Y;;_cIK8!gm05EhYb6lvV#N zhxTf^rAYL?U{=fiKuf8IHE8La;-ou?kT zgj&>p^GAel7XDXj!PPJB*z^3x!ve1Lp)c#db>ve29f?IN^xvVB+LxMhO3cFR?l5vJ z;*ABr*R1~AKn?1@V~AV83gcoRQU4u9++k48@Adpw_21#t72|+v`tKO>xgK5UzZ1AG z>%Zf$mKxk?Kg+fOpFOaw|F#3`NWoo8c0jXNvszc^zYCN8JC_>#?nDbI%b>%ltgvn` z>Ay3ul5Qd<$Aanj?+kM7z}7mIw%z4N{dXMprMu?861;=*>{!vE{*nNcYLzf#FuoGvGFONzOymj4E?7E zs`}5-g8ENue0-m)o}7A7OrTsZ@jiKC{2&GQ>>rcJr%v$PhI}}p@M$!M!~MY2FzP?w zms9`wH78-T*ZE#srT+5?EOug`{`0#@mHJO>{d~#?Z`FT`NFQDQ9YQbk>nZL-)l9E1 z^xqmVME}+EzKr)4xgOE7CZ*oLQ|DA_S9t7WyK-OlmmU%oi98c};AawzfdMWkoqQ;Y} z=)WtdzpVd`f&%Kl%dq5Moch|?)ZIYr7S^rRe}0?B9kbPcS78NLgYAU2^^72{c|dxyJ~U(T;%=g@!d z=wc|3|L)<=9hE}=eXg|H@IH7yy#9NV_{UhmxQ26~|J-f<4(^8!w?MB?g5CeXi&y=3 zJu5Rmgm!Pim*XDZFgupCU&8;;e=k6nC#e4n@`V2TM$&&Tlk1a%^xrK>|2@hZNACsO zFH=*Y{~m^(zd--J3@@JGEtQOS*#2Tf`uQ|nirh3p@l|kVE)Z-^`p@qPOh%HLi7D&9 zy;HCDTL`XBwIJE*$*JUZWZ_ThsV&FX-fM zXX?KVN&lUg^q~a(|3H`T)nmQ;o5`2dstD*niLQAXZ5xqQ(94(xS zlq}%7(0?}%(SJvShwn$;fc|?2vT+;UOs}FB9FAv31O71=;pe@9KC+Yb!sSTvG2rO< z?;LcD`tNpn)%&wP;Ja!R{r6Yo`zAg|>c6ig{dW&EeGy4Vlr_;$Q0n{Wkr#Lvs{j5Xdyu#BLjQd=>A$by_45UMdMfqb zL%=y$|NSjKT0chr-HE=**sbVvV160AU&f!yH?!1#UxuoUT>pF&{kJebg0BLo|9*&k zg#P<3+&z?c09NMHc$cj`FZ5q4?*{xc-ZkpKe@CMJ4j!ui7UuuLyJNpa|DA+?|B-2B za|1BV%Ae+S|1d?fYXcLUeicu!3R_lM{uetYZ+=yx%){Pxs;-$tC{7uUZ# zC^d5bU6mh*#7%%p&FsQo?!S$^f$@dxS3nixmz&YyPm`}9`zn3lA$sv7Ok{(cAko&^VK1+{9c!L@AR)!tptbz{1&t*oP{fVx;^1+<*i7F@g5iXLlpVeNMfr}iKRE$5p9%79}v?FzL8-#2w_Tf4h9 zzks85{FQjeaN5P?gqXOl_)3D@bLD9){C6EYJluK8-M(uLzAL;G>dj>2<61{2 zSAJ)>)-aiIma9ee%moVmyBbn!Sjil}ozYG3e<8K>GLKnMYjH-Z+JoHj-4&LFa8sYy z+WUW*|8tYQDQ9%Kl6hXOVHR^R`M(q>w!Q-X@5NlM16z;$cSb7z4@mR7S|KRsYhZ@h z#~j7ou4@fiR+h3NG?Ou(d;N4WbJ*t<@_#+OXf6H!&@u4;EJk(P6912&|DVhVzn3}h zP_NaIv01}7s+Vzb@c%UUuidP6{vU>QV;eNzMZa0jNYbwsu4F7$YdDP=i2T2ZImIjE ze?R=cnbG!{j97#JZ~rgx|6cgdn6$&*q?!$pX9gJu!b?d{J$&p|I?V^?aN!_we$aTCH{YfnUwth*ckc$ zgX~8o{{IEsyAPX}`d_<#J93n3 zNrlGnV@bzj*5_X_yKtsdZmqbs;>hKdd5V(WS-OZby{N4y9p|Xk^yI7JmSy#U0*UTeC}esDR7HxJx0uJ z-U1)zQpSxX#H`WwY|+-7J%vwEKoC?Z*Btzfw!_cTn3zF2`;0j2&|Avd;#WAW#k{o! zOADDZGUuuKF?o&_3;8L|La#SNv@2!8Bh#|ZE`?cGgiORd1uSmy%HvCS8GgtmaBz${8Q`!r|F;r$hA3w93&{`()dgTnq+|k3Gy+tj0D@l#9aJW`Hgj`?TcrQ#3BioPp zw<+O0FO7{8XYmm4=pW+Z9A6*a+UNJNzk!qxXC+D>JE^5?8ROhpYC31u0$`isuPs0- z2~F@YWLFDGz$9$JZ)d&UiJN?IeYe)&4qldW9Za7&A+mKPKj4rf#tNH|%cJlB*2BDefq>xmJP&@XyZNkikzp^d=WYKKq1DygCr>FpGKRG$O!)N{(->56~ABg9%%#7U1v zC06OPMY(GbSFNggga)o!9pWlHuWIifem~8X8SB)S)46b=|AbhNfY3GO)4xl&)AvUGcAB1beg{#V;FYwS#91G`T7&z6DC6#a7yh$)W9$2=7p*j%lHgG8q)zBR z=O2?vQ{pCZRn~vPSL{$HEPjVk?_8mF=kxex;8^sZK9iFvtNzmx>i5jti#YV3SE2v> zqMz1|E^>u`ukYBZd&I+@T&e%8qZMev7v66ay63g~@)%qD{AwaKh-D8g$G7n8l}eT0 zl=INfU1`*FM+=e^_gjWBX42=!zA}*z^VWArw;ume=GH$ z@2cA~EA^jmK=*)UP^-{?vuVMc-PBfVXu_^D2Pi`S`5mrV#Pq=lDOJ{g-Q*fi%v>;; zJxKov$COm2(0@{UE}T&RO(wM&>y!F#3h?P8?(UJl>)_6tdIIX2QCyc$gWlYJv(zs_s{hui zDLo0@C37m2m_j=BWmB2lXTGW5@C@~iO*GGw!w5#Wm9CEM9)mZW-K#6%kw}7_Xb>8oI zuA$$A{?nhYkG$%?Irt~I`&S3~SMax(`@KlhpR~|_dlA=xFHkRSEd}DS=s({pP$Cv# zne*$F>c71c%st#Mg<@UQJ{jnge)n-*MO$;>U7`P0fRCQg_EY_;+sQWzj;jCG!IMtx ztt+W_Bfl%)k8c#z8rH$ht<+N1e=BKwEig|4UiIH9stWz52b$llSpw9{Xxm*hl+?xG z=Ux@YG;{4fylW|~{?m)yxMk$riu~y{y=e^V6HBp%&tXNO(0>Plx%$t&j`o3O`iVEe z@oqe9*795EKflu(8LjUast6IZOYFb3iC({=Wr=~U_K8TujK$Rna^;p(dn&H}^#J&p5 z)qj2o^?2G>|LLE9BJ|jZe1-no#My5v?n90Pu!wI1ze4{Viieo7`_u{^vT-gvI|xXc z@Wg6^HlhFa2AU1&ID*xl6VMEY0A&NKIidfy)6Q;M*+H7$570%) zZ0Nsj$WQ3MBY`0F-_Q1#!5c%k*H30N;i5`?2W1*CzejHAvWP)O5vw{(BfaK0{4^K<+2`eYDo@fiL1+^jJNtL;s2O%X{d*Ym)xcbFmZo znT*8mh2(uF>A$bwefl)|?_(wX_nxHx?t{X&(?8yVY<>oO%lhx$G3vi(pvXdGZxOiv zeM$fQ0Wg0YE%6b0>7(?+4bbDmQ0;rH1|N$bYv{i_p>!Sc_`?DH_hc0x-}A`gOJLjr1|Q;$2ld~*Y5e!!`Y*QrWcmMW z{pUJD@#i=o{_I|P>SO-KRpr@SwFTEuw6vMuv%#3Sj&pIH5>ws+jwojxBL!D9ia+Zq zR$jfflxxk=w(AhK?R~5OdR-h`)))eMYjX|5Ae63d*k*bCI3N%<*AzwyvDRx1<}1@j z>uRiV$Lg=Ed4Z>G6n|dZzE}(&w0oKEdR45g3AyW6)?rM*ZSBU2m8)<;wOF&XhLJ)+ zd(W;&Xv4H_TXc=nl^j=VV*R0@e^@$gCFnmgeYBWbpR1y=>LESkpQTN;X4hQY<)*+? zxV_farY(CcD}v^B-M|$s;SwJ)3G1!v2huVy(sJeacVzg3rnWCUVi4bq4ymvv$5P>! z9k9B(sJ-3w6X_o7v|J1u8W;@~tJ*?nkQVO2rDfi;hjR&GcXia2IS*Ggf>I-o=cK&e z3DzpC;v+A#zAI76i(jS=T4^QLcIy1%o z)b6ee(#91PYZw`R`55bELhcOO)su`iLEE?1BJg0VZqv@-sVops#L z#>v zg-Sb_>z3}W)0XC`?qO_<-u~`UrTqIItl#o-j}IlQy8OFGzzk}dN?qDU{I0U{-%HFi z{`|6$KIYo_{icO$*h-VDk;?zn)V8<{A42|J7xf!guC?ebul)PPu^H5-$GUHb$NF;@ z*Yafwt<9ot?_IGQDf9r3`|Hf3&UP$)A^)@BLh#bPPh7{4Lhi)l_rUsq!FN?%aa8_& ztGMO6w*Eq)Z?g=uH*}_cfR{oXP=}^(t)6wPMoeunV$6QLxXGSdtmnHdk zSCECwzsE64^4)?;`FEvs5oKH(>!AEdK`i^AhF`Bz{rtN{kd{rBZ#AEaYD}XVRj3RIGrz6PfS2Bg-U|A6Qm{?^;Uvt>v5+wI4Tui}Jr0t!b5A$Xqhye_4`?CA2x3{&ydfEz~@f znw9?r+%2G;&CJiIQJ3<+nwnN)JL<;nqWmwRz4c(Q2)@|jbXpuK6!O0gKI{kH%Kv6y z4*7Rq3ct^*{4a#(EkMx+58Nf%9ikU=@0Z_3lYifEZ(!c(p4SIaUwlv4@3Xou&J5~N z{+HAG7Vh@v=z|B{*)}jz{>M}8lp z6Do)N9|=F_GyC5Qs7@emGf*l2?yzz^ErtB=2W1+8UEVCha-hxFm6nl$Z}E%oB}>O}-L40>kpEpt{&$1PPEy=gYot&I)MqF8_wA08v2YaffBJy@?}Uq& zl;r<3EH#HJgF|Jz2Y9vKMv-;Jalp5*_vlyQ~dvP9$UN&Ziy?N#u`Z=$%% z$bqD;qlKkV>MXc3viu(g_r?Lwm6W_5x*QD0He;U(`M(Z%y)4Q9?vngpk>vk%*orm* z#Rb^NwqX}Kc0~C7-t-J0e+Lj=gDvNTVdei^EJXXUZ@2P)4z;eqQmp)+ndJXwaH>6= z3AW8Z{kA0k=fJ;pSVkML>21bB^cwp2IwYph|L;ih|CSM}zko8QK$mey;9HXX-+}x; zP24-N{VM-YLg%Lj$-i&hOvB#wChSU&U{!o4Y>@?A^M zQ~$pJwVom61Eb3SQ+vq&-O&DW`qKm8qW=GQlK*$W`M0ne#9x9>$p39{J>>tHk;sGf zaUs~QMvfoHzWaOhw7l(hV|1I8ed6YfrpXR;vPtn4Gq^{#F^@n)Z z{?A91|E~?m|JV3-qw@a^;QJ-=|4yX!I^_0ON&a6NkpBna!M`T?{{gN1(|^nV|IzZV z^})ZGZjG25`;I!Yw+`f8wEiB?6aA*~C_EK1as+SMH?3jT${&L3cY|`0T z?G&{A@cGr&Vr}8`SH1nP6WXHf>FFv&+S*2*(^l516-TI@#|VY(hV9FlZ}kw?FD*3s zqX+$CzioYrs|W2G+8gwr4EvR{Lg$FaR1ZqIBLrKMch(eV?K{MRuQcn&f{tg!Ycp$3bg#!9ujlcYBgwC3V-7GGLZhB@?W3cTG|i( z`@K&s5Bjtg{C8wsJp})!mH4mstTqbwRj!Ty(#x;h^rn(pZsJRz`peeFe|O#v{`)0S zePo?W^b%VO|C-4e{MUb0{`(fc{GT<-tf@>F`R`lz?n0msoqm~mxA`{x$fK%q`M3)H zJ71mw1?0c>g@r@24Rb#)@!y%NUW9Fwn*asnzhlDcp^aI*o_xz0i|c>g$zAmS#f)#O zhdwCP%$RI0^qx;0i-3Eq{9i@cjfwxWscBuB<@7MKs-6E!lC-U1)EWHuya|}9hee71 zOOk!SZ+RE|Uj+ZxS1-<(QNPOrq59Sm|MzD+HlK0Y0n8O@4eOx)3T7CSsA=D1_1MPM zku?-Q3NEc?ezU!T{|6A~9I_TK5Baax)2Yl2ga1dv13h9+teO9NC;lG^*6uzzBin}j z?FTj7TdrC-1Svhg#Q!bynG5m4xCF`H#mIX{wZf$5XxihEm7P#P{+|Hc4e4AP|J@Hu zKiqSm{q_p}pAY}9s-bS+|Jb* z(C}Sj;{UzOpQ8Vtj~~fc_J@X2a=x6)m`@aOac6wYR0gM;TFg`&FYj62 zaz4q6!!c&mW=c_;<2UPf&fqh-2*&v5xY%`EYl$`@hpk7dkdw_CRc{Q)jCJGt|4m2b{*95X;Fi9iodnQ8)U907O6rm{#xO+xH-2O4u99@ zTpJr6e^)MDJ8)Fu`dnrGfxqiVzVkDlv5W5xmD|_f*YD7~&y=w0(N$UAw+*M0!*YIQ zWhnkVlqm3bY&i{le0!*9!F4rT7Jt`?e6y;u{(4GGXCyI^w0R}`Ck>RQqBKgZ#NW4J zirW1~gL9erCH&nxy^VUx>Fyx!7ep%YFLt}PcE4^M_^$&0UdsEHOSya}F?%Ka-K~Ba z`R5Iiz`#GgI57pQvTukut|@8|{|#8w+8F~(CuLtWe`Wmz{@SDG@mzKf_l*Okg>W** z$oL-!z8iU_1pjv@Xe;qQvV{LZaA7;S4u%$oSJWT)@6Gdl6|fz}IAt*YJE`%K68<|# zKOIYAWe@DZ^K%@}m4lJK0{_bf;lB%8*%h=|;C~qw=7KuP|LM@>B4~6f_+Nq@`cmws z<@CV+G-^DXL;1hBqV^2S?pZt&9|N;jQl(!-#myvJMmY&1dn9>u0MwN=TQ9L3H~ix?tm3Pnk+Oi@Q@(c0>Xr;0YIuuB!cK5J?TVV^N)v>tXfuZKRz zhOf=peL$_2_DcQhb1I&A!eS4f)yYqtnOJOam&OhJv zm;YMXq?qoMg{2!2tkTF_(1 zoe!e_$bVaPz0f+U)8F^Ur|^u@`^CAUZ<1>v(^BVewcwaVFD={jNhb%jGxD5y`xL1Jh`u6ebUYSa+-@)*kPPOrWVTu2?IsFy#e<>I* zrR7D5{|nMpZTxq{HJ|6F{9g_wXG6th;Iahl>#4I^@Y_4RjH%@RTKGSc=XmgcUQPVh z8)bRo|9sBD|2{^1dSuLouhsZB75|03u&LEEdg%oMzl$FHUj`)A`M(H?yTZRO+}jsg zI1-*gjruRu@)n@pFTSxN|F;kDe+{;sO^F`W=(m~HmnS&o|Mn99H*>v#aplTt#esGM zb{O}6KR$7NBQf&-7|ts=s)gYHQD8BV5#Y|m|5L!_q{RP|s}+YzW&WQB|93G?4E~?M zm~&*mkfP!Zcw-FZ|A~zFYUls!692a{GVGI zx;{4kKL!7v0@F7kGxGl=zRNNZJKcrUGkWM{Pt5tO+porBAo%|VzWnf7*5K{`FN|K8 z)WQ6}lyYAy@&D7jXY^pz@*61OdvjL;#eGoXN{%ll{@;fz-c0$?`F98JA3X)O&kgYZ z{q+AYCH_BJ1OFeT$9;(Y|6A-~^8atJ%iRb6{~FAG0}rc(|7-aF2YJ?iO9d~!4rMCE zgAWn)zh)R}JwUlfIKE5SKjZxSoZnBrd7K}k%*VO*{4i&`>#w*zh2z4Cwul}aauU-_ zVcMMe3zrN|8*=w$vc8XY@8kS6&R^$vKi7ZE@d2*C$?*`^f5P!Wu3zH(9gau2evI?u zoL}ZRf#bEnh0(QN#qb=*kGOtSDb4eZrF(G^5A)BW4srEfoTiuZ@8XOBIMww=uE}Rz ze9R>B(nkN;#960j594l#xYYI=$o~W4O6~L?$F;|aain&sFO|KXa^;Oy;W&Wu@?r;Z&@j={_`^6fAjpT0 zav-ZoHqG;T@+!OVU70mc{~;Wfv8;TMueMX-Gr4LEc_Iw-0DtE4Vl9p8>*{lk*7lC^ z6FMh4L?0CTpQEjJ(B>yOUgY|-oZrSF4!_4)*zO|!Sz!AJ2l$$n;x}`>l{9FRXds>L zCQTWaZqn=;&i3_}I9|s!dHQ#AJ;so@4Qk>?06DPB>zi8IMqkD4{}wQOhT~5u`bo~~ zIX=&UjBAqW|8Q;Bqk}6jKvQ4e(9j4>6`A`#3e2D2cq@3{$$^w68bZ57H)tcR2F35J zsK86ant&+hdrS!Xzd`zUspF40e=cxIIK7i=aU1UJaJ@3r)ipFUH8nTa?^%ELhrsp% zu*%olxh{BK;;C?FEgS`puOiRYrToajaKZix3+oeN8cjwE-=y7dbHKOk#S%XE4|6W~ zDZZwc?)R*k##8H!gr=stYVAKy{@XafG08e|occ!TzCxDa5S^}JNQ>tG6miO$aCs<$ z#dVn%bq#e*%?(4#KS{e!(f%`>pXGcL=W{6kX0G4D^=VxHJI6(|@t++3!u1oJpW^&9 z=dGN#ao)~Z+T6;qh_bhHURNq_+zPHuC(Zhc^z@8=k$CI>VkzCc9+bB|^9Y0OCwMIX zA_w{RD1Rws$X}!nP`S8*~T&)2aRF6<` z>bgm((1m$y)L}R>D4q53pNx^_9VUQd|CfmW3g@qK_)K2LJ$@+&W zUkRV^h)-&R`ii;=dL-+N(?-xE=+*fjq;&YucdnChj>BzDRX{=`e1@V1G#uA)j##jm=GsO)bq$ zEv>E1t!-^Qh1*#22A3wfheCLD-6DCgV?ChE}v1`&~{wn|gF?b&b`Yq{2bVeE*Gal)m&*3xhPSO@~-OBZN4)rbamYze5<3afaXqxmW*O*t_(k|$EBWHDh@$jJke9pCphBUA?zq+Ob zyM4%KY}wdXAWR&ge*!Y`_gwsn>wn~6oS#i2uA9SW-P<{Mex-4-&+W;i3*XtqGj8x1 zp2n-_urxP2lQi^p8aw_4ao^`q9-if394MXASnVFp(#mq;EUnJt_+5n(nm!d9o6rI6 z9aE+b?F`o1C^#+bNbAL1E>p6p0 zqLH!>Ui~XMujY7Vp^joaZ5nv&lq)FVRgM_$>gTlm3l8Ty4e8O|2xF7NRQ;tSx*Tiun*OuALu@A>C>hrmG3dcnp z^x5?6{yOJ(k{$u#6XG{wO1}erjORz1d-rml&oPT*4s{4CZB?Gr`0Z-qP9rS>(DK|X z?kdmfb7+gnFX|yv{|t@}?x&Q`sm7W92^M(5hG#Jr{|0B|An7{#p<(byb{L{Xw)o{a)&C%u(h9s1-R5&$ zqFbWfHsUWNPW}+z@4YnToNOB2FXcFcgJAm}X-ZqBK_m|Ob*!Iohjtic6I~M=!myY) zX)0W$d+DC&Z`ukD;gBD;Bi#wnwlh#h{0)WOB+`cd@@zeuXZ8u`rmfjwNFf_*^1F-U z1Y~mu$1eJkn<}2re+n3H-$U9{l@4vw^n%xZz#AY+Ev@Tc)2};zZ#H4zyr4h*r8qwL z#vM6~V+1`RN!B1ReJ(KsQA8aa*QF70kz*01T+FZOuRr&%C|WvOFRHMml|f!IBBc>s zT`Bdj{==DzZ02ug|GsdGkF@n~>puia*fUZnDop1UXzJen8SrEde@oNvoc?9~vlBN< z`Jq)Ypl5Lw-tn0YW)TC2afzd){7x5A@5zTggK`?pn>tz=np&n!>~34L_kP63#PVH)+)YUU}`HEGm*RET?VXuvwHgDNy->v&^FEtSLGNl~fp4T_lH;?P=Xm0In zm^^u6SIfA`UgM&mvUAE^94Q(`T`IeRr02tpjrDtZ} z+&zX&$aQ;rXXlhDQ>RXI^xKrTwK+DQII*j1^5hw_OVyLBQ=6!Iuu4!{Yui8rI`?wU z)!f?B+|t&{xPM&hxb}9Q{^L73CQKMVzO!>eXV=7u6DLigwJDP(PnpX9v~K=;dTb`4 z(^l8m)X>qmJ^=(agLkk_LvAMmGpSDKlAI)v!IvQIW+uJ(E zH6yCy#&=EaabP)T?!u+Zmaka3dd=E(Lt9JmfL>io-kdkJHa0i5HMO>k8#k`Kd0cac zGn$T8u$b08y?4GUML?iIb8~YmnK~G~?olJOsz=%`X=MM zP~*U6<%WOhrAShi4gY!;(WUF(+-jDH|E<@Zas9u%?vCsK z^t!K&A5hG_SsXWcx>+4Jb?IhP+|;L=ZE@3>Zg$2^Q@S}iZkp50iE-1K9|MSI#Lc+; zByKKRr>E^1qnUp(bye4j@x+cZr&3&tJBScakD1fJQg==)6Fw+vo80E^zpdakYIZ;ZZ_su)6VB{ zzaTWcuf&mtNJn3lQ3HMKZ1YL}CO-J#GJD?3x{%|)!A zB_K@jr(yrx__*F)aeY9#ZfbcqnVO#>OQ+czAG7(m{BZg5@qx>x>1UCx{iEdi6$fwg z|F|g7)N4#hEK36_BB=hea-exU55_{uTT&NEP_@ji+eAuJi}I9OZrxJ8+=EV5 zT?3bG@Ak5*vB6W@octlGn#5)Hrpf*$wR}G|7@=t@EbgB5xip@|MAosiD6s8e;3LzZ_`jZAK4m=(gb^ z?-(4J>f9eSoe07vH*2^Kg1pP

^IpT;zL(i@blh$oCHy`GLWaNx;5S0n+COK>Co; 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