Skip to content

Commit

Permalink
std::simd::simd build on top of VCL (#769)
Browse files Browse the repository at this point in the history
* add vectorclass library

https://github.com/vectorclass

* hook-up std::simd using VCL

* build with GCC

* stdx instead of std for SIMD as it's not yet part of C++26

* SIMD unittest

* SIMD unittest

* build with GCC
  • Loading branch information
J. Daniel Smith authored Feb 8, 2024
1 parent 2d4497f commit 3cb2e67
Show file tree
Hide file tree
Showing 55 changed files with 55,399 additions and 17 deletions.
4 changes: 4 additions & 0 deletions UnitTest/UnitTest.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\modules\c++\sys\unittests\test_simd.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\modules\c++\types\unittests\test_complex.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
Expand Down
3 changes: 3 additions & 0 deletions UnitTest/UnitTest.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@
<ClCompile Include="..\modules\drivers\highfive\unittests\tests_high_five_base.cpp">
<Filter>hdf5.lite</Filter>
</ClCompile>
<ClCompile Include="..\modules\c++\sys\unittests\test_simd.cpp">
<Filter>sys</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
Expand Down
1 change: 1 addition & 0 deletions UnitTest/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <std/span>
#include <std/string>
#include <std/type_traits>
#include <std/simd>

#include "CppUnitTest.h"

Expand Down
5 changes: 5 additions & 0 deletions UnitTest/sys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "CppUnitTest.h"

#include <coda_oss/numbers.h>
#include <coda_oss/simd.h>

#include <import/sys.h>
#include <sys/Runnable.h>
Expand Down Expand Up @@ -58,4 +59,8 @@ TEST_CLASS(test_path){ public:
#include "sys/unittests/test_path.cpp"
};

TEST_CLASS(test_simd){ public:
#include "sys/unittests/test_simd.cpp"
};

}
6 changes: 4 additions & 2 deletions modules/c++/coda-oss.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<ClInclude Include="coda_oss\include\coda_oss\numbers.h" />
<ClInclude Include="coda_oss\include\coda_oss\optional.h" />
<ClInclude Include="coda_oss\include\coda_oss\optional_.h" />
<ClInclude Include="coda_oss\include\coda_oss\simd.h" />
<ClInclude Include="coda_oss\include\coda_oss\span.h" />
<ClInclude Include="coda_oss\include\coda_oss\span_.h" />
<ClInclude Include="coda_oss\include\coda_oss\string.h" />
Expand Down Expand Up @@ -517,6 +518,7 @@
<None Include="std\include\std\memory" />
<None Include="std\include\std\numbers" />
<None Include="std\include\std\optional" />
<None Include="std\include\std\simd" />
<None Include="std\include\std\span" />
<None Include="std\include\std\string" />
<None Include="std\include\std\type_traits" />
Expand Down Expand Up @@ -572,7 +574,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions);MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1;CODA_OSS_EXPORTS;CODA_OSS_LIBRARY_SHARED=1</PreprocessorDefinitions>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>cli\include;coda_oss\include;config\include;dbi\include;except\include;gsl\include;hdf5.lite\include;io\include;logging\include;math\include;math.linear\include;math.poly\include;mem\include;mt\include;net\include;net.ssl\include;plugin\include;polygon\include;re\include;sio.lite\include;std\include;str\include;sys\include;tiff\include;types\include;unique\include;units\include;xml.lite\include;zip\include;$(ProjectDir)include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\$(ProjectName)\out\install\$(Platform)-$(Configuration)\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>cli\include;coda_oss\include;config\include;dbi\include;except\include;gsl\include;hdf5.lite\include;io\include;logging\include;math\include;math.linear\include;math.poly\include;mem\include;mt\include;net\include;net.ssl\include;plugin\include;polygon\include;re\include;sio.lite\include;std\include;str\include;sys\include;tiff\include;types\include;unique\include;units\include;xml.lite\include;vectorclass\include;zip\include;$(ProjectDir)include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\$(ProjectName)\out\install\$(Platform)-$(Configuration)\include</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
Expand Down Expand Up @@ -605,7 +607,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions);MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1;CODA_OSS_EXPORTS;CODA_OSS_LIBRARY_SHARED=1</PreprocessorDefinitions>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>cli\include;coda_oss\include;config\include;dbi\include;except\include;gsl\include;hdf5.lite\include;io\include;logging\include;math\include;math.linear\include;math.poly\include;mem\include;mt\include;net\include;net.ssl\include;plugin\include;polygon\include;re\include;sio.lite\include;std\include;str\include;sys\include;tiff\include;types\include;unique\include;units\include;xml.lite\include;zip\include;$(ProjectDir)include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\$(ProjectName)\out\install\$(Platform)-$(Configuration)\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>cli\include;coda_oss\include;config\include;dbi\include;except\include;gsl\include;hdf5.lite\include;io\include;logging\include;math\include;math.linear\include;math.poly\include;mem\include;mt\include;net\include;net.ssl\include;plugin\include;polygon\include;re\include;sio.lite\include;std\include;str\include;sys\include;tiff\include;types\include;unique\include;units\include;xml.lite\include;vectorclass\include;zip\include;$(ProjectDir)include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\$(ProjectName)\out\install\$(Platform)-$(Configuration)\include</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
Expand Down
6 changes: 6 additions & 0 deletions modules/c++/coda-oss.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,9 @@
<ClInclude Include="tiff\include\tiff\TiffUtils.h">
<Filter>tiff</Filter>
</ClInclude>
<ClInclude Include="coda_oss\include\coda_oss\simd.h">
<Filter>coda_oss</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
Expand Down Expand Up @@ -1574,5 +1577,8 @@
<None Include="std\include\std\mdspan">
<Filter>std</Filter>
</None>
<None Include="std\include\std\simd">
<Filter>std</Filter>
</None>
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion modules/c++/coda_oss/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ coda_generate_module_config_header(${MODULE_NAME})
coda_add_module(
${MODULE_NAME}
VERSION 1.0
DEPS config-c++ gsl-c++)
DEPS config-c++ gsl-c++ vectorclass-c++)

coda_add_tests(
MODULE_NAME ${MODULE_NAME}
Expand Down
2 changes: 2 additions & 0 deletions modules/c++/coda_oss/include/coda_oss/CPlusPlus.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#define CODA_OSS_cplusplus17 201703L
#define CODA_OSS_cplusplus20 202002L
#define CODA_OSS_cplusplus23 202302L
#define CODA_OSS_cplusplus26 202699L // TODO: real version number when C++26 is official

#if CODA_OSS_cplusplus < CODA_OSS_cplusplus11
#undef CODA_OSS_cplusplus // oops...try to fix
Expand Down Expand Up @@ -78,6 +79,7 @@
#define CODA_OSS_cpp17 (CODA_OSS_cplusplus >= CODA_OSS_cplusplus17)
#define CODA_OSS_cpp20 (CODA_OSS_cplusplus >= CODA_OSS_cplusplus20)
#define CODA_OSS_cpp23 (CODA_OSS_cplusplus >= CODA_OSS_cplusplus23)
#define CODA_OSS_cpp26 0 // TODO: (CODA_OSS_cplusplus >= CODA_OSS_cplusplus26)

#if !CODA_OSS_cpp17
#error "Must compile with C++17 or greater."
Expand Down
122 changes: 122 additions & 0 deletions modules/c++/coda_oss/include/coda_oss/simd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/* =========================================================================
* This file is part of coda_oss-c++
* =========================================================================
*
* (C) Copyright 2004 - 2014, MDA Information Systems LLC
* © Copyright 2024, Maxar Technologies, Inc.
*
* coda_oss-c++ is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; If not,
* see <http://www.gnu.org/licenses/>.
*
*/
#pragma once

#include "coda_oss/CPlusPlus.h"
#include "config/disable_compiler_warnings.h"

// This logic needs to be here rather than <std/simd> so that `coda_oss::simd` will
// be the same as `std::simd`.
#ifndef CODA_OSS_HAVE_std_simd_
#define CODA_OSS_HAVE_std_simd_ 0 // assume no <simd>
#endif
#ifndef CODA_OSS_HAVE_experimental_simd_
#define CODA_OSS_HAVE_experimental_simd_ 0 // assume no std::experimental::simd
#endif
#ifndef CODA_OSS_HAVE_vcl_simd_
#define CODA_OSS_HAVE_vcl_simd_ 0 // assume no vcl::simd
#endif
#if CODA_OSS_cpp17 // __has_include
#if __has_include(<simd>) // <simd> not until C++26 (hopefully!)
#include <simd>
#undef CODA_OSS_HAVE_std_simd_
#define CODA_OSS_HAVE_std_simd_ 1 // provided by the implementation, probably C++26
#endif

/* not quite ready for experimental::simd
#if __has_include(<experimental/simd>) // G++11
#include <experimental/simd>
#undef CODA_OSS_HAVE_experimental_simd_
#define CODA_OSS_HAVE_experimental_simd_ 1 // provided by <experimental/simd>
#endif
*/

#if __has_include("vectorclass/simd/simd") // our own implementation using VCL
#ifdef VCL_NAMESPACE
#error "VCL_NAMESPACE already #define'd"
#endif

#define VCL_NAMESPACE vcl

// The vectorclass headers #pragma-away some warnings; be sure those don't persist
CODA_OSS_disable_warning_push
#if _MSC_VER
#pragma warning(disable: 4100) // '...': unreferenced formal parameter
#pragma warning(disable: 4127) // conditional expression is constant
#pragma warning(disable: 4244) // '...': conversion from '...' to '...', possible loss of data
#pragma warning(disable: 4723) // potential divide by 0
#pragma warning(disable: 6001) // Using uninitialized memory '...'.
#pragma warning(disable: 26485) // Expression '...': No array to pointer decay (bounds.3).
#pragma warning(disable: 26440) // Function '...' can be declared 'noexcept' (f.6).
#pragma warning(disable: 26493) // Don't use C-style casts (type.4).
#pragma warning(disable: 26814) // The const variable '...' can be computed at compile-time. Consider using constexpr (con.5).
#pragma warning(disable: 26434) // Function '... hides a non-virtual function '...'.
#pragma warning(disable: 26429) // Symbol '...' is never tested for nullness, it can be marked as not_null (f.23).
#pragma warning(disable: 26482) // Only index into arrays using constant expressions (bounds.2).
#pragma warning(disable: 26481) // Don't use pointer arithmetic. Use span instead (bounds.1).
#pragma warning(disable: 26446) // Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4).
#pragma warning(disable: 26823) // Dereferencing a possibly null pointer '...' (lifetime.1).
#pragma warning(disable: 26496) // The variable '...' does not change after construction, mark it as const (con.4).
#pragma warning(disable: 26472) // Don't use a static_cast for arithmetic conversions. Use brace initialization, gsl::narrow_cast or gsl::narrow (type.1).
#pragma warning(disable: 26494) // Variable '...' is uninitialized. Always initialize an object (type.5).
#pragma warning(disable: 26458) // Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4).
#pragma warning(disable: 26497) // You can attempt to make '...' constexpr unless it contains any undefined behavior (f.4).
#pragma warning(disable: 26818) // Switch statement does not cover all cases. Consider adding a '...' label (es.79).
#pragma warning(disable: 26475) // Do not use function style casts (es.49). Prefer '...' over '...'.
#pragma warning(disable: 26477) // Use '...' rather than 0 or NULL (es.47).

#elif defined(__GNUC__) || defined(__clang__)

CODA_OSS_disable_warning(-Wzero-as-null-pointer-constant)
CODA_OSS_disable_warning(-Wshadow)

#endif

#include "vectorclass/version2/vectorclass.h"
#include "vectorclass/version2/vectormath_trig.h"
CODA_OSS_disable_warning_pop

CODA_OSS_disable_warning_push
#if _MSC_VER
#pragma warning(disable: 26472) // Don't use a static_cast for arithmetic conversions. Use brace initialization, gsl::narrow_cast or gsl::narrow (type.1).
#endif
#include "vectorclass/simd/simd"
CODA_OSS_disable_warning_pop

#undef CODA_OSS_HAVE_vcl_simd_
#define CODA_OSS_HAVE_vcl_simd_ 1 // provided by vectorclass/simd/simd.h
#endif

#endif // CODA_OSS_cpp17

namespace coda_oss
{
#if CODA_OSS_HAVE_std_simd_
namespace simd = std::simd;
#elif CODA_OSS_HAVE_experimental_simd_
namespace simd = std::experimental;
#elif CODA_OSS_HAVE_vcl_simd_
namespace simd = vcl::simd;
#endif
}

2 changes: 1 addition & 1 deletion modules/c++/coda_oss/wscript
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
NAME = 'coda_oss'
VERSION = '1.0'
MODULE_DEPS = 'config gsl'
MODULE_DEPS = 'config gsl vectorclass'
USELIB = 'THREAD DL RT SOCKET'
UNITTEST_DEPS = ''

Expand Down
1 change: 1 addition & 0 deletions modules/c++/std/include/import/std.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ CODA_OSS_disable_warning_system_header_push
#include <coda_oss/string.h>
#include <coda_oss/type_traits.h>
#include <coda_oss/mdspan.h>
#include <coda_oss/simd.h>

CODA_OSS_disable_warning_pop

Expand Down
47 changes: 47 additions & 0 deletions modules/c++/std/include/std/simd
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* =========================================================================
* This file is part of std-c++
* =========================================================================
*
* � Copyright 2023, Maxar Technologies, Inc.
*
* std-c++ is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; If not, http://www.gnu.org/licenses/.
*
*/
#pragma once

#include "coda_oss/simd.h"
#include "coda_oss/CPlusPlus.h"

// Calling this **stdx** (instead of *std*) for now as it hasn't yet been voted into C++26

// Make it (too?) easy for clients to get our various std:: implementations
#ifndef CODA_OSS_NO_stdx_simd
#if CODA_OSS_cpp26
#include <simd>
#define CODA_OSS_NO_stdx_simd 1 // part of C++26 (hopefully)
#else
#define CODA_OSS_NO_stdx_simd 0 // use our own
#endif
#endif

#if !CODA_OSS_NO_stdx_simd
namespace stdx // TODO: This is slightly uncouth: we're not supposed to augment "std".
{
namespace simd = coda_oss::simd;
}
//#ifndef __cpp_lib_simd
//#define __cpp_lib_simd 202402L // https://en.cppreference.com/w/cpp/feature_test#cpp_lib_simd
//#endif

#endif // CODA_OSS_NO_stdx_simd
12 changes: 0 additions & 12 deletions modules/c++/sys/unittests/test_os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,17 +511,6 @@ TEST_CASE(test_make_ifstream)
TEST_ASSERT_TRUE(ifs.is_open());
}

TEST_CASE(test_SIMD_Instructions)
{
const sys::OS os;
const auto simdInstructionSet = os.getSIMDInstructionSet();

const auto isSSE2 = simdInstructionSet == sys::SIMDInstructionSet::SSE2;
const auto isAVX2 = simdInstructionSet == sys::SIMDInstructionSet::AVX2;
const auto isAVX512F = simdInstructionSet == sys::SIMDInstructionSet::AVX512F;
TEST_ASSERT(isSSE2 || isAVX2 || isAVX512F);
}

TEST_MAIN(
//sys::AbstractOS::setArgvPathname(argv[0]);
TEST_CHECK(testRecursiveRemove);
Expand All @@ -538,5 +527,4 @@ TEST_MAIN(
TEST_CHECK(test_sys_fopen_failure);
TEST_CHECK(test_sys_open);
TEST_CHECK(test_make_ifstream);
TEST_CHECK(test_SIMD_Instructions);
)
Loading

0 comments on commit 3cb2e67

Please sign in to comment.