Eigen  5.0.1
 
Loading...
Searching...
No Matches
Assign_MKL.h
1/*
2 Copyright (c) 2011, Intel Corporation. All rights reserved.
3 Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice, this
9 list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of Intel Corporation nor the names of its contributors may
14 be used to endorse or promote products derived from this software without
15 specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 ********************************************************************************
29 * Content : Eigen bindings to Intel(R) MKL
30 * MKL VML support for coefficient-wise unary Eigen expressions like a=b.sin()
31 ********************************************************************************
32*/
33// SPDX-License-Identifier: BSD-3-Clause
34
35#ifndef EIGEN_ASSIGN_VML_H
36#define EIGEN_ASSIGN_VML_H
37
38// IWYU pragma: private
39#include "./InternalHeaderCheck.h"
40
41namespace Eigen {
42
43namespace internal {
44
45template <typename Dst, typename Src>
46class vml_assign_traits {
47 private:
48 enum {
49 DstHasDirectAccess = Dst::Flags & DirectAccessBit,
50 SrcHasDirectAccess = Src::Flags & DirectAccessBit,
51 StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)),
52 InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime)
53 : int(Dst::Flags) & RowMajorBit ? int(Dst::MaxColsAtCompileTime)
54 : int(Dst::MaxRowsAtCompileTime),
55 MaxSizeAtCompileTime = Dst::SizeAtCompileTime,
56
57 MightEnableVml = bool(StorageOrdersAgree) && bool(DstHasDirectAccess) && bool(SrcHasDirectAccess) &&
58 Src::InnerStrideAtCompileTime == 1 && Dst::InnerStrideAtCompileTime == 1,
59 MightLinearize = bool(MightEnableVml) && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit),
60 VmlSize = bool(MightLinearize) ? MaxSizeAtCompileTime : InnerMaxSize,
61 LargeEnough = (VmlSize == Dynamic) || VmlSize >= EIGEN_MKL_VML_THRESHOLD
62 };
63
64 public:
65 enum { EnableVml = MightEnableVml && LargeEnough, Traversal = MightLinearize ? LinearTraversal : DefaultTraversal };
66};
67
68#define EIGEN_PP_EXPAND(ARG) ARG
69#if !defined(EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1)
70#define EIGEN_VMLMODE_EXPAND_xLA , VML_HA
71#else
72#define EIGEN_VMLMODE_EXPAND_xLA , VML_LA
73#endif
74
75#define EIGEN_VMLMODE_EXPAND_x_
76
77#define EIGEN_VMLMODE_PREFIX_xLA vm
78#define EIGEN_VMLMODE_PREFIX_x_ v
79#define EIGEN_VMLMODE_PREFIX(VMLMODE) EIGEN_CAT(EIGEN_VMLMODE_PREFIX_x, VMLMODE)
80
81#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
82 template <typename DstXprType, typename SrcXprNested> \
83 struct Assignment<DstXprType, CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested>, \
84 assign_op<EIGENTYPE, EIGENTYPE>, Dense2Dense, \
85 std::enable_if_t<vml_assign_traits<DstXprType, SrcXprNested>::EnableVml>> { \
86 typedef CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested> SrcXprType; \
87 static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE, EIGENTYPE> &func) { \
88 resize_if_allowed(dst, src, func); \
89 eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
90 EIGEN_IF_CONSTEXPR (vml_assign_traits<DstXprType, SrcXprNested>::Traversal == (int)LinearTraversal) { \
91 VMLOP(dst.size(), (const VMLTYPE *)src.nestedExpression().data(), \
92 (VMLTYPE *)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
93 } else { \
94 const Index outerSize = dst.outerSize(); \
95 for (Index outer = 0; outer < outerSize; ++outer) { \
96 const EIGENTYPE *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer, 0)) \
97 : &(src.nestedExpression().coeffRef(0, outer)); \
98 EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer, 0)) : &(dst.coeffRef(0, outer)); \
99 VMLOP(dst.innerSize(), (const VMLTYPE *)src_ptr, \
100 (VMLTYPE *)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
101 } \
102 } \
103 } \
104 };
105
106#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP, VMLMODE) \
107 EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE), s##VMLOP), float, float, VMLMODE) \
108 EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE), d##VMLOP), double, double, VMLMODE)
109
110#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(EIGENOP, VMLOP, VMLMODE) \
111 EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE), c##VMLOP), scomplex, \
112 MKL_Complex8, VMLMODE) \
113 EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE), z##VMLOP), dcomplex, \
114 MKL_Complex16, VMLMODE)
115
116#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP, VMLMODE) \
117 EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP, VMLMODE) \
118 EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(EIGENOP, VMLOP, VMLMODE)
119
120EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sin, Sin, LA)
121EIGEN_MKL_VML_DECLARE_UNARY_CALLS(asin, Asin, LA)
122EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sinh, Sinh, LA)
123EIGEN_MKL_VML_DECLARE_UNARY_CALLS(cos, Cos, LA)
124EIGEN_MKL_VML_DECLARE_UNARY_CALLS(acos, Acos, LA)
125EIGEN_MKL_VML_DECLARE_UNARY_CALLS(cosh, Cosh, LA)
126EIGEN_MKL_VML_DECLARE_UNARY_CALLS(tan, Tan, LA)
127EIGEN_MKL_VML_DECLARE_UNARY_CALLS(atan, Atan, LA)
128EIGEN_MKL_VML_DECLARE_UNARY_CALLS(tanh, Tanh, LA)
129// EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs, _)
130EIGEN_MKL_VML_DECLARE_UNARY_CALLS(exp, Exp, LA)
131EIGEN_MKL_VML_DECLARE_UNARY_CALLS(log, Ln, LA)
132EIGEN_MKL_VML_DECLARE_UNARY_CALLS(log10, Log10, LA)
133EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sqrt, Sqrt, _)
134
135EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr, _)
136EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(arg, Arg, _)
137EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(round, Round, _)
138EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(floor, Floor, _)
139EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil, _)
140EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(cbrt, Cbrt, _)
141
142#define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
143 template <typename DstXprType, typename SrcXprNested, typename Plain> \
144 struct Assignment<DstXprType, \
145 CwiseBinaryOp<scalar_##EIGENOP##_op<EIGENTYPE, EIGENTYPE>, SrcXprNested, \
146 const CwiseNullaryOp<internal::scalar_constant_op<EIGENTYPE>, Plain>>, \
147 assign_op<EIGENTYPE, EIGENTYPE>, Dense2Dense, \
148 std::enable_if_t<vml_assign_traits<DstXprType, SrcXprNested>::EnableVml>> { \
149 typedef CwiseBinaryOp<scalar_##EIGENOP##_op<EIGENTYPE, EIGENTYPE>, SrcXprNested, \
150 const CwiseNullaryOp<internal::scalar_constant_op<EIGENTYPE>, Plain>> \
151 SrcXprType; \
152 static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE, EIGENTYPE> &func) { \
153 resize_if_allowed(dst, src, func); \
154 eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
155 VMLTYPE exponent = reinterpret_cast<const VMLTYPE &>(src.rhs().functor().m_other); \
156 EIGEN_IF_CONSTEXPR (vml_assign_traits<DstXprType, SrcXprNested>::Traversal == LinearTraversal) { \
157 VMLOP(dst.size(), (const VMLTYPE *)src.lhs().data(), exponent, \
158 (VMLTYPE *)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
159 } else { \
160 const Index outerSize = dst.outerSize(); \
161 for (Index outer = 0; outer < outerSize; ++outer) { \
162 const EIGENTYPE *src_ptr = \
163 src.IsRowMajor ? &(src.lhs().coeffRef(outer, 0)) : &(src.lhs().coeffRef(0, outer)); \
164 EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer, 0)) : &(dst.coeffRef(0, outer)); \
165 VMLOP(dst.innerSize(), (const VMLTYPE *)src_ptr, exponent, \
166 (VMLTYPE *)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
167 } \
168 } \
169 } \
170 };
171
172EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmsPowx, float, float, LA)
173EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdPowx, double, double, LA)
174EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcPowx, scomplex, MKL_Complex8, LA)
175EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzPowx, dcomplex, MKL_Complex16, LA)
176
177} // end namespace internal
178
179} // end namespace Eigen
180
181#endif // EIGEN_ASSIGN_VML_H
constexpr unsigned int DirectAccessBit
Definition Constants.h:160
constexpr unsigned int LinearAccessBit
Definition Constants.h:134
constexpr unsigned int RowMajorBit
Definition Constants.h:71