From 668ab3fc474e54c7919eda4fbaf11f3a99246494 Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen Date: Fri, 18 Oct 2019 16:42:00 -0700 Subject: [PATCH] Drop support for c++03 in Eigen tensor. Get rid of some code used to emulate c++11 functionality with older compilers. --- unsupported/Eigen/CXX11/Tensor | 8 +- .../Eigen/CXX11/src/Tensor/TensorBlockV2.h | 27 +- .../Eigen/CXX11/src/Tensor/TensorDeviceGpu.h | 10 - .../Eigen/CXX11/src/Tensor/TensorExecutor.h | 5 - .../Eigen/CXX11/src/Tensor/TensorFFT.h | 7 - .../src/Tensor/TensorForwardDeclarations.h | 22 -- .../Eigen/CXX11/src/Tensor/TensorReduction.h | 2 +- unsupported/Eigen/CXX11/src/util/CXX11Meta.h | 101 +++++- .../Eigen/CXX11/src/util/EmulateArray.h | 261 --------------- .../Eigen/CXX11/src/util/EmulateCXX11Meta.h | 311 ------------------ unsupported/test/CMakeLists.txt | 96 +++--- 11 files changed, 139 insertions(+), 711 deletions(-) delete mode 100644 unsupported/Eigen/CXX11/src/util/EmulateArray.h delete mode 100644 unsupported/Eigen/CXX11/src/util/EmulateCXX11Meta.h diff --git a/unsupported/Eigen/CXX11/Tensor b/unsupported/Eigen/CXX11/Tensor index 04b20f464..a110b52f4 100644 --- a/unsupported/Eigen/CXX11/Tensor +++ b/unsupported/Eigen/CXX11/Tensor @@ -13,6 +13,8 @@ #include "../../../Eigen/Core" +#if EIGEN_HAS_CXX11 + #if defined(EIGEN_USE_SYCL) #undef min #undef max @@ -47,6 +49,7 @@ #include #include #include +#include #ifdef _WIN32 typedef __int16 int16_t; @@ -61,10 +64,6 @@ typedef unsigned __int64 uint64_t; #include #endif -#if __cplusplus > 199711 || EIGEN_COMP_MSVC >= 1900 -#include -#endif - #ifdef _WIN32 #include #elif defined(__APPLE__) @@ -164,4 +163,5 @@ typedef unsigned __int64 uint64_t; #include "../../../Eigen/src/Core/util/ReenableStupidWarnings.h" +#endif // EIGEN_HAS_CXX11 //#endif // EIGEN_CXX11_TENSOR_MODULE diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorBlockV2.h b/unsupported/Eigen/CXX11/src/Tensor/TensorBlockV2.h index c85c4c6c8..e9086a7f1 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorBlockV2.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorBlockV2.h @@ -51,13 +51,11 @@ EIGEN_ALWAYS_INLINE DSizes strides( return strides(DSizes(dimensions)); } -#if EIGEN_HAS_CXX11 template EIGEN_STRONG_INLINE DSizes strides( const Sizes& sizes) { return strides(DSizes(sizes)); } -#endif // -------------------------------------------------------------------------- // // TensorBlockDescriptor specifies a block offset within a tensor and the block @@ -185,7 +183,7 @@ class TensorBlockDescriptor { Scalar* dst_base, const DSizes& dst_strides) { // DSizes constructor will do index type promotion if it's safe. - AddDestinationBuffer(*this, dst_base, Dimensions(dst_strides)); + AddDestinationBuffer(dst_base, Dimensions(dst_strides)); } TensorBlockDescriptor& DropDestinationBuffer() { @@ -285,11 +283,6 @@ class TensorBlockScratchAllocator { // -------------------------------------------------------------------------- // // TensorBlockKind represents all possible block kinds, that can be produced by // TensorEvaluator::evalBlock function. -#if !EIGEN_HAS_CXX11 -// To be able to use `TensorBlockKind::kExpr` in C++03 we need a namespace. -// (Use of enumeration in a nested name specifier is a c++11 extension). -namespace TensorBlockKind { -#endif enum TensorBlockKind { // Tensor block that is a lazy expression that must be assigned to a // destination using TensorBlockAssign. @@ -313,9 +306,6 @@ enum TensorBlockKind { // TensorBlockAssign or for constructing another block expression. kMaterializedInOutput }; -#if !EIGEN_HAS_CXX11 -} // namespace TensorBlockKind -#endif // -------------------------------------------------------------------------- // // TensorBlockNotImplemented should be used to defined TensorBlock typedef in @@ -361,9 +351,6 @@ struct XprScalar { template class TensorMaterializedBlock { -#if !EIGEN_HAS_CXX11 - typedef internal::TensorBlockKind::TensorBlockKind TensorBlockKind; -#endif public: typedef DSizes Dimensions; typedef TensorMap > XprType; @@ -543,9 +530,6 @@ class TensorMaterializedBlock { template class TensorCwiseUnaryBlock { -#if !EIGEN_HAS_CXX11 - typedef internal::TensorBlockKind::TensorBlockKind TensorBlockKind; -#endif static const bool NoArgBlockAccess = internal::is_void::value; @@ -578,9 +562,6 @@ class TensorCwiseUnaryBlock { template class TensorCwiseBinaryBlock { -#if !EIGEN_HAS_CXX11 - typedef internal::TensorBlockKind::TensorBlockKind TensorBlockKind; -#endif static const bool NoArgBlockAccess = internal::is_void::value || @@ -628,9 +609,6 @@ class TensorCwiseBinaryBlock { template class TensorUnaryExprBlock { -#if !EIGEN_HAS_CXX11 - typedef internal::TensorBlockKind::TensorBlockKind TensorBlockKind; -#endif typedef typename ArgTensorBlock::XprType ArgXprType; static const bool NoArgBlockAccess = internal::is_void::value; @@ -663,9 +641,6 @@ class TensorUnaryExprBlock { template class TensorTernaryExprBlock { -#if !EIGEN_HAS_CXX11 - typedef internal::TensorBlockKind::TensorBlockKind TensorBlockKind; -#endif typedef typename Arg1TensorBlock::XprType Arg1XprType; typedef typename Arg2TensorBlock::XprType Arg2XprType; diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h index 5b1abdc40..7f3394438 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h @@ -53,14 +53,8 @@ static void initializeDeviceProp() { // compile with nvcc, so we resort to atomics and thread fences instead. // Note that if the caller uses a compiler that doesn't support c++11 we // can't ensure that the initialization is thread safe. -#if __cplusplus >= 201103L static std::atomic first(true); if (first.exchange(false)) { -#else - static bool first = true; - if (first) { - first = false; -#endif // We're the first thread to reach this point. int num_devices; gpuError_t status = gpuGetDeviceCount(&num_devices); @@ -83,16 +77,12 @@ static void initializeDeviceProp() { } } -#if __cplusplus >= 201103L std::atomic_thread_fence(std::memory_order_release); -#endif m_devicePropInitialized = true; } else { // Wait for the other thread to inititialize the properties. while (!m_devicePropInitialized) { -#if __cplusplus >= 201103L std::atomic_thread_fence(std::memory_order_acquire); -#endif EIGEN_SLEEP(1000); } } diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h b/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h index 97ac96db1..11cec3d1c 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h @@ -76,13 +76,8 @@ struct ExpressionHasTensorBroadcastingOp< * Default strategy: the expression is evaluated sequentially with a single cpu * thread, without vectorization and block evaluation. */ -#if EIGEN_HAS_CXX11 template -#else - template -#endif class TensorExecutor { public: typedef typename Expression::Index StorageIndex; diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h b/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h index 7be007d94..55c7d6831 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h @@ -10,10 +10,6 @@ #ifndef EIGEN_CXX11_TENSOR_TENSOR_FFT_H #define EIGEN_CXX11_TENSOR_TENSOR_FFT_H -// This code requires the ability to initialize arrays of constant -// values directly inside a class. -#if __cplusplus >= 201103L || EIGEN_COMP_MSVC >= 1900 - namespace Eigen { /** \class TensorFFT @@ -671,7 +667,4 @@ struct TensorEvaluator, D } // end namespace Eigen -#endif // EIGEN_HAS_CONSTEXPR - - #endif // EIGEN_CXX11_TENSOR_TENSOR_FFT_H diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h b/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h index 802cf21d8..5549cbdb2 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h @@ -155,19 +155,11 @@ struct IsVectorizable { }; // Tiled evaluation strategy. -#if !EIGEN_HAS_CXX11 -// To be able to use `TiledEvaluation::Off` in C++03 we need a namespace. -// (Use of enumeration in a nested name specifier is a c++11 extension). -namespace TiledEvaluation { -#endif enum TiledEvaluation { Off = 0, // tiled evaluation is not supported On = 1, // still work in progress (see TensorBlockV2.h) Legacy = 2 // soon to be deprecated (see TensorBock.h) }; -#if !EIGEN_HAS_CXX11 -} // namespace TiledEvaluation -#endif template struct IsTileable { @@ -182,30 +174,16 @@ struct IsTileable { TensorEvaluator::BlockAccessV2 && TensorEvaluator::PreferBlockAccess; -#if EIGEN_HAS_CXX11 static const TiledEvaluation value = BlockAccessV2 ? TiledEvaluation::On : (BlockAccess ? TiledEvaluation::Legacy : TiledEvaluation::Off); -#else - static const TiledEvaluation::TiledEvaluation value = - BlockAccessV2 - ? TiledEvaluation::On - : (BlockAccess ? TiledEvaluation::Legacy : TiledEvaluation::Off); -#endif }; -#if EIGEN_HAS_CXX11 template ::value, TiledEvaluation Tiling = IsTileable::value> class TensorExecutor; -#else -template ::value, - TiledEvaluation::TiledEvaluation Tiling = IsTileable::value> -class TensorExecutor; -#endif // TODO(ezhulenev): Add TiledEvaluation support to async executor. template struct ReductionReturnType { -#if EIGEN_HAS_CXX11 && defined(EIGEN_USE_SYCL) +#if defined(EIGEN_USE_SYCL) typedef typename remove_const().initialize())>::type type; #else typedef typename remove_const::type type; diff --git a/unsupported/Eigen/CXX11/src/util/CXX11Meta.h b/unsupported/Eigen/CXX11/src/util/CXX11Meta.h index 6c95d0a6c..86f56b9bd 100644 --- a/unsupported/Eigen/CXX11/src/util/CXX11Meta.h +++ b/unsupported/Eigen/CXX11/src/util/CXX11Meta.h @@ -11,19 +11,102 @@ #define EIGEN_CXX11META_H #include -#include "EmulateArray.h" - -// Emulate the cxx11 functionality that we need if the compiler doesn't support it. -// Visual studio 2015 doesn't advertise itself as cxx11 compliant, although it -// supports enough of the standard for our needs -#if __cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900 +#include #include "CXX11Workarounds.h" namespace Eigen { +// Workaround for constructors used by legacy code calling Eigen::array. +template +class array : public std::array { + public: + + typedef std::array Base; + + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array() : Base() {} + + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array(const T& v) : Base{v} { + EIGEN_STATIC_ASSERT(N == 1, YOU_MADE_A_PROGRAMMING_MISTAKE); + } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array(const T& v1, const T& v2) : Base{v1, v2} { + EIGEN_STATIC_ASSERT(N == 2, YOU_MADE_A_PROGRAMMING_MISTAKE); + } + + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array(const T& v1, const T& v2, const T& v3) : Base{v1, v2, v3} { + EIGEN_STATIC_ASSERT(N == 3, YOU_MADE_A_PROGRAMMING_MISTAKE); + } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array(const T& v1, const T& v2, const T& v3, const T& v4) + : Base{v1, v2, v3, v4} { + EIGEN_STATIC_ASSERT(N == 4, YOU_MADE_A_PROGRAMMING_MISTAKE); + } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) + : Base{v1, v2, v3, v4, v5} { + EIGEN_STATIC_ASSERT(N == 5, YOU_MADE_A_PROGRAMMING_MISTAKE); + } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, + const T& v6) : Base{v1, v2, v3, v4, v5, v6} { + EIGEN_STATIC_ASSERT(N == 6, YOU_MADE_A_PROGRAMMING_MISTAKE); + } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, + const T& v6, const T& v7) + : Base{v1, v2, v3, v4, v5, v6, v7} { + EIGEN_STATIC_ASSERT(N == 7, YOU_MADE_A_PROGRAMMING_MISTAKE); + } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, + const T& v6, const T& v7, const T& v8) + : Base{v1, v2, v3, v4, v5, v6, v7, v8} { + EIGEN_STATIC_ASSERT(N == 8, YOU_MADE_A_PROGRAMMING_MISTAKE); + } +#if EIGEN_HAS_VARIADIC_TEMPLATES + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array(std::initializer_list l) { + eigen_assert(l.size() == N); + internal::smart_copy(l.begin(), l.end(), this->begin()); + } +#endif +}; + +template struct internal::array_size > { + enum { value = N }; +}; +template struct internal::array_size > { + enum { value = N }; +}; + namespace internal { +/* std::get is only constexpr in C++14, not yet in C++11 + * - libstdc++ from version 4.7 onwards has it nevertheless, + * so use that + * - libstdc++ older versions: use _M_instance directly + * - libc++ all versions so far: use __elems_ directly + * - all other libs: use std::get to be portable, but + * this may not be constexpr + */ +#if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322 +#define STD_GET_ARR_HACK a._M_instance[I_] +#elif defined(_LIBCPP_VERSION) +#define STD_GET_ARR_HACK a.__elems_[I_] +#else +#define STD_GET_ARR_HACK std::template get(a) +#endif + +template constexpr inline T& array_get(std::array& a) { return (T&) STD_GET_ARR_HACK; } +template constexpr inline T&& array_get(std::array&& a) { return (T&&) STD_GET_ARR_HACK; } +template constexpr inline T const& array_get(std::array const& a) { return (T const&) STD_GET_ARR_HACK; } + +#undef STD_GET_ARR_HACK + /** \internal * \file CXX11/util/CXX11Meta.h * This file contains generic metaprogramming classes which are not specifically related to Eigen. @@ -537,10 +620,4 @@ InstType instantiate_by_c_array(ArrType* arr) } // end namespace Eigen -#else // Non C++11, fallback to emulation mode - -#include "EmulateCXX11Meta.h" - -#endif - #endif // EIGEN_CXX11META_H diff --git a/unsupported/Eigen/CXX11/src/util/EmulateArray.h b/unsupported/Eigen/CXX11/src/util/EmulateArray.h deleted file mode 100644 index 834b20b55..000000000 --- a/unsupported/Eigen/CXX11/src/util/EmulateArray.h +++ /dev/null @@ -1,261 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2014 Benoit Steiner -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_EMULATE_ARRAY_H -#define EIGEN_EMULATE_ARRAY_H - - - -// The array class is only available starting with cxx11. Emulate our own here -// if needed. Beware, msvc still doesn't advertise itself as a c++11 compiler! -// Moreover, CUDA doesn't support the STL containers, so we use our own instead. -#if (__cplusplus <= 199711L && EIGEN_COMP_MSVC < 1900) || defined(EIGEN_GPUCC) || defined(EIGEN_AVOID_STL_ARRAY) - -namespace Eigen { -template class array { - public: - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE T& operator[] (size_t index) { eigen_internal_assert(index < size()); return values[index]; } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const T& operator[] (size_t index) const { eigen_internal_assert(index < size()); return values[index]; } - - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE T& at(size_t index) { eigen_assert(index < size()); return values[index]; } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const T& at(size_t index) const { eigen_assert(index < size()); return values[index]; } - - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE T& front() { return values[0]; } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const T& front() const { return values[0]; } - - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE T& back() { return values[n-1]; } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const T& back() const { return values[n-1]; } - - EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE - static std::size_t size() { return n; } - - T values[n]; - - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array() { } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array(const T& v) { - EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE) - values[0] = v; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array(const T& v1, const T& v2) { - EIGEN_STATIC_ASSERT(n==2, YOU_MADE_A_PROGRAMMING_MISTAKE) - values[0] = v1; - values[1] = v2; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) { - EIGEN_STATIC_ASSERT(n==3, YOU_MADE_A_PROGRAMMING_MISTAKE) - values[0] = v1; - values[1] = v2; - values[2] = v3; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, - const T& v4) { - EIGEN_STATIC_ASSERT(n==4, YOU_MADE_A_PROGRAMMING_MISTAKE) - values[0] = v1; - values[1] = v2; - values[2] = v3; - values[3] = v4; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5) { - EIGEN_STATIC_ASSERT(n==5, YOU_MADE_A_PROGRAMMING_MISTAKE) - values[0] = v1; - values[1] = v2; - values[2] = v3; - values[3] = v4; - values[4] = v5; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6) { - EIGEN_STATIC_ASSERT(n==6, YOU_MADE_A_PROGRAMMING_MISTAKE) - values[0] = v1; - values[1] = v2; - values[2] = v3; - values[3] = v4; - values[4] = v5; - values[5] = v6; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7) { - EIGEN_STATIC_ASSERT(n==7, YOU_MADE_A_PROGRAMMING_MISTAKE) - values[0] = v1; - values[1] = v2; - values[2] = v3; - values[3] = v4; - values[4] = v5; - values[5] = v6; - values[6] = v7; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array( - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8) { - EIGEN_STATIC_ASSERT(n==8, YOU_MADE_A_PROGRAMMING_MISTAKE) - values[0] = v1; - values[1] = v2; - values[2] = v3; - values[3] = v4; - values[4] = v5; - values[5] = v6; - values[6] = v7; - values[7] = v8; - } - -#if EIGEN_HAS_VARIADIC_TEMPLATES - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array(std::initializer_list l) { - eigen_assert(l.size() == n); - internal::smart_copy(l.begin(), l.end(), values); - } -#endif -}; - - -// Specialize array for zero size -template class array { - public: - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE T& operator[] (size_t) { - eigen_assert(false && "Can't index a zero size array"); - return dummy; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const T& operator[] (size_t) const { - eigen_assert(false && "Can't index a zero size array"); - return dummy; - } - - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE T& front() { - eigen_assert(false && "Can't index a zero size array"); - return dummy; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const T& front() const { - eigen_assert(false && "Can't index a zero size array"); - return dummy; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE T& back() { - eigen_assert(false && "Can't index a zero size array"); - return dummy; - } - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const T& back() const { - eigen_assert(false && "Can't index a zero size array"); - return dummy; - } - - static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::size_t size() { return 0; } - - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE array() : dummy() { } - -#if EIGEN_HAS_VARIADIC_TEMPLATES - EIGEN_DEVICE_FUNC array(std::initializer_list l) : dummy() { - EIGEN_UNUSED_VARIABLE(l); - eigen_assert(l.size() == 0); - } -#endif - - private: - T dummy; -}; - -// Comparison operator -// Todo: implement !=, <, <=, >, and >= -template -EIGEN_DEVICE_FUNC bool operator==(const array& lhs, const array& rhs) { - for (std::size_t i = 0; i < N; ++i) { - if (lhs[i] != rhs[i]) { - return false; - } - } - return true; -} - - -namespace internal { -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array& a) { - return a[I_]; -} -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array& a) { - return a[I_]; -} - -template struct array_size > { - enum { value = N }; -}; -template struct array_size& > { - enum { value = N }; -}; -template struct array_size > { - enum { value = N }; -}; -template struct array_size& > { - enum { value = N }; -}; - -} // end namespace internal -} // end namespace Eigen - -#else - -// The compiler supports c++11, and we're not targeting cuda: use std::array as Eigen::array -#include -namespace Eigen { - -template using array = std::array; - -namespace internal { -/* std::get is only constexpr in C++14, not yet in C++11 - * - libstdc++ from version 4.7 onwards has it nevertheless, - * so use that - * - libstdc++ older versions: use _M_instance directly - * - libc++ all versions so far: use __elems_ directly - * - all other libs: use std::get to be portable, but - * this may not be constexpr - */ -#if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322 -#define STD_GET_ARR_HACK a._M_instance[I_] -#elif defined(_LIBCPP_VERSION) -#define STD_GET_ARR_HACK a.__elems_[I_] -#else -#define STD_GET_ARR_HACK std::template get(a) -#endif - -template constexpr inline T& array_get(std::array& a) { return (T&) STD_GET_ARR_HACK; } -template constexpr inline T&& array_get(std::array&& a) { return (T&&) STD_GET_ARR_HACK; } -template constexpr inline T const& array_get(std::array const& a) { return (T const&) STD_GET_ARR_HACK; } - -#undef STD_GET_ARR_HACK - -} // end namespace internal -} // end namespace Eigen - -#endif - -#endif // EIGEN_EMULATE_ARRAY_H diff --git a/unsupported/Eigen/CXX11/src/util/EmulateCXX11Meta.h b/unsupported/Eigen/CXX11/src/util/EmulateCXX11Meta.h deleted file mode 100644 index d02d86f85..000000000 --- a/unsupported/Eigen/CXX11/src/util/EmulateCXX11Meta.h +++ /dev/null @@ -1,311 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2014 Benoit Steiner -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_EMULATE_CXX11_META_H -#define EIGEN_EMULATE_CXX11_META_H - - - -namespace Eigen { - -namespace internal { - -/** \internal - * \file CXX11/util/EmulateCXX11Meta.h - * This file emulates a subset of the functionality provided by CXXMeta.h for - * compilers that don't yet support cxx11 such as nvcc. - */ - -struct empty_list { static const std::size_t count = 0; }; - -template struct type_list { - typedef T HeadType; - typedef Tail TailType; - static const T head; - static const Tail tail; - static const std::size_t count = 1 + Tail::count; -}; - -struct null_type { }; - -template -struct make_type_list { - typedef typename make_type_list::type tailresult; - - typedef type_list type; -}; - -template<> struct make_type_list<> { - typedef empty_list type; -}; - - -template struct get_type; - -template -struct get_type<0, type_list > -{ - typedef Head type; -}; - -template -struct get_type > -{ - typedef typename get_type::type type; -}; - - -/* numeric list */ -template -struct type2val { - typedef T type; - static const T value = n; -}; - - -template struct gen_numeric_list_repeated; - -template struct gen_numeric_list_repeated { - typedef typename make_type_list >::type type; -}; - -template struct gen_numeric_list_repeated { - typedef typename make_type_list, type2val >::type type; -}; - -template struct gen_numeric_list_repeated { - typedef typename make_type_list, type2val, type2val >::type type; -}; - -template struct gen_numeric_list_repeated { - typedef typename make_type_list, type2val, type2val, type2val >::type type; -}; - -template struct gen_numeric_list_repeated { - typedef typename make_type_list, type2val, type2val, type2val, type2val >::type type; -}; - -template struct gen_numeric_list_repeated { - typedef typename make_type_list, type2val, type2val, - type2val, type2val, type2val >::type type; -}; - -template struct gen_numeric_list_repeated { - typedef typename make_type_list, type2val, type2val, - type2val, type2val, type2val, - type2val >::type type; -}; - -template struct gen_numeric_list_repeated { - typedef typename make_type_list, type2val, type2val, - type2val, type2val, type2val, - type2val, type2val >::type type; -}; - - -template struct get; - -template -struct get -{ - get() { eigen_assert(false && "index overflow"); } - typedef void type; - static const char value = '\0'; -}; - -template -struct get > -{ - get() { eigen_assert(false && "index overflow"); } - typedef void type; - static const char value = '\0'; -}; - -template -struct get<0, type_list > -{ - typedef typename Head::type type; - static const type value = Head::value; -}; - -template -struct get<0, type_list > -{ - typedef typename Head::type type; - static const type value = Head::value; -}; - -template -struct get > -{ - typedef typename Tail::HeadType::type type; - static const type value = get::value; -}; - - -template struct arg_prod { - static const typename NList::HeadType::type value = get<0, NList>::value * arg_prod::value; -}; -template <> struct arg_prod { - static const int value = 1; -}; - - -template -array repeat(t v) { - array array; - array.fill(v); - return array; -} - -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename Head::type array_get(type_list&) { - return get >::value; -} -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename Head::type array_get(const type_list&) { - return get >::value; -} - -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NList::HeadType::type array_prod(const NList&) { - return arg_prod::value; -} - -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const array& a) { - t prod = 1; - for (size_t i = 0; i < n; ++i) { prod *= a[i]; } - return prod; -} -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const array& /*a*/) { - return 1; -} - -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const std::vector& a) { - eigen_assert(a.size() > 0); - t prod = 1; - for (size_t i = 0; i < a.size(); ++i) { prod *= a[i]; } - return prod; -} - - -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(std::vector& a) { - return a[I_]; -} -template -EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const std::vector& a) { - return a[I_]; -} - -struct sum_op { - template static inline bool run(A a, B b) { return a + b; } -}; -struct product_op { - template static inline bool run(A a, B b) { return a * b; } -}; - -struct logical_and_op { - template static inline bool run(A a, B b) { return a && b; } -}; -struct logical_or_op { - template static inline bool run(A a, B b) { return a || b; } -}; - -struct equal_op { - template static inline bool run(A a, B b) { return a == b; } -}; -struct not_equal_op { - template static inline bool run(A a, B b) { return a != b; } -}; -struct lesser_op { - template static inline bool run(A a, B b) { return a < b; } -}; -struct lesser_equal_op { - template static inline bool run(A a, B b) { return a <= b; } -}; - -struct greater_op { - template static inline bool run(A a, B b) { return a > b; } -}; -struct greater_equal_op { - template static inline bool run(A a, B b) { return a >= b; } -}; - -struct not_op { - template static inline bool run(A a) { return !a; } -}; -struct negation_op { - template static inline bool run(A a) { return -a; } -}; -struct greater_equal_zero_op { - template static inline bool run(A a) { return a >= 0; } -}; - - -template -struct ArrayApplyAndReduce { - static inline bool run(const array& a) { - EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE); - bool result = Reducer::run(Op::run(a[0]), Op::run(a[1])); - for (size_t i = 2; i < N; ++i) { - result = Reducer::run(result, Op::run(a[i])); - } - return result; - } -}; - -template -struct ArrayApplyAndReduce { - static inline bool run(const array& a) { - return Op::run(a[0]); - } -}; - -template -inline bool array_apply_and_reduce(const array& a) { - return ArrayApplyAndReduce::run(a); -} - -template -struct ArrayZipAndReduce { - static inline bool run(const array& a, const array& b) { - EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE); - bool result = Reducer::run(Op::run(a[0], b[0]), Op::run(a[1], b[1])); - for (size_t i = 2; i < N; ++i) { - result = Reducer::run(result, Op::run(a[i], b[i])); - } - return result; - } -}; - -template -struct ArrayZipAndReduce { - static inline bool run(const array& a, const array& b) { - return Op::run(a[0], b[0]); - } -}; - -template -inline bool array_zip_and_reduce(const array& a, const array& b) { - return ArrayZipAndReduce::run(a, b); -} - -} // end namespace internal - -} // end namespace Eigen - - - -#endif // EIGEN_EMULATE_CXX11_META_H diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt index ffc8af49c..40174769d 100644 --- a/unsupported/test/CMakeLists.txt +++ b/unsupported/test/CMakeLists.txt @@ -109,31 +109,6 @@ ei_add_test(kronecker_product) ei_add_test(bessel_functions) ei_add_test(special_functions) -# TODO: The following test names are prefixed with the cxx11 string, since historically -# the tests depended on c++11. This isn't the case anymore so we ought to rename them. -# FIXME: Old versions of MSVC fail to compile this code, so we just disable these tests -# when using visual studio. We should make the check more strict to enable the tests for -# newer versions of MSVC. -if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") -ei_add_test(cxx11_tensor_dimension) -ei_add_test(cxx11_tensor_map) -ei_add_test(cxx11_tensor_assign) -ei_add_test(cxx11_tensor_block_access) -ei_add_test(cxx11_tensor_broadcasting) -ei_add_test(cxx11_tensor_comparisons) -ei_add_test(cxx11_tensor_forced_eval) -ei_add_test(cxx11_tensor_math) -ei_add_test(cxx11_tensor_const) -ei_add_test(cxx11_tensor_intdiv) -ei_add_test(cxx11_tensor_casts) -ei_add_test(cxx11_tensor_empty) -ei_add_test(cxx11_tensor_sugar) -ei_add_test(cxx11_tensor_roundings) -ei_add_test(cxx11_tensor_layout_swap) -ei_add_test(cxx11_tensor_io) -ei_add_test(cxx11_maxsizevector) -endif() - if(EIGEN_TEST_CXX11) if(EIGEN_TEST_SYCL) if(EIGEN_SYCL_TRISYCL) @@ -177,46 +152,63 @@ if(EIGEN_TEST_CXX11) ei_add_test(cxx11_non_blocking_thread_pool "-pthread" "${CMAKE_THREAD_LIBS_INIT}") ei_add_test(cxx11_meta) - ei_add_test(cxx11_tensor_simple) -# ei_add_test(cxx11_tensor_symmetry) - ei_add_test(cxx11_tensor_index_list) - ei_add_test(cxx11_tensor_mixed_indices) - ei_add_test(cxx11_tensor_contraction) - ei_add_test(cxx11_tensor_convolution) - ei_add_test(cxx11_tensor_expr) - ei_add_test(cxx11_tensor_fixed_size) - ei_add_test(cxx11_tensor_of_const_values) - ei_add_test(cxx11_tensor_of_complex) - ei_add_test(cxx11_tensor_of_strings) - ei_add_test(cxx11_tensor_lvalue) - ei_add_test(cxx11_tensor_chipping) + ei_add_test(cxx11_maxsizevector) + ei_add_test(cxx11_tensor_argmax) + ei_add_test(cxx11_tensor_assign) + ei_add_test(cxx11_tensor_block_access) ei_add_test(cxx11_tensor_block_eval) ei_add_test(cxx11_tensor_block_io) + ei_add_test(cxx11_tensor_broadcasting) + ei_add_test(cxx11_tensor_casts) + ei_add_test(cxx11_tensor_chipping) + ei_add_test(cxx11_tensor_comparisons) ei_add_test(cxx11_tensor_concatenation) + ei_add_test(cxx11_tensor_const) + ei_add_test(cxx11_tensor_contraction) + ei_add_test(cxx11_tensor_convolution) + ei_add_test(cxx11_tensor_custom_index) + ei_add_test(cxx11_tensor_custom_op) + ei_add_test(cxx11_tensor_dimension) + ei_add_test(cxx11_tensor_empty) + ei_add_test(cxx11_tensor_executor "-pthread" "${CMAKE_THREAD_LIBS_INIT}") + ei_add_test(cxx11_tensor_expr) + ei_add_test(cxx11_tensor_fft) + ei_add_test(cxx11_tensor_fixed_size) + ei_add_test(cxx11_tensor_forced_eval) + ei_add_test(cxx11_tensor_generator) + ei_add_test(cxx11_tensor_ifft) + ei_add_test(cxx11_tensor_image_patch) + ei_add_test(cxx11_tensor_index_list) ei_add_test(cxx11_tensor_inflation) + ei_add_test(cxx11_tensor_intdiv) + ei_add_test(cxx11_tensor_io) + ei_add_test(cxx11_tensor_layout_swap) + ei_add_test(cxx11_tensor_lvalue) + ei_add_test(cxx11_tensor_map) + ei_add_test(cxx11_tensor_math) + ei_add_test(cxx11_tensor_mixed_indices) ei_add_test(cxx11_tensor_morphing) + ei_add_test(cxx11_tensor_move) + ei_add_test(cxx11_tensor_notification "-pthread" "${CMAKE_THREAD_LIBS_INIT}") + ei_add_test(cxx11_tensor_of_complex) + ei_add_test(cxx11_tensor_of_const_values) + ei_add_test(cxx11_tensor_of_strings) ei_add_test(cxx11_tensor_padding) ei_add_test(cxx11_tensor_patch) - ei_add_test(cxx11_tensor_image_patch) - ei_add_test(cxx11_tensor_volume_patch) + ei_add_test(cxx11_tensor_random) ei_add_test(cxx11_tensor_reduction) - ei_add_test(cxx11_tensor_argmax) + ei_add_test(cxx11_tensor_ref) + ei_add_test(cxx11_tensor_roundings) + ei_add_test(cxx11_tensor_scan) ei_add_test(cxx11_tensor_shuffling) + ei_add_test(cxx11_tensor_simple) ei_add_test(cxx11_tensor_striding) - ei_add_test(cxx11_tensor_notification "-pthread" "${CMAKE_THREAD_LIBS_INIT}") + ei_add_test(cxx11_tensor_sugar) ei_add_test(cxx11_tensor_thread_local "-pthread" "${CMAKE_THREAD_LIBS_INIT}") ei_add_test(cxx11_tensor_thread_pool "-pthread" "${CMAKE_THREAD_LIBS_INIT}") - ei_add_test(cxx11_tensor_executor "-pthread" "${CMAKE_THREAD_LIBS_INIT}") - ei_add_test(cxx11_tensor_ref) - ei_add_test(cxx11_tensor_random) - ei_add_test(cxx11_tensor_generator) - ei_add_test(cxx11_tensor_custom_op) - ei_add_test(cxx11_tensor_custom_index) - ei_add_test(cxx11_tensor_fft) - ei_add_test(cxx11_tensor_ifft) - ei_add_test(cxx11_tensor_scan) ei_add_test(cxx11_tensor_trace) - ei_add_test(cxx11_tensor_move) + ei_add_test(cxx11_tensor_volume_patch) +# ei_add_test(cxx11_tensor_symmetry) if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8" AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") # This test requires __uint128_t which is only available on 64bit systems ei_add_test(cxx11_tensor_uint128)