Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
eb3199fc
P
Paddle
项目概览
Crayon鑫
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
eb3199fc
编写于
4月 01, 2021
作者:
W
wuhuanzhou
提交者:
GitHub
4月 01, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix compilation error on rocm, test=develop (#31991)
上级
d5b5004b
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
815 addition
and
1 deletion
+815
-1
cmake/external/eigen.cmake
cmake/external/eigen.cmake
+9
-1
patches/eigen/Meta.h
patches/eigen/Meta.h
+806
-0
未找到文件。
cmake/external/eigen.cmake
浏览文件 @
eb3199fc
...
...
@@ -27,6 +27,14 @@ cache_third_party(extern_eigen3
if
(
WIN32
)
add_definitions
(
-DEIGEN_STRONG_INLINE=inline
)
elseif
(
LINUX
)
if
(
WITH_ROCM
)
# For HIPCC Eigen::internal::device::numeric_limits is not EIGEN_DEVICE_FUNC
# which will cause compiler error of using __host__ funciont in __host__ __device__
file
(
TO_NATIVE_PATH
${
PADDLE_SOURCE_DIR
}
/patches/eigen/Meta.h native_src
)
file
(
TO_NATIVE_PATH
${
EIGEN_SOURCE_DIR
}
/Eigen/src/Core/util/Meta.h native_dst
)
set
(
EIGEN_PATCH_COMMAND cp
${
native_src
}
${
native_dst
}
)
endif
()
endif
()
set
(
EIGEN_INCLUDE_DIR
${
EIGEN_SOURCE_DIR
}
)
...
...
@@ -40,7 +48,7 @@ ExternalProject_Add(
PREFIX
${
EIGEN_PREFIX_DIR
}
SOURCE_DIR
${
EIGEN_SOURCE_DIR
}
UPDATE_COMMAND
""
PATCH_COMMAND
""
PATCH_COMMAND
${
EIGEN_PATCH_COMMAND
}
CONFIGURE_COMMAND
""
BUILD_COMMAND
""
INSTALL_COMMAND
""
...
...
patches/eigen/Meta.h
0 → 100755
浏览文件 @
eb3199fc
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// 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_META_H
#define EIGEN_META_H
#if defined(EIGEN_GPU_COMPILE_PHASE)
#include <cfloat>
#if defined(EIGEN_CUDA_ARCH)
#include <math_constants.h>
#endif
#if defined(EIGEN_HIP_DEVICE_COMPILE)
#include "Eigen/src/Core/arch/HIP/hcc/math_constants.h"
#endif
#endif
// Recent versions of ICC require <cstdint> for pointer types below.
#define EIGEN_ICC_NEEDS_CSTDINT (EIGEN_COMP_ICC>=1600 && EIGEN_COMP_CXXVER >= 11)
// Define portable (u)int{32,64} types
#if EIGEN_HAS_CXX11 || EIGEN_ICC_NEEDS_CSTDINT
#include <cstdint>
namespace
Eigen
{
namespace
numext
{
typedef
std
::
uint8_t
uint8_t
;
typedef
std
::
int8_t
int8_t
;
typedef
std
::
uint16_t
uint16_t
;
typedef
std
::
int16_t
int16_t
;
typedef
std
::
uint32_t
uint32_t
;
typedef
std
::
int32_t
int32_t
;
typedef
std
::
uint64_t
uint64_t
;
typedef
std
::
int64_t
int64_t
;
}
}
#else
// Without c++11, all compilers able to compile Eigen also
// provide the C99 stdint.h header file.
#include <stdint.h>
namespace
Eigen
{
namespace
numext
{
typedef
::
uint8_t
uint8_t
;
typedef
::
int8_t
int8_t
;
typedef
::
uint16_t
uint16_t
;
typedef
::
int16_t
int16_t
;
typedef
::
uint32_t
uint32_t
;
typedef
::
int32_t
int32_t
;
typedef
::
uint64_t
uint64_t
;
typedef
::
int64_t
int64_t
;
}
}
#endif
namespace
Eigen
{
typedef
EIGEN_DEFAULT_DENSE_INDEX_TYPE
DenseIndex
;
/**
* \brief The Index type as used for the API.
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
* \sa \blank \ref TopicPreprocessorDirectives, StorageIndex.
*/
typedef
EIGEN_DEFAULT_DENSE_INDEX_TYPE
Index
;
namespace
internal
{
/** \internal
* \file Meta.h
* This file contains generic metaprogramming classes which are not specifically related to Eigen.
* \note In case you wonder, yes we're aware that Boost already provides all these features,
* we however don't want to add a dependency to Boost.
*/
// Only recent versions of ICC complain about using ptrdiff_t to hold pointers,
// and older versions do not provide *intptr_t types.
#if EIGEN_ICC_NEEDS_CSTDINT
typedef
std
::
intptr_t
IntPtr
;
typedef
std
::
uintptr_t
UIntPtr
;
#else
typedef
std
::
ptrdiff_t
IntPtr
;
typedef
std
::
size_t
UIntPtr
;
#endif
#undef EIGEN_ICC_NEEDS_CSTDINT
struct
true_type
{
enum
{
value
=
1
};
};
struct
false_type
{
enum
{
value
=
0
};
};
template
<
bool
Condition
>
struct
bool_constant
;
template
<
>
struct
bool_constant
<
true
>
:
true_type
{};
template
<
>
struct
bool_constant
<
false
>
:
false_type
{};
template
<
bool
Condition
,
typename
Then
,
typename
Else
>
struct
conditional
{
typedef
Then
type
;
};
template
<
typename
Then
,
typename
Else
>
struct
conditional
<
false
,
Then
,
Else
>
{
typedef
Else
type
;
};
template
<
typename
T
>
struct
remove_reference
{
typedef
T
type
;
};
template
<
typename
T
>
struct
remove_reference
<
T
&>
{
typedef
T
type
;
};
template
<
typename
T
>
struct
remove_pointer
{
typedef
T
type
;
};
template
<
typename
T
>
struct
remove_pointer
<
T
*>
{
typedef
T
type
;
};
template
<
typename
T
>
struct
remove_pointer
<
T
*
const
>
{
typedef
T
type
;
};
template
<
class
T
>
struct
remove_const
{
typedef
T
type
;
};
template
<
class
T
>
struct
remove_const
<
const
T
>
{
typedef
T
type
;
};
template
<
class
T
>
struct
remove_const
<
const
T
[]
>
{
typedef
T
type
[];
};
template
<
class
T
,
unsigned
int
Size
>
struct
remove_const
<
const
T
[
Size
]
>
{
typedef
T
type
[
Size
];
};
template
<
typename
T
>
struct
remove_all
{
typedef
T
type
;
};
template
<
typename
T
>
struct
remove_all
<
const
T
>
{
typedef
typename
remove_all
<
T
>::
type
type
;
};
template
<
typename
T
>
struct
remove_all
<
T
const
&>
{
typedef
typename
remove_all
<
T
>::
type
type
;
};
template
<
typename
T
>
struct
remove_all
<
T
&>
{
typedef
typename
remove_all
<
T
>::
type
type
;
};
template
<
typename
T
>
struct
remove_all
<
T
const
*>
{
typedef
typename
remove_all
<
T
>::
type
type
;
};
template
<
typename
T
>
struct
remove_all
<
T
*>
{
typedef
typename
remove_all
<
T
>::
type
type
;
};
template
<
typename
T
>
struct
is_arithmetic
{
enum
{
value
=
false
};
};
template
<
>
struct
is_arithmetic
<
float
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
double
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
long
double
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
bool
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
char
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
signed
char
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
unsigned
char
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
signed
short
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
unsigned
short
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
signed
int
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
unsigned
int
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
signed
long
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
unsigned
long
>
{
enum
{
value
=
true
};
};
template
<
typename
T
,
typename
U
>
struct
is_same
{
enum
{
value
=
0
};
};
template
<
typename
T
>
struct
is_same
<
T
,
T
>
{
enum
{
value
=
1
};
};
template
<
class
T
>
struct
is_void
:
is_same
<
void
,
typename
remove_const
<
T
>::
type
>
{};
#if EIGEN_HAS_CXX11
template
<
>
struct
is_arithmetic
<
signed
long
long
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_arithmetic
<
unsigned
long
long
>
{
enum
{
value
=
true
};
};
using
std
::
is_integral
;
#else
template
<
typename
T
>
struct
is_integral
{
enum
{
value
=
false
};
};
template
<
>
struct
is_integral
<
bool
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
char
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
signed
char
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
unsigned
char
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
signed
short
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
unsigned
short
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
signed
int
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
unsigned
int
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
signed
long
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
unsigned
long
>
{
enum
{
value
=
true
};
};
#if EIGEN_COMP_MSVC
template
<
>
struct
is_integral
<
signed
__int64
>
{
enum
{
value
=
true
};
};
template
<
>
struct
is_integral
<
unsigned
__int64
>
{
enum
{
value
=
true
};
};
#endif
#endif
#if EIGEN_HAS_CXX11
using
std
::
make_unsigned
;
#else
// TODO: Possibly improve this implementation of make_unsigned.
// It is currently used only by
// template<typename Scalar> struct random_default_impl<Scalar, false, true>.
template
<
typename
>
struct
make_unsigned
;
template
<
>
struct
make_unsigned
<
char
>
{
typedef
unsigned
char
type
;
};
template
<
>
struct
make_unsigned
<
signed
char
>
{
typedef
unsigned
char
type
;
};
template
<
>
struct
make_unsigned
<
unsigned
char
>
{
typedef
unsigned
char
type
;
};
template
<
>
struct
make_unsigned
<
signed
short
>
{
typedef
unsigned
short
type
;
};
template
<
>
struct
make_unsigned
<
unsigned
short
>
{
typedef
unsigned
short
type
;
};
template
<
>
struct
make_unsigned
<
signed
int
>
{
typedef
unsigned
int
type
;
};
template
<
>
struct
make_unsigned
<
unsigned
int
>
{
typedef
unsigned
int
type
;
};
template
<
>
struct
make_unsigned
<
signed
long
>
{
typedef
unsigned
long
type
;
};
template
<
>
struct
make_unsigned
<
unsigned
long
>
{
typedef
unsigned
long
type
;
};
#if EIGEN_COMP_MSVC
template
<
>
struct
make_unsigned
<
signed
__int64
>
{
typedef
unsigned
__int64
type
;
};
template
<
>
struct
make_unsigned
<
unsigned
__int64
>
{
typedef
unsigned
__int64
type
;
};
#endif
// Some platforms define int64_t as long long even for C++03. In this case we
// are missing the definition for make_unsigned. If we just define it, we get
// duplicated definitions for platforms defining int64_t as signed long for
// C++03. We therefore add the specialization for C++03 long long for these
// platforms only.
#if EIGEN_OS_MAC
template
<
>
struct
make_unsigned
<
unsigned
long
long
>
{
typedef
unsigned
long
long
type
;
};
template
<
>
struct
make_unsigned
<
long
long
>
{
typedef
unsigned
long
long
type
;
};
#endif
#endif
template
<
typename
T
>
struct
add_const
{
typedef
const
T
type
;
};
template
<
typename
T
>
struct
add_const
<
T
&>
{
typedef
T
&
type
;
};
template
<
typename
T
>
struct
is_const
{
enum
{
value
=
0
};
};
template
<
typename
T
>
struct
is_const
<
T
const
>
{
enum
{
value
=
1
};
};
template
<
typename
T
>
struct
add_const_on_value_type
{
typedef
const
T
type
;
};
template
<
typename
T
>
struct
add_const_on_value_type
<
T
&>
{
typedef
T
const
&
type
;
};
template
<
typename
T
>
struct
add_const_on_value_type
<
T
*>
{
typedef
T
const
*
type
;
};
template
<
typename
T
>
struct
add_const_on_value_type
<
T
*
const
>
{
typedef
T
const
*
const
type
;
};
template
<
typename
T
>
struct
add_const_on_value_type
<
T
const
*
const
>
{
typedef
T
const
*
const
type
;
};
#if EIGEN_HAS_CXX11
using
std
::
is_convertible
;
#else
template
<
typename
From
,
typename
To
>
struct
is_convertible_impl
{
private:
struct
any_conversion
{
template
<
typename
T
>
any_conversion
(
const
volatile
T
&
);
template
<
typename
T
>
any_conversion
(
T
&
);
};
struct
yes
{
int
a
[
1
];};
struct
no
{
int
a
[
2
];};
template
<
typename
T
>
static
yes
test
(
T
,
int
);
template
<
typename
T
>
static
no
test
(
any_conversion
,
...);
public:
static
typename
internal
::
remove_reference
<
From
>::
type
*
ms_from
;
#ifdef __INTEL_COMPILER
#pragma warning push
#pragma warning ( disable : 2259 )
#endif
enum
{
value
=
sizeof
(
test
<
To
>
(
*
ms_from
,
0
))
==
sizeof
(
yes
)
};
#ifdef __INTEL_COMPILER
#pragma warning pop
#endif
};
template
<
typename
From
,
typename
To
>
struct
is_convertible
{
enum
{
value
=
is_convertible_impl
<
From
,
To
>::
value
};
};
template
<
typename
T
>
struct
is_convertible
<
T
,
T
&>
{
enum
{
value
=
false
};
};
template
<
typename
T
>
struct
is_convertible
<
const
T
,
const
T
&>
{
enum
{
value
=
true
};
};
#endif
/** \internal Allows to enable/disable an overload
* according to a compile time condition.
*/
template
<
bool
Condition
,
typename
T
=
void
>
struct
enable_if
;
template
<
typename
T
>
struct
enable_if
<
true
,
T
>
{
typedef
T
type
;
};
#if defined(EIGEN_GPU_COMPILE_PHASE)
#if !defined(__FLT_EPSILON__)
#define __FLT_EPSILON__ FLT_EPSILON
#define __DBL_EPSILON__ DBL_EPSILON
#endif
namespace
device
{
template
<
typename
T
>
struct
numeric_limits
{
EIGEN_DEVICE_FUNC
static
T
epsilon
()
{
return
0
;
}
EIGEN_DEVICE_FUNC
static
T
(
max
)()
{
assert
(
false
&&
"Highest not supported for this type"
);
}
EIGEN_DEVICE_FUNC
static
T
(
min
)()
{
assert
(
false
&&
"Lowest not supported for this type"
);
}
EIGEN_DEVICE_FUNC
static
T
infinity
()
{
assert
(
false
&&
"Infinity not supported for this type"
);
}
EIGEN_DEVICE_FUNC
static
T
quiet_NaN
()
{
assert
(
false
&&
"quiet_NaN not supported for this type"
);
}
};
template
<
>
struct
numeric_limits
<
float
>
{
EIGEN_DEVICE_FUNC
static
float
epsilon
()
{
return
__FLT_EPSILON__
;
}
EIGEN_DEVICE_FUNC
static
float
(
max
)()
{
#if defined(EIGEN_CUDA_ARCH)
return
CUDART_MAX_NORMAL_F
;
#else
return
HIPRT_MAX_NORMAL_F
;
#endif
}
EIGEN_DEVICE_FUNC
static
float
(
min
)()
{
return
FLT_MIN
;
}
EIGEN_DEVICE_FUNC
static
float
infinity
()
{
#if defined(EIGEN_CUDA_ARCH)
return
CUDART_INF_F
;
#else
return
HIPRT_INF_F
;
#endif
}
EIGEN_DEVICE_FUNC
static
float
quiet_NaN
()
{
#if defined(EIGEN_CUDA_ARCH)
return
CUDART_NAN_F
;
#else
return
HIPRT_NAN_F
;
#endif
}
};
template
<
>
struct
numeric_limits
<
double
>
{
EIGEN_DEVICE_FUNC
static
double
epsilon
()
{
return
__DBL_EPSILON__
;
}
EIGEN_DEVICE_FUNC
static
double
(
max
)()
{
return
DBL_MAX
;
}
EIGEN_DEVICE_FUNC
static
double
(
min
)()
{
return
DBL_MIN
;
}
EIGEN_DEVICE_FUNC
static
double
infinity
()
{
#if defined(EIGEN_CUDA_ARCH)
return
CUDART_INF
;
#else
return
HIPRT_INF
;
#endif
}
EIGEN_DEVICE_FUNC
static
double
quiet_NaN
()
{
#if defined(EIGEN_CUDA_ARCH)
return
CUDART_NAN
;
#else
return
HIPRT_NAN
;
#endif
}
};
template
<
>
struct
numeric_limits
<
int
>
{
EIGEN_DEVICE_FUNC
static
int
epsilon
()
{
return
0
;
}
EIGEN_DEVICE_FUNC
static
int
(
max
)()
{
return
INT_MAX
;
}
EIGEN_DEVICE_FUNC
static
int
(
min
)()
{
return
INT_MIN
;
}
};
template
<
>
struct
numeric_limits
<
unsigned
int
>
{
EIGEN_DEVICE_FUNC
static
unsigned
int
epsilon
()
{
return
0
;
}
EIGEN_DEVICE_FUNC
static
unsigned
int
(
max
)()
{
return
UINT_MAX
;
}
EIGEN_DEVICE_FUNC
static
unsigned
int
(
min
)()
{
return
0
;
}
};
template
<
>
struct
numeric_limits
<
long
>
{
EIGEN_DEVICE_FUNC
static
long
epsilon
()
{
return
0
;
}
EIGEN_DEVICE_FUNC
static
long
(
max
)()
{
return
LONG_MAX
;
}
EIGEN_DEVICE_FUNC
static
long
(
min
)()
{
return
LONG_MIN
;
}
};
template
<
>
struct
numeric_limits
<
unsigned
long
>
{
EIGEN_DEVICE_FUNC
static
unsigned
long
epsilon
()
{
return
0
;
}
EIGEN_DEVICE_FUNC
static
unsigned
long
(
max
)()
{
return
ULONG_MAX
;
}
EIGEN_DEVICE_FUNC
static
unsigned
long
(
min
)()
{
return
0
;
}
};
template
<
>
struct
numeric_limits
<
long
long
>
{
EIGEN_DEVICE_FUNC
static
long
long
epsilon
()
{
return
0
;
}
EIGEN_DEVICE_FUNC
static
long
long
(
max
)()
{
return
LLONG_MAX
;
}
EIGEN_DEVICE_FUNC
static
long
long
(
min
)()
{
return
LLONG_MIN
;
}
};
template
<
>
struct
numeric_limits
<
unsigned
long
long
>
{
EIGEN_DEVICE_FUNC
static
unsigned
long
long
epsilon
()
{
return
0
;
}
EIGEN_DEVICE_FUNC
static
unsigned
long
long
(
max
)()
{
return
ULLONG_MAX
;
}
EIGEN_DEVICE_FUNC
static
unsigned
long
long
(
min
)()
{
return
0
;
}
};
template
<
>
struct
numeric_limits
<
bool
>
{
EIGEN_DEVICE_FUNC
static
bool
epsilon
()
{
return
false
;
}
EIGEN_DEVICE_FUNC
static
bool
(
max
)()
{
return
true
;
}
EIGEN_DEVICE_FUNC
static
bool
(
min
)()
{
return
false
;
}
};
}
#endif
/** \internal
* A base class do disable default copy ctor and copy assignment operator.
*/
class
noncopyable
{
EIGEN_DEVICE_FUNC
noncopyable
(
const
noncopyable
&
);
EIGEN_DEVICE_FUNC
const
noncopyable
&
operator
=
(
const
noncopyable
&
);
protected:
EIGEN_DEVICE_FUNC
noncopyable
()
{}
EIGEN_DEVICE_FUNC
~
noncopyable
()
{}
};
/** \internal
* Provides access to the number of elements in the object of as a compile-time constant expression.
* It "returns" Eigen::Dynamic if the size cannot be resolved at compile-time (default).
*
* Similar to std::tuple_size, but more general.
*
* It currently supports:
* - any types T defining T::SizeAtCompileTime
* - plain C arrays as T[N]
* - std::array (c++11)
* - some internal types such as SingleRange and AllRange
*
* The second template parameter eases SFINAE-based specializations.
*/
template
<
typename
T
,
typename
EnableIf
=
void
>
struct
array_size
{
enum
{
value
=
Dynamic
};
};
template
<
typename
T
>
struct
array_size
<
T
,
typename
internal
::
enable_if
<
((
T
::
SizeAtCompileTime
&
0
)
==
0
)
>::
type
>
{
enum
{
value
=
T
::
SizeAtCompileTime
};
};
template
<
typename
T
,
int
N
>
struct
array_size
<
const
T
(
&
)[
N
]
>
{
enum
{
value
=
N
};
};
template
<
typename
T
,
int
N
>
struct
array_size
<
T
(
&
)[
N
]
>
{
enum
{
value
=
N
};
};
#if EIGEN_HAS_CXX11
template
<
typename
T
,
std
::
size_t
N
>
struct
array_size
<
const
std
::
array
<
T
,
N
>
>
{
enum
{
value
=
N
};
};
template
<
typename
T
,
std
::
size_t
N
>
struct
array_size
<
std
::
array
<
T
,
N
>
>
{
enum
{
value
=
N
};
};
#endif
/** \internal
* Analogue of the std::size free function.
* It returns the size of the container or view \a x of type \c T
*
* It currently supports:
* - any types T defining a member T::size() const
* - plain C arrays as T[N]
*
*/
template
<
typename
T
>
Index
size
(
const
T
&
x
)
{
return
x
.
size
();
}
template
<
typename
T
,
std
::
size_t
N
>
Index
size
(
const
T
(
&
)
[
N
])
{
return
N
;
}
/** \internal
* Convenient struct to get the result type of a nullary, unary, binary, or
* ternary functor.
*
* Pre C++11:
* Supports both a Func::result_type member and templated
* Func::result<Func(ArgTypes...)>::type member.
*
* If none of these members is provided, then the type of the first
* argument is returned.
*
* Post C++11:
* This uses std::result_of. However, note the `type` member removes
* const and converts references/pointers to their corresponding value type.
*/
#if EIGEN_HAS_STD_INVOKE_RESULT
template
<
typename
T
>
struct
result_of
;
template
<
typename
F
,
typename
...
ArgTypes
>
struct
result_of
<
F
(
ArgTypes
...)
>
{
typedef
typename
std
::
invoke_result
<
F
,
ArgTypes
...
>::
type
type1
;
typedef
typename
remove_all
<
type1
>::
type
type
;
};
#elif EIGEN_HAS_STD_RESULT_OF
template
<
typename
T
>
struct
result_of
{
typedef
typename
std
::
result_of
<
T
>::
type
type1
;
typedef
typename
remove_all
<
type1
>::
type
type
;
};
#else
template
<
typename
T
>
struct
result_of
{
};
struct
has_none
{
int
a
[
1
];};
struct
has_std_result_type
{
int
a
[
2
];};
struct
has_tr1_result
{
int
a
[
3
];};
template
<
typename
Func
,
int
SizeOf
>
struct
nullary_result_of_select
{};
template
<
typename
Func
>
struct
nullary_result_of_select
<
Func
,
sizeof
(
has_std_result_type
)
>
{
typedef
typename
Func
::
result_type
type
;};
template
<
typename
Func
>
struct
nullary_result_of_select
<
Func
,
sizeof
(
has_tr1_result
)
>
{
typedef
typename
Func
::
template
result
<
Func
()>
::
type
type
;};
template
<
typename
Func
>
struct
result_of
<
Func
()
>
{
template
<
typename
T
>
static
has_std_result_type
testFunctor
(
T
const
*
,
typename
T
::
result_type
const
*
=
0
);
template
<
typename
T
>
static
has_tr1_result
testFunctor
(
T
const
*
,
typename
T
::
template
result
<
T
()>
::
type
const
*
=
0
);
static
has_none
testFunctor
(...);
// note that the following indirection is needed for gcc-3.3
enum
{
FunctorType
=
sizeof
(
testFunctor
(
static_cast
<
Func
*>
(
0
)))};
typedef
typename
nullary_result_of_select
<
Func
,
FunctorType
>::
type
type
;
};
template
<
typename
Func
,
typename
ArgType
,
int
SizeOf
=
sizeof
(
has_none
)>
struct
unary_result_of_select
{
typedef
typename
internal
::
remove_all
<
ArgType
>::
type
type
;};
template
<
typename
Func
,
typename
ArgType
>
struct
unary_result_of_select
<
Func
,
ArgType
,
sizeof
(
has_std_result_type
)
>
{
typedef
typename
Func
::
result_type
type
;};
template
<
typename
Func
,
typename
ArgType
>
struct
unary_result_of_select
<
Func
,
ArgType
,
sizeof
(
has_tr1_result
)
>
{
typedef
typename
Func
::
template
result
<
Func
(
ArgType
)>
::
type
type
;};
template
<
typename
Func
,
typename
ArgType
>
struct
result_of
<
Func
(
ArgType
)
>
{
template
<
typename
T
>
static
has_std_result_type
testFunctor
(
T
const
*
,
typename
T
::
result_type
const
*
=
0
);
template
<
typename
T
>
static
has_tr1_result
testFunctor
(
T
const
*
,
typename
T
::
template
result
<
T
(
ArgType
)>
::
type
const
*
=
0
);
static
has_none
testFunctor
(...);
// note that the following indirection is needed for gcc-3.3
enum
{
FunctorType
=
sizeof
(
testFunctor
(
static_cast
<
Func
*>
(
0
)))};
typedef
typename
unary_result_of_select
<
Func
,
ArgType
,
FunctorType
>::
type
type
;
};
template
<
typename
Func
,
typename
ArgType0
,
typename
ArgType1
,
int
SizeOf
=
sizeof
(
has_none
)>
struct
binary_result_of_select
{
typedef
typename
internal
::
remove_all
<
ArgType0
>::
type
type
;};
template
<
typename
Func
,
typename
ArgType0
,
typename
ArgType1
>
struct
binary_result_of_select
<
Func
,
ArgType0
,
ArgType1
,
sizeof
(
has_std_result_type
)
>
{
typedef
typename
Func
::
result_type
type
;};
template
<
typename
Func
,
typename
ArgType0
,
typename
ArgType1
>
struct
binary_result_of_select
<
Func
,
ArgType0
,
ArgType1
,
sizeof
(
has_tr1_result
)
>
{
typedef
typename
Func
::
template
result
<
Func
(
ArgType0
,
ArgType1
)>
::
type
type
;};
template
<
typename
Func
,
typename
ArgType0
,
typename
ArgType1
>
struct
result_of
<
Func
(
ArgType0
,
ArgType1
)
>
{
template
<
typename
T
>
static
has_std_result_type
testFunctor
(
T
const
*
,
typename
T
::
result_type
const
*
=
0
);
template
<
typename
T
>
static
has_tr1_result
testFunctor
(
T
const
*
,
typename
T
::
template
result
<
T
(
ArgType0
,
ArgType1
)>
::
type
const
*
=
0
);
static
has_none
testFunctor
(...);
// note that the following indirection is needed for gcc-3.3
enum
{
FunctorType
=
sizeof
(
testFunctor
(
static_cast
<
Func
*>
(
0
)))};
typedef
typename
binary_result_of_select
<
Func
,
ArgType0
,
ArgType1
,
FunctorType
>::
type
type
;
};
template
<
typename
Func
,
typename
ArgType0
,
typename
ArgType1
,
typename
ArgType2
,
int
SizeOf
=
sizeof
(
has_none
)>
struct
ternary_result_of_select
{
typedef
typename
internal
::
remove_all
<
ArgType0
>::
type
type
;};
template
<
typename
Func
,
typename
ArgType0
,
typename
ArgType1
,
typename
ArgType2
>
struct
ternary_result_of_select
<
Func
,
ArgType0
,
ArgType1
,
ArgType2
,
sizeof
(
has_std_result_type
)
>
{
typedef
typename
Func
::
result_type
type
;};
template
<
typename
Func
,
typename
ArgType0
,
typename
ArgType1
,
typename
ArgType2
>
struct
ternary_result_of_select
<
Func
,
ArgType0
,
ArgType1
,
ArgType2
,
sizeof
(
has_tr1_result
)
>
{
typedef
typename
Func
::
template
result
<
Func
(
ArgType0
,
ArgType1
,
ArgType2
)>
::
type
type
;};
template
<
typename
Func
,
typename
ArgType0
,
typename
ArgType1
,
typename
ArgType2
>
struct
result_of
<
Func
(
ArgType0
,
ArgType1
,
ArgType2
)
>
{
template
<
typename
T
>
static
has_std_result_type
testFunctor
(
T
const
*
,
typename
T
::
result_type
const
*
=
0
);
template
<
typename
T
>
static
has_tr1_result
testFunctor
(
T
const
*
,
typename
T
::
template
result
<
T
(
ArgType0
,
ArgType1
,
ArgType2
)>
::
type
const
*
=
0
);
static
has_none
testFunctor
(...);
// note that the following indirection is needed for gcc-3.3
enum
{
FunctorType
=
sizeof
(
testFunctor
(
static_cast
<
Func
*>
(
0
)))};
typedef
typename
ternary_result_of_select
<
Func
,
ArgType0
,
ArgType1
,
ArgType2
,
FunctorType
>::
type
type
;
};
#endif
#if EIGEN_HAS_STD_INVOKE_RESULT
template
<
typename
F
,
typename
...
ArgTypes
>
struct
invoke_result
{
typedef
typename
std
::
invoke_result
<
F
,
ArgTypes
...
>::
type
type1
;
typedef
typename
remove_all
<
type1
>::
type
type
;
};
#elif EIGEN_HAS_CXX11
template
<
typename
F
,
typename
...
ArgTypes
>
struct
invoke_result
{
typedef
typename
result_of
<
F
(
ArgTypes
...)
>::
type
type1
;
typedef
typename
remove_all
<
type1
>::
type
type
;
};
#else
template
<
typename
F
,
typename
ArgType0
=
void
,
typename
ArgType1
=
void
,
typename
ArgType2
=
void
>
struct
invoke_result
{
typedef
typename
result_of
<
F
(
ArgType0
,
ArgType1
,
ArgType2
)
>::
type
type1
;
typedef
typename
remove_all
<
type1
>::
type
type
;
};
template
<
typename
F
>
struct
invoke_result
<
F
,
void
,
void
,
void
>
{
typedef
typename
result_of
<
F
()
>::
type
type1
;
typedef
typename
remove_all
<
type1
>::
type
type
;
};
template
<
typename
F
,
typename
ArgType0
>
struct
invoke_result
<
F
,
ArgType0
,
void
,
void
>
{
typedef
typename
result_of
<
F
(
ArgType0
)
>::
type
type1
;
typedef
typename
remove_all
<
type1
>::
type
type
;
};
template
<
typename
F
,
typename
ArgType0
,
typename
ArgType1
>
struct
invoke_result
<
F
,
ArgType0
,
ArgType1
,
void
>
{
typedef
typename
result_of
<
F
(
ArgType0
,
ArgType1
)
>::
type
type1
;
typedef
typename
remove_all
<
type1
>::
type
type
;
};
#endif
struct
meta_yes
{
char
a
[
1
];
};
struct
meta_no
{
char
a
[
2
];
};
// Check whether T::ReturnType does exist
template
<
typename
T
>
struct
has_ReturnType
{
template
<
typename
C
>
static
meta_yes
testFunctor
(
C
const
*
,
typename
C
::
ReturnType
const
*
=
0
);
template
<
typename
C
>
static
meta_no
testFunctor
(...);
enum
{
value
=
sizeof
(
testFunctor
<
T
>
(
static_cast
<
T
*>
(
0
)))
==
sizeof
(
meta_yes
)
};
};
template
<
typename
T
>
const
T
*
return_ptr
();
template
<
typename
T
,
typename
IndexType
=
Index
>
struct
has_nullary_operator
{
template
<
typename
C
>
static
meta_yes
testFunctor
(
C
const
*
,
typename
enable_if
<
(
sizeof
(
return_ptr
<
C
>
()
->
operator
()())
>
0
)
>::
type
*
=
0
);
static
meta_no
testFunctor
(...);
enum
{
value
=
sizeof
(
testFunctor
(
static_cast
<
T
*>
(
0
)))
==
sizeof
(
meta_yes
)
};
};
template
<
typename
T
,
typename
IndexType
=
Index
>
struct
has_unary_operator
{
template
<
typename
C
>
static
meta_yes
testFunctor
(
C
const
*
,
typename
enable_if
<
(
sizeof
(
return_ptr
<
C
>
()
->
operator
()(
IndexType
(
0
)))
>
0
)
>::
type
*
=
0
);
static
meta_no
testFunctor
(...);
enum
{
value
=
sizeof
(
testFunctor
(
static_cast
<
T
*>
(
0
)))
==
sizeof
(
meta_yes
)
};
};
template
<
typename
T
,
typename
IndexType
=
Index
>
struct
has_binary_operator
{
template
<
typename
C
>
static
meta_yes
testFunctor
(
C
const
*
,
typename
enable_if
<
(
sizeof
(
return_ptr
<
C
>
()
->
operator
()(
IndexType
(
0
),
IndexType
(
0
)))
>
0
)
>::
type
*
=
0
);
static
meta_no
testFunctor
(...);
enum
{
value
=
sizeof
(
testFunctor
(
static_cast
<
T
*>
(
0
)))
==
sizeof
(
meta_yes
)
};
};
/** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer.
* Usage example: \code meta_sqrt<1023>::ret \endcode
*/
template
<
int
Y
,
int
InfX
=
0
,
int
SupX
=
((
Y
==
1
)
?
1
:
Y
/
2
),
bool
Done
=
((
SupX
-
InfX
)
<=
1
?
true
:
((
SupX
*
SupX
<=
Y
)
&&
((
SupX
+
1
)
*
(
SupX
+
1
)
>
Y
)))
>
// use ?: instead of || just to shut up a stupid gcc 4.3 warning
class
meta_sqrt
{
enum
{
MidX
=
(
InfX
+
SupX
)
/
2
,
TakeInf
=
MidX
*
MidX
>
Y
?
1
:
0
,
NewInf
=
int
(
TakeInf
)
?
InfX
:
int
(
MidX
),
NewSup
=
int
(
TakeInf
)
?
int
(
MidX
)
:
SupX
};
public:
enum
{
ret
=
meta_sqrt
<
Y
,
NewInf
,
NewSup
>::
ret
};
};
template
<
int
Y
,
int
InfX
,
int
SupX
>
class
meta_sqrt
<
Y
,
InfX
,
SupX
,
true
>
{
public
:
enum
{
ret
=
(
SupX
*
SupX
<=
Y
)
?
SupX
:
InfX
};
};
/** \internal Computes the least common multiple of two positive integer A and B
* at compile-time. It implements a naive algorithm testing all multiples of A.
* It thus works better if A>=B.
*/
template
<
int
A
,
int
B
,
int
K
=
1
,
bool
Done
=
((
A
*
K
)
%
B
)
==
0
>
struct
meta_least_common_multiple
{
enum
{
ret
=
meta_least_common_multiple
<
A
,
B
,
K
+
1
>::
ret
};
};
template
<
int
A
,
int
B
,
int
K
>
struct
meta_least_common_multiple
<
A
,
B
,
K
,
true
>
{
enum
{
ret
=
A
*
K
};
};
/** \internal determines whether the product of two numeric types is allowed and what the return type is */
template
<
typename
T
,
typename
U
>
struct
scalar_product_traits
{
enum
{
Defined
=
0
};
};
// FIXME quick workaround around current limitation of result_of
// template<typename Scalar, typename ArgType0, typename ArgType1>
// struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
// typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type;
// };
/** \internal Obtains a POD type suitable to use as storage for an object of a size
* of at most Len bytes, aligned as specified by \c Align.
*/
template
<
unsigned
Len
,
unsigned
Align
>
struct
aligned_storage
{
struct
type
{
EIGEN_ALIGN_TO_BOUNDARY
(
Align
)
unsigned
char
data
[
Len
];
};
};
}
// end namespace internal
namespace
numext
{
#if defined(EIGEN_GPU_COMPILE_PHASE)
template
<
typename
T
>
EIGEN_DEVICE_FUNC
void
swap
(
T
&
a
,
T
&
b
)
{
T
tmp
=
b
;
b
=
a
;
a
=
tmp
;
}
#else
template
<
typename
T
>
EIGEN_STRONG_INLINE
void
swap
(
T
&
a
,
T
&
b
)
{
std
::
swap
(
a
,
b
);
}
#endif
#if defined(EIGEN_GPU_COMPILE_PHASE)
using
internal
::
device
::
numeric_limits
;
#else
using
std
::
numeric_limits
;
#endif
// Integer division with rounding up.
// T is assumed to be an integer type with a>=0, and b>0
template
<
typename
T
>
EIGEN_DEVICE_FUNC
T
div_ceil
(
const
T
&
a
,
const
T
&
b
)
{
return
(
a
+
b
-
1
)
/
b
;
}
// The aim of the following functions is to bypass -Wfloat-equal warnings
// when we really want a strict equality comparison on floating points.
template
<
typename
X
,
typename
Y
>
EIGEN_STRONG_INLINE
EIGEN_DEVICE_FUNC
bool
equal_strict
(
const
X
&
x
,
const
Y
&
y
)
{
return
x
==
y
;
}
#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
template
<
>
EIGEN_STRONG_INLINE
EIGEN_DEVICE_FUNC
bool
equal_strict
(
const
float
&
x
,
const
float
&
y
)
{
return
std
::
equal_to
<
float
>
()(
x
,
y
);
}
template
<
>
EIGEN_STRONG_INLINE
EIGEN_DEVICE_FUNC
bool
equal_strict
(
const
double
&
x
,
const
double
&
y
)
{
return
std
::
equal_to
<
double
>
()(
x
,
y
);
}
#endif
template
<
typename
X
,
typename
Y
>
EIGEN_STRONG_INLINE
EIGEN_DEVICE_FUNC
bool
not_equal_strict
(
const
X
&
x
,
const
Y
&
y
)
{
return
x
!=
y
;
}
#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
template
<
>
EIGEN_STRONG_INLINE
EIGEN_DEVICE_FUNC
bool
not_equal_strict
(
const
float
&
x
,
const
float
&
y
)
{
return
std
::
not_equal_to
<
float
>
()(
x
,
y
);
}
template
<
>
EIGEN_STRONG_INLINE
EIGEN_DEVICE_FUNC
bool
not_equal_strict
(
const
double
&
x
,
const
double
&
y
)
{
return
std
::
not_equal_to
<
double
>
()(
x
,
y
);
}
#endif
}
// end namespace numext
}
// end namespace Eigen
#endif // EIGEN_META_H
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录