|
| 1 | + |
| 2 | + |
1 | 3 | use crate::{ |
2 | 4 | alphabet::{Symbol, SymbolAlphabet}, |
3 | 5 | search::SearchPtr, |
4 | | - simd_instructions::{Vec256, SimdVec256}, |
| 6 | + simd_instructions::{masked_popcount, simd_and, simd_andnot, simd_or, Vec256}, |
5 | 7 | }; |
6 | 8 | use mem_dbg::MemSize; |
7 | 9 | use serde::{Deserialize, Serialize}; |
@@ -112,21 +114,21 @@ impl NucleotideBwtBlock { |
112 | 114 | pub (crate) fn global_occurrence(&self, local_query_position: u64, symbol: &Symbol) -> u64 { |
113 | 115 | unsafe{ |
114 | 116 | let milestone_count = self.milestone(&symbol); |
115 | | - let vec0 = SimdVec256::from(*self.bit_vectors.get_unchecked(0)); |
116 | | - let vec1 = SimdVec256::from(*self.bit_vectors.get_unchecked(1)); |
117 | | - let vec2 = SimdVec256::from(*self.bit_vectors.get_unchecked(2)); |
| 117 | + let vec0 = self.bit_vectors.get_unchecked(0).to_simd(); |
| 118 | + let vec1 = self.bit_vectors.get_unchecked(1).to_simd(); |
| 119 | + let vec2 = self.bit_vectors.get_unchecked(2).to_simd(); |
118 | 120 | let occurrence_vector = match &symbol.index() { |
119 | | - 1 => vec2.and(&vec1), //A: 0b110 |
120 | | - 2 => vec2.and(&vec0), //C: 0b101 |
121 | | - 3 => vec1.and(&vec0), //G: 0b011 |
122 | | - 4 => vec2.andnot(&vec0.andnot(&vec1)), //N: 0b010 |
123 | | - 5 => vec2.andnot(&vec1.andnot(&vec0)), //T: 0b001 |
| 121 | + 1 => simd_and(vec1, vec2), //A: 0b110 |
| 122 | + 2 => simd_and(vec0, vec2), //C: 0b101 |
| 123 | + 3 => simd_and(vec0, vec1), //G: 0b011 |
| 124 | + 4 => simd_andnot(vec2, simd_andnot(vec0, vec1)), //N: 0b010 |
| 125 | + 5 => simd_andnot(vec2, simd_andnot(vec1, vec0)), //T: 0b001 |
124 | 126 | _ => { |
125 | 127 | panic!("illegal letter index given in global occurrence function symbol idx given: {}", symbol.index()); |
126 | 128 | } //assume every other character is an N, since it's illegal to search for a sentinel |
127 | 129 | }; |
128 | 130 |
|
129 | | - let popcount = occurrence_vector.masked_popcount(local_query_position); |
| 131 | + let popcount = masked_popcount(occurrence_vector, local_query_position); |
130 | 132 |
|
131 | 133 | return milestone_count + popcount as u64; |
132 | 134 | } |
@@ -225,44 +227,44 @@ impl AminoBwtBlock { |
225 | 227 | /// The occurrence function uses the milestone value and the masked occurrenc vector to |
226 | 228 | /// determine how many instances of the given character were before this position. |
227 | 229 | #[inline] |
228 | | - pub (crate) fn global_occurrence(&self, local_query_position: SearchPtr, symbol: &Symbol) -> SearchPtr { |
| 230 | + pub (crate) fn global_occurrence(&self, local_query_position: SearchPtr, symbol: &Symbol) -> SearchPtr { |
229 | 231 | let milestone_count = self.milestone(symbol); |
230 | 232 |
|
231 | 233 | unsafe{ |
232 | | - let vec0 = SimdVec256::from(*self.bit_vectors.get_unchecked(0)); |
233 | | - let vec1 = SimdVec256::from(*self.bit_vectors.get_unchecked(1)); |
234 | | - let vec2 = SimdVec256::from(*self.bit_vectors.get_unchecked(2)); |
235 | | - let vec3 = SimdVec256::from(*self.bit_vectors.get_unchecked(3)); |
236 | | - let vec4 = SimdVec256::from(*self.bit_vectors.get_unchecked(4)); |
| 234 | + let vec0 = self.bit_vectors.get_unchecked(0).to_simd(); |
| 235 | + let vec1 = self.bit_vectors.get_unchecked(1).to_simd(); |
| 236 | + let vec2 = self.bit_vectors.get_unchecked(2).to_simd(); |
| 237 | + let vec3 = self.bit_vectors.get_unchecked(3).to_simd(); |
| 238 | + let vec4 = self.bit_vectors.get_unchecked(4).to_simd(); |
237 | 239 | let occurrence_vector = match symbol.index() { |
238 | | - 1 => vec3.and(&vec4.andnot(&vec2)), //A: 0b01100 |
239 | | - 2 => vec3.andnot(&vec2).and(&vec1.and(&vec0)), //C: 0b10111 |
240 | | - 3 => vec1.and(&vec4.andnot(&vec0)), //D: 0b00011 |
241 | | - 4 => vec4.andnot(&vec2.and(&vec1)), //E: 0b00110 |
242 | | - 5 => vec0.andnot(&vec3).and(&vec2.and(&vec1)), //F: 0b11110 |
243 | | - 6 => vec2.andnot(&vec0.andnot(&vec4)), //G: 0b11010 |
244 | | - 7 => vec2.andnot(&vec3).and(&vec1.and(&vec0)), //H: 0b11011 |
245 | | - 8 => vec2.andnot(&vec1.andnot(&vec4)), //I: 0b11001 |
246 | | - 9 => vec3.andnot(&vec1.andnot(&vec4)), //K: 0b10101 |
247 | | - 10 => vec1.andnot(&vec0.andnot(&vec4)), //L: 0b11100 |
248 | | - 11 => vec1.andnot(&vec3).and(&vec2.and(&vec0)), //M: 0b11101 |
249 | | - 12 => vec0.or(&vec1).andnot(&vec2.andnot(&vec3)), //N: 0b01000 |
250 | | - 13 => vec3.and(&vec4.andnot(&vec0)), //P: 0b01001, |
251 | | - 14 => vec3.or(&vec1).andnot(&vec0.andnot(&vec2)), //Q: 0b00100 |
252 | | - 15 => vec3.andnot(&vec2.andnot(&vec4)), //R: 0b10011 |
253 | | - 16 => vec3.and(&vec4.andnot(&vec1)), //S: 0b01010 |
254 | | - 17 => vec2.and(&vec4.andnot(&vec0)), //T: 0b00101 |
255 | | - 18 => vec3.andnot(&vec0.andnot(&vec4)), //V: 0b10110 |
256 | | - 19 => vec3.or(&vec2).andnot(&vec1.andnot(&vec0)), //W: 0b00001 |
257 | | - 20 => vec3.and(&vec2).and(&vec1.and(&vec0)), //Ambiguity character X: 0b11111 |
258 | | - 21 => vec0.or(&vec2).andnot(&vec3.andnot(&vec1)), //Y: 0b00010 |
| 240 | + 1 => simd_and(vec2,simd_andnot(vec4, vec3)), //A: 0b01100 |
| 241 | + 2 => simd_andnot(vec3, simd_and(simd_and(vec0, vec1), vec2)), //C: 0b10111 |
| 242 | + 3 => simd_andnot(vec4, simd_and(vec0, vec1)), //D: 0b00011 |
| 243 | + 4 => simd_andnot(vec4, simd_and(vec1, vec2)), //E: 0b00110 |
| 244 | + 5 => simd_andnot(vec0, simd_and(simd_and(vec1, vec2), vec3)), //F: 0b11110 |
| 245 | + 6 => simd_andnot(vec2, simd_andnot(vec0, vec4)), //G: 0b11010 |
| 246 | + 7 => simd_andnot(vec2, simd_and(vec0, simd_and(vec1, vec3))), //H: 0b11011 |
| 247 | + 8 => simd_andnot(vec2, simd_andnot(vec1, vec4)), //I: 0b11001 |
| 248 | + 9 => simd_andnot(vec1, simd_andnot(vec3, vec4)), //K: 0b10101 |
| 249 | + 10 => simd_andnot(vec1, simd_andnot(vec0, vec4)), //L: 0b11100 |
| 250 | + 11 => simd_andnot(vec1, simd_and(vec3, simd_and(vec2, vec0))), //M: 0b11101 |
| 251 | + 12 => simd_andnot(simd_or(vec0, vec1), simd_andnot(vec2, vec3)), //N: 0b01000 |
| 252 | + 13 => simd_and(vec3, simd_andnot(vec4, vec0)), //P: 0b01001, |
| 253 | + 14 => simd_andnot(simd_or(vec0, vec1), simd_andnot(vec3, vec2)),//Q: 0b00100 |
| 254 | + 15 => simd_andnot(vec2, simd_andnot(vec3, vec4)), //R: 0b10011 |
| 255 | + 16 => simd_and(vec1, simd_andnot(vec4, vec3)), //S: 0b01010 |
| 256 | + 17 => simd_and(vec0, simd_andnot(vec4, vec2)), //T: 0b00101 |
| 257 | + 18 => simd_andnot(vec3, simd_andnot(vec0, vec4)), //V: 0b10110 |
| 258 | + 19 => simd_andnot(simd_or(vec1, vec2), simd_andnot(vec3, vec0)), //W: 0b00001 |
| 259 | + 20 => simd_and(simd_and(vec0, vec1), simd_and(vec2, vec3)), //Ambiguity character X: 0b11111 |
| 260 | + 21 => simd_andnot(simd_or(vec0, vec2), simd_andnot(vec3, vec1)), //Y: 0b00010 |
259 | 261 | // 0b00000 is sentinel, but since you can't search for sentinels, it is not included here. |
260 | 262 | _ => { |
261 | 263 | panic!("illegal letter index given in global occurrence function"); |
262 | 264 | } |
263 | 265 | }; |
264 | 266 |
|
265 | | - let popcount = occurrence_vector.masked_popcount(local_query_position); |
| 267 | + let popcount = masked_popcount(occurrence_vector, local_query_position); |
266 | 268 |
|
267 | 269 | return milestone_count + popcount as u64; |
268 | 270 | } |
|
0 commit comments