Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
846ce406
P
Paddle
项目概览
机器未来
/
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看板
未验证
提交
846ce406
编写于
1月 25, 2021
作者:
Q
Qi Li
提交者:
GitHub
1月 25, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[ROCM] update eigen cmake and patch, test=develop (#30602)
上级
173660be
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
1258 addition
and
39 deletion
+1258
-39
cmake/external/eigen.cmake
cmake/external/eigen.cmake
+27
-39
patches/eigen/BinaryFunctors.h
patches/eigen/BinaryFunctors.h
+509
-0
patches/eigen/Meta.h
patches/eigen/Meta.h
+722
-0
未找到文件。
cmake/external/eigen.cmake
浏览文件 @
846ce406
...
...
@@ -26,13 +26,6 @@ if(WIN32)
set
(
EIGEN_TAG 917060c364181f33a735dc023818d5a54f60e54c
)
endif
()
# eigen on cuda9.1 missing header of math_funtions.hpp
# https://stackoverflow.com/questions/43113508/math-functions-hpp-not-found-when-using-cuda-with-eigen
if
(
WITH_ROCM_PLATFORM
)
set
(
EIGEN_REPOSITORY
${
GIT_URL
}
/sabreshao/hipeigen.git
)
set
(
EIGEN_TAG 7cb2b6e5a4b4a1efe658abb215cd866c6fb2275e
)
endif
()
cache_third_party
(
extern_eigen3
REPOSITORY
${
EIGEN_REPOSITORY
}
TAG
${
EIGEN_TAG
}
...
...
@@ -56,14 +49,25 @@ elseif(LINUX)
# add patch to avoid compilation error in c++11
file
(
TO_NATIVE_PATH
${
PADDLE_SOURCE_DIR
}
/patches/eigen/MathFunctions.h native_src2
)
file
(
TO_NATIVE_PATH
${
EIGEN_SOURCE_DIR
}
/Eigen/src/Core/MathFunctions.h native_dst2
)
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_src3
)
file
(
TO_NATIVE_PATH
${
EIGEN_SOURCE_DIR
}
/Eigen/src/Core/util/Meta.h native_dst3
)
# For HIPCC Eigen::internal::scalar_sum_op<bool,bool> 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/BinaryFunctors.h native_src4
)
file
(
TO_NATIVE_PATH
${
EIGEN_SOURCE_DIR
}
/Eigen/src/Core/functors/BinaryFunctors.h native_dst4
)
set
(
EIGEN_PATCH_COMMAND cp
${
native_src1
}
${
native_dst1
}
&& cp
${
native_src2
}
${
native_dst2
}
&& cp
${
native_src3
}
${
native_dst3
}
&& cp
${
native_src4
}
${
native_dst4
}
)
else
()
set
(
EIGEN_PATCH_COMMAND cp
${
native_src1
}
${
native_dst1
}
&& cp
${
native_src2
}
${
native_dst2
}
)
endif
()
endif
()
set
(
EIGEN_INCLUDE_DIR
${
EIGEN_SOURCE_DIR
}
)
INCLUDE_DIRECTORIES
(
${
EIGEN_INCLUDE_DIR
}
)
if
(
WITH_AMD_GPU
)
ExternalProject_Add
(
ExternalProject_Add
(
extern_eigen3
${
EXTERNAL_PROJECT_LOG_ARGS
}
${
SHALLOW_CLONE
}
...
...
@@ -76,23 +80,7 @@ if(WITH_AMD_GPU)
BUILD_COMMAND
""
INSTALL_COMMAND
""
TEST_COMMAND
""
)
else
()
ExternalProject_Add
(
extern_eigen3
${
EXTERNAL_PROJECT_LOG_ARGS
}
${
SHALLOW_CLONE
}
"
${
EIGEN_DOWNLOAD_CMD
}
"
PREFIX
${
EIGEN_PREFIX_DIR
}
SOURCE_DIR
${
EIGEN_SOURCE_DIR
}
UPDATE_COMMAND
""
PATCH_COMMAND
${
EIGEN_PATCH_COMMAND
}
CONFIGURE_COMMAND
""
BUILD_COMMAND
""
INSTALL_COMMAND
""
TEST_COMMAND
""
)
endif
()
)
add_library
(
eigen3 INTERFACE
)
...
...
patches/eigen/BinaryFunctors.h
0 → 100644
浏览文件 @
846ce406
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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/.
// clang-format off
#ifndef EIGEN_BINARY_FUNCTORS_H
#define EIGEN_BINARY_FUNCTORS_H
namespace
Eigen
{
namespace
internal
{
//---------- associative binary functors ----------
template
<
typename
Arg1
,
typename
Arg2
>
struct
binary_op_base
{
typedef
Arg1
first_argument_type
;
typedef
Arg2
second_argument_type
;
};
/** \internal
* \brief Template functor to compute the sum of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, DenseBase::sum()
*/
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_sum_op
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
typename
ScalarBinaryOpTraits
<
LhsScalar
,
RhsScalar
,
scalar_sum_op
>::
ReturnType
result_type
;
#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_sum_op
)
#else
scalar_sum_op
()
{
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
+
b
;
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
a
,
const
Packet
&
b
)
const
{
return
internal
::
padd
(
a
,
b
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
predux
(
const
Packet
&
a
)
const
{
return
internal
::
predux
(
a
);
}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
functor_traits
<
scalar_sum_op
<
LhsScalar
,
RhsScalar
>
>
{
enum
{
Cost
=
(
NumTraits
<
LhsScalar
>::
AddCost
+
NumTraits
<
RhsScalar
>::
AddCost
)
/
2
,
// rough estimate!
PacketAccess
=
is_same
<
LhsScalar
,
RhsScalar
>::
value
&&
packet_traits
<
LhsScalar
>::
HasAdd
&&
packet_traits
<
RhsScalar
>::
HasAdd
// TODO vectorize mixed sum
};
};
/** \internal
* \brief Template specialization to deprecate the summation of boolean expressions.
* This is required to solve Bug 426.
* \sa DenseBase::count(), DenseBase::any(), ArrayBase::cast(), MatrixBase::cast()
*/
template
<
>
struct
scalar_sum_op
<
bool
,
bool
>
:
scalar_sum_op
<
int
,
int
>
{
EIGEN_DEPRECATED
EIGEN_DEVICE_FUNC
scalar_sum_op
()
{}
};
/** \internal
* \brief Template functor to compute the product of two scalars
*
* \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
*/
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_product_op
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
typename
ScalarBinaryOpTraits
<
LhsScalar
,
RhsScalar
,
scalar_product_op
>::
ReturnType
result_type
;
#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_product_op
)
#else
scalar_product_op
()
{
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
*
b
;
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
a
,
const
Packet
&
b
)
const
{
return
internal
::
pmul
(
a
,
b
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
predux
(
const
Packet
&
a
)
const
{
return
internal
::
predux_mul
(
a
);
}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
functor_traits
<
scalar_product_op
<
LhsScalar
,
RhsScalar
>
>
{
enum
{
Cost
=
(
NumTraits
<
LhsScalar
>::
MulCost
+
NumTraits
<
RhsScalar
>::
MulCost
)
/
2
,
// rough estimate!
PacketAccess
=
is_same
<
LhsScalar
,
RhsScalar
>::
value
&&
packet_traits
<
LhsScalar
>::
HasMul
&&
packet_traits
<
RhsScalar
>::
HasMul
// TODO vectorize mixed product
};
};
/** \internal
* \brief Template functor to compute the conjugate product of two scalars
*
* This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y)
*/
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_conj_product_op
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
enum
{
Conj
=
NumTraits
<
LhsScalar
>::
IsComplex
};
typedef
typename
ScalarBinaryOpTraits
<
LhsScalar
,
RhsScalar
,
scalar_conj_product_op
>::
ReturnType
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_conj_product_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
conj_helper
<
LhsScalar
,
RhsScalar
,
Conj
,
false
>
().
pmul
(
a
,
b
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
a
,
const
Packet
&
b
)
const
{
return
conj_helper
<
Packet
,
Packet
,
Conj
,
false
>
().
pmul
(
a
,
b
);
}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
functor_traits
<
scalar_conj_product_op
<
LhsScalar
,
RhsScalar
>
>
{
enum
{
Cost
=
NumTraits
<
LhsScalar
>::
MulCost
,
PacketAccess
=
internal
::
is_same
<
LhsScalar
,
RhsScalar
>::
value
&&
packet_traits
<
LhsScalar
>::
HasMul
};
};
/** \internal
* \brief Template functor to compute the min of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
*/
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_min_op
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
typename
ScalarBinaryOpTraits
<
LhsScalar
,
RhsScalar
,
scalar_min_op
>::
ReturnType
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_min_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
numext
::
mini
(
a
,
b
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
a
,
const
Packet
&
b
)
const
{
return
internal
::
pmin
(
a
,
b
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
predux
(
const
Packet
&
a
)
const
{
return
internal
::
predux_min
(
a
);
}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
functor_traits
<
scalar_min_op
<
LhsScalar
,
RhsScalar
>
>
{
enum
{
Cost
=
(
NumTraits
<
LhsScalar
>::
AddCost
+
NumTraits
<
RhsScalar
>::
AddCost
)
/
2
,
PacketAccess
=
internal
::
is_same
<
LhsScalar
,
RhsScalar
>::
value
&&
packet_traits
<
LhsScalar
>::
HasMin
};
};
/** \internal
* \brief Template functor to compute the max of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
*/
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_max_op
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
typename
ScalarBinaryOpTraits
<
LhsScalar
,
RhsScalar
,
scalar_max_op
>::
ReturnType
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_max_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
numext
::
maxi
(
a
,
b
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
a
,
const
Packet
&
b
)
const
{
return
internal
::
pmax
(
a
,
b
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
predux
(
const
Packet
&
a
)
const
{
return
internal
::
predux_max
(
a
);
}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
functor_traits
<
scalar_max_op
<
LhsScalar
,
RhsScalar
>
>
{
enum
{
Cost
=
(
NumTraits
<
LhsScalar
>::
AddCost
+
NumTraits
<
RhsScalar
>::
AddCost
)
/
2
,
PacketAccess
=
internal
::
is_same
<
LhsScalar
,
RhsScalar
>::
value
&&
packet_traits
<
LhsScalar
>::
HasMax
};
};
/** \internal
* \brief Template functors for comparison of two scalars
* \todo Implement packet-comparisons
*/
template
<
typename
LhsScalar
,
typename
RhsScalar
,
ComparisonName
cmp
>
struct
scalar_cmp_op
;
template
<
typename
LhsScalar
,
typename
RhsScalar
,
ComparisonName
cmp
>
struct
functor_traits
<
scalar_cmp_op
<
LhsScalar
,
RhsScalar
,
cmp
>
>
{
enum
{
Cost
=
(
NumTraits
<
LhsScalar
>::
AddCost
+
NumTraits
<
RhsScalar
>::
AddCost
)
/
2
,
PacketAccess
=
false
};
};
template
<
ComparisonName
Cmp
,
typename
LhsScalar
,
typename
RhsScalar
>
struct
result_of
<
scalar_cmp_op
<
LhsScalar
,
RhsScalar
,
Cmp
>
(
LhsScalar
,
RhsScalar
)
>
{
typedef
bool
type
;
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_cmp_op
<
LhsScalar
,
RhsScalar
,
cmp_EQ
>
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
bool
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_cmp_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
==
b
;}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_cmp_op
<
LhsScalar
,
RhsScalar
,
cmp_LT
>
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
bool
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_cmp_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
<
b
;}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_cmp_op
<
LhsScalar
,
RhsScalar
,
cmp_LE
>
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
bool
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_cmp_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
<=
b
;}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_cmp_op
<
LhsScalar
,
RhsScalar
,
cmp_GT
>
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
bool
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_cmp_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
>
b
;}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_cmp_op
<
LhsScalar
,
RhsScalar
,
cmp_GE
>
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
bool
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_cmp_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
>=
b
;}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_cmp_op
<
LhsScalar
,
RhsScalar
,
cmp_UNORD
>
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
bool
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_cmp_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
!
(
a
<=
b
||
b
<=
a
);}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_cmp_op
<
LhsScalar
,
RhsScalar
,
cmp_NEQ
>
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
bool
result_type
;
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_cmp_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
!=
b
;}
};
/** \internal
* \brief Template functor to compute the hypot of two \b positive \b and \b real scalars
*
* \sa MatrixBase::stableNorm(), class Redux
*/
template
<
typename
Scalar
>
struct
scalar_hypot_op
<
Scalar
,
Scalar
>
:
binary_op_base
<
Scalar
,
Scalar
>
{
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_hypot_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Scalar
operator
()
(
const
Scalar
&
x
,
const
Scalar
&
y
)
const
{
// This functor is used by hypotNorm only for which it is faster to first apply abs
// on all coefficients prior to reduction through hypot.
// This way we avoid calling abs on positive and real entries, and this also permits
// to seamlessly handle complexes. Otherwise we would have to handle both real and complexes
// through the same functor...
return
internal
::
positive_real_hypot
(
x
,
y
);
}
};
template
<
typename
Scalar
>
struct
functor_traits
<
scalar_hypot_op
<
Scalar
,
Scalar
>
>
{
enum
{
Cost
=
3
*
NumTraits
<
Scalar
>::
AddCost
+
2
*
NumTraits
<
Scalar
>::
MulCost
+
2
*
scalar_div_cost
<
Scalar
,
false
>::
value
,
PacketAccess
=
false
};
};
/** \internal
* \brief Template functor to compute the pow of two scalars
*/
template
<
typename
Scalar
,
typename
Exponent
>
struct
scalar_pow_op
:
binary_op_base
<
Scalar
,
Exponent
>
{
typedef
typename
ScalarBinaryOpTraits
<
Scalar
,
Exponent
,
scalar_pow_op
>::
ReturnType
result_type
;
#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_pow_op
)
#else
scalar_pow_op
()
{
typedef
Scalar
LhsScalar
;
typedef
Exponent
RhsScalar
;
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
EIGEN_DEVICE_FUNC
inline
result_type
operator
()
(
const
Scalar
&
a
,
const
Exponent
&
b
)
const
{
return
numext
::
pow
(
a
,
b
);
}
};
template
<
typename
Scalar
,
typename
Exponent
>
struct
functor_traits
<
scalar_pow_op
<
Scalar
,
Exponent
>
>
{
enum
{
Cost
=
5
*
NumTraits
<
Scalar
>::
MulCost
,
PacketAccess
=
false
};
};
//---------- non associative binary functors ----------
/** \internal
* \brief Template functor to compute the difference of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::operator-
*/
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_difference_op
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
typename
ScalarBinaryOpTraits
<
LhsScalar
,
RhsScalar
,
scalar_difference_op
>::
ReturnType
result_type
;
#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_difference_op
)
#else
scalar_difference_op
()
{
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
-
b
;
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
a
,
const
Packet
&
b
)
const
{
return
internal
::
psub
(
a
,
b
);
}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
functor_traits
<
scalar_difference_op
<
LhsScalar
,
RhsScalar
>
>
{
enum
{
Cost
=
(
NumTraits
<
LhsScalar
>::
AddCost
+
NumTraits
<
RhsScalar
>::
AddCost
)
/
2
,
PacketAccess
=
is_same
<
LhsScalar
,
RhsScalar
>::
value
&&
packet_traits
<
LhsScalar
>::
HasSub
&&
packet_traits
<
RhsScalar
>::
HasSub
};
};
/** \internal
* \brief Template functor to compute the quotient of two scalars
*
* \sa class CwiseBinaryOp, Cwise::operator/()
*/
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_quotient_op
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
typename
ScalarBinaryOpTraits
<
LhsScalar
,
RhsScalar
,
scalar_quotient_op
>::
ReturnType
result_type
;
#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_quotient_op
)
#else
scalar_quotient_op
()
{
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
a
/
b
;
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
a
,
const
Packet
&
b
)
const
{
return
internal
::
pdiv
(
a
,
b
);
}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
functor_traits
<
scalar_quotient_op
<
LhsScalar
,
RhsScalar
>
>
{
typedef
typename
scalar_quotient_op
<
LhsScalar
,
RhsScalar
>::
result_type
result_type
;
enum
{
PacketAccess
=
is_same
<
LhsScalar
,
RhsScalar
>::
value
&&
packet_traits
<
LhsScalar
>::
HasDiv
&&
packet_traits
<
RhsScalar
>::
HasDiv
,
Cost
=
scalar_div_cost
<
result_type
,
PacketAccess
>::
value
};
};
/** \internal
* \brief Template functor to compute the and of two booleans
*
* \sa class CwiseBinaryOp, ArrayBase::operator&&
*/
struct
scalar_boolean_and_op
{
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_boolean_and_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()
(
const
bool
&
a
,
const
bool
&
b
)
const
{
return
a
&&
b
;
}
};
template
<
>
struct
functor_traits
<
scalar_boolean_and_op
>
{
enum
{
Cost
=
NumTraits
<
bool
>::
AddCost
,
PacketAccess
=
false
};
};
/** \internal
* \brief Template functor to compute the or of two booleans
*
* \sa class CwiseBinaryOp, ArrayBase::operator||
*/
struct
scalar_boolean_or_op
{
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_boolean_or_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()
(
const
bool
&
a
,
const
bool
&
b
)
const
{
return
a
||
b
;
}
};
template
<
>
struct
functor_traits
<
scalar_boolean_or_op
>
{
enum
{
Cost
=
NumTraits
<
bool
>::
AddCost
,
PacketAccess
=
false
};
};
/** \internal
* \brief Template functor to compute the xor of two booleans
*
* \sa class CwiseBinaryOp, ArrayBase::operator^
*/
struct
scalar_boolean_xor_op
{
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_boolean_xor_op
)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
bool
operator
()
(
const
bool
&
a
,
const
bool
&
b
)
const
{
return
a
^
b
;
}
};
template
<
>
struct
functor_traits
<
scalar_boolean_xor_op
>
{
enum
{
Cost
=
NumTraits
<
bool
>::
AddCost
,
PacketAccess
=
false
};
};
/** \internal
* \brief Template functor to compute the absolute difference of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::absolute_difference
*/
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
scalar_absolute_difference_op
:
binary_op_base
<
LhsScalar
,
RhsScalar
>
{
typedef
typename
ScalarBinaryOpTraits
<
LhsScalar
,
RhsScalar
,
scalar_absolute_difference_op
>::
ReturnType
result_type
;
#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
EIGEN_EMPTY_STRUCT_CTOR
(
scalar_absolute_difference_op
)
#else
scalar_absolute_difference_op
()
{
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
LhsScalar
&
a
,
const
RhsScalar
&
b
)
const
{
return
numext
::
absdiff
(
a
,
b
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
a
,
const
Packet
&
b
)
const
{
return
internal
::
pabsdiff
(
a
,
b
);
}
};
template
<
typename
LhsScalar
,
typename
RhsScalar
>
struct
functor_traits
<
scalar_absolute_difference_op
<
LhsScalar
,
RhsScalar
>
>
{
enum
{
Cost
=
(
NumTraits
<
LhsScalar
>::
AddCost
+
NumTraits
<
RhsScalar
>::
AddCost
)
/
2
,
PacketAccess
=
is_same
<
LhsScalar
,
RhsScalar
>::
value
&&
packet_traits
<
LhsScalar
>::
HasAbsDiff
};
};
//---------- binary functors bound to a constant, thus appearing as a unary functor ----------
// The following two classes permits to turn any binary functor into a unary one with one argument bound to a constant value.
// They are analogues to std::binder1st/binder2nd but with the following differences:
// - they are compatible with packetOp
// - they are portable across C++ versions (the std::binder* are deprecated in C++11)
template
<
typename
BinaryOp
>
struct
bind1st_op
:
BinaryOp
{
typedef
typename
BinaryOp
::
first_argument_type
first_argument_type
;
typedef
typename
BinaryOp
::
second_argument_type
second_argument_type
;
typedef
typename
BinaryOp
::
result_type
result_type
;
EIGEN_DEVICE_FUNC
explicit
bind1st_op
(
const
first_argument_type
&
val
)
:
m_value
(
val
)
{}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
second_argument_type
&
b
)
const
{
return
BinaryOp
::
operator
()(
m_value
,
b
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
b
)
const
{
return
BinaryOp
::
packetOp
(
internal
::
pset1
<
Packet
>
(
m_value
),
b
);
}
first_argument_type
m_value
;
};
template
<
typename
BinaryOp
>
struct
functor_traits
<
bind1st_op
<
BinaryOp
>
>
:
functor_traits
<
BinaryOp
>
{};
template
<
typename
BinaryOp
>
struct
bind2nd_op
:
BinaryOp
{
typedef
typename
BinaryOp
::
first_argument_type
first_argument_type
;
typedef
typename
BinaryOp
::
second_argument_type
second_argument_type
;
typedef
typename
BinaryOp
::
result_type
result_type
;
EIGEN_DEVICE_FUNC
explicit
bind2nd_op
(
const
second_argument_type
&
val
)
:
m_value
(
val
)
{}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
result_type
operator
()
(
const
first_argument_type
&
a
)
const
{
return
BinaryOp
::
operator
()(
a
,
m_value
);
}
template
<
typename
Packet
>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE
const
Packet
packetOp
(
const
Packet
&
a
)
const
{
return
BinaryOp
::
packetOp
(
a
,
internal
::
pset1
<
Packet
>
(
m_value
));
}
second_argument_type
m_value
;
};
template
<
typename
BinaryOp
>
struct
functor_traits
<
bind2nd_op
<
BinaryOp
>
>
:
functor_traits
<
BinaryOp
>
{};
}
// end namespace internal
}
// end namespace Eigen
#endif // EIGEN_BINARY_FUNCTORS_H
// clang-format on
patches/eigen/Meta.h
0 → 100755
浏览文件 @
846ce406
// 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/.
// clang-format off
#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
#if EIGEN_COMP_ICC>=1600 && __cplusplus >= 201103L
#include <cstdint>
#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_COMP_ICC>=1600 && __cplusplus >= 201103L
typedef
std
::
intptr_t
IntPtr
;
typedef
std
::
uintptr_t
UIntPtr
;
#else
typedef
std
::
ptrdiff_t
IntPtr
;
typedef
std
::
size_t
UIntPtr
;
#endif
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
#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
;
}
};
}
#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 unary or binary functor.
*
* It supports both the current STL mechanism (using the result_type member) as well as
* upcoming next STL generation (using a templated result member).
* If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack.
*/
#if 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
,
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
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
/** \internal extract the bits of the float \a x */
inline
unsigned
int
as_uint
(
float
x
)
{
unsigned
int
ret
;
std
::
memcpy
(
&
ret
,
&
x
,
sizeof
(
float
));
return
ret
;
}
}
// end namespace numext
}
// end namespace Eigen
// Define portable (u)int{32,64} types
#if EIGEN_HAS_CXX11
#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
// provides 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
#endif // EIGEN_META_H
// clang-format on
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录