// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // SPDX-FileCopyrightText: Copyright Contributors to the Kokkos project #ifndef KOKKOS_SIMD_HPP #define KOKKOS_SIMD_HPP #include #include #include #include #include #if defined(KOKKOS_ARCH_AVX) && !defined(__AVX__) #error "__AVX__ must be defined for KOKKOS_ARCH_AVX" #endif #if defined(KOKKOS_ARCH_AVX2) #if !defined(__AVX2__) #error "__AVX2__ must be defined for KOKKOS_ARCH_AVX2" #endif #include #endif #if defined(KOKKOS_ARCH_AVX512XEON) #if !defined(__AVX512F__) #error "__AVX512F__ must be defined for KOKKOS_ARCH_AVX512XEON" #endif #include #endif #if defined(KOKKOS_ARCH_ARM_SVE) #if !defined(__ARM_FEATURE_SVE_BITS) || !defined(__ARM_NEON) #error \ "Both __ARM_FEATURE_SVE_BITS and __ARM_NEON must be definded for KOKKOS_ARCH_ARM_SVE" #endif #include #endif #if defined(KOKKOS_ARCH_ARM_NEON) #if !defined(__ARM_NEON) #error "__ARM_NEON must be defined for KOKKOS_ARCH_ARM_NEON" #endif #include #endif #include namespace Kokkos { namespace Experimental { namespace simd_abi { namespace Impl { #if defined(KOKKOS_ARCH_AVX512XEON) template using host_fixed_native = avx512_fixed_size<8>; template using host_native_abi = std::conditional_t, avx512_fixed_size>; #elif defined(KOKKOS_ARCH_AVX2) template using host_fixed_native = avx2_fixed_size<4>; template using host_native_abi = std::conditional_t, avx2_fixed_size>; #elif defined(KOKKOS_ARCH_ARM_SVE) template using host_fixed_native = sve_fixed_size<(__ARM_FEATURE_SVE_BITS / (CHAR_BIT * sizeof(T)))>; template using host_native_abi = std::conditional_t, sve_fixed_size>; #elif defined(KOKKOS_ARCH_ARM_NEON) template using host_fixed_native = neon_fixed_size<2>; template using host_native_abi = std::conditional_t, neon_fixed_size>; #else template using host_fixed_native = scalar; template using host_native_abi = scalar; #endif template struct ForSpace; #ifdef KOKKOS_ENABLE_SERIAL template <> struct ForSpace { template using type = host_fixed_native; template using simd_abi = host_native_abi; }; #endif #ifdef KOKKOS_ENABLE_CUDA template <> struct ForSpace { template using type = scalar; template using simd_abi = scalar; }; #endif #ifdef KOKKOS_ENABLE_THREADS template <> struct ForSpace { template using type = host_fixed_native; template using simd_abi = host_native_abi; }; #endif #ifdef KOKKOS_ENABLE_HPX template <> struct ForSpace { template using type = scalar; template using simd_abi = scalar; }; #endif #ifdef KOKKOS_ENABLE_OPENMP template <> struct ForSpace { template using type = host_fixed_native; template using simd_abi = host_native_abi; }; #endif #ifdef KOKKOS_ENABLE_OPENACC template <> struct ForSpace { template using type = scalar; template using simd_abi = scalar; }; #endif #ifdef KOKKOS_ENABLE_HIP template <> struct ForSpace { template using type = scalar; template using simd_abi = scalar; }; #endif #ifdef KOKKOS_ENABLE_SYCL template <> struct ForSpace { template using type = scalar; template using simd_abi = scalar; }; #endif template using native_fixed_abi = typename ForSpace::template type; template using native_abi = typename ForSpace::template simd_abi; } // namespace Impl #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 template using ForSpace = typename Impl::ForSpace::template type; template using native = ForSpace; #endif } // namespace simd_abi #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 template using native_simd KOKKOS_DEPRECATED_WITH_COMMENT("Use simd instead") = basic_simd>; template using native_simd_mask KOKKOS_DEPRECATED_WITH_COMMENT( "Use simd_mask instead") = basic_simd_mask>; #endif template using simd = basic_simd>; template using simd_mask = basic_simd_mask>; template requires Impl::NonScalarAbi> KOKKOS_IMPL_HOST_FORCEINLINE_FUNCTION basic_simd> simd_unchecked_load(const T* ptr, simd_flags flag = simd_flag_default) { return simd_unchecked_load< basic_simd>>(ptr, flag); } template requires Impl::ScalarAbi> KOKKOS_FORCEINLINE_FUNCTION constexpr basic_simd simd_unchecked_load(const T* ptr, simd_flags flag = simd_flag_default) { return simd_unchecked_load>(ptr, flag); } namespace Impl { template class abi_set {}; template class data_types {}; #if defined(KOKKOS_ARCH_AVX512XEON) using host_abi_set = abi_set, simd_abi::avx512_fixed_size<16>>; using data_type_set = data_types; #elif defined(KOKKOS_ARCH_AVX2) using host_abi_set = abi_set, simd_abi::avx2_fixed_size<8>>; using data_type_set = data_types; #elif defined(KOKKOS_ARCH_ARM_SVE) using host_abi_set = abi_set, simd_abi::sve_fixed_size<4>, simd_abi::sve_fixed_size<8>, simd_abi::sve_fixed_size<16>>; using data_type_set = data_types; #elif defined(KOKKOS_ARCH_ARM_NEON) using host_abi_set = abi_set, simd_abi::neon_fixed_size<4>>; using data_type_set = data_types; #else using host_abi_set = abi_set; using data_type_set = data_types; #endif using device_abi_set = abi_set; } // namespace Impl } // namespace Experimental } // namespace Kokkos #endif