Skip to content

Commit

Permalink
Make it easier to turn off SIMD support (#770)
Browse files Browse the repository at this point in the history
* make it easier for other projects to turn on ASAN

* add AVX2 and AVX512 CMake options

* build AFX2 and AFX512F in GitHub

* unittest for getSIMDInstructionSet()

* enable AVX2 by default, it's from 2013

* Allow SIMD supoprt to be turned off; enable it based on compiler macros
  • Loading branch information
J. Daniel Smith authored Feb 14, 2024
1 parent a6f8cc4 commit 463cb15
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 21 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build_unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
os: [windows-latest]
platform: [x64]
configuration: [Debug] # Debug turns on more compiler warnings
avx: [AVX2, AVX512F]
avx: [AVX512F]
name: ${{ matrix.os }}-${{ matrix.avx }}-msbuild
runs-on: ${{ matrix.os }}

Expand Down Expand Up @@ -132,7 +132,7 @@ jobs:
matrix:
os: [ubuntu-latest]
configuration: [Debug, Release]
avx: [AVX2, AVX512F]
avx: [AVX512F]
name: ${{ matrix.os }}-${{ matrix.configuration }}-${{ matrix.avx }}-CMake
runs-on: ${{ matrix.os }}
steps:
Expand Down
28 changes: 21 additions & 7 deletions modules/c++/avx/unittests/test_m256.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,24 @@ TEST_CASE(test_getSIMDInstructionSet)
{
// This is the reverse of getSIMDInstructionSet(): it uses the macros to generate a value.
constexpr auto simdInstructionSet = sys::getSIMDInstructionSet();
#if __AVX512F__
static_assert(simdInstructionSet == sys::SIMDInstructionSet::AVX512F, "getSIMDInstructionSet()");
#elif __AVX2__
static_assert(simdInstructionSet == sys::SIMDInstructionSet::AVX2, "getSIMDInstructionSet()");
#if CODA_OSS_ENABLE_SIMD
#if __AVX512F__
static_assert(simdInstructionSet == sys::SIMDInstructionSet::AVX512F, "getSIMDInstructionSet()");
#elif __AVX2__
static_assert(simdInstructionSet == sys::SIMDInstructionSet::AVX2, "getSIMDInstructionSet()");
#else
static_assert(simdInstructionSet == sys::SIMDInstructionSet::SSE2, "getSIMDInstructionSet()");
#endif
#else
static_assert(simdInstructionSet == sys::SIMDInstructionSet::SSE2, "getSIMDInstructionSet()");
#endif
static_assert(simdInstructionSet == sys::SIMDInstructionSet::Disabled, "getSIMDInstructionSet()");
#endif // CODA_OSS_ENABLE_SIMD

CODA_OSS_disable_warning_push
#if _MSC_VER
#pragma warning(disable: 4127) // conditional expression is constant
#endif

switch (sys::getSIMDInstructionSet()) // run-time value
switch (sys::getSIMDInstructionSet()) // run-time value (well, not really, but it could be)
{
case sys::SIMDInstructionSet::SSE2:
{
Expand All @@ -86,6 +90,16 @@ TEST_CASE(test_getSIMDInstructionSet)
TEST_ASSERT(simdInstructionSet == sys::SIMDInstructionSet::AVX512F);
break;
}
case sys::SIMDInstructionSet::Disabled:
{
TEST_ASSERT(simdInstructionSet == sys::SIMDInstructionSet::Disabled);
break;
}
case sys::SIMDInstructionSet::Unknown:
{
TEST_ASSERT(simdInstructionSet == sys::SIMDInstructionSet::Unknown);
break;
}
default:
{
TEST_FAIL;
Expand Down
54 changes: 42 additions & 12 deletions modules/c++/sys/include/sys/AbstractOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,27 +55,57 @@ namespace sys
* Also see https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
* "... For the x86-64 compiler, these extensions [ -msse2 ] are enabled by default."
* We're 64-bit only.
*
* Well ... it turns out third parties want to compile this code in different
* enviroments which we don't know about; SIMD support makes that
* more difficult.
*/
#ifdef CODA_OSS_DISABLE_SIMD
#ifdef CODA_OSS_ENABLE_SIMD
#error "CODA_OSS_ENABLE_SIMD already #define'd'"
#endif
#define CODA_OSS_ENABLE_SIMD 0
#endif // CODA_OSS_DISABLE_SIMD

#ifndef CODA_OSS_ENABLE_SIMD
#if __AVX512F__ || __AVX2__
#define CODA_OSS_ENABLE_SIMD 1
#elif _MSC_VER && _M_X64 /*MSVC for SSE2*/
#define CODA_OSS_ENABLE_SIMD 1
#elif __GNUC__ && __SSE2__
#define CODA_OSS_ENABLE_SIMD 1
#else
#define CODA_OSS_ENABLE_SIMD 0
#endif
#endif

enum class SIMDInstructionSet
{
Disabled, // CODA_OSS_ENABLE_SIMD = 0
Unknown, // CODA_OSS_ENABLE_SIMD = 1, but can't determine

SSE2, // https://en.wikipedia.org/wiki/SSE2
AVX2, // https://en.wikipedia.org/wiki/Advanced_Vector_Extensions
AVX512F, // https://en.wikipedia.org/wiki/AVX-512
};

constexpr auto getSIMDInstructionSet() { return SIMDInstructionSet::
// https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170

#if __AVX512F__
AVX512F
#elif __AVX2__
AVX2
#elif _M_X64 /*MSVC*/ || __SSE2__ /*GCC*/
SSE2
constexpr auto getSIMDInstructionSet() {
#if !CODA_OSS_ENABLE_SIMD
return SIMDInstructionSet::Disabled;
#else
#error "Can't determine SIMDInstructionSet'"
#endif
; }
// https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170
#if __AVX512F__
return SIMDInstructionSet::AVX512F;
#elif __AVX2__
return SIMDInstructionSet::AVX2;
#elif _M_X64 /*MSVC*/ || __SSE2__ /*GCC*/
return SIMDInstructionSet::SSE2;
#else
#error "Can't determine SIMDInstructionSet'"
return SIMDInstructionSet::Unknown;
#endif
#endif // CODA_OSS_ENABLE_SIMD
}

/*!
* \class AbstractOS
Expand Down

0 comments on commit 463cb15

Please sign in to comment.