Skip to content
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8df7fb0
WIP: AVX10.1
stefanatwork Jun 17, 2025
4c01b7a
Added AVX10.1 flags for gcc and clang
stefanatwork Feb 18, 2026
75d34b1
Added CPU ID feature detection of AVX 10.x and APX
stefanatwork Mar 18, 2026
5ce6720
More changes to ISA detection and selection to include new instructio…
stefanatwork Mar 18, 2026
3d2278f
More updates for AVX10/APX support
stefanatwork Mar 18, 2026
d117ca7
Added display names for new CPUs
stefanatwork Mar 19, 2026
6f646dc
Corrected CPU feature detection
stefanatwork Mar 19, 2026
a760f20
Fixed clang APX compile flags
stefanatwork Mar 19, 2026
badd856
remoted duplicate macros in isa.h
stefanatwork Mar 19, 2026
aea9b43
Updated ISA macros and BVH build selections to AVX10.x and APX isas
stefanatwork Mar 20, 2026
dc4421b
Merge branch 'master' into sw/avx10
stefanatwork Mar 23, 2026
8638fda
Consolidating AVX10 and APX into one ISA
stefanatwork Apr 20, 2026
d2123f0
simd: add AVX10.2 guarded intrinsics in AVX-512 wrappers
stefanatwork Apr 20, 2026
e132ff4
simd: fix vuint16 multiply to use mullo_epi32
stefanatwork Apr 20, 2026
76ab1d6
Merge branch 'master' into sw/avx10
stefanatwork Jun 18, 2026
06bd0e1
Fix auto detection of compiler ISA
stefanatwork Jun 18, 2026
e2e97cd
Merge branch 'master' into sw/avx10
stefanatwork Jun 24, 2026
dad07cc
Revert "simd: add AVX10.2 guarded intrinsics in AVX-512 wrappers"
stefanatwork Jun 26, 2026
515afbd
Revert "simd: fix vuint16 multiply to use mullo_epi32"
stefanatwork Jun 26, 2026
1049cd2
Requiring AVX10.2 and prior to enable APX
stefanatwork Jun 26, 2026
d4d29c7
Removed AVX10.1/10.2 from command line parser
stefanatwork Jun 26, 2026
bcf9792
Gate AVX10 detection on 512-bit vector support
stefanatwork Jun 26, 2026
3a35c97
Removed reference to unreleased product
stefanatwork Jun 26, 2026
2a50980
Fixed a comment
stefanatwork Jun 26, 2026
6721a6a
Removed superfluous guard macro
stefanatwork Jun 26, 2026
d5b7801
Workaround for gcc code creation bug in apx
stefanatwork Jun 29, 2026
15f5a63
Support for APX in MSVC
stefanatwork Jun 29, 2026
fc06c0f
Fixed preprocesor macros for AVX10 to work across clang,gcc and MSVC
stefanatwork Jun 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ ENDIF()
IF (EMBREE_ARM)
SET_PROPERTY(CACHE EMBREE_MAX_ISA PROPERTY STRINGS NONE NEON NEON2X)
ELSE()
SET_PROPERTY(CACHE EMBREE_MAX_ISA PROPERTY STRINGS NONE SSE2 SSE4.2 AVX AVX2 AVX512 DEFAULT)
SET_PROPERTY(CACHE EMBREE_MAX_ISA PROPERTY STRINGS NONE SSE2 SSE4.2 AVX AVX2 AVX512 APX DEFAULT)
ENDIF()

IF (EMBREE_MAX_ISA STREQUAL "NONE")
Expand All @@ -380,18 +380,21 @@ IF (EMBREE_MAX_ISA STREQUAL "NONE")
OPTION(EMBREE_ISA_NEON2X "Enables NEON ISA double pumped." OFF)
ENDIF()
ELSE()
TRY_COMPILE(COMPILER_SUPPORTS_AVX "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_AVX})
TRY_COMPILE(COMPILER_SUPPORTS_AVX2 "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_AVX2})
TRY_COMPILE(COMPILER_SUPPORTS_AVX512 "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_AVX512})
TRY_COMPILE(COMPILER_SUPPORTS_AVX "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_AVX})
TRY_COMPILE(COMPILER_SUPPORTS_AVX2 "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_AVX2})
TRY_COMPILE(COMPILER_SUPPORTS_AVX512 "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_AVX512})
TRY_COMPILE(COMPILER_SUPPORTS_APX "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_APX})

OPTION(EMBREE_ISA_SSE2 "Enables SSE2 ISA." ON)
OPTION(EMBREE_ISA_SSE42 "Enables SSE4.2 ISA." ON)
OPTION(EMBREE_ISA_AVX "Enables AVX ISA." ${COMPILER_SUPPORTS_AVX})
OPTION(EMBREE_ISA_AVX2 "Enables AVX2 ISA." ${COMPILER_SUPPORTS_AVX2})
IF (APPLE)
OPTION(EMBREE_ISA_AVX512 "Enables AVX512 ISA." OFF)
OPTION(EMBREE_ISA_APX "Enables APX ISA." OFF)
ELSE()
OPTION(EMBREE_ISA_AVX512 "Enables AVX512 ISA." ${COMPILER_SUPPORTS_AVX512})
OPTION(EMBREE_ISA_APX "Enables APX ISA." ${COMPILER_SUPPORTS_APX})
ENDIF()
# Don't use OPTION, but still set them to OFF, so that embree-config.cmake is consisten with its definitions
SET(EMBREE_ISA_NEON OFF)
Expand All @@ -406,13 +409,15 @@ ELSEIF (EMBREE_MAX_ISA STREQUAL "DEFAULT")
UNSET(EMBREE_ISA_AVX CACHE)
UNSET(EMBREE_ISA_AVX2 CACHE)
UNSET(EMBREE_ISA_AVX512 CACHE)
UNSET(EMBREE_ISA_APX CACHE)
SET(EMBREE_ISA_NEON OFF)
SET(EMBREE_ISA_NEON2X OFF)
SET(EMBREE_ISA_SSE2 OFF)
SET(EMBREE_ISA_SSE42 OFF)
SET(EMBREE_ISA_AVX OFF)
SET(EMBREE_ISA_AVX2 OFF)
SET(EMBREE_ISA_AVX512 OFF)
SET(EMBREE_ISA_APX OFF)
MESSAGE(STATUS "Detecting default ISA...")
INCLUDE(check_isa_default)
CHECK_ISA_DEFAULT(EMBREE_ISA_DEFAULT)
Expand All @@ -427,6 +432,7 @@ ELSE()
UNSET(EMBREE_ISA_AVX CACHE)
UNSET(EMBREE_ISA_AVX2 CACHE)
UNSET(EMBREE_ISA_AVX512 CACHE)
UNSET(EMBREE_ISA_APX CACHE)

IF(EMBREE_MAX_ISA STREQUAL "NEON")
SET(ISA 1)
Expand All @@ -444,6 +450,8 @@ ELSE()
SET(ISA 5)
ELSEIF(EMBREE_MAX_ISA STREQUAL "AVX512SKX") # just for compatibility
SET(ISA 5)
ELSEIF(EMBREE_MAX_ISA STREQUAL "APX")
SET(ISA 6)
ELSE()
MESSAGE(FATAL_ERROR "Unsupported ISA specified: " ${EMBREE_MAX_ISA})
ENDIF()
Expand All @@ -455,6 +463,7 @@ ELSE()
SET(EMBREE_ISA_AVX OFF)
SET(EMBREE_ISA_AVX2 OFF)
SET(EMBREE_ISA_AVX512 OFF)
SET(EMBREE_ISA_APX OFF)

IF (EMBREE_ARM)
IF (ISA GREATER 0)
Expand All @@ -479,6 +488,9 @@ ELSE()
IF (ISA GREATER 4)
SET(EMBREE_ISA_AVX512 ON)
ENDIF ()
IF (ISA GREATER 5)
SET(EMBREE_ISA_APX ON)
ENDIF ()
ENDIF()
ENDIF()

Expand Down Expand Up @@ -511,6 +523,9 @@ IF (APPLE AND EMBREE_STATIC_LIB)
IF (EMBREE_ISA_AVX512)
MATH(EXPR NUMISA "${NUMISA}+1")
ENDIF()
IF (EMBREE_ISA_APX)
MATH(EXPR NUMISA "${NUMISA}+1")
ENDIF()

IF (NUMISA GREATER 1)
IF (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
Expand All @@ -530,6 +545,7 @@ SET(SSE42 1)
SET(AVX 2)
SET(AVX2 3)
SET(AVX512 4)
SET(APX 5)

UNSET(FLAGS_LOWEST)
SET(ISA_LOWEST -1)
Expand Down Expand Up @@ -612,6 +628,19 @@ IF (EMBREE_ISA_AVX512)
ENDIF()
ENDIF ()

IF (EMBREE_ISA_APX)
ADD_DEFINITIONS(-DEMBREE_TARGET_APX)
IF (NOT EMBREE_ARM)
# APX support in ISPC?
# LIST(APPEND ISPC_TARGETS "")
ENDIF()
IF(NOT FLAGS_LOWEST)
SET(ISA_LOWEST ${APX})
SET(ISA_LOWEST_AVX ${APX})
SET(FLAGS_LOWEST ${FLAGS_APX})
ENDIF()
ENDIF ()

IF (ISA_LOWEST EQUAL -1)
MESSAGE(FATAL_ERROR "You have to enable at least one ISA!")
ENDIF()
Expand Down
5 changes: 4 additions & 1 deletion common/cmake/check_isa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
// limitations under the License. //
// ======================================================================== //

#if \
// Require APX and 10.2 if both are available, otherwise require the highest available ISA
#if defined(__APX_F__) && defined(__AVX10_2__)
char const *info_isa = "ISA" ":" "APX";
#elif \
defined(__AVX512F__) && defined(__AVX512CD__) && \
defined(__AVX512DQ__) && defined(__AVX512BW__) && defined(__AVX512VL__)
char const *info_isa = "ISA" ":" "AVX512";
Expand Down
1 change: 1 addition & 0 deletions common/cmake/clang.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ELSE ()
_SET_IF_EMPTY(FLAGS_AVX "-mavx")
_SET_IF_EMPTY(FLAGS_AVX2 "-mf16c -mavx2 -mfma -mlzcnt -mbmi -mbmi2")
_SET_IF_EMPTY(FLAGS_AVX512 "-march=skx")
_SET_IF_EMPTY(FLAGS_APX "-march=novalake")
ENDIF ()

IF (WIN32)
Expand Down
1 change: 1 addition & 0 deletions common/cmake/dpcpp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ _SET_IF_EMPTY(FLAGS_SSE42 "-msse4.2")
_SET_IF_EMPTY(FLAGS_AVX "-mavx")
_SET_IF_EMPTY(FLAGS_AVX2 "-mf16c -mavx2 -mfma -mlzcnt -mbmi -mbmi2")
_SET_IF_EMPTY(FLAGS_AVX512 "-march=skx")
_SET_IF_EMPTY(FLAGS_APX "-march=novalake")

IF (NOT WIN32)
OPTION(EMBREE_IGNORE_CMAKE_CXX_FLAGS "When enabled Embree ignores default CMAKE_CXX_FLAGS." ON)
Expand Down
5 changes: 5 additions & 0 deletions common/cmake/embree-config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SET(EMBREE_ISA_SSE42 @EMBREE_ISA_SSE42@)
SET(EMBREE_ISA_AVX @EMBREE_ISA_AVX@)
SET(EMBREE_ISA_AVX2 @EMBREE_ISA_AVX2@)
SET(EMBREE_ISA_AVX512 @EMBREE_ISA_AVX512@)
SET(EMBREE_ISA_APX @EMBREE_ISA_APX@)
SET(EMBREE_ISA_AVX512SKX @EMBREE_ISA_AVX512@) # just for compatibility
SET(EMBREE_ISA_NEON @EMBREE_ISA_NEON@)
SET(EMBREE_ISA_NEON2X @EMBREE_ISA_NEON2X@)
Expand Down Expand Up @@ -85,6 +86,10 @@ IF (EMBREE_STATIC_LIB)
INCLUDE("${EMBREE_ROOT_DIR}/@EMBREE_CMAKEEXPORT_DIR@/embree_avx512-targets.cmake")
ENDIF()

IF (EMBREE_ISA_APX)
INCLUDE("${EMBREE_ROOT_DIR}/@EMBREE_CMAKEEXPORT_DIR@/embree_apx-targets.cmake")
ENDIF()

ENDIF()

IF (EMBREE_SYCL_SUPPORT)
Expand Down
1 change: 1 addition & 0 deletions common/cmake/gnu.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ ELSE ()
_SET_IF_EMPTY(FLAGS_AVX "-mavx")
_SET_IF_EMPTY(FLAGS_AVX2 "-mf16c -mavx2 -mfma -mlzcnt -mbmi -mbmi2")
_SET_IF_EMPTY(FLAGS_AVX512 "-march=skylake-avx512")
_SET_IF_EMPTY(FLAGS_APX "-march=novalake")
ENDIF ()

OPTION(EMBREE_IGNORE_CMAKE_CXX_FLAGS "When enabled Embree ignores default CMAKE_CXX_FLAGS." ON)
Expand Down
1 change: 1 addition & 0 deletions common/cmake/msvc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ SET(FLAGS_SSE42 "${FLAGS_SSE2} /D__SSE3__ /D__SSSE3__ /D__SSE4_1__ /D__SSE4_2__"
SET(FLAGS_AVX "${FLAGS_SSE42} /arch:AVX")
SET(FLAGS_AVX2 "${FLAGS_SSE42} /arch:AVX2")
SET(FLAGS_AVX512 "${FLAGS_AVX2} /arch:AVX512")
SET(FLAGS_APX "${FLAGS_AVX512} /arch:AVX10.2")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not sufficient one also needs to enable APX separately. Also we want 512-bit AVX10.2 not sure what that default actually does, but /arch:AVX10.2/512 should be used here, and /arch:APX


SET(COMMON_CXX_FLAGS "")
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /EHsc") # catch C++ exceptions only and extern "C" functions never throw a C++ exception
Expand Down
31 changes: 31 additions & 0 deletions common/simd/vboold4_avx512.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,29 @@ namespace embree
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX10_2__)
__forceinline vboold4 operator !(const vboold4& a) { return _kandn_mask8(a, (__mmask8)0xf); }
#else
__forceinline vboold4 operator !(const vboold4& a) { return _mm512_kandn(a, 0xf); }
#endif

////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX10_2__)
__forceinline vboold4 operator &(const vboold4& a, const vboold4& b) { return _kand_mask8(a, b); }
__forceinline vboold4 operator |(const vboold4& a, const vboold4& b) { return _kor_mask8(a, b); }
__forceinline vboold4 operator ^(const vboold4& a, const vboold4& b) { return _kxor_mask8(a, b); }

__forceinline vboold4 andn(const vboold4& a, const vboold4& b) { return _kandn_mask8(b, a); }
#else
__forceinline vboold4 operator &(const vboold4& a, const vboold4& b) { return _mm512_kand(a, b); }
__forceinline vboold4 operator |(const vboold4& a, const vboold4& b) { return _mm512_kor(a, b); }
__forceinline vboold4 operator ^(const vboold4& a, const vboold4& b) { return _mm512_kxor(a, b); }

__forceinline vboold4 andn(const vboold4& a, const vboold4& b) { return _mm512_kandn(b, a); }
#endif

////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
Expand All @@ -97,26 +109,45 @@ namespace embree
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX10_2__)
__forceinline vboold4 operator !=(const vboold4& a, const vboold4& b) { return _kxor_mask8(a, b); }
__forceinline vboold4 operator ==(const vboold4& a, const vboold4& b) { return _kand_mask8(_kxnor_mask8(a, b), (__mmask8)0xf); }

__forceinline vboold4 select(const vboold4& s, const vboold4& a, const vboold4& b) {
return _kor_mask8(_kand_mask8(s, a), _kandn_mask8(s, b));
}
#else
__forceinline vboold4 operator !=(const vboold4& a, const vboold4& b) { return _mm512_kxor(a, b); }
__forceinline vboold4 operator ==(const vboold4& a, const vboold4& b) { return _mm512_kand(_mm512_kxnor(a, b), 0xf); }

__forceinline vboold4 select(const vboold4& s, const vboold4& a, const vboold4& b) {
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
}
#endif

////////////////////////////////////////////////////////////////////////////////
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX10_2__)
__forceinline int all (const vboold4& a) { return a.v == 0xf; }
__forceinline int any (const vboold4& a) { return _kortestz_mask8_u8(a, a) == 0; }
__forceinline int none(const vboold4& a) { return _kortestz_mask8_u8(a, a) != 0; }
#else
__forceinline int all (const vboold4& a) { return a.v == 0xf; }
__forceinline int any (const vboold4& a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboold4& a) { return _mm512_kortestz(a, a) != 0; }
#endif

__forceinline int all (const vboold4& valid, const vboold4& b) { return all((!valid) | b); }
__forceinline int any (const vboold4& valid, const vboold4& b) { return any(valid & b); }
__forceinline int none(const vboold4& valid, const vboold4& b) { return none(valid & b); }

#if defined(__AVX10_2__)
__forceinline size_t movemask(const vboold4& a) { return _cvtmask8_u32(a); }
#else
__forceinline size_t movemask(const vboold4& a) { return _mm512_kmov(a); }
#endif
__forceinline size_t popcnt (const vboold4& a) { return popcnt(a.v); }

////////////////////////////////////////////////////////////////////////////////
Expand Down
33 changes: 32 additions & 1 deletion common/simd/vboold8_avx512.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,29 @@ namespace embree
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX10_2__)
__forceinline vboold8 operator !(const vboold8& a) { return _knot_mask8(a); }
#else
__forceinline vboold8 operator !(const vboold8& a) { return _mm512_knot(a); }
#endif

////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX10_2__)
__forceinline vboold8 operator &(const vboold8& a, const vboold8& b) { return _kand_mask8(a, b); }
__forceinline vboold8 operator |(const vboold8& a, const vboold8& b) { return _kor_mask8(a, b); }
__forceinline vboold8 operator ^(const vboold8& a, const vboold8& b) { return _kxor_mask8(a, b); }

__forceinline vboold8 andn(const vboold8& a, const vboold8& b) { return _kandn_mask8(b, a); }
#else
__forceinline vboold8 operator &(const vboold8& a, const vboold8& b) { return _mm512_kand(a, b); }
__forceinline vboold8 operator |(const vboold8& a, const vboold8& b) { return _mm512_kor(a, b); }
__forceinline vboold8 operator ^(const vboold8& a, const vboold8& b) { return _mm512_kxor(a, b); }

__forceinline vboold8 andn(const vboold8& a, const vboold8& b) { return _mm512_kandn(b, a); }
#endif

////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
Expand All @@ -92,26 +104,45 @@ namespace embree
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX10_2__)
__forceinline vboold8 operator !=(const vboold8& a, const vboold8& b) { return _kxor_mask8(a, b); }
__forceinline vboold8 operator ==(const vboold8& a, const vboold8& b) { return _kxnor_mask8(a, b); }

__forceinline vboold8 select(const vboold8& s, const vboold8& a, const vboold8& b) {
return _kor_mask8(_kand_mask8(s, a), _kandn_mask8(s, b));
}
#else
__forceinline vboold8 operator !=(const vboold8& a, const vboold8& b) { return _mm512_kxor(a, b); }
__forceinline vboold8 operator ==(const vboold8& a, const vboold8& b) { return _mm512_kxnor(a, b); }

__forceinline vboold8 select(const vboold8& s, const vboold8& a, const vboold8& b) {
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
}
#endif

////////////////////////////////////////////////////////////////////////////////
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX10_2__)
__forceinline int all (const vboold8& a) { return a.v == 0xff; }
__forceinline int any (const vboold8& a) { return _kortestz_mask8_u8(a, a) == 0; }
__forceinline int none(const vboold8& a) { return _kortestz_mask8_u8(a, a) != 0; }
#else
__forceinline int all (const vboold8& a) { return a.v == 0xff; }
__forceinline int any (const vboold8& a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboold8& a) { return _mm512_kortestz(a, a) != 0; }
#endif

__forceinline int all (const vboold8& valid, const vboold8& b) { return all((!valid) | b); }
__forceinline int any (const vboold8& valid, const vboold8& b) { return any(valid & b); }
__forceinline int none(const vboold8& valid, const vboold8& b) { return none(valid & b); }

#if defined(__AVX10_2__)
__forceinline size_t movemask(const vboold8& a) { return _cvtmask8_u32(a); }
#else
__forceinline size_t movemask(const vboold8& a) { return _mm512_kmov(a); }
#endif
__forceinline size_t popcnt (const vboold8& a) { return popcnt(a.v); }

////////////////////////////////////////////////////////////////////////////////
Expand Down
Loading
Loading