SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
simd_algorithm_avx512.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
18 
19 //-----------------------------------------------------------------------------
20 // forward declare avx512 simd algorithms that use avx512 intrinsics
21 //-----------------------------------------------------------------------------
22 
23 namespace seqan3::detail
24 {
28 template <simd::simd_concept simd_t>
29 constexpr simd_t load_avx512(void const * mem_addr);
30 
34 template <simd::simd_concept simd_t>
35 inline void transpose_matrix_avx512(std::array<simd_t, simd_traits<simd_t>::length> & matrix);
36 
40 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
41 constexpr target_simd_t upcast_signed_avx512(source_simd_t const & src);
42 
46 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
47 constexpr target_simd_t upcast_unsigned_avx512(source_simd_t const & src);
48 
52 template <uint8_t index, simd::simd_concept simd_t>
53 constexpr simd_t extract_halve_avx512(simd_t const & src);
54 
58 template <uint8_t index, simd::simd_concept simd_t>
59 constexpr simd_t extract_quarter_avx512(simd_t const & src);
60 
64 template <uint8_t index, simd::simd_concept simd_t>
65 constexpr simd_t extract_eighth_avx512(simd_t const & src);
66 
67 }
68 
69 //-----------------------------------------------------------------------------
70 // implementation
71 //-----------------------------------------------------------------------------
72 
73 #ifdef __AVX512F__
74 
75 namespace seqan3::detail
76 {
77 
78 template <simd::simd_concept simd_t>
79 constexpr simd_t load_avx512(void const * mem_addr)
80 {
81  return reinterpret_cast<simd_t>(_mm512_loadu_si512(mem_addr));
82 }
83 
84 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::simd::transpose
85 template <simd::simd_concept simd_t>
86 inline void transpose_matrix_avx512(std::array<simd_t, simd_traits<simd_t>::length> & matrix);
87 
88 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
89 constexpr target_simd_t upcast_signed_avx512(source_simd_t const & src)
90 {
91  __m512i const & tmp = reinterpret_cast<__m512i const &>(src);
92  if constexpr (simd_traits<source_simd_t>::length == 64) // cast from epi8 ...
93  {
94  if constexpr (simd_traits<target_simd_t>::length == 32) // to epi16
95  return reinterpret_cast<target_simd_t>(_mm512_cvtepi8_epi16(_mm512_castsi512_si256(tmp)));
96  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
97  return reinterpret_cast<target_simd_t>(_mm512_cvtepi8_epi32(_mm512_castsi512_si128(tmp)));
98  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
99  return reinterpret_cast<target_simd_t>(_mm512_cvtepi8_epi64(_mm512_castsi512_si128(tmp)));
100  }
101  else if constexpr (simd_traits<source_simd_t>::length == 32) // cast from epi16 ...
102  {
103  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
104  return reinterpret_cast<target_simd_t>(_mm512_cvtepi16_epi32(_mm512_castsi512_si256(tmp)));
105  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
106  return reinterpret_cast<target_simd_t>(_mm512_cvtepi16_epi64(_mm512_castsi512_si128(tmp)));
107  }
108  else // cast from epi32 to epi64
109  {
110  static_assert(simd_traits<source_simd_t>::length == 16, "Expected 32 bit scalar type.");
111  return reinterpret_cast<target_simd_t>(_mm512_cvtepi32_epi64(_mm512_castsi512_si256(tmp)));
112  }
113 }
114 
115 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
116 constexpr target_simd_t upcast_unsigned_avx512(source_simd_t const & src)
117 {
118  __m512i const & tmp = reinterpret_cast<__m512i const &>(src);
119  if constexpr (simd_traits<source_simd_t>::length == 64) // cast from epi8 ...
120  {
121  if constexpr (simd_traits<target_simd_t>::length == 32) // to epi16
122  return reinterpret_cast<target_simd_t>(_mm512_cvtepu8_epi16(_mm512_castsi512_si256(tmp)));
123  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
124  return reinterpret_cast<target_simd_t>(_mm512_cvtepu8_epi32(_mm512_castsi512_si128(tmp)));
125  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
126  return reinterpret_cast<target_simd_t>(_mm512_cvtepu8_epi64(_mm512_castsi512_si128(tmp)));
127  }
128  else if constexpr (simd_traits<source_simd_t>::length == 32) // cast from epi16 ...
129  {
130  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
131  return reinterpret_cast<target_simd_t>(_mm512_cvtepu16_epi32(_mm512_castsi512_si256(tmp)));
132  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
133  return reinterpret_cast<target_simd_t>(_mm512_cvtepu16_epi64(_mm512_castsi512_si128(tmp)));
134  }
135  else // cast from epi32 to epi64
136  {
137  static_assert(simd_traits<source_simd_t>::length == 16, "Expected 32 bit scalar type.");
138  return reinterpret_cast<target_simd_t>(_mm512_cvtepu32_epi64(_mm512_castsi512_si256(tmp)));
139  }
140 }
141 
142 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_halve
143 template <uint8_t index, simd::simd_concept simd_t>
144 constexpr simd_t extract_halve_avx512(simd_t const & src);
145 
146 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_quarter
147 template <uint8_t index, simd::simd_concept simd_t>
148 constexpr simd_t extract_quarter_avx512(simd_t const & src);
149 
150 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_eighth
151 template <uint8_t index, simd::simd_concept simd_t>
152 constexpr simd_t extract_eighth_avx512(simd_t const & src);
153 
154 } // namespace seqan3::detail
155 
156 #endif // __AVX512F__
concept.hpp
Provides seqan3::simd::simd_concept.
simd_traits.hpp
Provides seqan3::simd::simd_traits.
builtin_simd_intrinsics.hpp
Provides intrinsics include for builtin simd.
std::array