#include "hwy/base.h"
#include "hwy/detect_compiler_arch.h"
#include "hwy/detect_targets.h"
#include "hwy/highway_export.h"
#include "hwy/targets.h"
#if HWY_CXX_LANG < 201703L
#define HWY_DISPATCH_MAP …
#else
#define HWY_DISPATCH_MAP …
#endif
#ifndef HWY_HIGHWAY_INCLUDED
#define HWY_HIGHWAY_INCLUDED
namespace hwy {
#define HWY_FULL1(T) …
#define HWY_FULL2(T, LMUL) …
#define HWY_3TH_ARG(arg1, arg2, arg3, ...) …
#define HWY_FULL_RECOMPOSER(args_with_paren) …
#define HWY_CHOOSE_FULL(...) …
#define HWY_FULL(...) …
#define HWY_CAPPED(T, MAX_N) …
#ifndef HWY_ONCE
#define HWY_ONCE …
#endif
#if HWY_STATIC_TARGET == HWY_SCALAR
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_EMU128
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_RVV
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_WASM_EMU256
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_WASM
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_NEON_WITHOUT_AES
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_NEON
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_NEON_BF16
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_SVE
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_SVE2
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_SVE_256
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_SVE2_128
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_PPC8
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_PPC9
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_PPC10
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_Z14
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_Z15
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_SSE2
#define HWY_STATIC_DISPATCH(FUNC_NAME) …
#elif HWY_STATIC_TARGET == HWY_SSSE3
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_SSE4
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_AVX2
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_AVX3
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_AVX3_DL
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_AVX3_ZEN4
#define HWY_STATIC_DISPATCH …
#elif HWY_STATIC_TARGET == HWY_AVX3_SPR
#define HWY_STATIC_DISPATCH …
#endif
#if HWY_TARGETS & HWY_EMU128
#define HWY_CHOOSE_FALLBACK …
#elif HWY_TARGETS & HWY_SCALAR
#define HWY_CHOOSE_FALLBACK …
#else
#define HWY_CHOOSE_FALLBACK(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_WASM_EMU256
#define HWY_CHOOSE_WASM_EMU256 …
#else
#define HWY_CHOOSE_WASM_EMU256(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_WASM
#define HWY_CHOOSE_WASM …
#else
#define HWY_CHOOSE_WASM(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_RVV
#define HWY_CHOOSE_RVV …
#else
#define HWY_CHOOSE_RVV(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_NEON_WITHOUT_AES
#define HWY_CHOOSE_NEON_WITHOUT_AES …
#else
#define HWY_CHOOSE_NEON_WITHOUT_AES(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_NEON
#define HWY_CHOOSE_NEON …
#else
#define HWY_CHOOSE_NEON(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_NEON_BF16
#define HWY_CHOOSE_NEON_BF16 …
#else
#define HWY_CHOOSE_NEON_BF16(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_SVE
#define HWY_CHOOSE_SVE …
#else
#define HWY_CHOOSE_SVE(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_SVE2
#define HWY_CHOOSE_SVE2 …
#else
#define HWY_CHOOSE_SVE2(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_SVE_256
#define HWY_CHOOSE_SVE_256 …
#else
#define HWY_CHOOSE_SVE_256(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_SVE2_128
#define HWY_CHOOSE_SVE2_128 …
#else
#define HWY_CHOOSE_SVE2_128(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_PPC8
#define HWY_CHOOSE_PPC8 …
#else
#define HWY_CHOOSE_PPC8(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_PPC9
#define HWY_CHOOSE_PPC9 …
#else
#define HWY_CHOOSE_PPC9(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_PPC10
#define HWY_CHOOSE_PPC10 …
#else
#define HWY_CHOOSE_PPC10(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_Z14
#define HWY_CHOOSE_Z14 …
#else
#define HWY_CHOOSE_Z14(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_Z15
#define HWY_CHOOSE_Z15 …
#else
#define HWY_CHOOSE_Z15(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_SSE2
#define HWY_CHOOSE_SSE2(FUNC_NAME) …
#else
#define HWY_CHOOSE_SSE2 …
#endif
#if HWY_TARGETS & HWY_SSSE3
#define HWY_CHOOSE_SSSE3(FUNC_NAME) …
#else
#define HWY_CHOOSE_SSSE3 …
#endif
#if HWY_TARGETS & HWY_SSE4
#define HWY_CHOOSE_SSE4(FUNC_NAME) …
#else
#define HWY_CHOOSE_SSE4 …
#endif
#if HWY_TARGETS & HWY_AVX2
#define HWY_CHOOSE_AVX2(FUNC_NAME) …
#else
#define HWY_CHOOSE_AVX2 …
#endif
#if HWY_TARGETS & HWY_AVX3
#define HWY_CHOOSE_AVX3(FUNC_NAME) …
#else
#define HWY_CHOOSE_AVX3 …
#endif
#if HWY_TARGETS & HWY_AVX3_DL
#define HWY_CHOOSE_AVX3_DL …
#else
#define HWY_CHOOSE_AVX3_DL(FUNC_NAME) …
#endif
#if HWY_TARGETS & HWY_AVX3_ZEN4
#define HWY_CHOOSE_AVX3_ZEN4(FUNC_NAME) …
#else
#define HWY_CHOOSE_AVX3_ZEN4 …
#endif
#if HWY_TARGETS & HWY_AVX3_SPR
#define HWY_CHOOSE_AVX3_SPR(FUNC_NAME) …
#else
#define HWY_CHOOSE_AVX3_SPR …
#endif
#if (HWY_COMPILER_MSVC && HWY_COMPILER_MSVC < 1915) || \
(HWY_COMPILER_GCC_ACTUAL && HWY_COMPILER_GCC_ACTUAL < 700)
#define HWY_DISPATCH_WORKAROUND …
#else
#define HWY_DISPATCH_WORKAROUND …
#endif
#if HWY_DISPATCH_MAP
struct AllExports {
template <class FuncPtr, class ExportsKey, uint64_t kHash>
static const FuncPtr*& GetRefToExportsPtr() {
static const FuncPtr* s_exports = nullptr;
return s_exports;
}
};
#endif
template <typename RetType, typename... Args>
struct FunctionCache { … };
template <typename RetType, typename... Args>
FunctionCache<RetType, Args...> DeduceFunctionCache(RetType (*)(Args...)) { … }
#define HWY_DISPATCH_TABLE(FUNC_NAME) …
#if HWY_IDE || ((HWY_TARGETS & (HWY_TARGETS - 1)) == 0)
#define HWY_EXPORT_T …
#define HWY_DYNAMIC_DISPATCH_T …
#define HWY_EXPORT …
#define HWY_DYNAMIC_POINTER …
#define HWY_DYNAMIC_DISPATCH …
#else
#if HWY_DISPATCH_MAP
static constexpr uint64_t FNV(const char* name) {
return *name ? static_cast<uint64_t>(static_cast<uint8_t>(*name)) ^
(0x100000001b3ULL * FNV(name + 1))
: 0xcbf29ce484222325ULL;
}
template <uint64_t kHash>
struct AddExport {
template <class ExportsKey, class FuncPtr>
AddExport(ExportsKey , const char* table_name,
const FuncPtr* table) {
using FuncCache = decltype(DeduceFunctionCache(hwy::DeclVal<FuncPtr>()));
static_assert(
hwy::IsSame<RemoveCvRef<FuncPtr>, typename FuncCache::FuncPtr>(),
"FuncPtr should be same type as FuncCache::FuncPtr");
const FuncPtr*& exports_ptr = AllExports::template GetRefToExportsPtr<
RemoveCvRef<FuncPtr>, RemoveCvRef<ExportsKey>, kHash>();
if (exports_ptr && exports_ptr != table) {
HWY_ABORT("Hash collision for %s, rename the function\n", table_name);
} else {
exports_ptr = table;
}
}
};
#define HWY_EXPORT_T …
#if HWY_DISPATCH_WORKAROUND
#define HWY_EXPORT …
#else
#define HWY_EXPORT …
#endif
#else
#define HWY_EXPORT_T(TABLE_NAME, FUNC_NAME) …
#define HWY_EXPORT(FUNC_NAME) …
#endif
#define HWY_DYNAMIC_POINTER(FUNC_NAME) …
#define HWY_DYNAMIC_DISPATCH(FUNC_NAME) …
#define HWY_DYNAMIC_DISPATCH_T(TABLE_NAME) …
#endif
#define HWY_DISPATCH_TABLE_T() …
#define HWY_EXPORT_AND_DYNAMIC_DISPATCH_T(FUNC_NAME) …
#define HWY_CAP_INTEGER64 …
#define HWY_CAP_FLOAT16 …
#define HWY_CAP_FLOAT64 …
}
#endif
#if defined(HWY_HIGHWAY_PER_TARGET) == defined(HWY_TARGET_TOGGLE)
#ifdef HWY_HIGHWAY_PER_TARGET
#undef HWY_HIGHWAY_PER_TARGET
#else
#define HWY_HIGHWAY_PER_TARGET
#endif
#if HWY_TARGET == HWY_SSE2 || HWY_TARGET == HWY_SSSE3 || HWY_TARGET == HWY_SSE4
#include "hwy/ops/x86_128-inl.h"
#elif HWY_TARGET == HWY_AVX2
#include "hwy/ops/x86_256-inl.h"
#elif HWY_TARGET == HWY_AVX3 || HWY_TARGET == HWY_AVX3_DL || \
HWY_TARGET == HWY_AVX3_ZEN4 || HWY_TARGET == HWY_AVX3_SPR
#include "hwy/ops/x86_512-inl.h"
#elif HWY_TARGET == HWY_Z14 || HWY_TARGET == HWY_Z15 || \
(HWY_TARGET & HWY_ALL_PPC)
#include "hwy/ops/ppc_vsx-inl.h"
#elif HWY_TARGET & HWY_ALL_NEON
#include "hwy/ops/arm_neon-inl.h"
#elif HWY_TARGET & HWY_ALL_SVE
#include "hwy/ops/arm_sve-inl.h"
#elif HWY_TARGET == HWY_WASM_EMU256
#include "hwy/ops/wasm_256-inl.h"
#elif HWY_TARGET == HWY_WASM
#include "hwy/ops/wasm_128-inl.h"
#elif HWY_TARGET == HWY_RVV
#include "hwy/ops/rvv-inl.h"
#elif HWY_TARGET == HWY_EMU128
#include "hwy/ops/emu128-inl.h"
#elif HWY_TARGET == HWY_SCALAR
#include "hwy/ops/scalar-inl.h"
#else
#pragma message("HWY_TARGET does not match any known target")
#endif
#include "hwy/ops/generic_ops-inl.h"
#endif