#include "Levenshtein_distance.h" #include #define init_simd_ed4(PSA, PNA, THRE, ABS_DIAG, R_ERR, R_PE, SI, TN, CUT, BD, I, MM, PEQ_MM, LZ, IBD) {\ (R_ERR)[(SI)] = INT32_MAX; (R_PE)[(SI)] = -1; (IBD)[(SI)] = ((THRE)<<1) - (ABS_DIAG)[(SI)];\ if(((PNA)[(SI)] <= (TN) + (CUT)) && ((TN) <= (PNA)[(SI)] + (CUT))) {\ (BD) = (((THRE)<<1)+1)-(ABS_DIAG)[(SI)]; (BD) = (((BD)<=(PNA)[(SI)])?(BD):(PNA)[(SI)]); (LZ) |= (((int32_t)1u) << (SI));\ for ((I) = 0, (MM) = (((Word)1)<<((ABS_DIAG)[(SI)])); (I) < (BD); (I)++) {\ (PEQ_MM)[seq_nt4_table[(uint8_t)(PSA)[(SI)][(I)]]][(SI)] |= (MM); (MM) <<= 1;\ }\ }\ } #define ed_core_64x4(PEQz, VPz, VNz, Xz, D0z, HNz, HPz) { \ /**(X) = (Peq)|(VN);**/\ (Xz) = _mm256_or_si256((PEQz), (VNz)); \ /**(D0) = (((VP) + ((X)&(VP))) ^ (VP)) | (X);**/\ (D0z) = _mm256_or_si256(_mm256_xor_si256(_mm256_add_epi64((VPz), _mm256_and_si256((Xz), (VPz))), (VPz)), (Xz)); \ /**(HN) = (VP)&(D0);**/\ (HNz) = _mm256_and_si256((VPz), (D0z)); \ /**(HP) = (VN) | ~((VP) | (D0));**/\ (HPz) = _mm256_or_si256((VNz), _mm256_andnot_si256(_mm256_or_si256((VPz), (D0z)), _mm256_set1_epi64x(-1))); \ /**(X) = (D0) >> 1;**/\ (Xz) = _mm256_srli_epi64((D0z), 1); \ /**(VN) = (X)&(HP);**/\ (VNz) = _mm256_and_si256((Xz), (HPz)); \ /**(VP) = (HN) | ~((X) | (HP));**/\ (VPz) = _mm256_or_si256((HNz), _mm256_andnot_si256(_mm256_or_si256((Xz), (HPz)), _mm256_set1_epi64x(-1))); \ } #define ed_core_upx4(PEQz, PSA, PNA, IBD, HT, CC, MMK, SI) { \ if((HT) & (((int32_t)1u) << (SI))) {\ (IBD)[(SI)]++;\ if((IBD)[(SI)] < (PNA)[(SI)]) {\ (CC) = seq_nt4_table[(uint8_t)(PSA)[(SI)][(IBD)[(SI)]]];\ if((CC) < 4) (PEQz)[(CC)] = _mm256_or_si256((PEQz)[(CC)], (MMK)[(SI)]);\ }\ }\ } #define ed_tail_upx4(HT, SI, ST, AI, PNA, ABS_DIAG, K, ERR_MM, VP_MM, VN_MM, THRE, R_ERR, R_PE, BD, I) {\ if((HT) & (((int32_t)1u) << (SI))) {\ (ST)[(SI)] -= (ABS_DIAG)[(SI)]; (AI)[(SI)] += (PNA)[(SI)] + (ABS_DIAG)[(SI)];\ for ((K)[(SI)] = 0; (ST)[(SI)] < 0 && (K)[(SI)] < (AI)[(SI)]; (K)[(SI)]++, (ST)[(SI)]++) {\ (ERR_MM)[(SI)] += ((VP_MM)[(SI)]&(1ULL)); (VP_MM)[(SI)]>>=1;\ (ERR_MM)[(SI)] -= ((VN_MM)[(SI)]&(1ULL)); (VN_MM)[(SI)]>>=1;\ }\ if (((ERR_MM)[(SI)] <= (THRE)) && ((ERR_MM)[(SI)] <= (R_ERR)[(SI)])) {\ (R_ERR)[(SI)] = (ERR_MM)[(SI)]; (R_PE)[(SI)] = (ST)[(SI)];\ }\ (ST)[(SI)] -= (K)[(SI)]; (BD)++; (I) = (SI);\ }\ } #define ED_TAIL_LANE(K) do { \ if ((ht) & (((int32_t)1u) << (K))) { \ st = tn - 1 - abs_diag_a[(K)]; \ ai = pna[(K)] - tn + abs_diag_a[(K)]; \ for (i = 0, uge = INT64_MAX; st < 0 && i < ai; i++, st++) { \ err_mm[(K)] += ((VP_mm[(K)] >> i) & 1ULL); \ err_mm[(K)] -= ((VN_mm[(K)] >> i) & 1ULL); \ } \ if ((err_mm[(K)] <= thre) && (err_mm[(K)] <= r_err[(K)])) { \ r_err[(K)] = err_mm[(K)]; \ r_pe[(K)] = st; \ } \ st -= i; \ while (i < ai) { \ err_mm[(K)] += ((VP_mm[(K)] >> i) & 1ULL); \ err_mm[(K)] -= ((VN_mm[(K)] >> i) & 1ULL); \ ++i; \ if ((err_mm[(K)] <= thre) && (err_mm[(K)] <= r_err[(K)])) { \ r_err[(K)] = err_mm[(K)]; \ r_pe[(K)] = st + i; \ } \ if (i == thre) uge = err_mm[(K)]; \ } \ if ((uge <= thre) && (uge == r_err[(K)])) r_pe[(K)] = st + thre; \ } \ } while (0) void ed_band_cal_semi_64_w_absent_diag_avx4(char **psa, int32_t *pna, char *tstr, int32_t tn, int32_t thre, int32_t *abs_diag_a, int64_t *r_err, int64_t *r_pe) { // r_err[0] = r_err[1] = r_err[2] = r_err[3] = r_err[4] = r_err[5] = r_err[6] = r_err[7] = thre+1; // r_pe[0] = r_pe[1] = r_pe[2] = r_pe[3] = r_pe[4] = r_pe[5] = r_pe[6] = r_pe[7] = -1; Word mm, Peq_mm[5][AVX_GS2] = {{0}}, *VN_mm = NULL, *VP_mm = NULL, c = 0; __m256i Peq[5], VP, VN, X, D0, HN, HP, lone, E, C, mmk[AVX_GS2]; int32_t lz = 0, ht = (((int32_t)1u)<