1 /**** 2 DIAMOND protein aligner 3 Copyright (C) 2016-2020 Max Planck Society for the Advancement of Science e.V. 4 Benjamin Buchfink 5 6 Code developed by Benjamin Buchfink <benjamin.buchfink@tue.mpg.de> 7 8 This program is free software: you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation, either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 ****/ 21 22 #pragma once 23 #include "../util/simd.h" 24 #include "../basic/config.h" 25 26 #ifdef __AVX2__ 27 28 struct Byte_finger_print_32 29 { Byte_finger_print_32Byte_finger_print_3230 Byte_finger_print_32(const Letter* q) : 31 #ifdef SEQ_MASK 32 r1(letter_mask(_mm256_loadu_si256((__m256i const*)(q - 16)))) 33 #else 34 r1(_mm256_loadu_si256((__m256i const*)(q - 16))) 35 #endif 36 {} match_blockByte_finger_print_3237 static uint64_t match_block(__m256i x, __m256i y) 38 { 39 return (uint64_t)_mm256_movemask_epi8(_mm256_cmpeq_epi8(x, y)); 40 } matchByte_finger_print_3241 unsigned match(const Byte_finger_print_32& rhs) const 42 { 43 return popcount64(match_block(r1, rhs.r1)); 44 } 45 __m256i r1; 46 }; 47 48 struct Byte_finger_print_64 49 { Byte_finger_print_64Byte_finger_print_6450 Byte_finger_print_64(const Letter* q) : 51 #ifdef SEQ_MASK 52 r1(letter_mask(_mm256_loadu_si256((__m256i const*)(q - 32)))), 53 r2(letter_mask(_mm256_loadu_si256((__m256i const*)q))) 54 #else 55 r1(_mm256_loadu_si256((__m256i const*)(q - 32))), 56 r2(_mm256_loadu_si256((__m256i const*)q)) 57 #endif 58 {} match_blockByte_finger_print_6459 static uint64_t match_block(__m256i x, __m256i y) 60 { 61 return (uint64_t)_mm256_movemask_epi8(_mm256_cmpeq_epi8(x, y)); 62 } matchByte_finger_print_6463 unsigned match(const Byte_finger_print_64& rhs) const 64 { 65 return popcount64(match_block(r1, rhs.r1) << 32 | match_block(r2, rhs.r2)); 66 } 67 __m256i r1, r2; 68 }; 69 70 #endif 71 72 #ifdef __SSE2__ 73 74 struct Byte_finger_print_48 75 { Byte_finger_print_48Byte_finger_print_4876 Byte_finger_print_48(const Letter *q) : 77 #ifdef SEQ_MASK 78 r1(letter_mask(_mm_loadu_si128((__m128i const*)(q - 16)))), 79 r2(letter_mask(_mm_loadu_si128((__m128i const*)(q)))), 80 r3(letter_mask(_mm_loadu_si128((__m128i const*)(q + 16)))) 81 #else 82 r1(_mm_loadu_si128((__m128i const*)(q - 16))), 83 r2(_mm_loadu_si128((__m128i const*)(q))), 84 r3(_mm_loadu_si128((__m128i const*)(q + 16))) 85 #endif 86 {} match_blockByte_finger_print_4887 static uint64_t match_block(__m128i x, __m128i y) 88 { 89 return (uint64_t)_mm_movemask_epi8(_mm_cmpeq_epi8(x, y)); 90 } matchByte_finger_print_4891 unsigned match(const Byte_finger_print_48 &rhs) const 92 { 93 return popcount64(match_block(r3, rhs.r3) << 32 | match_block(r1, rhs.r1) << 16 | match_block(r2, rhs.r2)); 94 } 95 alignas(16) __m128i r1, r2, r3; 96 }; 97 98 #else 99 100 struct Byte_finger_print_48 101 { Byte_finger_print_48Byte_finger_print_48102 Byte_finger_print_48() 103 {} Byte_finger_print_48Byte_finger_print_48104 Byte_finger_print_48(const Letter *q) 105 { 106 //printf("%llx\n", q); 107 memcpy(r, q - 16, 48); 108 #ifdef SEQ_MASK 109 for (int i = 0; i < 48; ++i) 110 r[i] &= LETTER_MASK; 111 #endif 112 } matchByte_finger_print_48113 unsigned match(const Byte_finger_print_48 &rhs) const 114 { 115 unsigned n = 0; 116 for (unsigned i = 0; i < 48; ++i) 117 if (r[i] == rhs.r[i]) 118 ++n; 119 return n; 120 } 121 Letter r[48]; 122 //char r[32]; 123 }; 124 125 #endif 126 127 #ifdef __AVX2__ 128 typedef Byte_finger_print_48 FingerPrint; 129 #else 130 typedef Byte_finger_print_48 FingerPrint; 131 #endif