1/**************************************************************************** 2 * Copyright (C) 2017 Intel Corporation. All Rights Reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 ****************************************************************************/ 23#pragma once 24 25#include "simdlib_types.hpp" 26 27// For documentation, please see the following include... 28// #include "simdlib_interface.hpp" 29 30namespace SIMDImpl 31{ 32 namespace SIMD128Impl 33 { 34#if SIMD_ARCH >= SIMD_ARCH_AVX 35 struct AVXImpl 36 { 37#define __SIMD_LIB_AVX_HPP__ 38#include "simdlib_128_avx.inl" 39#undef __SIMD_LIB_AVX_HPP__ 40 }; // struct AVXImpl 41#endif // #if SIMD_ARCH >= SIMD_ARCH_AVX 42 43#if SIMD_ARCH >= SIMD_ARCH_AVX2 44 struct AVX2Impl : AVXImpl 45 { 46#define __SIMD_LIB_AVX2_HPP__ 47#include "simdlib_128_avx2.inl" 48#undef __SIMD_LIB_AVX2_HPP__ 49 }; // struct AVX2Impl 50#endif // #if SIMD_ARCH >= SIMD_ARCH_AVX2 51 52#if SIMD_ARCH >= SIMD_ARCH_AVX512 53 struct AVX512Impl : AVX2Impl 54 { 55#if defined(SIMD_OPT_128_AVX512) 56#define __SIMD_LIB_AVX512_HPP__ 57#include "simdlib_128_avx512.inl" 58#if defined(SIMD_ARCH_KNIGHTS) 59#include "simdlib_128_avx512_knights.inl" 60#else // optimize for core 61#include "simdlib_128_avx512_core.inl" 62#endif // defined(SIMD_ARCH_KNIGHTS) 63#undef __SIMD_LIB_AVX512_HPP__ 64#endif // SIMD_OPT_128_AVX512 65 }; // struct AVX2Impl 66#endif // #if SIMD_ARCH >= SIMD_ARCH_AVX512 67 68 struct Traits : SIMDImpl::Traits 69 { 70#if SIMD_ARCH == SIMD_ARCH_AVX 71 using IsaImpl = AVXImpl; 72#elif SIMD_ARCH == SIMD_ARCH_AVX2 73 using IsaImpl = AVX2Impl; 74#elif SIMD_ARCH == SIMD_ARCH_AVX512 75 using IsaImpl = AVX512Impl; 76#else 77#error Invalid value for SIMD_ARCH 78#endif 79 80 using Float = SIMD128Impl::Float; 81 using Double = SIMD128Impl::Double; 82 using Integer = SIMD128Impl::Integer; 83 using Vec4 = SIMD128Impl::Vec4; 84 using Mask = SIMD128Impl::Mask; 85 }; 86 } // namespace SIMD128Impl 87 88 namespace SIMD256Impl 89 { 90#if SIMD_ARCH >= SIMD_ARCH_AVX 91 struct AVXImpl 92 { 93#define __SIMD_LIB_AVX_HPP__ 94#include "simdlib_256_avx.inl" 95#undef __SIMD_LIB_AVX_HPP__ 96 }; // struct AVXImpl 97#endif // #if SIMD_ARCH >= SIMD_ARCH_AVX 98 99#if SIMD_ARCH >= SIMD_ARCH_AVX2 100 struct AVX2Impl : AVXImpl 101 { 102#define __SIMD_LIB_AVX2_HPP__ 103#include "simdlib_256_avx2.inl" 104#undef __SIMD_LIB_AVX2_HPP__ 105 }; // struct AVX2Impl 106#endif // #if SIMD_ARCH >= SIMD_ARCH_AVX2 107 108#if SIMD_ARCH >= SIMD_ARCH_AVX512 109 struct AVX512Impl : AVX2Impl 110 { 111#if defined(SIMD_OPT_256_AVX512) 112#define __SIMD_LIB_AVX512_HPP__ 113#include "simdlib_256_avx512.inl" 114#if defined(SIMD_ARCH_KNIGHTS) 115#include "simdlib_256_avx512_knights.inl" 116#else // optimize for core 117#include "simdlib_256_avx512_core.inl" 118#endif // defined(SIMD_ARCH_KNIGHTS) 119#undef __SIMD_LIB_AVX512_HPP__ 120#endif // SIMD_OPT_256_AVX512 121 }; // struct AVX2Impl 122#endif // #if SIMD_ARCH >= SIMD_ARCH_AVX512 123 124 struct Traits : SIMDImpl::Traits 125 { 126#if SIMD_ARCH == SIMD_ARCH_AVX 127 using IsaImpl = AVXImpl; 128#elif SIMD_ARCH == SIMD_ARCH_AVX2 129 using IsaImpl = AVX2Impl; 130#elif SIMD_ARCH == SIMD_ARCH_AVX512 131 using IsaImpl = AVX512Impl; 132#else 133#error Invalid value for SIMD_ARCH 134#endif 135 136 using Float = SIMD256Impl::Float; 137 using Double = SIMD256Impl::Double; 138 using Integer = SIMD256Impl::Integer; 139 using Vec4 = SIMD256Impl::Vec4; 140 using Mask = SIMD256Impl::Mask; 141 }; 142 } // namespace SIMD256Impl 143 144 namespace SIMD512Impl 145 { 146#if SIMD_ARCH >= SIMD_ARCH_AVX 147 template <typename SIMD256T> 148 struct AVXImplBase 149 { 150#define __SIMD_LIB_AVX_HPP__ 151#include "simdlib_512_emu.inl" 152#include "simdlib_512_emu_masks.inl" 153#undef __SIMD_LIB_AVX_HPP__ 154 }; // struct AVXImplBase 155 using AVXImpl = AVXImplBase<SIMD256Impl::AVXImpl>; 156#endif // #if SIMD_ARCH >= SIMD_ARCH_AVX 157 158#if SIMD_ARCH >= SIMD_ARCH_AVX2 159 using AVX2Impl = AVXImplBase<SIMD256Impl::AVX2Impl>; 160#endif // #if SIMD_ARCH >= SIMD_ARCH_AVX2 161 162#if SIMD_ARCH >= SIMD_ARCH_AVX512 163 struct AVX512Impl : AVXImplBase<SIMD256Impl::AVX512Impl> 164 { 165#define __SIMD_LIB_AVX512_HPP__ 166#include "simdlib_512_avx512.inl" 167#include "simdlib_512_avx512_masks.inl" 168#if defined(SIMD_ARCH_KNIGHTS) 169#include "simdlib_512_avx512_knights.inl" 170#include "simdlib_512_avx512_masks_knights.inl" 171#else // optimize for core 172#include "simdlib_512_avx512_core.inl" 173#include "simdlib_512_avx512_masks_core.inl" 174#endif // defined(SIMD_ARCH_KNIGHTS) 175#undef __SIMD_LIB_AVX512_HPP__ 176 }; // struct AVX512ImplBase 177#endif // #if SIMD_ARCH >= SIMD_ARCH_AVX512 178 179 struct Traits : SIMDImpl::Traits 180 { 181#if SIMD_ARCH == SIMD_ARCH_AVX 182 using IsaImpl = AVXImpl; 183#elif SIMD_ARCH == SIMD_ARCH_AVX2 184 using IsaImpl = AVX2Impl; 185#elif SIMD_ARCH == SIMD_ARCH_AVX512 186 using IsaImpl = AVX512Impl; 187#else 188#error Invalid value for SIMD_ARCH 189#endif 190 191 using Float = SIMD512Impl::Float; 192 using Double = SIMD512Impl::Double; 193 using Integer = SIMD512Impl::Integer; 194 using Vec4 = SIMD512Impl::Vec4; 195 using Mask = SIMD512Impl::Mask; 196 }; 197 } // namespace SIMD512Impl 198} // namespace SIMDImpl 199 200template <typename Traits> 201struct SIMDBase : Traits::IsaImpl 202{ 203 using CompareType = typename Traits::CompareType; 204 using ScaleFactor = typename Traits::ScaleFactor; 205 using RoundMode = typename Traits::RoundMode; 206 using SIMD = typename Traits::IsaImpl; 207 using Float = typename Traits::Float; 208 using Double = typename Traits::Double; 209 using Integer = typename Traits::Integer; 210 using Vec4 = typename Traits::Vec4; 211 using Mask = typename Traits::Mask; 212}; // struct SIMDBase 213 214using SIMD128 = SIMDBase<SIMDImpl::SIMD128Impl::Traits>; 215using SIMD256 = SIMDBase<SIMDImpl::SIMD256Impl::Traits>; 216using SIMD512 = SIMDBase<SIMDImpl::SIMD512Impl::Traits>; 217 218template <typename SIMD_T> 219using CompareType = typename SIMD_T::CompareType; 220template <typename SIMD_T> 221using ScaleFactor = typename SIMD_T::ScaleFactor; 222template <typename SIMD_T> 223using RoundMode = typename SIMD_T::RoundMode; 224template <typename SIMD_T> 225using Float = typename SIMD_T::Float; 226template <typename SIMD_T> 227using Double = typename SIMD_T::Double; 228template <typename SIMD_T> 229using Integer = typename SIMD_T::Integer; 230template <typename SIMD_T> 231using Vec4 = typename SIMD_T::Vec4; 232template <typename SIMD_T> 233using Mask = typename SIMD_T::Mask; 234 235