SeqAn3  3.0.2
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 
15 #include <array>
16 
20 
21 //-----------------------------------------------------------------------------
22 // forward declare avx512 simd algorithms that use avx512 intrinsics
23 //-----------------------------------------------------------------------------
24 
25 namespace seqan3::detail
26 {
30 template <simd::simd_concept simd_t>
31 constexpr simd_t load_avx512(void const * mem_addr);
32 
36 template <simd::simd_concept simd_t>
37 inline void transpose_matrix_avx512(std::array<simd_t, simd_traits<simd_t>::length> & matrix);
38 
42 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
43 constexpr target_simd_t upcast_signed_avx512(source_simd_t const & src);
44 
48 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
49 constexpr target_simd_t upcast_unsigned_avx512(source_simd_t const & src);
50 
54 template <uint8_t index, simd::simd_concept simd_t>
55 constexpr simd_t extract_half_avx512(simd_t const & src);
56 
60 template <uint8_t index, simd::simd_concept simd_t>
61 constexpr simd_t extract_quarter_avx512(simd_t const & src);
62 
66 template <uint8_t index, simd::simd_concept simd_t>
67 constexpr simd_t extract_eighth_avx512(simd_t const & src);
68 
69 }
70 
71 //-----------------------------------------------------------------------------
72 // implementation
73 //-----------------------------------------------------------------------------
74 
75 #ifdef __AVX512F__
76 
77 namespace seqan3::detail
78 {
79 
80 template <simd::simd_concept simd_t>
81 constexpr simd_t load_avx512(void const * mem_addr)
82 {
83  return reinterpret_cast<simd_t>(_mm512_loadu_si512(mem_addr));
84 }
85 
86 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::simd::transpose
87 template <simd::simd_concept simd_t>
88 inline void transpose_matrix_avx512(std::array<simd_t, simd_traits<simd_t>::length> & matrix);
89 
90 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
91 constexpr target_simd_t upcast_signed_avx512(source_simd_t const & src)
92 {
93  __m512i const & tmp = reinterpret_cast<__m512i const &>(src);
94  if constexpr (simd_traits<source_simd_t>::length == 64) // cast from epi8 ...
95  {
96  if constexpr (simd_traits<target_simd_t>::length == 32) // to epi16
97  return reinterpret_cast<target_simd_t>(_mm512_cvtepi8_epi16(_mm512_castsi512_si256(tmp)));
98  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
99  return reinterpret_cast<target_simd_t>(_mm512_cvtepi8_epi32(_mm512_castsi512_si128(tmp)));
100  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
101  return reinterpret_cast<target_simd_t>(_mm512_cvtepi8_epi64(_mm512_castsi512_si128(tmp)));
102  }
103  else if constexpr (simd_traits<source_simd_t>::length == 32) // cast from epi16 ...
104  {
105  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
106  return reinterpret_cast<target_simd_t>(_mm512_cvtepi16_epi32(_mm512_castsi512_si256(tmp)));
107  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
108  return reinterpret_cast<target_simd_t>(_mm512_cvtepi16_epi64(_mm512_castsi512_si128(tmp)));
109  }
110  else // cast from epi32 to epi64
111  {
112  static_assert(simd_traits<source_simd_t>::length == 16, "Expected 32 bit scalar type.");
113  return reinterpret_cast<target_simd_t>(_mm512_cvtepi32_epi64(_mm512_castsi512_si256(tmp)));
114  }
115 }
116 
117 template <simd::simd_concept target_simd_t, simd::simd_concept source_simd_t>
118 constexpr target_simd_t upcast_unsigned_avx512(source_simd_t const & src)
119 {
120  __m512i const & tmp = reinterpret_cast<__m512i const &>(src);
121  if constexpr (simd_traits<source_simd_t>::length == 64) // cast from epi8 ...
122  {
123  if constexpr (simd_traits<target_simd_t>::length == 32) // to epi16
124  return reinterpret_cast<target_simd_t>(_mm512_cvtepu8_epi16(_mm512_castsi512_si256(tmp)));
125  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
126  return reinterpret_cast<target_simd_t>(_mm512_cvtepu8_epi32(_mm512_castsi512_si128(tmp)));
127  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
128  return reinterpret_cast<target_simd_t>(_mm512_cvtepu8_epi64(_mm512_castsi512_si128(tmp)));
129  }
130  else if constexpr (simd_traits<source_simd_t>::length == 32) // cast from epi16 ...
131  {
132  if constexpr (simd_traits<target_simd_t>::length == 16) // to epi32
133  return reinterpret_cast<target_simd_t>(_mm512_cvtepu16_epi32(_mm512_castsi512_si256(tmp)));
134  if constexpr (simd_traits<target_simd_t>::length == 8) // to epi64
135  return reinterpret_cast<target_simd_t>(_mm512_cvtepu16_epi64(_mm512_castsi512_si128(tmp)));
136  }
137  else // cast from epi32 to epi64
138  {
139  static_assert(simd_traits<source_simd_t>::length == 16, "Expected 32 bit scalar type.");
140  return reinterpret_cast<target_simd_t>(_mm512_cvtepu32_epi64(_mm512_castsi512_si256(tmp)));
141  }
142 }
143 
144 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_half
145 template <uint8_t index, simd::simd_concept simd_t>
146 constexpr simd_t extract_half_avx512(simd_t const & src);
147 
148 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_quarter
149 template <uint8_t index, simd::simd_concept simd_t>
150 constexpr simd_t extract_quarter_avx512(simd_t const & src);
151 
152 // TODO: not implemented and used yet, if you implement it don't forget to add it to seqan3::detail::extract_eighth
153 template <uint8_t index, simd::simd_concept simd_t>
154 constexpr simd_t extract_eighth_avx512(simd_t const & src);
155 
156 } // namespace seqan3::detail
157 
158 #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.
array