Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-17 08:39:06

0001 /* Copyright 2025 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See https://www.boost.org/libs/bloom for library home page.
0007  */
0008 
0009 #ifndef BOOST_BLOOM_DETAIL_FAST_MULTIBLOCK64_AVX2_HPP
0010 #define BOOST_BLOOM_DETAIL_FAST_MULTIBLOCK64_AVX2_HPP
0011 
0012 #include <boost/bloom/detail/avx2.hpp>
0013 #include <boost/bloom/detail/multiblock_fpr_base.hpp>
0014 #include <boost/bloom/detail/mulx64.hpp>
0015 #include <boost/config.hpp>
0016 #include <boost/config/workaround.hpp>
0017 #include <cstddef>
0018 #include <cstdint>
0019 
0020 namespace boost{
0021 namespace bloom{
0022 
0023 #if defined(BOOST_MSVC)
0024 #pragma warning(push)
0025 #pragma warning(disable:4714) /* marked as __forceinline not inlined */
0026 #endif
0027 
0028 namespace detail{
0029 
0030 struct m256ix2
0031 {
0032   __m256i lo,hi;
0033 };
0034 
0035 } /* namespace detail */
0036 
0037 template<std::size_t K>
0038 struct fast_multiblock64:detail::multiblock_fpr_base<K>
0039 {
0040   static constexpr std::size_t k=K;
0041   using value_type=detail::m256ix2[(k+7)/8];
0042   static constexpr std::size_t used_value_size=sizeof(std::uint64_t)*k;
0043 
0044   static BOOST_FORCEINLINE void mark(value_type& x,std::uint64_t hash)
0045   {
0046     for(int i=0;i<k/8;++i){
0047       mark_m256ix2(x[i],hash,8);
0048       hash=detail::mulx64(hash);
0049     }
0050     if(k%8){
0051       mark_m256ix2(x[k/8],hash,k%8);
0052     }
0053   }
0054 
0055   static BOOST_FORCEINLINE bool check(const value_type& x,std::uint64_t hash)
0056   {
0057     bool res=true;
0058     for(int i=0;i<k/8;++i){
0059       res&=check_m256ix2(x[i],hash,8);
0060       hash=detail::mulx64(hash);
0061     }
0062     if(k%8){
0063       res&=check_m256ix2(x[k/8],hash,k%8);
0064     }
0065     return res;
0066   }
0067 
0068 private:
0069   static BOOST_FORCEINLINE detail::m256ix2 make_m256ix2(
0070     std::uint64_t hash,std::size_t kp)
0071   {
0072     const detail::m256ix2 ones[8]={
0073       {_mm256_set_epi64x(0,0,0,1),_mm256_set_epi64x(0,0,0,0)},
0074       {_mm256_set_epi64x(0,0,1,1),_mm256_set_epi64x(0,0,0,0)},
0075       {_mm256_set_epi64x(0,1,1,1),_mm256_set_epi64x(0,0,0,0)},
0076       {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(0,0,0,0)},
0077       {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(0,0,0,1)},
0078       {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(0,0,1,1)},
0079       {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(0,1,1,1)},
0080       {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(1,1,1,1)},
0081     };
0082 
0083     __m256i h=_mm256_set1_epi64x(hash);
0084     h=_mm256_sllv_epi64(h,_mm256_set_epi64x(18,12,6,0));
0085     h=_mm256_srli_epi32(h,32-6);
0086     return {
0087       _mm256_sllv_epi64(
0088         ones[kp-1].lo,_mm256_cvtepu32_epi64(_mm256_extracti128_si256(h,0))),
0089       kp<=4?
0090       _mm256_set1_epi64x(0):
0091       _mm256_sllv_epi64(
0092         ones[kp-1].hi,_mm256_cvtepu32_epi64(_mm256_extracti128_si256(h,1)))
0093     };
0094   }
0095 
0096   static BOOST_FORCEINLINE void mark_m256ix2(
0097     detail::m256ix2& x,std::uint64_t hash,std::size_t kp)
0098   {
0099     detail::m256ix2 h=make_m256ix2(hash,kp);
0100     x.lo=_mm256_or_si256(x.lo,h.lo);
0101     if(kp>4)x.hi=_mm256_or_si256(x.hi,h.hi);
0102   }
0103 
0104 #if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
0105 /* 'int': forcing value to bool 'true' or 'false' */
0106 #pragma warning(push)
0107 #pragma warning(disable:4800)
0108 #endif
0109 
0110   static BOOST_FORCEINLINE bool check_m256ix2(
0111     const detail::m256ix2& x,std::uint64_t hash,std::size_t kp)
0112   {
0113     detail::m256ix2 h=make_m256ix2(hash,kp);
0114     auto res=_mm256_testc_si256(x.lo,h.lo);
0115     if(kp>4)res&=_mm256_testc_si256(x.hi,h.hi);
0116     return res;
0117   }
0118 
0119 #if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
0120 #pragma warning(pop) /* C4800 */
0121 #endif
0122 };
0123 
0124 #if defined(BOOST_MSVC)
0125 #pragma warning(pop) /* C4714 */
0126 #endif
0127 
0128 } /* namespace bloom */
0129 } /* namespace boost */
0130 
0131 #endif