Skip to content

Commit

Permalink
Support multi-arch compilation on OSX with CMAKE_OSX_ARCHITECTURES
Browse files Browse the repository at this point in the history
  • Loading branch information
Auburn committed Aug 7, 2024
1 parent 504e54f commit 7283f53
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 84 deletions.
45 changes: 2 additions & 43 deletions cmake/ArchDetect.cmake
Original file line number Diff line number Diff line change
@@ -1,48 +1,7 @@

function(target_architecture output_arch output_arch_ver)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
# On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set
# First let's normalize the order of the values

# Note that it's not possible to compile PowerPC applications if you are using
# the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
# disable it by default
# See this page for more information:
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4

# Architecture defaults to x86 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
# On OS X 10.6+ the default is x86_64 if the CPU supports it, x86 otherwise.

foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
set(osx_arch_ppc TRUE)
elseif("${osx_arch}" STREQUAL "i386")
set(osx_arch_x86 TRUE)
elseif("${osx_arch}" STREQUAL "x86_64")
set(osx_arch_x86_64 TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
else()
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
endif()
endforeach()

# Now add all the architectures in our normalized order
if(osx_arch_ppc)
list(APPEND ARCH ppc)
endif()

if(osx_arch_x86)
list(APPEND ARCH x86)
endif()

if(osx_arch_x86_64)
list(APPEND ARCH x86_64)
endif()

if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
endif()
set(ARCH "${CMAKE_OSX_ARCHITECTURES}")
set(ARCH_VER unknown)
else()

# Detect the architecture in a rather creative way...
Expand Down
8 changes: 1 addition & 7 deletions cmake/ArchDetect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@
#define TO_LITERAL_( string ) #string
#define TO_LITERAL( string ) TO_LITERAL_( string )

#ifdef TEST_FEATURE_SET_ACTIVE

#if FASTSIMD_FEATURE_VALUE( TEST_FEATURE_SET_ACTIVE ) > 0
static_assert( 0, "TEST_FEATURE_SET_ACTIVE_SUCCESS" );
#endif

#else
#if !defined( TEST_FEATURE_SET_ACTIVE ) || FASTSIMD_FEATURE_VALUE( TEST_FEATURE_SET_ACTIVE ) > 0

static_assert( 0, "FASTSIMD_ARCH<" TO_LITERAL( FASTSIMD_ARCH_NAME() ) ">" );

Expand Down
52 changes: 37 additions & 15 deletions dispatch/cmake/ClassSIMD.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -120,26 +120,48 @@ function(fastsimd_create_dispatch_library simd_library_name)

foreach(simd_inl ${fastsimd_create_dispatch_library_SOURCES})
foreach(feature_set ${fastsimd_create_dispatch_library_FEATURE_SETS})
try_run(
run_result_unused
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${FastSIMD_SOURCE_DIR}/cmake/ArchDetect.cpp"
COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
COMPILE_DEFINITIONS -DTEST_FEATURE_SET_ACTIVE=${feature_set}
)

if ("${COMPILE_OUTPUT}" MATCHES "TEST_FEATURE_SET_ACTIVE_SUCCESS")
list(APPEND feature_set_list "FastSIMD::FeatureSet::${feature_set}")
list(APPEND feature_set_list_debug "${feature_set}")
fastsimd_add_feature_set_source(${simd_inl} ${feature_set} ${fastsimd_create_dispatch_library_RELAXED})
if(DEFINED CMAKE_OSX_ARCHITECTURES AND NOT "${feature_set}" STREQUAL "SCALAR")
# Loop through OSX arches and test compile on each separately
foreach(CMAKE_OSX_ARCHITECTURES ${CMAKE_OSX_ARCHITECTURES})
#message(STATUS "${CMAKE_OSX_ARCHITECTURES} ${feature_set}")
try_compile(
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${FastSIMD_SOURCE_DIR}/cmake/ArchDetect.cpp"
OUTPUT_VARIABLE COMPILE_OUTPUT
COMPILE_DEFINITIONS -DTEST_FEATURE_SET_ACTIVE=${feature_set}
)

#message(STATUS ${COMPILE_OUTPUT})
if ("${COMPILE_OUTPUT}" MATCHES "FASTSIMD_ARCH<([^\"=]+)=([^>]+)")
set(feature_arch_detect "FASTSIMD_CURRENT_ARCH_IS( ${CMAKE_MATCH_1} )")
fastsimd_add_feature_set_source(${simd_inl} ${feature_set} ${fastsimd_create_dispatch_library_RELAXED})
string(APPEND feature_set_list "#if ${feature_arch_detect}\n,FastSIMD::FeatureSet::${feature_set}\n#endif\n" )
list(APPEND feature_set_list_debug "${feature_set}")
break()
endif()
endforeach()
else()
try_compile(
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${FastSIMD_SOURCE_DIR}/cmake/ArchDetect.cpp"
OUTPUT_VARIABLE COMPILE_OUTPUT
COMPILE_DEFINITIONS -DTEST_FEATURE_SET_ACTIVE=${feature_set}
)

#message(STATUS ${COMPILE_OUTPUT})
if ("${COMPILE_OUTPUT}" MATCHES "FASTSIMD_ARCH<([^\"=]+)=([^>]+)")
set(feature_arch_detect "1")
fastsimd_add_feature_set_source(${simd_inl} ${feature_set} ${fastsimd_create_dispatch_library_RELAXED})
string(APPEND feature_set_list ",FastSIMD::FeatureSet::${feature_set}\n" )
list(APPEND feature_set_list_debug "${feature_set}")
endif()
endif()
endforeach()
endforeach()

# Create array of compiled feature sets for lookup in FastSIMD::New()
string(REPLACE ";" ",\n" feature_set_list "${feature_set_list}")
configure_file("${FastSIMD_SOURCE_DIR}/dispatch/cmake/simd_lib_config.h.in" "${simd_library_source_dir}/include/FastSIMD/${simd_library_name}_config.h")

message(STATUS "FastSIMD: Created dispatch library \"${simd_library_name}\" with Feature Sets${relaxed_log_msg}: ${feature_set_list_debug}")
Expand Down
3 changes: 3 additions & 0 deletions dispatch/cmake/feature_set_source.cpp.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#define FASTSIMD_MAX_FEATURE_SET ${feature_set}
#include <FastSIMD/Utility/ArchDetect.h>

#if ${feature_arch_detect}
#include <FastSIMD/${simd_library_name}_config.h>

#include "${FastSIMD_SOURCE_DIR}/dispatch/impl/DispatchClassImpl.h"
#include "${simd_inl_full}"
#endif
2 changes: 1 addition & 1 deletion dispatch/cmake/simd_lib_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace FastSIMD
{
namespace ${simd_library_name}
{
using CompiledFeatureSets = FeatureSetList<
using CompiledFeatureSets = FeatureSetList<0
${feature_set_list}>;
}
}
4 changes: 2 additions & 2 deletions examples/dispatch_library/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

fastsimd_create_dispatch_library(example_simd SOURCES "example.inl")
fastsimd_create_dispatch_library(simd_example_dispatch_library SOURCES "example.inl")

add_executable(example_dispatch_library "main.cpp")
target_link_libraries(example_dispatch_library PRIVATE FastSIMD example_simd)
target_link_libraries(example_dispatch_library PRIVATE FastSIMD simd_example_dispatch_library)
23 changes: 15 additions & 8 deletions include/FastSIMD/ToolSet/Generic/Functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ namespace FS
}
else
{
return Register<T, N, SIMD> { SelectHighBit( mask.v0, ifTrue.v0, ifFalse.v0 ), SelectHighBit( mask.v1, ifTrue.v1, ifFalse.v1 ) };
return Register<T, N, SIMD>{ SelectHighBit( mask.v0, ifTrue.v0, ifFalse.v0 ), SelectHighBit( mask.v1, ifTrue.v1, ifFalse.v1 ) };
}
}

Expand All @@ -220,7 +220,7 @@ namespace FS
}
else
{
return Register<T, N, SIMD> { Increment( a.v0 ), Increment( a.v1 ) };
return Register<T, N, SIMD>{ Increment( a.v0 ), Increment( a.v1 ) };
}
}

Expand All @@ -234,7 +234,7 @@ namespace FS
}
else
{
return Register<T, N, SIMD> { Decrement( a.v0 ), Decrement( a.v1 ) };
return Register<T, N, SIMD>{ Decrement( a.v0 ), Decrement( a.v1 ) };
}
}

Expand Down Expand Up @@ -290,7 +290,7 @@ namespace FS
}
else
{
return Register<T, N, SIMD> { FNMulSub( a.v0, b.v0, c.v0 ), FNMulSub( a.v1, b.v1, c.v1 ) };
return Register<T, N, SIMD>{ FNMulSub( a.v0, b.v0, c.v0 ), FNMulSub( a.v1, b.v1, c.v1 ) };
}
}

Expand All @@ -304,7 +304,7 @@ namespace FS
}
else
{
return Register<T, N, SIMD> { BitwiseAndNot( a.v0, b.v0 ), BitwiseAndNot( a.v1, b.v1 ) };
return Register<T, N, SIMD>{ BitwiseAndNot( a.v0, b.v0 ), BitwiseAndNot( a.v1, b.v1 ) };
}
}

Expand Down Expand Up @@ -429,7 +429,7 @@ namespace FS
}
else
{
return Register<T, N, SIMD> { MaskedMul( mask.v0, a.v0, b.v0 ), MaskedMul( mask.v1, a.v1, b.v1 ) };
return Register<T, N, SIMD>{ MaskedMul( mask.v0, a.v0, b.v0 ), MaskedMul( mask.v1, a.v1, b.v1 ) };
}
}

Expand All @@ -442,7 +442,7 @@ namespace FS
}
else
{
return Register<T, N, SIMD> { InvMaskedMul( mask.v0, a.v0, b.v0 ), InvMaskedMul( mask.v1, a.v1, b.v1 ) };
return Register<T, N, SIMD>{ InvMaskedMul( mask.v0, a.v0, b.v0 ), InvMaskedMul( mask.v1, a.v1, b.v1 ) };
}
}

Expand Down Expand Up @@ -517,7 +517,14 @@ namespace FS
template<typename T, std::size_t N, FastSIMD::FeatureSet SIMD>
FS_FORCEINLINE Register<T, N, SIMD> Sin( const Register<T, N, SIMD>& a )
{
return Cos( Register<T, N, SIMD>( (T)1.57079632679 ) - a );
if constexpr( IsNativeV<Register<T, N, SIMD>> )
{
return Cos( Register<T, N, SIMD>( (T)1.57079632679 ) - a );
}
else
{
return Register<T, N, SIMD>{ Sin( a.v0 ), Sin( a.v1 ) };
}
}

template<std::size_t N, FastSIMD::FeatureSet SIMD>
Expand Down
10 changes: 5 additions & 5 deletions include/FastSIMD/Utility/FeatureSetList.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

namespace FastSIMD
{
template<FeatureSet...>
template<int, FeatureSet...>
struct FeatureSetList;

template<FeatureSet HEAD>
struct FeatureSetList<HEAD>
struct FeatureSetList<0, HEAD>
{
static constexpr FeatureSet AsArray[] = { HEAD };
static constexpr FeatureSet Minimum = HEAD;
Expand All @@ -18,14 +18,14 @@ namespace FastSIMD
};

template<FeatureSet HEAD, FeatureSet... TAIL>
struct FeatureSetList<HEAD, TAIL...>
struct FeatureSetList<0, HEAD, TAIL...>
{
static constexpr FeatureSet AsArray[] = { HEAD, TAIL... };
static constexpr FeatureSet Minimum = HEAD;
static constexpr FeatureSet Maximum = FeatureSetList<TAIL...>::Maximum;
static constexpr FeatureSet Maximum = FeatureSetList<0, TAIL...>::Maximum;

template<FeatureSet L>
static constexpr FeatureSet NextAfter = (L == HEAD) ? FeatureSetList<TAIL...>::Minimum : FeatureSetList<TAIL...>::template NextAfter<L>;
static constexpr FeatureSet NextAfter = (L == HEAD) ? FeatureSetList<0, TAIL...>::Minimum : FeatureSetList<0, TAIL...>::template NextAfter<L>;
};

}
6 changes: 3 additions & 3 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

fastsimd_create_dispatch_library(test_simd SOURCES "test.inl" FEATURE_SETS SCALAR SSE2 SSE41 AVX2 AVX512 NEON AARCH64 WASM)
fastsimd_create_dispatch_library(test_simd_relaxed RELAXED SOURCES "test.inl" FEATURE_SETS SCALAR SSE2 SSE41 AVX2 AVX512 NEON AARCH64 WASM)
fastsimd_create_dispatch_library(simd_test SOURCES "test.inl" FEATURE_SETS SCALAR SSE2 SSE41 AVX2 AVX512 NEON AARCH64 WASM)
fastsimd_create_dispatch_library(simd_test_relaxed RELAXED SOURCES "test.inl" FEATURE_SETS SCALAR SSE2 SSE41 AVX2 AVX512 NEON AARCH64 WASM)

add_executable(test "test.cpp")
target_link_libraries(test PRIVATE FastSIMD test_simd test_simd_relaxed)
target_link_libraries(test PRIVATE FastSIMD simd_test simd_test_relaxed)

if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
set(CMAKE_EXECUTABLE_SUFFIX ".html")
Expand Down

0 comments on commit 7283f53

Please sign in to comment.