272 lines
13 KiB
C++
272 lines
13 KiB
C++
|
// Copyright 2009-2020 Intel Corporation
|
||
|
// SPDX-License-Identifier: Apache-2.0
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include "../../common/sys/platform.h"
|
||
|
#include "../../common/sys/sysinfo.h"
|
||
|
|
||
|
namespace embree
|
||
|
{
|
||
|
#define DEFINE_SYMBOL2(type,name) \
|
||
|
typedef type (*name##Func)(); \
|
||
|
name##Func name;
|
||
|
|
||
|
#define DECLARE_SYMBOL2(type,name) \
|
||
|
namespace sse2 { extern type name(); } \
|
||
|
namespace sse42 { extern type name(); } \
|
||
|
namespace avx { extern type name(); } \
|
||
|
namespace avx2 { extern type name(); } \
|
||
|
namespace avx512knl { extern type name(); } \
|
||
|
namespace avx512skx { extern type name(); } \
|
||
|
void name##_error2() { throw_RTCError(RTC_ERROR_UNKNOWN,"internal error in ISA selection for " TOSTRING(name)); } \
|
||
|
type name##_error() { return type(name##_error2); } \
|
||
|
type name##_zero() { return type(nullptr); }
|
||
|
|
||
|
#define DECLARE_ISA_FUNCTION(type,symbol,args) \
|
||
|
namespace sse2 { extern type symbol(args); } \
|
||
|
namespace sse42 { extern type symbol(args); } \
|
||
|
namespace avx { extern type symbol(args); } \
|
||
|
namespace avx2 { extern type symbol(args); } \
|
||
|
namespace avx512knl { extern type symbol(args); } \
|
||
|
namespace avx512skx { extern type symbol(args); } \
|
||
|
inline type symbol##_error(args) { throw_RTCError(RTC_ERROR_UNSUPPORTED_CPU,"function " TOSTRING(symbol) " not supported by your CPU"); } \
|
||
|
typedef type (*symbol##Ty)(args); \
|
||
|
|
||
|
#define DEFINE_ISA_FUNCTION(type,symbol,args) \
|
||
|
typedef type (*symbol##Func)(args); \
|
||
|
symbol##Func symbol;
|
||
|
|
||
|
#define ZERO_SYMBOL(features,intersector) \
|
||
|
intersector = intersector##_zero;
|
||
|
|
||
|
#define INIT_SYMBOL(features,intersector) \
|
||
|
intersector = decltype(intersector)(intersector##_error);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT(features,intersector) \
|
||
|
intersector = isa::intersector;
|
||
|
|
||
|
#if defined(__SSE__) || defined(__ARM_NEON)
|
||
|
#if !defined(EMBREE_TARGET_SIMD4)
|
||
|
#define EMBREE_TARGET_SIMD4
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#if defined(EMBREE_TARGET_SSE42)
|
||
|
#define SELECT_SYMBOL_SSE42(features,intersector) \
|
||
|
if ((features & SSE42) == SSE42) intersector = sse42::intersector;
|
||
|
#else
|
||
|
#define SELECT_SYMBOL_SSE42(features,intersector)
|
||
|
#endif
|
||
|
|
||
|
#if defined(EMBREE_TARGET_AVX) || defined(__AVX__)
|
||
|
#if !defined(EMBREE_TARGET_SIMD8)
|
||
|
#define EMBREE_TARGET_SIMD8
|
||
|
#endif
|
||
|
#if defined(__AVX__) // if default ISA is >= AVX we treat AVX target as default target
|
||
|
#define SELECT_SYMBOL_AVX(features,intersector) \
|
||
|
if ((features & ISA) == ISA) intersector = isa::intersector;
|
||
|
#else
|
||
|
#define SELECT_SYMBOL_AVX(features,intersector) \
|
||
|
if ((features & AVX) == AVX) intersector = avx::intersector;
|
||
|
#endif
|
||
|
#else
|
||
|
#define SELECT_SYMBOL_AVX(features,intersector)
|
||
|
#endif
|
||
|
|
||
|
#if defined(EMBREE_TARGET_AVX2)
|
||
|
#if !defined(EMBREE_TARGET_SIMD8)
|
||
|
#define EMBREE_TARGET_SIMD8
|
||
|
#endif
|
||
|
#define SELECT_SYMBOL_AVX2(features,intersector) \
|
||
|
if ((features & AVX2) == AVX2) intersector = avx2::intersector;
|
||
|
#else
|
||
|
#define SELECT_SYMBOL_AVX2(features,intersector)
|
||
|
#endif
|
||
|
|
||
|
#if defined(EMBREE_TARGET_AVX512KNL)
|
||
|
#if !defined(EMBREE_TARGET_SIMD16)
|
||
|
#define EMBREE_TARGET_SIMD16
|
||
|
#endif
|
||
|
#define SELECT_SYMBOL_AVX512KNL(features,intersector) \
|
||
|
if ((features & AVX512KNL) == AVX512KNL) intersector = avx512knl::intersector;
|
||
|
#else
|
||
|
#define SELECT_SYMBOL_AVX512KNL(features,intersector)
|
||
|
#endif
|
||
|
|
||
|
#if defined(EMBREE_TARGET_AVX512SKX)
|
||
|
#if !defined(EMBREE_TARGET_SIMD16)
|
||
|
#define EMBREE_TARGET_SIMD16
|
||
|
#endif
|
||
|
#define SELECT_SYMBOL_AVX512SKX(features,intersector) \
|
||
|
if ((features & AVX512SKX) == AVX512SKX) intersector = avx512skx::intersector;
|
||
|
#else
|
||
|
#define SELECT_SYMBOL_AVX512SKX(features,intersector)
|
||
|
#endif
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_SSE42(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_SSE42_AVX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512SKX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_AVX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_AVX_AVX2(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL_AVX512SKX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_AVX_AVX512SKX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_AVX(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_AVX_AVX2(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_SSE42_AVX_AVX2(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_AVX_AVX512KNL_AVX512SKX(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_ZERO_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
|
||
|
ZERO_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
|
||
|
SELECT_SYMBOL_DEFAULT(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,intersector) \
|
||
|
INIT_SYMBOL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512KNL(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX512SKX(features,intersector);
|
||
|
|
||
|
#define SELECT_SYMBOL_SSE42_AVX_AVX2(features,intersector) \
|
||
|
SELECT_SYMBOL_SSE42(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX(features,intersector); \
|
||
|
SELECT_SYMBOL_AVX2(features,intersector);
|
||
|
|
||
|
struct VerifyMultiTargetLinking {
|
||
|
static __noinline int getISA(int depth = 5) {
|
||
|
if (depth == 0) return ISA;
|
||
|
else return getISA(depth-1);
|
||
|
}
|
||
|
};
|
||
|
namespace sse2 { int getISA(); };
|
||
|
namespace sse42 { int getISA(); };
|
||
|
namespace avx { int getISA(); };
|
||
|
namespace avx2 { int getISA(); };
|
||
|
namespace avx512knl { int getISA(); };
|
||
|
namespace avx512skx { int getISA(); };
|
||
|
}
|