summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2018-07-03 07:37:12 +0200
committerStanislaw Halik <sthalik@misaki.pl>2018-07-03 08:13:09 +0200
commit88534ba623421c956d8ffcda2d27f41d704d15ef (patch)
treefccc55245aec3f7381cd525a1355568e10ea37f4
parent3ee09beb3f0458fbeb0b0e816f854b9d5b406e6b (diff)
update eigen
-rw-r--r--eigen/.hgignore4
-rw-r--r--eigen/.hgtags4
-rw-r--r--eigen/CMakeLists.txt23
-rw-r--r--eigen/CTestConfig.cmake8
-rw-r--r--eigen/Eigen/Core30
-rw-r--r--eigen/Eigen/Geometry1
-rw-r--r--eigen/Eigen/src/Cholesky/LDLT.h1
-rw-r--r--eigen/Eigen/src/Cholesky/LLT.h1
-rw-r--r--eigen/Eigen/src/CholmodSupport/CholmodSupport.h71
-rw-r--r--eigen/Eigen/src/Core/ArithmeticSequence.h350
-rw-r--r--eigen/Eigen/src/Core/Array.h8
-rw-r--r--eigen/Eigen/src/Core/ArrayBase.h2
-rw-r--r--eigen/Eigen/src/Core/ArrayWrapper.h6
-rw-r--r--eigen/Eigen/src/Core/Assign.h2
-rw-r--r--eigen/Eigen/src/Core/BooleanRedux.h44
-rw-r--r--eigen/Eigen/src/Core/CommaInitializer.h4
-rw-r--r--eigen/Eigen/src/Core/CoreEvaluators.h203
-rw-r--r--eigen/Eigen/src/Core/CoreIterators.h5
-rw-r--r--eigen/Eigen/src/Core/CwiseBinaryOp.h5
-rw-r--r--eigen/Eigen/src/Core/CwiseNullaryOp.h4
-rw-r--r--eigen/Eigen/src/Core/DenseBase.h4
-rw-r--r--eigen/Eigen/src/Core/Diagonal.h10
-rw-r--r--eigen/Eigen/src/Core/DiagonalMatrix.h4
-rw-r--r--eigen/Eigen/src/Core/DiagonalProduct.h2
-rw-r--r--eigen/Eigen/src/Core/Dot.h16
-rw-r--r--eigen/Eigen/src/Core/EigenBase.h1
-rw-r--r--eigen/Eigen/src/Core/Fuzzy.h6
-rw-r--r--eigen/Eigen/src/Core/GeneralProduct.h2
-rw-r--r--eigen/Eigen/src/Core/GenericPacketMath.h5
-rw-r--r--eigen/Eigen/src/Core/GlobalFunctions.h1
-rw-r--r--eigen/Eigen/src/Core/IndexedView.h207
-rw-r--r--eigen/Eigen/src/Core/MathFunctions.h274
-rw-r--r--eigen/Eigen/src/Core/MathFunctionsImpl.h7
-rw-r--r--eigen/Eigen/src/Core/MatrixBase.h2
-rw-r--r--eigen/Eigen/src/Core/NestByValue.h10
-rw-r--r--eigen/Eigen/src/Core/NumTraits.h4
-rw-r--r--eigen/Eigen/src/Core/ProductEvaluators.h6
-rw-r--r--eigen/Eigen/src/Core/Random.h2
-rw-r--r--eigen/Eigen/src/Core/Redux.h14
-rw-r--r--eigen/Eigen/src/Core/Ref.h2
-rw-r--r--eigen/Eigen/src/Core/Replicate.h4
-rw-r--r--eigen/Eigen/src/Core/ReturnByValue.h2
-rw-r--r--eigen/Eigen/src/Core/Reverse.h6
-rw-r--r--eigen/Eigen/src/Core/SelfAdjointView.h4
-rw-r--r--eigen/Eigen/src/Core/Solve.h4
-rw-r--r--eigen/Eigen/src/Core/SolveTriangular.h2
-rw-r--r--eigen/Eigen/src/Core/Transpose.h10
-rw-r--r--eigen/Eigen/src/Core/TriangularMatrix.h15
-rw-r--r--eigen/Eigen/src/Core/VectorwiseOp.h4
-rw-r--r--eigen/Eigen/src/Core/arch/AVX/PacketMath.h24
-rw-r--r--eigen/Eigen/src/Core/arch/AVX512/PacketMath.h200
-rw-r--r--eigen/Eigen/src/Core/arch/CUDA/Half.h77
-rw-r--r--eigen/Eigen/src/Core/arch/CUDA/MathFunctions.h12
-rw-r--r--eigen/Eigen/src/Core/arch/CUDA/PacketMath.h4
-rw-r--r--eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h9
-rw-r--r--eigen/Eigen/src/Core/arch/NEON/PacketMath.h2
-rw-r--r--eigen/Eigen/src/Core/arch/SSE/PacketMath.h66
-rw-r--r--eigen/Eigen/src/Core/functors/NullaryFunctors.h11
-rw-r--r--eigen/Eigen/src/Core/functors/UnaryFunctors.h44
-rw-r--r--eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h19
-rw-r--r--eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h2
-rw-r--r--eigen/Eigen/src/Core/products/GeneralMatrixVector.h680
-rw-r--r--eigen/Eigen/src/Core/products/SelfadjointProduct.h2
-rw-r--r--eigen/Eigen/src/Core/products/SelfadjointRank2Update.h2
-rw-r--r--eigen/Eigen/src/Core/util/BlasUtil.h5
-rw-r--r--eigen/Eigen/src/Core/util/Constants.h4
-rw-r--r--eigen/Eigen/src/Core/util/DisableStupidWarnings.h6
-rw-r--r--eigen/Eigen/src/Core/util/ForwardDeclarations.h1
-rw-r--r--eigen/Eigen/src/Core/util/IndexedViewHelper.h187
-rw-r--r--eigen/Eigen/src/Core/util/IntegralConstant.h270
-rw-r--r--eigen/Eigen/src/Core/util/Macros.h44
-rw-r--r--eigen/Eigen/src/Core/util/Memory.h26
-rw-r--r--eigen/Eigen/src/Core/util/Meta.h86
-rw-r--r--eigen/Eigen/src/Core/util/SymbolicIndex.h300
-rw-r--r--eigen/Eigen/src/Core/util/XprHelper.h4
-rw-r--r--eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h4
-rw-r--r--eigen/Eigen/src/Geometry/AlignedBox.h2
-rw-r--r--eigen/Eigen/src/Geometry/ParametrizedLine.h39
-rw-r--r--eigen/Eigen/src/Geometry/Quaternion.h10
-rw-r--r--eigen/Eigen/src/Geometry/Transform.h14
-rw-r--r--eigen/Eigen/src/Geometry/arch/Geometry_SSE.h60
-rw-r--r--eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h27
-rw-r--r--eigen/Eigen/src/Jacobi/Jacobi.h42
-rw-r--r--eigen/Eigen/src/LU/FullPivLU.h2
-rw-r--r--eigen/Eigen/src/QR/ColPivHouseholderQR.h13
-rw-r--r--eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h2
-rw-r--r--eigen/Eigen/src/QR/FullPivHouseholderQR.h9
-rw-r--r--eigen/Eigen/src/QR/HouseholderQR.h9
-rw-r--r--eigen/Eigen/src/SVD/BDCSVD.h81
-rw-r--r--eigen/Eigen/src/SVD/SVDBase.h1
-rw-r--r--eigen/Eigen/src/SVD/UpperBidiagonalization.h4
-rw-r--r--eigen/Eigen/src/SparseCore/SparseCompressedBase.h16
-rw-r--r--eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h12
-rw-r--r--eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h3
-rw-r--r--eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h6
-rw-r--r--eigen/Eigen/src/misc/lapacke.h9
-rw-r--r--eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h17
-rw-r--r--eigen/Eigen/src/plugins/BlockMethods.h576
-rw-r--r--eigen/Eigen/src/plugins/IndexedViewMethods.h267
-rw-r--r--eigen/bench/btl/actions/basic_actions.hh2
-rw-r--r--eigen/bench/btl/libs/BLAS/blas_interface_impl.hh6
-rw-r--r--eigen/bench/btl/libs/BLAS/main.cpp2
-rw-r--r--eigen/bench/btl/libs/STL/STL_interface.hh24
-rw-r--r--eigen/bench/btl/libs/blaze/blaze_interface.hh17
-rw-r--r--eigen/bench/btl/libs/blaze/main.cpp6
-rw-r--r--eigen/bench/btl/libs/eigen3/eigen3_interface.hh8
-rw-r--r--eigen/bench/btl/libs/eigen3/main_matmat.cpp2
-rw-r--r--eigen/bench/perf_monitoring/gemm.cpp12
-rw-r--r--eigen/bench/perf_monitoring/gemm/changesets.txt (renamed from eigen/bench/perf_monitoring/changesets.txt)18
-rw-r--r--eigen/bench/perf_monitoring/gemm/gemm.cpp (renamed from eigen/bench/perf_monitoring/gemm_common.h)26
-rw-r--r--eigen/bench/perf_monitoring/gemm/gemm_settings.txt (renamed from eigen/bench/perf_monitoring/gemm_settings.txt)0
-rw-r--r--eigen/bench/perf_monitoring/gemm/lazy_gemm.cpp (renamed from eigen/bench/perf_monitoring/lazy_gemm.cpp)5
-rw-r--r--eigen/bench/perf_monitoring/gemm/lazy_gemm_settings.txt (renamed from eigen/bench/perf_monitoring/lazy_gemm_settings.txt)0
-rw-r--r--eigen/bench/perf_monitoring/gemm/make_plot.sh38
-rw-r--r--eigen/bench/perf_monitoring/gemm/run.sh (renamed from eigen/bench/perf_monitoring/run.sh)52
-rw-r--r--eigen/bench/perf_monitoring/gemm_square_settings.txt11
-rw-r--r--eigen/bench/perf_monitoring/gemv.cpp12
-rw-r--r--eigen/bench/perf_monitoring/gemv_common.h69
-rw-r--r--eigen/bench/perf_monitoring/gemv_settings.txt11
-rw-r--r--eigen/bench/perf_monitoring/gemv_square_settings.txt13
-rw-r--r--eigen/bench/perf_monitoring/gemvt.cpp12
-rw-r--r--eigen/bench/perf_monitoring/llt.cpp15
-rw-r--r--eigen/bench/perf_monitoring/make_plot.sh98
-rw-r--r--eigen/bench/perf_monitoring/resources/chart_footer.html37
-rw-r--r--eigen/bench/perf_monitoring/resources/chart_header.html46
-rw-r--r--eigen/bench/perf_monitoring/resources/footer.html3
-rw-r--r--eigen/bench/perf_monitoring/resources/header.html42
-rw-r--r--eigen/bench/perf_monitoring/resources/s1.js1
-rw-r--r--eigen/bench/perf_monitoring/resources/s2.js1
-rw-r--r--eigen/bench/perf_monitoring/runall.sh63
-rw-r--r--eigen/bench/perf_monitoring/trmv_lo.cpp12
-rw-r--r--eigen/bench/perf_monitoring/trmv_lot.cpp12
-rw-r--r--eigen/bench/perf_monitoring/trmv_up.cpp12
-rw-r--r--eigen/bench/perf_monitoring/trmv_upt.cpp12
-rw-r--r--eigen/bench/spbench/CMakeLists.txt27
-rw-r--r--eigen/bench/tensors/tensor_benchmarks_sycl.cc23
-rw-r--r--eigen/blas/CMakeLists.txt10
-rw-r--r--eigen/cmake/FindBLAS.cmake1499
-rw-r--r--eigen/cmake/FindBLASEXT.cmake380
-rw-r--r--eigen/cmake/FindComputeCpp.cmake2
-rw-r--r--eigen/cmake/FindHWLOC.cmake331
-rw-r--r--eigen/cmake/FindMetis.cmake297
-rw-r--r--eigen/cmake/FindPTSCOTCH.cmake423
-rw-r--r--eigen/cmake/FindPastix.cmake713
-rw-r--r--eigen/cmake/FindScotch.cmake379
-rw-r--r--eigen/cmake/FindXsmm.cmake25
-rw-r--r--eigen/debug/gdb/printers.py168
-rw-r--r--eigen/doc/AsciiQuickReference.txt2
-rw-r--r--eigen/doc/Doxyfile.in5
-rw-r--r--eigen/doc/FixedSizeVectorizable.dox10
-rw-r--r--eigen/doc/PassingByValue.dox8
-rw-r--r--eigen/doc/TopicCMakeGuide.dox10
-rw-r--r--eigen/doc/UnalignedArrayAssert.dox9
-rw-r--r--eigen/doc/eigendoxy.css5
-rw-r--r--eigen/scripts/eigen_monitor_perf.sh25
-rw-r--r--eigen/test/CMakeLists.txt32
-rw-r--r--eigen/test/array.cpp25
-rw-r--r--eigen/test/array_for_matrix.cpp22
-rw-r--r--eigen/test/basicstuff.cpp16
-rw-r--r--eigen/test/block.cpp19
-rw-r--r--eigen/test/cholmod_support.cpp42
-rw-r--r--eigen/test/geo_alignedbox.cpp11
-rw-r--r--eigen/test/geo_parametrizedline.cpp27
-rw-r--r--eigen/test/half_float.cpp29
-rw-r--r--eigen/test/indexed_view.cpp378
-rw-r--r--eigen/test/lscg.cpp8
-rw-r--r--eigen/test/main.h11
-rw-r--r--eigen/test/mixingtypes.cpp2
-rw-r--r--eigen/test/numext.cpp53
-rw-r--r--eigen/test/packetmath.cpp1
-rw-r--r--eigen/test/product_mmtr.cpp11
-rw-r--r--eigen/test/product_notemporary.cpp1
-rw-r--r--eigen/test/sparse_product.cpp4
-rw-r--r--eigen/test/symbolic_index.cpp104
-rw-r--r--eigen/unsupported/CMakeLists.txt10
-rw-r--r--eigen/unsupported/Eigen/CXX11/Tensor9
-rw-r--r--eigen/unsupported/Eigen/CXX11/ThreadPool13
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/README.md8
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h6
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h2
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h30
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h6
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h287
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h134
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionCuda.h101
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h76
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h400
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h208
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h3
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h2
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h476
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceCuda.h7
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h4
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h413
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h13
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h12
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h5
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h11
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h4
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h41
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h14
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h4
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h12
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h8
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h5
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h53
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h7
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h30
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionCuda.h1
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h179
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h5
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h10
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h8
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h16
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSycl.h12
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclConvertToDeviceExpression.h54
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExprConstructor.h188
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractAccessor.h265
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractFunctors.h322
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclFunctors.h245
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclLeafCount.h138
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclPlaceHolderExpr.h57
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclRun.h77
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclTuple.h2
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h6
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h1
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h142
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h7
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h8
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadCancel.h23
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h2
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h6
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/util/CXX11Meta.h6
-rw-r--r--eigen/unsupported/Eigen/CXX11/src/util/EmulateArray.h13
-rw-r--r--eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h7
-rw-r--r--eigen/unsupported/Eigen/src/EulerAngles/EulerAngles.h257
-rw-r--r--eigen/unsupported/Eigen/src/EulerAngles/EulerSystem.h184
-rw-r--r--eigen/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h11
-rw-r--r--eigen/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h2
-rw-r--r--eigen/unsupported/Eigen/src/Polynomials/Companion.h50
-rw-r--r--eigen/unsupported/Eigen/src/Polynomials/PolynomialSolver.h18
-rw-r--r--eigen/unsupported/Eigen/src/SparseExtra/MarketIO.h89
-rw-r--r--eigen/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h8
-rw-r--r--eigen/unsupported/doc/examples/EulerAngles.cpp4
-rw-r--r--eigen/unsupported/test/CMakeLists.txt21
-rw-r--r--eigen/unsupported/test/EulerAngles.cpp296
-rw-r--r--eigen/unsupported/test/autodiff_scalar.cpp15
-rw-r--r--eigen/unsupported/test/cxx11_non_blocking_thread_pool.cpp24
-rw-r--r--eigen/unsupported/test/cxx11_tensor_broadcast_sycl.cpp114
-rw-r--r--eigen/unsupported/test/cxx11_tensor_builtins_sycl.cpp267
-rw-r--r--eigen/unsupported/test/cxx11_tensor_chipping.cpp8
-rw-r--r--eigen/unsupported/test/cxx11_tensor_chipping_sycl.cpp622
-rw-r--r--eigen/unsupported/test/cxx11_tensor_concatenation_sycl.cpp180
-rw-r--r--eigen/unsupported/test/cxx11_tensor_contract_sycl.cpp290
-rw-r--r--eigen/unsupported/test/cxx11_tensor_convolution_sycl.cpp469
-rw-r--r--eigen/unsupported/test/cxx11_tensor_device_sycl.cpp60
-rw-r--r--eigen/unsupported/test/cxx11_tensor_expr.cpp46
-rw-r--r--eigen/unsupported/test/cxx11_tensor_fixed_size.cpp2
-rw-r--r--eigen/unsupported/test/cxx11_tensor_forced_eval_sycl.cpp54
-rw-r--r--eigen/unsupported/test/cxx11_tensor_morphing_sycl.cpp248
-rw-r--r--eigen/unsupported/test/cxx11_tensor_notification.cpp17
-rw-r--r--eigen/unsupported/test/cxx11_tensor_of_float16_cuda.cu6
-rw-r--r--eigen/unsupported/test/cxx11_tensor_padding_sycl.cpp157
-rw-r--r--eigen/unsupported/test/cxx11_tensor_reduction_sycl.cpp167
-rw-r--r--eigen/unsupported/test/cxx11_tensor_reverse_sycl.cpp221
-rw-r--r--eigen/unsupported/test/cxx11_tensor_shuffling_sycl.cpp119
-rw-r--r--eigen/unsupported/test/cxx11_tensor_striding_sycl.cpp203
-rw-r--r--eigen/unsupported/test/cxx11_tensor_sycl.cpp219
-rw-r--r--eigen/unsupported/test/polynomialsolver.cpp34
-rw-r--r--eigen/unsupported/test/sparse_extra.cpp23
270 files changed, 6699 insertions, 12585 deletions
diff --git a/eigen/.hgignore b/eigen/.hgignore
index dcd9f44..769a47f 100644
--- a/eigen/.hgignore
+++ b/eigen/.hgignore
@@ -28,11 +28,7 @@ activity.png
*.rej
log
patch
-*.patch
a
a.*
lapack/testing
lapack/reference
-.*project
-.settings
-Makefile
diff --git a/eigen/.hgtags b/eigen/.hgtags
index 7036de1..32ec946 100644
--- a/eigen/.hgtags
+++ b/eigen/.hgtags
@@ -27,3 +27,7 @@ ce5a455b34c0a0ac3545a1497cb4a16c38ed90e8 3.3-beta1
69d418c0699907bcd0bf9e0b3ba0a112ed091d85 3.3-beta2
bef509908b9da05d0d07ffc0da105e2c8c6d3996 3.3-rc1
04ab5fa4b241754afcf631117572276444c67239 3.3-rc2
+26667be4f70baf4f0d39e96f330714c87b399090 3.3.0
+f562a193118d4f40514e2f4a0ace6e974926ef06 3.3.1
+da9b4e14c2550e0d11078a3c39e6d56eba9905df 3.3.2
+67e894c6cd8f5f1f604b27d37ed47fdf012674ff 3.3.3
diff --git a/eigen/CMakeLists.txt b/eigen/CMakeLists.txt
index fe4227c..f584002 100644
--- a/eigen/CMakeLists.txt
+++ b/eigen/CMakeLists.txt
@@ -28,7 +28,7 @@ endif()
#############################################################################
-# retrieve version information #
+# retrieve version infomation #
#############################################################################
# automatically parse the version number
@@ -416,15 +416,16 @@ add_subdirectory(Eigen)
add_subdirectory(doc EXCLUDE_FROM_ALL)
-option(BUILD_TESTING "Enable creation of Eigen tests." ON)
-if(BUILD_TESTING)
- include(EigenConfigureTesting)
+include(EigenConfigureTesting)
- if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
- add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
- else()
- add_subdirectory(test EXCLUDE_FROM_ALL)
- endif()
+# fixme, not sure this line is still needed:
+enable_testing() # must be called from the root CMakeLists, see man page
+
+
+if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
+ add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
+else()
+ add_subdirectory(test EXCLUDE_FROM_ALL)
endif()
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
@@ -460,9 +461,7 @@ endif(NOT WIN32)
configure_file(scripts/cdashtesting.cmake.in cdashtesting.cmake @ONLY)
-if(BUILD_TESTING)
- ei_testing_print_summary()
-endif()
+ei_testing_print_summary()
message(STATUS "")
message(STATUS "Configured Eigen ${EIGEN_VERSION_NUMBER}")
diff --git a/eigen/CTestConfig.cmake b/eigen/CTestConfig.cmake
index 4c00278..755b473 100644
--- a/eigen/CTestConfig.cmake
+++ b/eigen/CTestConfig.cmake
@@ -4,14 +4,10 @@
## # The following are required to uses Dart and the Cdash dashboard
## ENABLE_TESTING()
## INCLUDE(CTest)
-set(CTEST_PROJECT_NAME "Eigen")
+set(CTEST_PROJECT_NAME "Eigen3.3")
set(CTEST_NIGHTLY_START_TIME "00:00:00 UTC")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "manao.inria.fr")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen")
+set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen3.3")
set(CTEST_DROP_SITE_CDASH TRUE)
-set(CTEST_PROJECT_SUBPROJECTS
-Official
-Unsupported
-)
diff --git a/eigen/Eigen/Core b/eigen/Eigen/Core
index d188356..0f7fa63 100644
--- a/eigen/Eigen/Core
+++ b/eigen/Eigen/Core
@@ -43,8 +43,10 @@
#else
#define EIGEN_DEVICE_FUNC
#endif
+
#else
#define EIGEN_DEVICE_FUNC
+
#endif
// When compiling CUDA device code with NVCC, pull in math functions from the
@@ -141,24 +143,15 @@
#endif
#ifdef __AVX2__
#define EIGEN_VECTORIZE_AVX2
- #define EIGEN_VECTORIZE_AVX
- #define EIGEN_VECTORIZE_SSE3
- #define EIGEN_VECTORIZE_SSSE3
- #define EIGEN_VECTORIZE_SSE4_1
- #define EIGEN_VECTORIZE_SSE4_2
#endif
#ifdef __FMA__
#define EIGEN_VECTORIZE_FMA
#endif
- #if defined(__AVX512F__)
+ #if defined(__AVX512F__) && defined(EIGEN_ENABLE_AVX512)
#define EIGEN_VECTORIZE_AVX512
#define EIGEN_VECTORIZE_AVX2
#define EIGEN_VECTORIZE_AVX
#define EIGEN_VECTORIZE_FMA
- #define EIGEN_VECTORIZE_SSE3
- #define EIGEN_VECTORIZE_SSSE3
- #define EIGEN_VECTORIZE_SSE4_1
- #define EIGEN_VECTORIZE_SSE4_2
#ifdef __AVX512DQ__
#define EIGEN_VECTORIZE_AVX512DQ
#endif
@@ -290,15 +283,6 @@
#include <intrin.h>
#endif
-#if defined(__SYCL_DEVICE_ONLY__)
- #undef min
- #undef max
- #undef isnan
- #undef isinf
- #undef isfinite
- #include <SYCL/sycl.hpp>
-#endif
-
/** \brief Namespace containing all symbols from the %Eigen library. */
namespace Eigen {
@@ -363,9 +347,6 @@ using std::ptrdiff_t;
#include "src/Core/util/StaticAssert.h"
#include "src/Core/util/XprHelper.h"
#include "src/Core/util/Memory.h"
-#include "src/Core/util/IntegralConstant.h"
-#include "src/Core/util/SymbolicIndex.h"
-
#include "src/Core/NumTraits.h"
#include "src/Core/MathFunctions.h"
@@ -376,8 +357,6 @@ using std::ptrdiff_t;
#include "src/Core/arch/SSE/PacketMath.h"
#include "src/Core/arch/AVX/PacketMath.h"
#include "src/Core/arch/AVX512/PacketMath.h"
- #include "src/Core/arch/SSE/MathFunctions.h"
- #include "src/Core/arch/AVX/MathFunctions.h"
#include "src/Core/arch/AVX512/MathFunctions.h"
#elif defined EIGEN_VECTORIZE_AVX
// Use AVX for floats and doubles, SSE for integers
@@ -430,8 +409,6 @@ using std::ptrdiff_t;
// on CUDA devices
#include "src/Core/arch/CUDA/Complex.h"
-#include "src/Core/util/IndexedViewHelper.h"
-#include "src/Core/ArithmeticSequence.h"
#include "src/Core/IO.h"
#include "src/Core/DenseCoeffsBase.h"
#include "src/Core/DenseBase.h"
@@ -473,7 +450,6 @@ using std::ptrdiff_t;
#include "src/Core/Ref.h"
#include "src/Core/Block.h"
#include "src/Core/VectorBlock.h"
-#include "src/Core/IndexedView.h"
#include "src/Core/Transpose.h"
#include "src/Core/DiagonalMatrix.h"
#include "src/Core/Diagonal.h"
diff --git a/eigen/Eigen/Geometry b/eigen/Eigen/Geometry
index 131a4ed..716d529 100644
--- a/eigen/Eigen/Geometry
+++ b/eigen/Eigen/Geometry
@@ -59,3 +59,4 @@
#endif // EIGEN_GEOMETRY_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/eigen/Eigen/src/Cholesky/LDLT.h b/eigen/Eigen/src/Cholesky/LDLT.h
index 9b4fdb4..fcee7b2 100644
--- a/eigen/Eigen/src/Cholesky/LDLT.h
+++ b/eigen/Eigen/src/Cholesky/LDLT.h
@@ -258,6 +258,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename RhsType, typename DstType>
+ EIGEN_DEVICE_FUNC
void _solve_impl(const RhsType &rhs, DstType &dst) const;
#endif
diff --git a/eigen/Eigen/src/Cholesky/LLT.h b/eigen/Eigen/src/Cholesky/LLT.h
index e6c02d8..87ca8d4 100644
--- a/eigen/Eigen/src/Cholesky/LLT.h
+++ b/eigen/Eigen/src/Cholesky/LLT.h
@@ -200,6 +200,7 @@ template<typename _MatrixType, int _UpLo> class LLT
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename RhsType, typename DstType>
+ EIGEN_DEVICE_FUNC
void _solve_impl(const RhsType &rhs, DstType &dst) const;
#endif
diff --git a/eigen/Eigen/src/CholmodSupport/CholmodSupport.h b/eigen/Eigen/src/CholmodSupport/CholmodSupport.h
index 61faf43..5719720 100644
--- a/eigen/Eigen/src/CholmodSupport/CholmodSupport.h
+++ b/eigen/Eigen/src/CholmodSupport/CholmodSupport.h
@@ -32,7 +32,7 @@ template<> struct cholmod_configure_matrix<std::complex<double> > {
}
};
-// Other scalar types are not yet supported by Cholmod
+// Other scalar types are not yet suppotred by Cholmod
// template<> struct cholmod_configure_matrix<float> {
// template<typename CholmodType>
// static void run(CholmodType& mat) {
@@ -124,9 +124,6 @@ cholmod_sparse viewAsCholmod(const SparseSelfAdjointView<const SparseMatrix<_Sca
if(UpLo==Upper) res.stype = 1;
if(UpLo==Lower) res.stype = -1;
- // swap stype for rowmajor matrices (only works for real matrices)
- EIGEN_STATIC_ASSERT((_Options & RowMajorBit) == 0 || NumTraits<_Scalar>::IsComplex == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
- if(_Options & RowMajorBit) res.stype *=-1;
return res;
}
@@ -162,44 +159,6 @@ MappedSparseMatrix<Scalar,Flags,StorageIndex> viewAsEigen(cholmod_sparse& cm)
static_cast<StorageIndex*>(cm.p), static_cast<StorageIndex*>(cm.i),static_cast<Scalar*>(cm.x) );
}
-namespace internal {
-
-// template specializations for int and long that call the correct cholmod method
-
-#define EIGEN_CHOLMOD_SPECIALIZE0(ret, name) \
- template<typename _StorageIndex> ret cm_ ## name (cholmod_common &Common) { return cholmod_ ## name (&Common); } \
- template<> ret cm_ ## name<long> (cholmod_common &Common) { return cholmod_l_ ## name (&Common); }
-
-#define EIGEN_CHOLMOD_SPECIALIZE1(ret, name, t1, a1) \
- template<typename _StorageIndex> ret cm_ ## name (t1& a1, cholmod_common &Common) { return cholmod_ ## name (&a1, &Common); } \
- template<> ret cm_ ## name<long> (t1& a1, cholmod_common &Common) { return cholmod_l_ ## name (&a1, &Common); }
-
-EIGEN_CHOLMOD_SPECIALIZE0(int, start)
-EIGEN_CHOLMOD_SPECIALIZE0(int, finish)
-
-EIGEN_CHOLMOD_SPECIALIZE1(int, free_factor, cholmod_factor*, L)
-EIGEN_CHOLMOD_SPECIALIZE1(int, free_dense, cholmod_dense*, X)
-EIGEN_CHOLMOD_SPECIALIZE1(int, free_sparse, cholmod_sparse*, A)
-
-EIGEN_CHOLMOD_SPECIALIZE1(cholmod_factor*, analyze, cholmod_sparse, A)
-
-template<typename _StorageIndex> cholmod_dense* cm_solve (int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common &Common) { return cholmod_solve (sys, &L, &B, &Common); }
-template<> cholmod_dense* cm_solve<long> (int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common &Common) { return cholmod_l_solve (sys, &L, &B, &Common); }
-
-template<typename _StorageIndex> cholmod_sparse* cm_spsolve (int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common &Common) { return cholmod_spsolve (sys, &L, &B, &Common); }
-template<> cholmod_sparse* cm_spsolve<long> (int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common &Common) { return cholmod_l_spsolve (sys, &L, &B, &Common); }
-
-template<typename _StorageIndex>
-int cm_factorize_p (cholmod_sparse* A, double beta[2], _StorageIndex* fset, std::size_t fsize, cholmod_factor* L, cholmod_common &Common) { return cholmod_factorize_p (A, beta, fset, fsize, L, &Common); }
-template<>
-int cm_factorize_p<long> (cholmod_sparse* A, double beta[2], long* fset, std::size_t fsize, cholmod_factor* L, cholmod_common &Common) { return cholmod_l_factorize_p (A, beta, fset, fsize, L, &Common); }
-
-#undef EIGEN_CHOLMOD_SPECIALIZE0
-#undef EIGEN_CHOLMOD_SPECIALIZE1
-
-} // namespace internal
-
-
enum CholmodMode {
CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt
};
@@ -236,7 +195,7 @@ class CholmodBase : public SparseSolverBase<Derived>
{
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
- internal::cm_start<StorageIndex>(m_cholmod);
+ cholmod_start(&m_cholmod);
}
explicit CholmodBase(const MatrixType& matrix)
@@ -244,15 +203,15 @@ class CholmodBase : public SparseSolverBase<Derived>
{
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
- internal::cm_start<StorageIndex>(m_cholmod);
+ cholmod_start(&m_cholmod);
compute(matrix);
}
~CholmodBase()
{
if(m_cholmodFactor)
- internal::cm_free_factor<StorageIndex>(m_cholmodFactor, m_cholmod);
- internal::cm_finish<StorageIndex>(m_cholmod);
+ cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
+ cholmod_finish(&m_cholmod);
}
inline StorageIndex cols() const { return internal::convert_index<StorageIndex, Index>(m_cholmodFactor->n); }
@@ -260,7 +219,7 @@ class CholmodBase : public SparseSolverBase<Derived>
/** \brief Reports whether previous computation was successful.
*
- * \returns \c Success if computation was successful,
+ * \returns \c Success if computation was succesful,
* \c NumericalIssue if the matrix.appears to be negative.
*/
ComputationInfo info() const
@@ -287,11 +246,11 @@ class CholmodBase : public SparseSolverBase<Derived>
{
if(m_cholmodFactor)
{
- internal::cm_free_factor<StorageIndex>(m_cholmodFactor, m_cholmod);
+ cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
m_cholmodFactor = 0;
}
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
- m_cholmodFactor = internal::cm_analyze<StorageIndex>(A, m_cholmod);
+ m_cholmodFactor = cholmod_analyze(&A, &m_cholmod);
this->m_isInitialized = true;
this->m_info = Success;
@@ -309,7 +268,7 @@ class CholmodBase : public SparseSolverBase<Derived>
{
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
- internal::cm_factorize_p<StorageIndex>(&A, m_shiftOffset, 0, 0, m_cholmodFactor, m_cholmod);
+ cholmod_factorize_p(&A, m_shiftOffset, 0, 0, m_cholmodFactor, &m_cholmod);
// If the factorization failed, minor is the column at which it did. On success minor == n.
this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue);
@@ -330,20 +289,19 @@ class CholmodBase : public SparseSolverBase<Derived>
EIGEN_UNUSED_VARIABLE(size);
eigen_assert(size==b.rows());
- // Cholmod needs column-major storage without inner-stride, which corresponds to the default behavior of Ref.
+ // Cholmod needs column-major stoarge without inner-stride, which corresponds to the default behavior of Ref.
Ref<const Matrix<typename Rhs::Scalar,Dynamic,Dynamic,ColMajor> > b_ref(b.derived());
cholmod_dense b_cd = viewAsCholmod(b_ref);
- cholmod_dense* x_cd = internal::cm_solve<StorageIndex>(CHOLMOD_A, *m_cholmodFactor, b_cd, m_cholmod);
+ cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod);
if(!x_cd)
{
this->m_info = NumericalIssue;
return;
}
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
- // NOTE Actually, the copy can be avoided by calling cholmod_solve2 instead of cholmod_solve
dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols());
- internal::cm_free_dense<StorageIndex>(x_cd, m_cholmod);
+ cholmod_free_dense(&x_cd, &m_cholmod);
}
/** \internal */
@@ -358,16 +316,15 @@ class CholmodBase : public SparseSolverBase<Derived>
// note: cs stands for Cholmod Sparse
Ref<SparseMatrix<typename RhsDerived::Scalar,ColMajor,typename RhsDerived::StorageIndex> > b_ref(b.const_cast_derived());
cholmod_sparse b_cs = viewAsCholmod(b_ref);
- cholmod_sparse* x_cs = internal::cm_spsolve<StorageIndex>(CHOLMOD_A, *m_cholmodFactor, b_cs, m_cholmod);
+ cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod);
if(!x_cs)
{
this->m_info = NumericalIssue;
return;
}
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
- // NOTE cholmod_spsolve in fact just calls the dense solver for blocks of 4 columns at a time (similar to Eigen's sparse solver)
dest.derived() = viewAsEigen<typename DestDerived::Scalar,ColMajor,typename DestDerived::StorageIndex>(*x_cs);
- internal::cm_free_sparse<StorageIndex>(x_cs, m_cholmod);
+ cholmod_free_sparse(&x_cs, &m_cholmod);
}
#endif // EIGEN_PARSED_BY_DOXYGEN
diff --git a/eigen/Eigen/src/Core/ArithmeticSequence.h b/eigen/Eigen/src/Core/ArithmeticSequence.h
deleted file mode 100644
index ada1571..0000000
--- a/eigen/Eigen/src/Core/ArithmeticSequence.h
+++ /dev/null
@@ -1,350 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2017 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/.
-
-#ifndef EIGEN_ARITHMETIC_SEQUENCE_H
-#define EIGEN_ARITHMETIC_SEQUENCE_H
-
-namespace Eigen {
-
-namespace internal {
-
-#if (!EIGEN_HAS_CXX11) || !((!EIGEN_COMP_GNUC) || EIGEN_COMP_GNUC>=48)
-template<typename T> struct aseq_negate {};
-
-template<> struct aseq_negate<Index> {
- typedef Index type;
-};
-
-template<int N> struct aseq_negate<FixedInt<N> > {
- typedef FixedInt<-N> type;
-};
-
-// Compilation error in the following case:
-template<> struct aseq_negate<FixedInt<DynamicIndex> > {};
-
-template<typename FirstType,typename SizeType,typename IncrType,
- bool FirstIsSymbolic=Symbolic::is_symbolic<FirstType>::value,
- bool SizeIsSymbolic =Symbolic::is_symbolic<SizeType>::value>
-struct aseq_reverse_first_type {
- typedef Index type;
-};
-
-template<typename FirstType,typename SizeType,typename IncrType>
-struct aseq_reverse_first_type<FirstType,SizeType,IncrType,true,true> {
- typedef Symbolic::AddExpr<FirstType,
- Symbolic::ProductExpr<Symbolic::AddExpr<SizeType,Symbolic::ValueExpr<FixedInt<-1> > >,
- Symbolic::ValueExpr<IncrType> >
- > type;
-};
-
-template<typename SizeType,typename IncrType,typename EnableIf = void>
-struct aseq_reverse_first_type_aux {
- typedef Index type;
-};
-
-template<typename SizeType,typename IncrType>
-struct aseq_reverse_first_type_aux<SizeType,IncrType,typename internal::enable_if<bool((SizeType::value+IncrType::value)|0x1)>::type> {
- typedef FixedInt<(SizeType::value-1)*IncrType::value> type;
-};
-
-template<typename FirstType,typename SizeType,typename IncrType>
-struct aseq_reverse_first_type<FirstType,SizeType,IncrType,true,false> {
- typedef typename aseq_reverse_first_type_aux<SizeType,IncrType>::type Aux;
- typedef Symbolic::AddExpr<FirstType,Symbolic::ValueExpr<Aux> > type;
-};
-
-template<typename FirstType,typename SizeType,typename IncrType>
-struct aseq_reverse_first_type<FirstType,SizeType,IncrType,false,true> {
- typedef Symbolic::AddExpr<Symbolic::ProductExpr<Symbolic::AddExpr<SizeType,Symbolic::ValueExpr<FixedInt<-1> > >,
- Symbolic::ValueExpr<IncrType> >,
- Symbolic::ValueExpr<> > type;
-};
-#endif
-
-// Helper to cleanup the type of the increment:
-template<typename T> struct cleanup_seq_incr {
- typedef typename cleanup_index_type<T,DynamicIndex>::type type;
-};
-
-}
-
-//--------------------------------------------------------------------------------
-// seq(first,last,incr) and seqN(first,size,incr)
-//--------------------------------------------------------------------------------
-
-template<typename FirstType=Index,typename SizeType=Index,typename IncrType=internal::FixedInt<1> >
-class ArithmeticSequence;
-
-template<typename FirstType,typename SizeType,typename IncrType>
-ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
- typename internal::cleanup_index_type<SizeType>::type,
- typename internal::cleanup_seq_incr<IncrType>::type >
-seqN(FirstType first, SizeType size, IncrType incr);
-
-/** \class ArithmeticSequence
- * \ingroup Core_Module
- *
- * This class represents an arithmetic progression \f$ a_0, a_1, a_2, ..., a_{n-1}\f$ defined by
- * its \em first value \f$ a_0 \f$, its \em size (aka length) \em n, and the \em increment (aka stride)
- * that is equal to \f$ a_{i+1}-a_{i}\f$ for any \em i.
- *
- * It is internally used as the return type of the Eigen::seq and Eigen::seqN functions, and as the input arguments
- * of DenseBase::operator()(const RowIndices&, const ColIndices&), and most of the time this is the
- * only way it is used.
- *
- * \tparam FirstType type of the first element, usually an Index,
- * but internally it can be a symbolic expression
- * \tparam SizeType type representing the size of the sequence, usually an Index
- * or a compile time integral constant. Internally, it can also be a symbolic expression
- * \tparam IncrType type of the increment, can be a runtime Index, or a compile time integral constant (default is compile-time 1)
- *
- * \sa Eigen::seq, Eigen::seqN, DenseBase::operator()(const RowIndices&, const ColIndices&), class IndexedView
- */
-template<typename FirstType,typename SizeType,typename IncrType>
-class ArithmeticSequence
-{
-public:
- ArithmeticSequence(FirstType first, SizeType size) : m_first(first), m_size(size) {}
- ArithmeticSequence(FirstType first, SizeType size, IncrType incr) : m_first(first), m_size(size), m_incr(incr) {}
-
- enum {
- SizeAtCompileTime = internal::get_fixed_value<SizeType>::value,
- IncrAtCompileTime = internal::get_fixed_value<IncrType,DynamicIndex>::value
- };
-
- /** \returns the size, i.e., number of elements, of the sequence */
- Index size() const { return m_size; }
-
- /** \returns the first element \f$ a_0 \f$ in the sequence */
- Index first() const { return m_first; }
-
- /** \returns the value \f$ a_i \f$ at index \a i in the sequence. */
- Index operator[](Index i) const { return m_first + i * m_incr; }
-
- const FirstType& firstObject() const { return m_first; }
- const SizeType& sizeObject() const { return m_size; }
- const IncrType& incrObject() const { return m_incr; }
-
-protected:
- FirstType m_first;
- SizeType m_size;
- IncrType m_incr;
-
-public:
-
-#if EIGEN_HAS_CXX11 && ((!EIGEN_COMP_GNUC) || EIGEN_COMP_GNUC>=48)
- auto reverse() const -> decltype(Eigen::seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr)) {
- return seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr);
- }
-#else
-protected:
- typedef typename internal::aseq_negate<IncrType>::type ReverseIncrType;
- typedef typename internal::aseq_reverse_first_type<FirstType,SizeType,IncrType>::type ReverseFirstType;
-public:
- ArithmeticSequence<ReverseFirstType,SizeType,ReverseIncrType>
- reverse() const {
- return seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr);
- }
-#endif
-};
-
-/** \returns an ArithmeticSequence starting at \a first, of length \a size, and increment \a incr
- *
- * \sa seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */
-template<typename FirstType,typename SizeType,typename IncrType>
-ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type,typename internal::cleanup_seq_incr<IncrType>::type >
-seqN(FirstType first, SizeType size, IncrType incr) {
- return ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type,typename internal::cleanup_seq_incr<IncrType>::type>(first,size,incr);
-}
-
-/** \returns an ArithmeticSequence starting at \a first, of length \a size, and unit increment
- *
- * \sa seqN(FirstType,SizeType,IncrType), seq(FirstType,LastType) */
-template<typename FirstType,typename SizeType>
-ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type >
-seqN(FirstType first, SizeType size) {
- return ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type>(first,size);
-}
-
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-
-/** \returns an ArithmeticSequence starting at \a f, up (or down) to \a l, and with positive (or negative) increment \a incr
- *
- * It is essentially an alias to:
- * \code
- * seqN(f, (l-f+incr)/incr, incr);
- * \endcode
- *
- * \sa seqN(FirstType,SizeType,IncrType), seq(FirstType,LastType)
- */
-template<typename FirstType,typename LastType, typename IncrType>
-auto seq(FirstType f, LastType l, IncrType incr);
-
-/** \returns an ArithmeticSequence starting at \a f, up (or down) to \a l, and unit increment
- *
- * It is essentially an alias to:
- * \code
- * seqN(f,l-f+1);
- * \endcode
- *
- * \sa seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType)
- */
-template<typename FirstType,typename LastType>
-auto seq(FirstType f, LastType l);
-
-#else // EIGEN_PARSED_BY_DOXYGEN
-
-#if EIGEN_HAS_CXX11
-template<typename FirstType,typename LastType>
-auto seq(FirstType f, LastType l) -> decltype(seqN(typename internal::cleanup_index_type<FirstType>::type(f),
- ( typename internal::cleanup_index_type<LastType>::type(l)
- - typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>())))
-{
- return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
- (typename internal::cleanup_index_type<LastType>::type(l)
- -typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>()));
-}
-
-template<typename FirstType,typename LastType, typename IncrType>
-auto seq(FirstType f, LastType l, IncrType incr)
- -> decltype(seqN(typename internal::cleanup_index_type<FirstType>::type(f),
- ( typename internal::cleanup_index_type<LastType>::type(l)
- - typename internal::cleanup_index_type<FirstType>::type(f)+typename internal::cleanup_seq_incr<IncrType>::type(incr)
- ) / typename internal::cleanup_seq_incr<IncrType>::type(incr),
- typename internal::cleanup_seq_incr<IncrType>::type(incr)))
-{
- typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
- return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
- ( typename internal::cleanup_index_type<LastType>::type(l)
- -typename internal::cleanup_index_type<FirstType>::type(f)+CleanedIncrType(incr)) / CleanedIncrType(incr),
- CleanedIncrType(incr));
-}
-#else
-
-template<typename FirstType,typename LastType>
-typename internal::enable_if<!(Symbolic::is_symbolic<FirstType>::value || Symbolic::is_symbolic<LastType>::value),
- ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,Index> >::type
-seq(FirstType f, LastType l)
-{
- return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
- Index((typename internal::cleanup_index_type<LastType>::type(l)-typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>())));
-}
-
-template<typename FirstTypeDerived,typename LastType>
-typename internal::enable_if<!Symbolic::is_symbolic<LastType>::value,
- ArithmeticSequence<FirstTypeDerived, Symbolic::AddExpr<Symbolic::AddExpr<Symbolic::NegateExpr<FirstTypeDerived>,Symbolic::ValueExpr<> >,
- Symbolic::ValueExpr<internal::FixedInt<1> > > > >::type
-seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, LastType l)
-{
- return seqN(f.derived(),(typename internal::cleanup_index_type<LastType>::type(l)-f.derived()+fix<1>()));
-}
-
-template<typename FirstType,typename LastTypeDerived>
-typename internal::enable_if<!Symbolic::is_symbolic<FirstType>::value,
- ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
- Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::ValueExpr<> >,
- Symbolic::ValueExpr<internal::FixedInt<1> > > > >::type
-seq(FirstType f, const Symbolic::BaseExpr<LastTypeDerived> &l)
-{
- return seqN(typename internal::cleanup_index_type<FirstType>::type(f),(l.derived()-typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>()));
-}
-
-template<typename FirstTypeDerived,typename LastTypeDerived>
-ArithmeticSequence<FirstTypeDerived,
- Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::NegateExpr<FirstTypeDerived> >,Symbolic::ValueExpr<internal::FixedInt<1> > > >
-seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, const Symbolic::BaseExpr<LastTypeDerived> &l)
-{
- return seqN(f.derived(),(l.derived()-f.derived()+fix<1>()));
-}
-
-
-template<typename FirstType,typename LastType, typename IncrType>
-typename internal::enable_if<!(Symbolic::is_symbolic<FirstType>::value || Symbolic::is_symbolic<LastType>::value),
- ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,Index,typename internal::cleanup_seq_incr<IncrType>::type> >::type
-seq(FirstType f, LastType l, IncrType incr)
-{
- typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
- return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
- Index((typename internal::cleanup_index_type<LastType>::type(l)-typename internal::cleanup_index_type<FirstType>::type(f)+CleanedIncrType(incr))/CleanedIncrType(incr)), incr);
-}
-
-template<typename FirstTypeDerived,typename LastType, typename IncrType>
-typename internal::enable_if<!Symbolic::is_symbolic<LastType>::value,
- ArithmeticSequence<FirstTypeDerived,
- Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<Symbolic::NegateExpr<FirstTypeDerived>,
- Symbolic::ValueExpr<> >,
- Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
- Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
- typename internal::cleanup_seq_incr<IncrType>::type> >::type
-seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, LastType l, IncrType incr)
-{
- typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
- return seqN(f.derived(),(typename internal::cleanup_index_type<LastType>::type(l)-f.derived()+CleanedIncrType(incr))/CleanedIncrType(incr), incr);
-}
-
-template<typename FirstType,typename LastTypeDerived, typename IncrType>
-typename internal::enable_if<!Symbolic::is_symbolic<FirstType>::value,
- ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
- Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::ValueExpr<> >,
- Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
- Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
- typename internal::cleanup_seq_incr<IncrType>::type> >::type
-seq(FirstType f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
-{
- typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
- return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
- (l.derived()-typename internal::cleanup_index_type<FirstType>::type(f)+CleanedIncrType(incr))/CleanedIncrType(incr), incr);
-}
-
-template<typename FirstTypeDerived,typename LastTypeDerived, typename IncrType>
-ArithmeticSequence<FirstTypeDerived,
- Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,
- Symbolic::NegateExpr<FirstTypeDerived> >,
- Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
- Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
- typename internal::cleanup_seq_incr<IncrType>::type>
-seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
-{
- typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
- return seqN(f.derived(),(l.derived()-f.derived()+CleanedIncrType(incr))/CleanedIncrType(incr), incr);
-}
-#endif
-
-#endif // EIGEN_PARSED_BY_DOXYGEN
-
-namespace internal {
-
-// Convert a symbolic span into a usable one (i.e., remove last/end "keywords")
-template<typename T>
-struct make_size_type {
- typedef typename internal::conditional<Symbolic::is_symbolic<T>::value, Index, T>::type type;
-};
-
-template<typename FirstType,typename SizeType,typename IncrType,int XprSize>
-struct IndexedViewCompatibleType<ArithmeticSequence<FirstType,SizeType,IncrType>, XprSize> {
- typedef ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType> type;
-};
-
-template<typename FirstType,typename SizeType,typename IncrType>
-ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>
-makeIndexedViewCompatible(const ArithmeticSequence<FirstType,SizeType,IncrType>& ids, Index size,SpecializedType) {
- return ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>(
- eval_expr_given_size(ids.firstObject(),size),eval_expr_given_size(ids.sizeObject(),size),ids.incrObject());
-}
-
-template<typename FirstType,typename SizeType,typename IncrType>
-struct get_compile_time_incr<ArithmeticSequence<FirstType,SizeType,IncrType> > {
- enum { value = get_fixed_value<IncrType,DynamicIndex>::value };
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_ARITHMETIC_SEQUENCE_H
diff --git a/eigen/Eigen/src/Core/Array.h b/eigen/Eigen/src/Core/Array.h
index 0d34269..e10020d 100644
--- a/eigen/Eigen/src/Core/Array.h
+++ b/eigen/Eigen/src/Core/Array.h
@@ -231,10 +231,16 @@ class Array
: Base(other)
{ }
+ private:
+ struct PrivateType {};
+ public:
+
/** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
template<typename OtherDerived>
EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other)
+ EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other,
+ typename internal::enable_if<internal::is_convertible<typename OtherDerived::Scalar,Scalar>::value,
+ PrivateType>::type = PrivateType())
: Base(other.derived())
{ }
diff --git a/eigen/Eigen/src/Core/ArrayBase.h b/eigen/Eigen/src/Core/ArrayBase.h
index 9da960f..3dbc708 100644
--- a/eigen/Eigen/src/Core/ArrayBase.h
+++ b/eigen/Eigen/src/Core/ArrayBase.h
@@ -69,7 +69,6 @@ template<typename Derived> class ArrayBase
using Base::coeff;
using Base::coeffRef;
using Base::lazyAssign;
- using Base::operator-;
using Base::operator=;
using Base::operator+=;
using Base::operator-=;
@@ -89,6 +88,7 @@ template<typename Derived> class ArrayBase
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
+# include "../plugins/CommonCwiseUnaryOps.h"
# include "../plugins/MatrixCwiseUnaryOps.h"
# include "../plugins/ArrayCwiseUnaryOps.h"
# include "../plugins/CommonCwiseBinaryOps.h"
diff --git a/eigen/Eigen/src/Core/ArrayWrapper.h b/eigen/Eigen/src/Core/ArrayWrapper.h
index a04521a..688aadd 100644
--- a/eigen/Eigen/src/Core/ArrayWrapper.h
+++ b/eigen/Eigen/src/Core/ArrayWrapper.h
@@ -32,7 +32,8 @@ struct traits<ArrayWrapper<ExpressionType> >
// Let's remove NestByRefBit
enum {
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
- Flags = Flags0 & ~NestByRefBit
+ LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
+ Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
};
};
}
@@ -129,7 +130,8 @@ struct traits<MatrixWrapper<ExpressionType> >
// Let's remove NestByRefBit
enum {
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
- Flags = Flags0 & ~NestByRefBit
+ LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
+ Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
};
};
}
diff --git a/eigen/Eigen/src/Core/Assign.h b/eigen/Eigen/src/Core/Assign.h
index 655412e..53806ba 100644
--- a/eigen/Eigen/src/Core/Assign.h
+++ b/eigen/Eigen/src/Core/Assign.h
@@ -16,7 +16,7 @@ namespace Eigen {
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
+EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
::lazyAssign(const DenseBase<OtherDerived>& other)
{
enum{
diff --git a/eigen/Eigen/src/Core/BooleanRedux.h b/eigen/Eigen/src/Core/BooleanRedux.h
index ccf5190..8409d87 100644
--- a/eigen/Eigen/src/Core/BooleanRedux.h
+++ b/eigen/Eigen/src/Core/BooleanRedux.h
@@ -14,54 +14,56 @@ namespace Eigen {
namespace internal {
-template<typename Derived, int UnrollCount, int Rows>
+template<typename Derived, int UnrollCount>
struct all_unroller
{
+ typedef typename Derived::ExpressionTraits Traits;
enum {
- col = (UnrollCount-1) / Rows,
- row = (UnrollCount-1) % Rows
+ col = (UnrollCount-1) / Traits::RowsAtCompileTime,
+ row = (UnrollCount-1) % Traits::RowsAtCompileTime
};
static inline bool run(const Derived &mat)
{
- return all_unroller<Derived, UnrollCount-1, Rows>::run(mat) && mat.coeff(row, col);
+ return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
}
};
-template<typename Derived, int Rows>
-struct all_unroller<Derived, 0, Rows>
+template<typename Derived>
+struct all_unroller<Derived, 0>
{
static inline bool run(const Derived &/*mat*/) { return true; }
};
-template<typename Derived, int Rows>
-struct all_unroller<Derived, Dynamic, Rows>
+template<typename Derived>
+struct all_unroller<Derived, Dynamic>
{
static inline bool run(const Derived &) { return false; }
};
-template<typename Derived, int UnrollCount, int Rows>
+template<typename Derived, int UnrollCount>
struct any_unroller
{
+ typedef typename Derived::ExpressionTraits Traits;
enum {
- col = (UnrollCount-1) / Rows,
- row = (UnrollCount-1) % Rows
+ col = (UnrollCount-1) / Traits::RowsAtCompileTime,
+ row = (UnrollCount-1) % Traits::RowsAtCompileTime
};
static inline bool run(const Derived &mat)
{
- return any_unroller<Derived, UnrollCount-1, Rows>::run(mat) || mat.coeff(row, col);
+ return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
}
};
-template<typename Derived, int Rows>
-struct any_unroller<Derived, 0, Rows>
+template<typename Derived>
+struct any_unroller<Derived, 0>
{
static inline bool run(const Derived & /*mat*/) { return false; }
};
-template<typename Derived, int Rows>
-struct any_unroller<Derived, Dynamic, Rows>
+template<typename Derived>
+struct any_unroller<Derived, Dynamic>
{
static inline bool run(const Derived &) { return false; }
};
@@ -76,7 +78,7 @@ struct any_unroller<Derived, Dynamic, Rows>
* \sa any(), Cwise::operator<()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::all() const
+inline bool DenseBase<Derived>::all() const
{
typedef internal::evaluator<Derived> Evaluator;
enum {
@@ -85,7 +87,7 @@ EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::all() const
};
Evaluator evaluator(derived());
if(unroll)
- return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic, internal::traits<Derived>::RowsAtCompileTime>::run(evaluator);
+ return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
else
{
for(Index j = 0; j < cols(); ++j)
@@ -100,7 +102,7 @@ EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::all() const
* \sa all()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::any() const
+inline bool DenseBase<Derived>::any() const
{
typedef internal::evaluator<Derived> Evaluator;
enum {
@@ -109,7 +111,7 @@ EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::any() const
};
Evaluator evaluator(derived());
if(unroll)
- return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic, internal::traits<Derived>::RowsAtCompileTime>::run(evaluator);
+ return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
else
{
for(Index j = 0; j < cols(); ++j)
@@ -124,7 +126,7 @@ EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::any() const
* \sa all(), any()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline Eigen::Index DenseBase<Derived>::count() const
+inline Eigen::Index DenseBase<Derived>::count() const
{
return derived().template cast<bool>().template cast<Index>().sum();
}
diff --git a/eigen/Eigen/src/Core/CommaInitializer.h b/eigen/Eigen/src/Core/CommaInitializer.h
index 35fdbb8..d218e98 100644
--- a/eigen/Eigen/src/Core/CommaInitializer.h
+++ b/eigen/Eigen/src/Core/CommaInitializer.h
@@ -141,7 +141,7 @@ struct CommaInitializer
* \sa CommaInitializer::finished(), class CommaInitializer
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s)
+inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s)
{
return CommaInitializer<Derived>(*static_cast<Derived*>(this), s);
}
@@ -149,7 +149,7 @@ EIGEN_DEVICE_FUNC inline CommaInitializer<Derived> DenseBase<Derived>::operator<
/** \sa operator<<(const Scalar&) */
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC inline CommaInitializer<Derived>
+inline CommaInitializer<Derived>
DenseBase<Derived>::operator<<(const DenseBase<OtherDerived>& other)
{
return CommaInitializer<Derived>(*static_cast<Derived *>(this), other);
diff --git a/eigen/Eigen/src/Core/CoreEvaluators.h b/eigen/Eigen/src/Core/CoreEvaluators.h
index 15b361b..f7c1eff 100644
--- a/eigen/Eigen/src/Core/CoreEvaluators.h
+++ b/eigen/Eigen/src/Core/CoreEvaluators.h
@@ -106,7 +106,7 @@ struct evaluator<const T>
// ---------- base class for all evaluators ----------
template<typename ExpressionType>
-struct evaluator_base
+struct evaluator_base : public noncopyable
{
// TODO that's not very nice to have to propagate all these traits. They are currently only needed to handle outer,inner indices.
typedef traits<ExpressionType> ExpressionTraits;
@@ -114,14 +114,6 @@ struct evaluator_base
enum {
Alignment = 0
};
- // noncopyable:
- // Don't make this class inherit noncopyable as this kills EBO (Empty Base Optimization)
- // and make complex evaluator much larger than then should do.
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE evaluator_base() {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~evaluator_base() {}
-private:
- EIGEN_DEVICE_FUNC evaluator_base(const evaluator_base&);
- EIGEN_DEVICE_FUNC const evaluator_base& operator=(const evaluator_base&);
};
// -------------------- Matrix and Array --------------------
@@ -131,27 +123,6 @@ private:
// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense,
// so no need for more sophisticated dispatching.
-// this helper permits to completely eliminate m_outerStride if it is known at compiletime.
-template<typename Scalar,int OuterStride> class plainobjectbase_evaluator_data {
-public:
- EIGEN_DEVICE_FUNC plainobjectbase_evaluator_data(const Scalar* ptr, Index outerStride) : data(ptr)
- {
- EIGEN_ONLY_USED_FOR_DEBUG(outerStride);
- eigen_internal_assert(outerStride==OuterStride);
- }
- EIGEN_DEVICE_FUNC Index outerStride() const { return OuterStride; }
- const Scalar *data;
-};
-
-template<typename Scalar> class plainobjectbase_evaluator_data<Scalar,Dynamic> {
-public:
- EIGEN_DEVICE_FUNC plainobjectbase_evaluator_data(const Scalar* ptr, Index outerStride) : data(ptr), m_outerStride(outerStride) {}
- EIGEN_DEVICE_FUNC Index outerStride() const { return m_outerStride; }
- const Scalar *data;
-protected:
- Index m_outerStride;
-};
-
template<typename Derived>
struct evaluator<PlainObjectBase<Derived> >
: evaluator_base<Derived>
@@ -170,21 +141,18 @@ struct evaluator<PlainObjectBase<Derived> >
Flags = traits<Derived>::EvaluatorFlags,
Alignment = traits<Derived>::Alignment
};
- enum {
- // We do not need to know the outer stride for vectors
- OuterStrideAtCompileTime = IsVectorAtCompileTime ? 0
- : int(IsRowMajor) ? ColsAtCompileTime
- : RowsAtCompileTime
- };
-
+
EIGEN_DEVICE_FUNC evaluator()
- : m_d(0,OuterStrideAtCompileTime)
+ : m_data(0),
+ m_outerStride(IsVectorAtCompileTime ? 0
+ : int(IsRowMajor) ? ColsAtCompileTime
+ : RowsAtCompileTime)
{
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
}
-
+
EIGEN_DEVICE_FUNC explicit evaluator(const PlainObjectType& m)
- : m_d(m.data(),IsVectorAtCompileTime ? 0 : m.outerStride())
+ : m_data(m.data()), m_outerStride(IsVectorAtCompileTime ? 0 : m.outerStride())
{
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
}
@@ -193,30 +161,30 @@ struct evaluator<PlainObjectBase<Derived> >
CoeffReturnType coeff(Index row, Index col) const
{
if (IsRowMajor)
- return m_d.data[row * m_d.outerStride() + col];
+ return m_data[row * m_outerStride.value() + col];
else
- return m_d.data[row + col * m_d.outerStride()];
+ return m_data[row + col * m_outerStride.value()];
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index index) const
{
- return m_d.data[index];
+ return m_data[index];
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Scalar& coeffRef(Index row, Index col)
{
if (IsRowMajor)
- return const_cast<Scalar*>(m_d.data)[row * m_d.outerStride() + col];
+ return const_cast<Scalar*>(m_data)[row * m_outerStride.value() + col];
else
- return const_cast<Scalar*>(m_d.data)[row + col * m_d.outerStride()];
+ return const_cast<Scalar*>(m_data)[row + col * m_outerStride.value()];
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Scalar& coeffRef(Index index)
{
- return const_cast<Scalar*>(m_d.data)[index];
+ return const_cast<Scalar*>(m_data)[index];
}
template<int LoadMode, typename PacketType>
@@ -224,16 +192,16 @@ struct evaluator<PlainObjectBase<Derived> >
PacketType packet(Index row, Index col) const
{
if (IsRowMajor)
- return ploadt<PacketType, LoadMode>(m_d.data + row * m_d.outerStride() + col);
+ return ploadt<PacketType, LoadMode>(m_data + row * m_outerStride.value() + col);
else
- return ploadt<PacketType, LoadMode>(m_d.data + row + col * m_d.outerStride());
+ return ploadt<PacketType, LoadMode>(m_data + row + col * m_outerStride.value());
}
template<int LoadMode, typename PacketType>
EIGEN_STRONG_INLINE
PacketType packet(Index index) const
{
- return ploadt<PacketType, LoadMode>(m_d.data + index);
+ return ploadt<PacketType, LoadMode>(m_data + index);
}
template<int StoreMode,typename PacketType>
@@ -242,22 +210,26 @@ struct evaluator<PlainObjectBase<Derived> >
{
if (IsRowMajor)
return pstoret<Scalar, PacketType, StoreMode>
- (const_cast<Scalar*>(m_d.data) + row * m_d.outerStride() + col, x);
+ (const_cast<Scalar*>(m_data) + row * m_outerStride.value() + col, x);
else
return pstoret<Scalar, PacketType, StoreMode>
- (const_cast<Scalar*>(m_d.data) + row + col * m_d.outerStride(), x);
+ (const_cast<Scalar*>(m_data) + row + col * m_outerStride.value(), x);
}
template<int StoreMode, typename PacketType>
EIGEN_STRONG_INLINE
void writePacket(Index index, const PacketType& x)
{
- return pstoret<Scalar, PacketType, StoreMode>(const_cast<Scalar*>(m_d.data) + index, x);
+ return pstoret<Scalar, PacketType, StoreMode>(const_cast<Scalar*>(m_data) + index, x);
}
protected:
+ const Scalar *m_data;
- plainobjectbase_evaluator_data<Scalar,OuterStrideAtCompileTime> m_d;
+ // We do not need to know the outer stride for vectors
+ variable_if_dynamic<Index, IsVectorAtCompileTime ? 0
+ : int(IsRowMajor) ? ColsAtCompileTime
+ : RowsAtCompileTime> m_outerStride;
};
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
@@ -555,7 +527,9 @@ struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
};
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- explicit unary_evaluator(const XprType& op) : m_d(op)
+ explicit unary_evaluator(const XprType& op)
+ : m_functor(op.functor()),
+ m_argImpl(op.nestedExpression())
{
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
@@ -566,43 +540,32 @@ struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index row, Index col) const
{
- return m_d.func()(m_d.argImpl.coeff(row, col));
+ return m_functor(m_argImpl.coeff(row, col));
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index index) const
{
- return m_d.func()(m_d.argImpl.coeff(index));
+ return m_functor(m_argImpl.coeff(index));
}
template<int LoadMode, typename PacketType>
EIGEN_STRONG_INLINE
PacketType packet(Index row, Index col) const
{
- return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(row, col));
+ return m_functor.packetOp(m_argImpl.template packet<LoadMode, PacketType>(row, col));
}
template<int LoadMode, typename PacketType>
EIGEN_STRONG_INLINE
PacketType packet(Index index) const
{
- return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(index));
+ return m_functor.packetOp(m_argImpl.template packet<LoadMode, PacketType>(index));
}
protected:
-
- // this helper permits to completely eliminate the functor if it is empty
- class Data : private UnaryOp
- {
- public:
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- Data(const XprType& xpr) : UnaryOp(xpr.functor()), argImpl(xpr.nestedExpression()) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- const UnaryOp& func() const { return static_cast<const UnaryOp&>(*this); }
- evaluator<ArgType> argImpl;
- };
-
- Data m_d;
+ const UnaryOp m_functor;
+ evaluator<ArgType> m_argImpl;
};
// -------------------- CwiseTernaryOp --------------------
@@ -646,7 +609,11 @@ struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased
evaluator<Arg3>::Alignment)
};
- EIGEN_DEVICE_FUNC explicit ternary_evaluator(const XprType& xpr) : m_d(xpr)
+ EIGEN_DEVICE_FUNC explicit ternary_evaluator(const XprType& xpr)
+ : m_functor(xpr.functor()),
+ m_arg1Impl(xpr.arg1()),
+ m_arg2Impl(xpr.arg2()),
+ m_arg3Impl(xpr.arg3())
{
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<TernaryOp>::Cost);
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
@@ -657,47 +624,38 @@ struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index row, Index col) const
{
- return m_d.func()(m_d.arg1Impl.coeff(row, col), m_d.arg2Impl.coeff(row, col), m_d.arg3Impl.coeff(row, col));
+ return m_functor(m_arg1Impl.coeff(row, col), m_arg2Impl.coeff(row, col), m_arg3Impl.coeff(row, col));
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index index) const
{
- return m_d.func()(m_d.arg1Impl.coeff(index), m_d.arg2Impl.coeff(index), m_d.arg3Impl.coeff(index));
+ return m_functor(m_arg1Impl.coeff(index), m_arg2Impl.coeff(index), m_arg3Impl.coeff(index));
}
template<int LoadMode, typename PacketType>
EIGEN_STRONG_INLINE
PacketType packet(Index row, Index col) const
{
- return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode,PacketType>(row, col),
- m_d.arg2Impl.template packet<LoadMode,PacketType>(row, col),
- m_d.arg3Impl.template packet<LoadMode,PacketType>(row, col));
+ return m_functor.packetOp(m_arg1Impl.template packet<LoadMode,PacketType>(row, col),
+ m_arg2Impl.template packet<LoadMode,PacketType>(row, col),
+ m_arg3Impl.template packet<LoadMode,PacketType>(row, col));
}
template<int LoadMode, typename PacketType>
EIGEN_STRONG_INLINE
PacketType packet(Index index) const
{
- return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode,PacketType>(index),
- m_d.arg2Impl.template packet<LoadMode,PacketType>(index),
- m_d.arg3Impl.template packet<LoadMode,PacketType>(index));
+ return m_functor.packetOp(m_arg1Impl.template packet<LoadMode,PacketType>(index),
+ m_arg2Impl.template packet<LoadMode,PacketType>(index),
+ m_arg3Impl.template packet<LoadMode,PacketType>(index));
}
protected:
- // this helper permits to completely eliminate the functor if it is empty
- struct Data : private TernaryOp
- {
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- Data(const XprType& xpr) : TernaryOp(xpr.functor()), arg1Impl(xpr.arg1()), arg2Impl(xpr.arg2()), arg3Impl(xpr.arg3()) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- const TernaryOp& func() const { return static_cast<const TernaryOp&>(*this); }
- evaluator<Arg1> arg1Impl;
- evaluator<Arg2> arg2Impl;
- evaluator<Arg3> arg3Impl;
- };
-
- Data m_d;
+ const TernaryOp m_functor;
+ evaluator<Arg1> m_arg1Impl;
+ evaluator<Arg2> m_arg2Impl;
+ evaluator<Arg3> m_arg3Impl;
};
// -------------------- CwiseBinaryOp --------------------
@@ -738,7 +696,10 @@ struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBase
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<Lhs>::Alignment,evaluator<Rhs>::Alignment)
};
- EIGEN_DEVICE_FUNC explicit binary_evaluator(const XprType& xpr) : m_d(xpr)
+ EIGEN_DEVICE_FUNC explicit binary_evaluator(const XprType& xpr)
+ : m_functor(xpr.functor()),
+ m_lhsImpl(xpr.lhs()),
+ m_rhsImpl(xpr.rhs())
{
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
@@ -749,45 +710,35 @@ struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBase
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index row, Index col) const
{
- return m_d.func()(m_d.lhsImpl.coeff(row, col), m_d.rhsImpl.coeff(row, col));
+ return m_functor(m_lhsImpl.coeff(row, col), m_rhsImpl.coeff(row, col));
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index index) const
{
- return m_d.func()(m_d.lhsImpl.coeff(index), m_d.rhsImpl.coeff(index));
+ return m_functor(m_lhsImpl.coeff(index), m_rhsImpl.coeff(index));
}
template<int LoadMode, typename PacketType>
EIGEN_STRONG_INLINE
PacketType packet(Index row, Index col) const
{
- return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode,PacketType>(row, col),
- m_d.rhsImpl.template packet<LoadMode,PacketType>(row, col));
+ return m_functor.packetOp(m_lhsImpl.template packet<LoadMode,PacketType>(row, col),
+ m_rhsImpl.template packet<LoadMode,PacketType>(row, col));
}
template<int LoadMode, typename PacketType>
EIGEN_STRONG_INLINE
PacketType packet(Index index) const
{
- return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode,PacketType>(index),
- m_d.rhsImpl.template packet<LoadMode,PacketType>(index));
+ return m_functor.packetOp(m_lhsImpl.template packet<LoadMode,PacketType>(index),
+ m_rhsImpl.template packet<LoadMode,PacketType>(index));
}
protected:
-
- // this helper permits to completely eliminate the functor if it is empty
- struct Data : private BinaryOp
- {
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- Data(const XprType& xpr) : BinaryOp(xpr.functor()), lhsImpl(xpr.lhs()), rhsImpl(xpr.rhs()) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- const BinaryOp& func() const { return static_cast<const BinaryOp&>(*this); }
- evaluator<Lhs> lhsImpl;
- evaluator<Rhs> rhsImpl;
- };
-
- Data m_d;
+ const BinaryOp m_functor;
+ evaluator<Lhs> m_lhsImpl;
+ evaluator<Rhs> m_rhsImpl;
};
// -------------------- CwiseUnaryView --------------------
@@ -806,7 +757,9 @@ struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType>, IndexBased>
Alignment = 0 // FIXME it is not very clear why alignment is necessarily lost...
};
- EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& op) : m_d(op)
+ EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& op)
+ : m_unaryOp(op.functor()),
+ m_argImpl(op.nestedExpression())
{
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
@@ -818,40 +771,30 @@ struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType>, IndexBased>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index row, Index col) const
{
- return m_d.func()(m_d.argImpl.coeff(row, col));
+ return m_unaryOp(m_argImpl.coeff(row, col));
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index index) const
{
- return m_d.func()(m_d.argImpl.coeff(index));
+ return m_unaryOp(m_argImpl.coeff(index));
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Scalar& coeffRef(Index row, Index col)
{
- return m_d.func()(m_d.argImpl.coeffRef(row, col));
+ return m_unaryOp(m_argImpl.coeffRef(row, col));
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Scalar& coeffRef(Index index)
{
- return m_d.func()(m_d.argImpl.coeffRef(index));
+ return m_unaryOp(m_argImpl.coeffRef(index));
}
protected:
-
- // this helper permits to completely eliminate the functor if it is empty
- struct Data : private UnaryOp
- {
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- Data(const XprType& xpr) : UnaryOp(xpr.functor()), argImpl(xpr.nestedExpression()) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- const UnaryOp& func() const { return static_cast<const UnaryOp&>(*this); }
- evaluator<ArgType> argImpl;
- };
-
- Data m_d;
+ const UnaryOp m_unaryOp;
+ evaluator<ArgType> m_argImpl;
};
// -------------------- Map --------------------
diff --git a/eigen/Eigen/src/Core/CoreIterators.h b/eigen/Eigen/src/Core/CoreIterators.h
index b967196..4eb42b9 100644
--- a/eigen/Eigen/src/Core/CoreIterators.h
+++ b/eigen/Eigen/src/Core/CoreIterators.h
@@ -48,11 +48,6 @@ public:
* Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
*/
EIGEN_STRONG_INLINE InnerIterator& operator++() { m_iter.operator++(); return *this; }
- EIGEN_STRONG_INLINE InnerIterator& operator+=(Index i) { m_iter.operator+=(i); return *this; }
- EIGEN_STRONG_INLINE InnerIterator operator+(Index i)
- { InnerIterator result(*this); result+=i; return result; }
-
-
/// \returns the column or row index of the current coefficient.
EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
/// \returns the row index of the current coefficient.
diff --git a/eigen/Eigen/src/Core/CwiseBinaryOp.h b/eigen/Eigen/src/Core/CwiseBinaryOp.h
index bf2632d..a36765e 100644
--- a/eigen/Eigen/src/Core/CwiseBinaryOp.h
+++ b/eigen/Eigen/src/Core/CwiseBinaryOp.h
@@ -158,7 +158,7 @@ public:
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
+EIGEN_STRONG_INLINE Derived &
MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
{
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
@@ -171,7 +171,7 @@ MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
+EIGEN_STRONG_INLINE Derived &
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
{
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
@@ -181,3 +181,4 @@ MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
} // end namespace Eigen
#endif // EIGEN_CWISE_BINARY_OP_H
+
diff --git a/eigen/Eigen/src/Core/CwiseNullaryOp.h b/eigen/Eigen/src/Core/CwiseNullaryOp.h
index 144608e..ddd607e 100644
--- a/eigen/Eigen/src/Core/CwiseNullaryOp.h
+++ b/eigen/Eigen/src/Core/CwiseNullaryOp.h
@@ -131,7 +131,7 @@ DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& f
*/
template<typename Derived>
template<typename CustomNullaryOp>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
+EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
@@ -170,7 +170,7 @@ DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
* \sa class CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
{
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
diff --git a/eigen/Eigen/src/Core/DenseBase.h b/eigen/Eigen/src/Core/DenseBase.h
index fd933ee..90066ae 100644
--- a/eigen/Eigen/src/Core/DenseBase.h
+++ b/eigen/Eigen/src/Core/DenseBase.h
@@ -570,17 +570,13 @@ template<typename Derived> class DenseBase
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
-#define EIGEN_DOC_UNARY_ADDONS(X,Y)
-# include "../plugins/CommonCwiseUnaryOps.h"
# include "../plugins/BlockMethods.h"
-# include "../plugins/IndexedViewMethods.h"
# ifdef EIGEN_DENSEBASE_PLUGIN
# include EIGEN_DENSEBASE_PLUGIN
# endif
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
#undef EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
#undef EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF
-#undef EIGEN_DOC_UNARY_ADDONS
// disable the use of evalTo for dense objects with a nice compilation error
template<typename Dest>
diff --git a/eigen/Eigen/src/Core/Diagonal.h b/eigen/Eigen/src/Core/Diagonal.h
index c62f5ff..49e7112 100644
--- a/eigen/Eigen/src/Core/Diagonal.h
+++ b/eigen/Eigen/src/Core/Diagonal.h
@@ -184,7 +184,7 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
*
* \sa class Diagonal */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::DiagonalReturnType
+inline typename MatrixBase<Derived>::DiagonalReturnType
MatrixBase<Derived>::diagonal()
{
return DiagonalReturnType(derived());
@@ -192,7 +192,7 @@ MatrixBase<Derived>::diagonal()
/** This is the const version of diagonal(). */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::ConstDiagonalReturnType
+inline typename MatrixBase<Derived>::ConstDiagonalReturnType
MatrixBase<Derived>::diagonal() const
{
return ConstDiagonalReturnType(derived());
@@ -210,7 +210,7 @@ MatrixBase<Derived>::diagonal() const
*
* \sa MatrixBase::diagonal(), class Diagonal */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::DiagonalDynamicIndexReturnType
+inline typename MatrixBase<Derived>::DiagonalDynamicIndexReturnType
MatrixBase<Derived>::diagonal(Index index)
{
return DiagonalDynamicIndexReturnType(derived(), index);
@@ -218,7 +218,7 @@ MatrixBase<Derived>::diagonal(Index index)
/** This is the const version of diagonal(Index). */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::ConstDiagonalDynamicIndexReturnType
+inline typename MatrixBase<Derived>::ConstDiagonalDynamicIndexReturnType
MatrixBase<Derived>::diagonal(Index index) const
{
return ConstDiagonalDynamicIndexReturnType(derived(), index);
@@ -237,7 +237,6 @@ MatrixBase<Derived>::diagonal(Index index) const
* \sa MatrixBase::diagonal(), class Diagonal */
template<typename Derived>
template<int Index_>
-EIGEN_DEVICE_FUNC
inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index_>::Type
MatrixBase<Derived>::diagonal()
{
@@ -247,7 +246,6 @@ MatrixBase<Derived>::diagonal()
/** This is the const version of diagonal<int>(). */
template<typename Derived>
template<int Index_>
-EIGEN_DEVICE_FUNC
inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index_>::Type
MatrixBase<Derived>::diagonal() const
{
diff --git a/eigen/Eigen/src/Core/DiagonalMatrix.h b/eigen/Eigen/src/Core/DiagonalMatrix.h
index 4e8297e..ecfdce8 100644
--- a/eigen/Eigen/src/Core/DiagonalMatrix.h
+++ b/eigen/Eigen/src/Core/DiagonalMatrix.h
@@ -44,7 +44,7 @@ class DiagonalBase : public EigenBase<Derived>
EIGEN_DEVICE_FUNC
DenseMatrixType toDenseMatrix() const { return derived(); }
-
+
EIGEN_DEVICE_FUNC
inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
EIGEN_DEVICE_FUNC
@@ -273,7 +273,7 @@ class DiagonalWrapper
* \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal()
**/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline const DiagonalWrapper<const Derived>
+inline const DiagonalWrapper<const Derived>
MatrixBase<Derived>::asDiagonal() const
{
return DiagonalWrapper<const Derived>(derived());
diff --git a/eigen/Eigen/src/Core/DiagonalProduct.h b/eigen/Eigen/src/Core/DiagonalProduct.h
index 7911d1c..d372b93 100644
--- a/eigen/Eigen/src/Core/DiagonalProduct.h
+++ b/eigen/Eigen/src/Core/DiagonalProduct.h
@@ -17,7 +17,7 @@ namespace Eigen {
*/
template<typename Derived>
template<typename DiagonalDerived>
-EIGEN_DEVICE_FUNC inline const Product<Derived, DiagonalDerived, LazyProduct>
+inline const Product<Derived, DiagonalDerived, LazyProduct>
MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &a_diagonal) const
{
return Product<Derived, DiagonalDerived, LazyProduct>(derived(),a_diagonal.derived());
diff --git a/eigen/Eigen/src/Core/Dot.h b/eigen/Eigen/src/Core/Dot.h
index bb8e3fe..06ef18b 100644
--- a/eigen/Eigen/src/Core/Dot.h
+++ b/eigen/Eigen/src/Core/Dot.h
@@ -90,7 +90,7 @@ MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
* \sa dot(), norm(), lpNorm()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
+EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
{
return numext::real((*this).cwiseAbs2().sum());
}
@@ -102,7 +102,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::trai
* \sa lpNorm(), dot(), squaredNorm()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
+inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
{
return numext::sqrt(squaredNorm());
}
@@ -117,7 +117,7 @@ EIGEN_DEVICE_FUNC inline typename NumTraits<typename internal::traits<Derived>::
* \sa norm(), normalize()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline const typename MatrixBase<Derived>::PlainObject
+inline const typename MatrixBase<Derived>::PlainObject
MatrixBase<Derived>::normalized() const
{
typedef typename internal::nested_eval<Derived,2>::type _Nested;
@@ -139,7 +139,7 @@ MatrixBase<Derived>::normalized() const
* \sa norm(), normalized()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline void MatrixBase<Derived>::normalize()
+inline void MatrixBase<Derived>::normalize()
{
RealScalar z = squaredNorm();
// NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
@@ -160,7 +160,7 @@ EIGEN_DEVICE_FUNC inline void MatrixBase<Derived>::normalize()
* \sa stableNorm(), stableNormalize(), normalized()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline const typename MatrixBase<Derived>::PlainObject
+inline const typename MatrixBase<Derived>::PlainObject
MatrixBase<Derived>::stableNormalized() const
{
typedef typename internal::nested_eval<Derived,3>::type _Nested;
@@ -185,7 +185,7 @@ MatrixBase<Derived>::stableNormalized() const
* \sa stableNorm(), stableNormalized(), normalize()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline void MatrixBase<Derived>::stableNormalize()
+inline void MatrixBase<Derived>::stableNormalize()
{
RealScalar w = cwiseAbs().maxCoeff();
RealScalar z = (derived()/w).squaredNorm();
@@ -257,9 +257,9 @@ struct lpNorm_selector<Derived, Infinity>
template<typename Derived>
template<int p>
#ifndef EIGEN_PARSED_BY_DOXYGEN
-EIGEN_DEVICE_FUNC inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
+inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
#else
-EIGEN_DEVICE_FUNC MatrixBase<Derived>::RealScalar
+MatrixBase<Derived>::RealScalar
#endif
MatrixBase<Derived>::lpNorm() const
{
diff --git a/eigen/Eigen/src/Core/EigenBase.h b/eigen/Eigen/src/Core/EigenBase.h
index ccc122c..b195506 100644
--- a/eigen/Eigen/src/Core/EigenBase.h
+++ b/eigen/Eigen/src/Core/EigenBase.h
@@ -14,6 +14,7 @@
namespace Eigen {
/** \class EigenBase
+ * \ingroup Core_Module
*
* Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
*
diff --git a/eigen/Eigen/src/Core/Fuzzy.h b/eigen/Eigen/src/Core/Fuzzy.h
index 43aa49b..3e403a0 100644
--- a/eigen/Eigen/src/Core/Fuzzy.h
+++ b/eigen/Eigen/src/Core/Fuzzy.h
@@ -100,7 +100,7 @@ struct isMuchSmallerThan_scalar_selector<Derived, true>
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isApprox(
+bool DenseBase<Derived>::isApprox(
const DenseBase<OtherDerived>& other,
const RealScalar& prec
) const
@@ -122,7 +122,7 @@ EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isApprox(
* \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isMuchSmallerThan(
+bool DenseBase<Derived>::isMuchSmallerThan(
const typename NumTraits<Scalar>::Real& other,
const RealScalar& prec
) const
@@ -142,7 +142,7 @@ EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isMuchSmallerThan(
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isMuchSmallerThan(
+bool DenseBase<Derived>::isMuchSmallerThan(
const DenseBase<OtherDerived>& other,
const RealScalar& prec
) const
diff --git a/eigen/Eigen/src/Core/GeneralProduct.h b/eigen/Eigen/src/Core/GeneralProduct.h
index b206b0a..0f16cd8 100644
--- a/eigen/Eigen/src/Core/GeneralProduct.h
+++ b/eigen/Eigen/src/Core/GeneralProduct.h
@@ -428,7 +428,7 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
template<typename Derived>
template<typename OtherDerived>
const Product<Derived,OtherDerived,LazyProduct>
-EIGEN_DEVICE_FUNC MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
+MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
{
enum {
ProductIsValid = Derived::ColsAtCompileTime==Dynamic
diff --git a/eigen/Eigen/src/Core/GenericPacketMath.h b/eigen/Eigen/src/Core/GenericPacketMath.h
index d19d5bb..029f8ac 100644
--- a/eigen/Eigen/src/Core/GenericPacketMath.h
+++ b/eigen/Eigen/src/Core/GenericPacketMath.h
@@ -61,7 +61,6 @@ struct default_packet_traits
HasSqrt = 0,
HasRsqrt = 0,
HasExp = 0,
- HasExpm1 = 0,
HasLog = 0,
HasLog1p = 0,
HasLog10 = 0,
@@ -402,10 +401,6 @@ Packet ptanh(const Packet& a) { using std::tanh; return tanh(a); }
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet pexp(const Packet& a) { using std::exp; return exp(a); }
-/** \internal \returns the expm1 of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pexpm1(const Packet& a) { return numext::expm1(a); }
-
/** \internal \returns the log of \a a (coeff-wise) */
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet plog(const Packet& a) { using std::log; return log(a); }
diff --git a/eigen/Eigen/src/Core/GlobalFunctions.h b/eigen/Eigen/src/Core/GlobalFunctions.h
index 12828a7..769dc25 100644
--- a/eigen/Eigen/src/Core/GlobalFunctions.h
+++ b/eigen/Eigen/src/Core/GlobalFunctions.h
@@ -71,7 +71,6 @@ namespace Eigen
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erf,scalar_erf_op,error function,\sa ArrayBase::erf)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erfc,scalar_erfc_op,complement error function,\sa ArrayBase::erfc)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op,exponential,\sa ArrayBase::exp)
- EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(expm1,scalar_expm1_op,exponential of a value minus 1,\sa ArrayBase::expm1)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op,natural logarithm,\sa Eigen::log10 DOXCOMMA ArrayBase::log)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log1p,scalar_log1p_op,natural logarithm of 1 plus the value,\sa ArrayBase::log1p)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op,base 10 logarithm,\sa Eigen::log DOXCOMMA ArrayBase::log)
diff --git a/eigen/Eigen/src/Core/IndexedView.h b/eigen/Eigen/src/Core/IndexedView.h
deleted file mode 100644
index 8c57a27..0000000
--- a/eigen/Eigen/src/Core/IndexedView.h
+++ /dev/null
@@ -1,207 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2017 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/.
-
-#ifndef EIGEN_INDEXED_VIEW_H
-#define EIGEN_INDEXED_VIEW_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<typename XprType, typename RowIndices, typename ColIndices>
-struct traits<IndexedView<XprType, RowIndices, ColIndices> >
- : traits<XprType>
-{
- enum {
- RowsAtCompileTime = int(array_size<RowIndices>::value),
- ColsAtCompileTime = int(array_size<ColIndices>::value),
- MaxRowsAtCompileTime = RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) : int(traits<XprType>::MaxRowsAtCompileTime),
- MaxColsAtCompileTime = ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : int(traits<XprType>::MaxColsAtCompileTime),
-
- XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
- IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
- : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
- : XprTypeIsRowMajor,
-
- RowIncr = int(get_compile_time_incr<RowIndices>::value),
- ColIncr = int(get_compile_time_incr<ColIndices>::value),
- InnerIncr = IsRowMajor ? ColIncr : RowIncr,
- OuterIncr = IsRowMajor ? RowIncr : ColIncr,
-
- HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
- XprInnerStride = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType>::ret) : int(outer_stride_at_compile_time<XprType>::ret),
- XprOuterstride = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType>::ret) : int(inner_stride_at_compile_time<XprType>::ret),
-
- InnerSize = XprTypeIsRowMajor ? ColsAtCompileTime : RowsAtCompileTime,
- IsBlockAlike = InnerIncr==1 && OuterIncr==1,
- IsInnerPannel = HasSameStorageOrderAsXprType && is_same<AllRange<InnerSize>,typename conditional<XprTypeIsRowMajor,ColIndices,RowIndices>::type>::value,
-
- InnerStrideAtCompileTime = InnerIncr<0 || InnerIncr==DynamicIndex || XprInnerStride==Dynamic ? Dynamic : XprInnerStride * InnerIncr,
- OuterStrideAtCompileTime = OuterIncr<0 || OuterIncr==DynamicIndex || XprOuterstride==Dynamic ? Dynamic : XprOuterstride * OuterIncr,
-
- ReturnAsScalar = is_same<RowIndices,SingleRange>::value && is_same<ColIndices,SingleRange>::value,
- ReturnAsBlock = (!ReturnAsScalar) && IsBlockAlike,
- ReturnAsIndexedView = (!ReturnAsScalar) && (!ReturnAsBlock),
-
- // FIXME we deal with compile-time strides if and only if we have DirectAccessBit flag,
- // but this is too strict regarding negative strides...
- DirectAccessMask = (int(InnerIncr)!=UndefinedIncr && int(OuterIncr)!=UndefinedIncr && InnerIncr>=0 && OuterIncr>=0) ? DirectAccessBit : 0,
- FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
- FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
- Flags = (traits<XprType>::Flags & (HereditaryBits | DirectAccessMask)) | FlagsLvalueBit | FlagsRowMajorBit
- };
-
- typedef Block<XprType,RowsAtCompileTime,ColsAtCompileTime,IsInnerPannel> BlockType;
-};
-
-}
-
-template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
-class IndexedViewImpl;
-
-
-/** \class IndexedView
- * \ingroup Core_Module
- *
- * \brief Expression of a non-sequential sub-matrix defined by arbitrary sequences of row and column indices
- *
- * \tparam XprType the type of the expression in which we are taking the intersections of sub-rows and sub-columns
- * \tparam RowIndices the type of the object defining the sequence of row indices
- * \tparam ColIndices the type of the object defining the sequence of column indices
- *
- * This class represents an expression of a sub-matrix (or sub-vector) defined as the intersection
- * of sub-sets of rows and columns, that are themself defined by generic sequences of row indices \f$ \{r_0,r_1,..r_{m-1}\} \f$
- * and column indices \f$ \{c_0,c_1,..c_{n-1} \}\f$. Let \f$ A \f$ be the nested matrix, then the resulting matrix \f$ B \f$ has \c m
- * rows and \c n columns, and its entries are given by: \f$ B(i,j) = A(r_i,c_j) \f$.
- *
- * The \c RowIndices and \c ColIndices types must be compatible with the following API:
- * \code
- * <integral type> operator[](Index) const;
- * Index size() const;
- * \endcode
- *
- * Typical supported types thus include:
- * - std::vector<int>
- * - std::valarray<int>
- * - std::array<int>
- * - Plain C arrays: int[N]
- * - Eigen::ArrayXi
- * - decltype(ArrayXi::LinSpaced(...))
- * - Any view/expressions of the previous types
- * - Eigen::ArithmeticSequence
- * - Eigen::internal::AllRange (helper for Eigen::all)
- * - Eigen::internal::SingleRange (helper for single index)
- * - etc.
- *
- * In typical usages of %Eigen, this class should never be used directly. It is the return type of
- * DenseBase::operator()(const RowIndices&, const ColIndices&).
- *
- * \sa class Block
- */
-template<typename XprType, typename RowIndices, typename ColIndices>
-class IndexedView : public IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>
-{
-public:
- typedef typename IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>::Base Base;
- EIGEN_GENERIC_PUBLIC_INTERFACE(IndexedView)
- EIGEN_INHERIT_ASSIGNMENT_OPERATORS(IndexedView)
-
- typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
- typedef typename internal::remove_all<XprType>::type NestedExpression;
-
- template<typename T0, typename T1>
- IndexedView(XprType& xpr, const T0& rowIndices, const T1& colIndices)
- : m_xpr(xpr), m_rowIndices(rowIndices), m_colIndices(colIndices)
- {}
-
- /** \returns number of rows */
- Index rows() const { return internal::size(m_rowIndices); }
-
- /** \returns number of columns */
- Index cols() const { return internal::size(m_colIndices); }
-
- /** \returns the nested expression */
- const typename internal::remove_all<XprType>::type&
- nestedExpression() const { return m_xpr; }
-
- /** \returns the nested expression */
- typename internal::remove_reference<XprType>::type&
- nestedExpression() { return m_xpr.const_cast_derived(); }
-
- /** \returns a const reference to the object storing/generating the row indices */
- const RowIndices& rowIndices() const { return m_rowIndices; }
-
- /** \returns a const reference to the object storing/generating the column indices */
- const ColIndices& colIndices() const { return m_colIndices; }
-
-protected:
- MatrixTypeNested m_xpr;
- RowIndices m_rowIndices;
- ColIndices m_colIndices;
-};
-
-
-// Generic API dispatcher
-template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
-class IndexedViewImpl
- : public internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type
-{
-public:
- typedef typename internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type Base;
-};
-
-namespace internal {
-
-
-template<typename ArgType, typename RowIndices, typename ColIndices>
-struct unary_evaluator<IndexedView<ArgType, RowIndices, ColIndices>, IndexBased>
- : evaluator_base<IndexedView<ArgType, RowIndices, ColIndices> >
-{
- typedef IndexedView<ArgType, RowIndices, ColIndices> XprType;
-
- enum {
- CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of row/col index */,
-
- Flags = (evaluator<ArgType>::Flags & (HereditaryBits /*| LinearAccessBit | DirectAccessBit*/)),
-
- Alignment = 0
- };
-
- EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
- {
- EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
- }
-
- typedef typename XprType::Scalar Scalar;
- typedef typename XprType::CoeffReturnType CoeffReturnType;
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- CoeffReturnType coeff(Index row, Index col) const
- {
- return m_argImpl.coeff(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
- }
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- Scalar& coeffRef(Index row, Index col)
- {
- return m_argImpl.coeffRef(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
- }
-
-protected:
-
- evaluator<ArgType> m_argImpl;
- const XprType& m_xpr;
-
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_INDEXED_VIEW_H
diff --git a/eigen/Eigen/src/Core/MathFunctions.h b/eigen/Eigen/src/Core/MathFunctions.h
index 5ec6c39..a648aa0 100644
--- a/eigen/Eigen/src/Core/MathFunctions.h
+++ b/eigen/Eigen/src/Core/MathFunctions.h
@@ -14,6 +14,7 @@
// TODO this should better be moved to NumTraits
#define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406L
+
namespace Eigen {
// On WINCE, std::abs is defined for int only, so let's defined our own overloads:
@@ -412,7 +413,7 @@ inline NewType cast(const OldType& x)
static inline Scalar run(const Scalar& x)
{
EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
- EIGEN_USING_STD_MATH(round);
+ using std::round;
return round(x);
}
};
@@ -482,55 +483,6 @@ struct arg_retval
};
/****************************************************************************
-* Implementation of expm1 *
-****************************************************************************/
-
-// This implementation is based on GSL Math's expm1.
-namespace std_fallback {
- // fallback expm1 implementation in case there is no expm1(Scalar) function in namespace of Scalar,
- // or that there is no suitable std::expm1 function available. Implementation
- // attributed to Kahan. See: http://www.plunk.org/~hatch/rightway.php.
- template<typename Scalar>
- EIGEN_DEVICE_FUNC inline Scalar expm1(const Scalar& x) {
- EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
- typedef typename NumTraits<Scalar>::Real RealScalar;
-
- EIGEN_USING_STD_MATH(exp);
- Scalar u = exp(x);
- if (u == Scalar(1)) {
- return x;
- }
- Scalar um1 = u - RealScalar(1);
- if (um1 == Scalar(-1)) {
- return RealScalar(-1);
- }
-
- EIGEN_USING_STD_MATH(log);
- return (u - RealScalar(1)) * x / log(u);
- }
-}
-
-template<typename Scalar>
-struct expm1_impl {
- EIGEN_DEVICE_FUNC static inline Scalar run(const Scalar& x)
- {
- EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
- #if EIGEN_HAS_CXX11_MATH
- using std::expm1;
- #endif
- using std_fallback::expm1;
- return expm1(x);
- }
-};
-
-
-template<typename Scalar>
-struct expm1_retval
-{
- typedef Scalar type;
-};
-
-/****************************************************************************
* Implementation of log1p *
****************************************************************************/
@@ -549,7 +501,7 @@ namespace std_fallback {
template<typename Scalar>
struct log1p_impl {
- EIGEN_DEVICE_FUNC static inline Scalar run(const Scalar& x)
+ static inline Scalar run(const Scalar& x)
{
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
#if EIGEN_HAS_CXX11_MATH
@@ -688,7 +640,7 @@ template<typename Scalar>
struct random_default_impl<Scalar, false, true>
{
static inline Scalar run(const Scalar& x, const Scalar& y)
- {
+ {
typedef typename conditional<NumTraits<Scalar>::IsSigned,std::ptrdiff_t,std::size_t>::type ScalarX;
if(y<x)
return x;
@@ -874,7 +826,7 @@ template<typename T> T generic_fast_tanh_float(const T& a_x);
namespace numext {
-#if !defined(__CUDA_ARCH__) && !defined(__SYCL_DEVICE_ONLY__)
+#ifndef __CUDA_ARCH__
template<typename T>
EIGEN_DEVICE_FUNC
EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
@@ -890,84 +842,6 @@ EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
EIGEN_USING_STD_MATH(max);
return max EIGEN_NOT_A_MACRO (x,y);
}
-
-
-#elif defined(__SYCL_DEVICE_ONLY__)
-template<typename T>
-EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
-{
-
- return y < x ? y : x;
-}
-
-template<typename T>
-EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
-{
-
- return x < y ? y : x;
-}
-
-EIGEN_ALWAYS_INLINE int mini(const int& x, const int& y)
-{
- return cl::sycl::min(x,y);
-}
-
-EIGEN_ALWAYS_INLINE int maxi(const int& x, const int& y)
-{
- return cl::sycl::max(x,y);
-}
-
-EIGEN_ALWAYS_INLINE unsigned int mini(const unsigned int& x, const unsigned int& y)
-{
- return cl::sycl::min(x,y);
-}
-
-EIGEN_ALWAYS_INLINE unsigned int maxi(const unsigned int& x, const unsigned int& y)
-{
- return cl::sycl::max(x,y);
-}
-
-EIGEN_ALWAYS_INLINE long mini(const long & x, const long & y)
-{
- return cl::sycl::min(x,y);
-}
-
-EIGEN_ALWAYS_INLINE long maxi(const long & x, const long & y)
-{
- return cl::sycl::max(x,y);
-}
-
-EIGEN_ALWAYS_INLINE unsigned long mini(const unsigned long& x, const unsigned long& y)
-{
- return cl::sycl::min(x,y);
-}
-
-EIGEN_ALWAYS_INLINE unsigned long maxi(const unsigned long& x, const unsigned long& y)
-{
- return cl::sycl::max(x,y);
-}
-
-
-EIGEN_ALWAYS_INLINE float mini(const float& x, const float& y)
-{
- return cl::sycl::fmin(x,y);
-}
-
-EIGEN_ALWAYS_INLINE float maxi(const float& x, const float& y)
-{
- return cl::sycl::fmax(x,y);
-}
-
-EIGEN_ALWAYS_INLINE double mini(const double& x, const double& y)
-{
- return cl::sycl::fmin(x,y);
-}
-
-EIGEN_ALWAYS_INLINE double maxi(const double& x, const double& y)
-{
- return cl::sycl::fmax(x,y);
-}
-
#else
template<typename T>
EIGEN_DEVICE_FUNC
@@ -1080,11 +954,6 @@ inline EIGEN_MATHFUNC_RETVAL(log1p, Scalar) log1p(const Scalar& x)
return EIGEN_MATHFUNC_IMPL(log1p, Scalar)::run(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float log1p(float x) { return cl::sycl::log1p(x); }
-EIGEN_ALWAYS_INLINE double log1p(double x) { return cl::sycl::log1p(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float log1p(const float &x) { return ::log1pf(x); }
@@ -1100,24 +969,10 @@ inline typename internal::pow_impl<ScalarX,ScalarY>::result_type pow(const Scala
return internal::pow_impl<ScalarX,ScalarY>::run(x, y);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float pow(float x, float y) { return cl::sycl::pow(x, y); }
-EIGEN_ALWAYS_INLINE double pow(double x, double y) { return cl::sycl::pow(x, y); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
template<typename T> EIGEN_DEVICE_FUNC bool (isnan) (const T &x) { return internal::isnan_impl(x); }
template<typename T> EIGEN_DEVICE_FUNC bool (isinf) (const T &x) { return internal::isinf_impl(x); }
template<typename T> EIGEN_DEVICE_FUNC bool (isfinite)(const T &x) { return internal::isfinite_impl(x); }
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float isnan(float x) { return cl::sycl::isnan(x); }
-EIGEN_ALWAYS_INLINE double isnan(double x) { return cl::sycl::isnan(x); }
-EIGEN_ALWAYS_INLINE float isinf(float x) { return cl::sycl::isinf(x); }
-EIGEN_ALWAYS_INLINE double isinf(double x) { return cl::sycl::isinf(x); }
-EIGEN_ALWAYS_INLINE float isfinite(float x) { return cl::sycl::isfinite(x); }
-EIGEN_ALWAYS_INLINE double isfinite(double x) { return cl::sycl::isfinite(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
template<typename Scalar>
EIGEN_DEVICE_FUNC
inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x)
@@ -1125,11 +980,6 @@ inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x)
return EIGEN_MATHFUNC_IMPL(round, Scalar)::run(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float round(float x) { return cl::sycl::round(x); }
-EIGEN_ALWAYS_INLINE double round(double x) { return cl::sycl::round(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
template<typename T>
EIGEN_DEVICE_FUNC
T (floor)(const T& x)
@@ -1138,11 +988,6 @@ T (floor)(const T& x)
return floor(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float floor(float x) { return cl::sycl::floor(x); }
-EIGEN_ALWAYS_INLINE double floor(double x) { return cl::sycl::floor(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float floor(const float &x) { return ::floorf(x); }
@@ -1159,11 +1004,6 @@ T (ceil)(const T& x)
return ceil(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float ceil(float x) { return cl::sycl::ceil(x); }
-EIGEN_ALWAYS_INLINE double ceil(double x) { return cl::sycl::ceil(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float ceil(const float &x) { return ::ceilf(x); }
@@ -1204,11 +1044,6 @@ T sqrt(const T &x)
return sqrt(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float sqrt(float x) { return cl::sycl::sqrt(x); }
-EIGEN_ALWAYS_INLINE double sqrt(double x) { return cl::sycl::sqrt(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
template<typename T>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
T log(const T &x) {
@@ -1216,12 +1051,6 @@ T log(const T &x) {
return log(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float log(float x) { return cl::sycl::log(x); }
-EIGEN_ALWAYS_INLINE double log(double x) { return cl::sycl::log(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float log(const float &x) { return ::logf(x); }
@@ -1232,11 +1061,19 @@ double log(const double &x) { return ::log(x); }
template<typename T>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-typename NumTraits<T>::Real abs(const T &x) {
+typename internal::enable_if<NumTraits<T>::IsSigned || NumTraits<T>::IsComplex,typename NumTraits<T>::Real>::type
+abs(const T &x) {
EIGEN_USING_STD_MATH(abs);
return abs(x);
}
+template<typename T>
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+typename internal::enable_if<!(NumTraits<T>::IsSigned || NumTraits<T>::IsComplex),typename NumTraits<T>::Real>::type
+abs(const T &x) {
+ return x;
+}
+
#if defined(__SYCL_DEVICE_ONLY__)
EIGEN_ALWAYS_INLINE float abs(float x) { return cl::sycl::fabs(x); }
EIGEN_ALWAYS_INLINE double abs(double x) { return cl::sycl::fabs(x); }
@@ -1267,11 +1104,6 @@ T exp(const T &x) {
return exp(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float exp(float x) { return cl::sycl::exp(x); }
-EIGEN_ALWAYS_INLINE double exp(double x) { return cl::sycl::exp(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float exp(const float &x) { return ::expf(x); }
@@ -1280,26 +1112,6 @@ template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
double exp(const double &x) { return ::exp(x); }
#endif
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(expm1, Scalar) expm1(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(expm1, Scalar)::run(x);
-}
-
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float expm1(float x) { return cl::sycl::expm1(x); }
-EIGEN_ALWAYS_INLINE double expm1(double x) { return cl::sycl::expm1(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float expm1(const float &x) { return ::expm1f(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double expm1(const double &x) { return ::expm1(x); }
-#endif
-
template<typename T>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
T cos(const T &x) {
@@ -1307,11 +1119,6 @@ T cos(const T &x) {
return cos(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float cos(float x) { return cl::sycl::cos(x); }
-EIGEN_ALWAYS_INLINE double cos(double x) { return cl::sycl::cos(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float cos(const float &x) { return ::cosf(x); }
@@ -1327,11 +1134,6 @@ T sin(const T &x) {
return sin(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float sin(float x) { return cl::sycl::sin(x); }
-EIGEN_ALWAYS_INLINE double sin(double x) { return cl::sycl::sin(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float sin(const float &x) { return ::sinf(x); }
@@ -1347,11 +1149,6 @@ T tan(const T &x) {
return tan(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float tan(float x) { return cl::sycl::tan(x); }
-EIGEN_ALWAYS_INLINE double tan(double x) { return cl::sycl::tan(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float tan(const float &x) { return ::tanf(x); }
@@ -1367,11 +1164,6 @@ T acos(const T &x) {
return acos(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float acos(float x) { return cl::sycl::acos(x); }
-EIGEN_ALWAYS_INLINE double acos(double x) { return cl::sycl::acos(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float acos(const float &x) { return ::acosf(x); }
@@ -1387,11 +1179,6 @@ T asin(const T &x) {
return asin(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float asin(float x) { return cl::sycl::asin(x); }
-EIGEN_ALWAYS_INLINE double asin(double x) { return cl::sycl::asin(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float asin(const float &x) { return ::asinf(x); }
@@ -1407,11 +1194,6 @@ T atan(const T &x) {
return atan(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float atan(float x) { return cl::sycl::atan(x); }
-EIGEN_ALWAYS_INLINE double atan(double x) { return cl::sycl::atan(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float atan(const float &x) { return ::atanf(x); }
@@ -1428,11 +1210,6 @@ T cosh(const T &x) {
return cosh(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float cosh(float x) { return cl::sycl::cosh(x); }
-EIGEN_ALWAYS_INLINE double cosh(double x) { return cl::sycl::cosh(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float cosh(const float &x) { return ::coshf(x); }
@@ -1448,11 +1225,6 @@ T sinh(const T &x) {
return sinh(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float sinh(float x) { return cl::sycl::sinh(x); }
-EIGEN_ALWAYS_INLINE double sinh(double x) { return cl::sycl::sinh(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float sinh(const float &x) { return ::sinhf(x); }
@@ -1468,10 +1240,7 @@ T tanh(const T &x) {
return tanh(x);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float tanh(float x) { return cl::sycl::tanh(x); }
-EIGEN_ALWAYS_INLINE double tanh(double x) { return cl::sycl::tanh(x); }
-#elif (!defined(__CUDACC__)) && EIGEN_FAST_MATH
+#if (!defined(__CUDACC__)) && EIGEN_FAST_MATH
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float tanh(float x) { return internal::generic_fast_tanh_float(x); }
#endif
@@ -1491,11 +1260,6 @@ T fmod(const T& a, const T& b) {
return fmod(a, b);
}
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float fmod(float x, float y) { return cl::sycl::fmod(x, y); }
-EIGEN_ALWAYS_INLINE double fmod(double x, double y) { return cl::sycl::fmod(x, y); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
#ifdef __CUDACC__
template <>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
@@ -1638,13 +1402,13 @@ template<> struct random_impl<bool>
template<> struct scalar_fuzzy_impl<bool>
{
typedef bool RealScalar;
-
+
template<typename OtherScalar> EIGEN_DEVICE_FUNC
static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
{
return !x;
}
-
+
EIGEN_DEVICE_FUNC
static inline bool isApprox(bool x, bool y, bool)
{
@@ -1656,10 +1420,10 @@ template<> struct scalar_fuzzy_impl<bool>
{
return (!x) || y;
}
-
+
};
-
+
} // end namespace internal
} // end namespace Eigen
diff --git a/eigen/Eigen/src/Core/MathFunctionsImpl.h b/eigen/Eigen/src/Core/MathFunctionsImpl.h
index ae1386b..3c9ef22 100644
--- a/eigen/Eigen/src/Core/MathFunctionsImpl.h
+++ b/eigen/Eigen/src/Core/MathFunctionsImpl.h
@@ -29,7 +29,12 @@ T generic_fast_tanh_float(const T& a_x)
// this range is +/-1.0f in single-precision.
const T plus_9 = pset1<T>(9.f);
const T minus_9 = pset1<T>(-9.f);
- const T x = pmax(pmin(a_x, plus_9), minus_9);
+ // NOTE GCC prior to 6.3 might improperly optimize this max/min
+ // step such that if a_x is nan, x will be either 9 or -9,
+ // and tanh will return 1 or -1 instead of nan.
+ // This is supposed to be fixed in gcc6.3,
+ // see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867
+ const T x = pmax(minus_9,pmin(plus_9,a_x));
// The monomial coefficients of the numerator polynomial (odd).
const T alpha_1 = pset1<T>(4.89352455891786e-03f);
const T alpha_3 = pset1<T>(6.37261928875436e-04f);
diff --git a/eigen/Eigen/src/Core/MatrixBase.h b/eigen/Eigen/src/Core/MatrixBase.h
index 200e577..ce41218 100644
--- a/eigen/Eigen/src/Core/MatrixBase.h
+++ b/eigen/Eigen/src/Core/MatrixBase.h
@@ -76,7 +76,6 @@ template<typename Derived> class MatrixBase
using Base::coeffRef;
using Base::lazyAssign;
using Base::eval;
- using Base::operator-;
using Base::operator+=;
using Base::operator-=;
using Base::operator*=;
@@ -123,6 +122,7 @@ template<typename Derived> class MatrixBase
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
+# include "../plugins/CommonCwiseUnaryOps.h"
# include "../plugins/CommonCwiseBinaryOps.h"
# include "../plugins/MatrixCwiseUnaryOps.h"
# include "../plugins/MatrixCwiseBinaryOps.h"
diff --git a/eigen/Eigen/src/Core/NestByValue.h b/eigen/Eigen/src/Core/NestByValue.h
index 01cf192..13adf07 100644
--- a/eigen/Eigen/src/Core/NestByValue.h
+++ b/eigen/Eigen/src/Core/NestByValue.h
@@ -67,25 +67,25 @@ template<typename ExpressionType> class NestByValue
}
template<int LoadMode>
- EIGEN_DEVICE_FUNC inline const PacketScalar packet(Index row, Index col) const
+ inline const PacketScalar packet(Index row, Index col) const
{
return m_expression.template packet<LoadMode>(row, col);
}
template<int LoadMode>
- EIGEN_DEVICE_FUNC inline void writePacket(Index row, Index col, const PacketScalar& x)
+ inline void writePacket(Index row, Index col, const PacketScalar& x)
{
m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
}
template<int LoadMode>
- EIGEN_DEVICE_FUNC inline const PacketScalar packet(Index index) const
+ inline const PacketScalar packet(Index index) const
{
return m_expression.template packet<LoadMode>(index);
}
template<int LoadMode>
- EIGEN_DEVICE_FUNC inline void writePacket(Index index, const PacketScalar& x)
+ inline void writePacket(Index index, const PacketScalar& x)
{
m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
}
@@ -99,7 +99,7 @@ template<typename ExpressionType> class NestByValue
/** \returns an expression of the temporary version of *this.
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline const NestByValue<Derived>
+inline const NestByValue<Derived>
DenseBase<Derived>::nestByValue() const
{
return NestByValue<Derived>(derived());
diff --git a/eigen/Eigen/src/Core/NumTraits.h b/eigen/Eigen/src/Core/NumTraits.h
index aebc0c2..daf4898 100644
--- a/eigen/Eigen/src/Core/NumTraits.h
+++ b/eigen/Eigen/src/Core/NumTraits.h
@@ -71,7 +71,7 @@ struct default_digits10_impl<T,false,true> // Integer
* and to \c 0 otherwise.
* \li Enum values ReadCost, AddCost and MulCost representing a rough estimate of the number of CPU cycles needed
* to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers.
- * Stay vague here. No need to do architecture-specific stuff. If you don't know what this means, just use \c Eigen::HugeCost.
+ * Stay vague here. No need to do architecture-specific stuff.
* \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned.
* \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must
* be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise.
@@ -215,6 +215,8 @@ struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
EIGEN_DEVICE_FUNC
static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
+
+ static inline int digits10() { return NumTraits<Scalar>::digits10(); }
};
template<> struct NumTraits<std::string>
diff --git a/eigen/Eigen/src/Core/ProductEvaluators.h b/eigen/Eigen/src/Core/ProductEvaluators.h
index 583b7f5..c42725d 100644
--- a/eigen/Eigen/src/Core/ProductEvaluators.h
+++ b/eigen/Eigen/src/Core/ProductEvaluators.h
@@ -207,6 +207,12 @@ struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_sum_op<typename
static const bool value = true;
};
+template<typename OtherXpr, typename Lhs, typename Rhs>
+struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_difference_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr,
+ const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > {
+ static const bool value = true;
+};
+
template<typename DstXprType, typename OtherXpr, typename ProductType, typename Func1, typename Func2>
struct assignment_from_xpr_op_product
{
diff --git a/eigen/Eigen/src/Core/Random.h b/eigen/Eigen/src/Core/Random.h
index 486e9ed..6faf789 100644
--- a/eigen/Eigen/src/Core/Random.h
+++ b/eigen/Eigen/src/Core/Random.h
@@ -128,7 +128,7 @@ DenseBase<Derived>::Random()
* \sa class CwiseNullaryOp, setRandom(Index), setRandom(Index,Index)
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline Derived& DenseBase<Derived>::setRandom()
+inline Derived& DenseBase<Derived>::setRandom()
{
return *this = Random(rows(), cols());
}
diff --git a/eigen/Eigen/src/Core/Redux.h b/eigen/Eigen/src/Core/Redux.h
index 2b5b73b..b6e8f88 100644
--- a/eigen/Eigen/src/Core/Redux.h
+++ b/eigen/Eigen/src/Core/Redux.h
@@ -407,7 +407,7 @@ protected:
*/
template<typename Derived>
template<typename Func>
-EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar
+typename internal::traits<Derived>::Scalar
DenseBase<Derived>::redux(const Func& func) const
{
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
@@ -422,7 +422,7 @@ DenseBase<Derived>::redux(const Func& func) const
* \warning the result is undefined if \c *this contains NaN.
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::minCoeff() const
{
return derived().redux(Eigen::internal::scalar_min_op<Scalar,Scalar>());
@@ -432,7 +432,7 @@ DenseBase<Derived>::minCoeff() const
* \warning the result is undefined if \c *this contains NaN.
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::maxCoeff() const
{
return derived().redux(Eigen::internal::scalar_max_op<Scalar,Scalar>());
@@ -445,7 +445,7 @@ DenseBase<Derived>::maxCoeff() const
* \sa trace(), prod(), mean()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::sum() const
{
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
@@ -458,7 +458,7 @@ DenseBase<Derived>::sum() const
* \sa trace(), prod(), sum()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::mean() const
{
#ifdef __INTEL_COMPILER
@@ -479,7 +479,7 @@ DenseBase<Derived>::mean() const
* \sa sum(), mean(), trace()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::prod() const
{
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
@@ -494,7 +494,7 @@ DenseBase<Derived>::prod() const
* \sa diagonal(), sum()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
MatrixBase<Derived>::trace() const
{
return derived().diagonal().sum();
diff --git a/eigen/Eigen/src/Core/Ref.h b/eigen/Eigen/src/Core/Ref.h
index abb1e51..bdf24f5 100644
--- a/eigen/Eigen/src/Core/Ref.h
+++ b/eigen/Eigen/src/Core/Ref.h
@@ -184,8 +184,6 @@ protected:
* void foo(const Ref<MatrixXf,0,Stride<> >& A) { foo_impl(A); }
* \endcode
*
- * See also the following stackoverflow questions for further references:
- * - <a href="http://stackoverflow.com/questions/21132538/correct-usage-of-the-eigenref-class">Correct usage of the Eigen::Ref<> class</a>
*
* \sa PlainObjectBase::Map(), \ref TopicStorageOrders
*/
diff --git a/eigen/Eigen/src/Core/Replicate.h b/eigen/Eigen/src/Core/Replicate.h
index 0b2d6d7..9960ef8 100644
--- a/eigen/Eigen/src/Core/Replicate.h
+++ b/eigen/Eigen/src/Core/Replicate.h
@@ -115,7 +115,7 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
*/
template<typename Derived>
template<int RowFactor, int ColFactor>
-EIGEN_DEVICE_FUNC const Replicate<Derived,RowFactor,ColFactor>
+const Replicate<Derived,RowFactor,ColFactor>
DenseBase<Derived>::replicate() const
{
return Replicate<Derived,RowFactor,ColFactor>(derived());
@@ -130,7 +130,7 @@ DenseBase<Derived>::replicate() const
* \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate
*/
template<typename ExpressionType, int Direction>
-EIGEN_DEVICE_FUNC const typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
+const typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
VectorwiseOp<ExpressionType,Direction>::replicate(Index factor) const
{
return typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
diff --git a/eigen/Eigen/src/Core/ReturnByValue.h b/eigen/Eigen/src/Core/ReturnByValue.h
index 11dc86d..c44b767 100644
--- a/eigen/Eigen/src/Core/ReturnByValue.h
+++ b/eigen/Eigen/src/Core/ReturnByValue.h
@@ -79,7 +79,7 @@ template<typename Derived> class ReturnByValue
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
+Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
{
other.evalTo(derived());
return derived();
diff --git a/eigen/Eigen/src/Core/Reverse.h b/eigen/Eigen/src/Core/Reverse.h
index 8b6b3ab..0640cda 100644
--- a/eigen/Eigen/src/Core/Reverse.h
+++ b/eigen/Eigen/src/Core/Reverse.h
@@ -114,7 +114,7 @@ template<typename MatrixType, int Direction> class Reverse
*
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ReverseReturnType
+inline typename DenseBase<Derived>::ReverseReturnType
DenseBase<Derived>::reverse()
{
return ReverseReturnType(derived());
@@ -136,7 +136,7 @@ DenseBase<Derived>::reverse()
*
* \sa VectorwiseOp::reverseInPlace(), reverse() */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline void DenseBase<Derived>::reverseInPlace()
+inline void DenseBase<Derived>::reverseInPlace()
{
if(cols()>rows())
{
@@ -201,7 +201,7 @@ struct vectorwise_reverse_inplace_impl<Horizontal>
*
* \sa DenseBase::reverseInPlace(), reverse() */
template<typename ExpressionType, int Direction>
-EIGEN_DEVICE_FUNC void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
+void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
{
internal::vectorwise_reverse_inplace_impl<Direction>::run(_expression().const_cast_derived());
}
diff --git a/eigen/Eigen/src/Core/SelfAdjointView.h b/eigen/Eigen/src/Core/SelfAdjointView.h
index 7e71fe3..504c98f 100644
--- a/eigen/Eigen/src/Core/SelfAdjointView.h
+++ b/eigen/Eigen/src/Core/SelfAdjointView.h
@@ -322,7 +322,7 @@ public:
/** This is the const version of MatrixBase::selfadjointView() */
template<typename Derived>
template<unsigned int UpLo>
-EIGEN_DEVICE_FUNC typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type
+typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type
MatrixBase<Derived>::selfadjointView() const
{
return typename ConstSelfAdjointViewReturnType<UpLo>::Type(derived());
@@ -339,7 +339,7 @@ MatrixBase<Derived>::selfadjointView() const
*/
template<typename Derived>
template<unsigned int UpLo>
-EIGEN_DEVICE_FUNC typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type
+typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type
MatrixBase<Derived>::selfadjointView()
{
return typename SelfAdjointViewReturnType<UpLo>::Type(derived());
diff --git a/eigen/Eigen/src/Core/Solve.h b/eigen/Eigen/src/Core/Solve.h
index 960a585..a8daea5 100644
--- a/eigen/Eigen/src/Core/Solve.h
+++ b/eigen/Eigen/src/Core/Solve.h
@@ -34,12 +34,12 @@ template<typename Decomposition, typename RhsType,typename StorageKind> struct s
template<typename Decomposition, typename RhsType>
struct solve_traits<Decomposition,RhsType,Dense>
{
- typedef Matrix<typename RhsType::Scalar,
+ typedef typename make_proper_matrix_type<typename RhsType::Scalar,
Decomposition::ColsAtCompileTime,
RhsType::ColsAtCompileTime,
RhsType::PlainObject::Options,
Decomposition::MaxColsAtCompileTime,
- RhsType::MaxColsAtCompileTime> PlainObject;
+ RhsType::MaxColsAtCompileTime>::type PlainObject;
};
template<typename Decomposition, typename RhsType>
diff --git a/eigen/Eigen/src/Core/SolveTriangular.h b/eigen/Eigen/src/Core/SolveTriangular.h
index a0011d4..049890b 100644
--- a/eigen/Eigen/src/Core/SolveTriangular.h
+++ b/eigen/Eigen/src/Core/SolveTriangular.h
@@ -164,7 +164,7 @@ struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename MatrixType, unsigned int Mode>
template<int Side, typename OtherDerived>
-EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
+void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
{
OtherDerived& other = _other.const_cast_derived();
eigen_assert( derived().cols() == derived().rows() && ((Side==OnTheLeft && derived().cols() == other.rows()) || (Side==OnTheRight && derived().cols() == other.cols())) );
diff --git a/eigen/Eigen/src/Core/Transpose.h b/eigen/Eigen/src/Core/Transpose.h
index ba7d6e6..79b767b 100644
--- a/eigen/Eigen/src/Core/Transpose.h
+++ b/eigen/Eigen/src/Core/Transpose.h
@@ -168,7 +168,7 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
*
* \sa transposeInPlace(), adjoint() */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline Transpose<Derived>
+inline Transpose<Derived>
DenseBase<Derived>::transpose()
{
return TransposeReturnType(derived());
@@ -180,7 +180,7 @@ DenseBase<Derived>::transpose()
*
* \sa transposeInPlace(), adjoint() */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ConstTransposeReturnType
+inline typename DenseBase<Derived>::ConstTransposeReturnType
DenseBase<Derived>::transpose() const
{
return ConstTransposeReturnType(derived());
@@ -206,7 +206,7 @@ DenseBase<Derived>::transpose() const
*
* \sa adjointInPlace(), transpose(), conjugate(), class Transpose, class internal::scalar_conjugate_op */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline const typename MatrixBase<Derived>::AdjointReturnType
+inline const typename MatrixBase<Derived>::AdjointReturnType
MatrixBase<Derived>::adjoint() const
{
return AdjointReturnType(this->transpose());
@@ -281,7 +281,7 @@ struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non squ
*
* \sa transpose(), adjoint(), adjointInPlace() */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline void DenseBase<Derived>::transposeInPlace()
+inline void DenseBase<Derived>::transposeInPlace()
{
eigen_assert((rows() == cols() || (RowsAtCompileTime == Dynamic && ColsAtCompileTime == Dynamic))
&& "transposeInPlace() called on a non-square non-resizable matrix");
@@ -312,7 +312,7 @@ EIGEN_DEVICE_FUNC inline void DenseBase<Derived>::transposeInPlace()
*
* \sa transpose(), adjoint(), transposeInPlace() */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline void MatrixBase<Derived>::adjointInPlace()
+inline void MatrixBase<Derived>::adjointInPlace()
{
derived() = adjoint().eval();
}
diff --git a/eigen/Eigen/src/Core/TriangularMatrix.h b/eigen/Eigen/src/Core/TriangularMatrix.h
index ed80da3..667ef09 100644
--- a/eigen/Eigen/src/Core/TriangularMatrix.h
+++ b/eigen/Eigen/src/Core/TriangularMatrix.h
@@ -488,6 +488,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
* \sa TriangularView::solveInPlace()
*/
template<int Side, typename Other>
+ EIGEN_DEVICE_FUNC
inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
solve(const MatrixBase<Other>& other) const;
@@ -553,7 +554,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
// FIXME should we keep that possibility
template<typename MatrixType, unsigned int Mode>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC inline TriangularView<MatrixType, Mode>&
+inline TriangularView<MatrixType, Mode>&
TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDerived>& other)
{
internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
@@ -563,7 +564,7 @@ TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDer
// FIXME should we keep that possibility
template<typename MatrixType, unsigned int Mode>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<OtherDerived>& other)
+void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<OtherDerived>& other)
{
internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
}
@@ -572,7 +573,7 @@ EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(c
template<typename MatrixType, unsigned int Mode>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC inline TriangularView<MatrixType, Mode>&
+inline TriangularView<MatrixType, Mode>&
TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<OtherDerived>& other)
{
eigen_assert(Mode == int(OtherDerived::Mode));
@@ -582,7 +583,7 @@ TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<Othe
template<typename MatrixType, unsigned int Mode>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBase<OtherDerived>& other)
+void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBase<OtherDerived>& other)
{
eigen_assert(Mode == int(OtherDerived::Mode));
internal::call_assignment_no_alias(derived(), other.derived());
@@ -597,7 +598,7 @@ EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(c
* If the matrix is triangular, the opposite part is set to zero. */
template<typename Derived>
template<typename DenseDerived>
-EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
+void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
{
evalToLazy(other.derived());
}
@@ -623,7 +624,6 @@ EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived>
*/
template<typename Derived>
template<unsigned int Mode>
-EIGEN_DEVICE_FUNC
typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
MatrixBase<Derived>::triangularView()
{
@@ -633,7 +633,6 @@ MatrixBase<Derived>::triangularView()
/** This is the const version of MatrixBase::triangularView() */
template<typename Derived>
template<unsigned int Mode>
-EIGEN_DEVICE_FUNC
typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
MatrixBase<Derived>::triangularView() const
{
@@ -931,7 +930,7 @@ struct triangular_assignment_loop<Kernel, Mode, Dynamic, SetOpposite>
* If the matrix is triangular, the opposite part is set to zero. */
template<typename Derived>
template<typename DenseDerived>
-EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
+void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
{
other.derived().resize(this->rows(), this->cols());
internal::call_triangular_assignment_loop<Derived::Mode,(Derived::Mode&SelfAdjoint)==0 /* SetOpposite */>(other.derived(), derived().nestedExpression());
diff --git a/eigen/Eigen/src/Core/VectorwiseOp.h b/eigen/Eigen/src/Core/VectorwiseOp.h
index 893bc79..4fe267e 100644
--- a/eigen/Eigen/src/Core/VectorwiseOp.h
+++ b/eigen/Eigen/src/Core/VectorwiseOp.h
@@ -670,7 +670,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
* \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ColwiseReturnType
+inline typename DenseBase<Derived>::ColwiseReturnType
DenseBase<Derived>::colwise()
{
return ColwiseReturnType(derived());
@@ -684,7 +684,7 @@ DenseBase<Derived>::colwise()
* \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::RowwiseReturnType
+inline typename DenseBase<Derived>::RowwiseReturnType
DenseBase<Derived>::rowwise()
{
return RowwiseReturnType(derived());
diff --git a/eigen/Eigen/src/Core/arch/AVX/PacketMath.h b/eigen/Eigen/src/Core/arch/AVX/PacketMath.h
index 6362309..195d40f 100644
--- a/eigen/Eigen/src/Core/arch/AVX/PacketMath.h
+++ b/eigen/Eigen/src/Core/arch/AVX/PacketMath.h
@@ -183,22 +183,12 @@ template<> EIGEN_STRONG_INLINE Packet4d pmadd(const Packet4d& a, const Packet4d&
}
#endif
-template<> EIGEN_STRONG_INLINE Packet8f pmin<Packet8f>(const Packet8f& a, const Packet8f& b) {
- // Arguments are swapped to match NaN propagation behavior of std::min.
- return _mm256_min_ps(b,a);
-}
-template<> EIGEN_STRONG_INLINE Packet4d pmin<Packet4d>(const Packet4d& a, const Packet4d& b) {
- // Arguments are swapped to match NaN propagation behavior of std::min.
- return _mm256_min_pd(b,a);
-}
-template<> EIGEN_STRONG_INLINE Packet8f pmax<Packet8f>(const Packet8f& a, const Packet8f& b) {
- // Arguments are swapped to match NaN propagation behavior of std::max.
- return _mm256_max_ps(b,a);
-}
-template<> EIGEN_STRONG_INLINE Packet4d pmax<Packet4d>(const Packet4d& a, const Packet4d& b) {
- // Arguments are swapped to match NaN propagation behavior of std::max.
- return _mm256_max_pd(b,a);
-}
+template<> EIGEN_STRONG_INLINE Packet8f pmin<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_min_ps(a,b); }
+template<> EIGEN_STRONG_INLINE Packet4d pmin<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_min_pd(a,b); }
+
+template<> EIGEN_STRONG_INLINE Packet8f pmax<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_max_ps(a,b); }
+template<> EIGEN_STRONG_INLINE Packet4d pmax<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_max_pd(a,b); }
+
template<> EIGEN_STRONG_INLINE Packet8f pround<Packet8f>(const Packet8f& a) { return _mm256_round_ps(a, _MM_FROUND_CUR_DIRECTION); }
template<> EIGEN_STRONG_INLINE Packet4d pround<Packet4d>(const Packet4d& a) { return _mm256_round_pd(a, _MM_FROUND_CUR_DIRECTION); }
@@ -235,7 +225,7 @@ template<> EIGEN_STRONG_INLINE Packet8f ploaddup<Packet8f>(const float* from)
// Packet8f tmp = _mm256_castps128_ps256(_mm_loadu_ps(from));
// tmp = _mm256_insertf128_ps(tmp, _mm_movehl_ps(_mm256_castps256_ps128(tmp),_mm256_castps256_ps128(tmp)), 1);
// return _mm256_unpacklo_ps(tmp,tmp);
-
+
// _mm256_insertf128_ps is very slow on Haswell, thus:
Packet8f tmp = _mm256_broadcast_ps((const __m128*)(const void*)from);
// mimic an "inplace" permutation of the lower 128bits using a blend
diff --git a/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h b/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h
index 12b8975..f6500a1 100644
--- a/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h
+++ b/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h
@@ -59,8 +59,8 @@ template<> struct packet_traits<float> : default_packet_traits
HasLog = 1,
#endif
HasExp = 1,
- HasSqrt = EIGEN_FAST_MATH,
- HasRsqrt = EIGEN_FAST_MATH,
+ HasSqrt = 1,
+ HasRsqrt = 1,
#endif
HasDiv = 1
};
@@ -75,7 +75,7 @@ template<> struct packet_traits<double> : default_packet_traits
size = 8,
HasHalfPacket = 1,
#if EIGEN_GNUC_AT_LEAST(5, 3)
- HasSqrt = EIGEN_FAST_MATH,
+ HasSqrt = 1,
HasRsqrt = EIGEN_FAST_MATH,
#endif
HasDiv = 1
@@ -230,27 +230,23 @@ EIGEN_STRONG_INLINE Packet8d pmadd(const Packet8d& a, const Packet8d& b,
template <>
EIGEN_STRONG_INLINE Packet16f pmin<Packet16f>(const Packet16f& a,
const Packet16f& b) {
- // Arguments are reversed to match NaN propagation behavior of std::min.
- return _mm512_min_ps(b, a);
+ return _mm512_min_ps(a, b);
}
template <>
EIGEN_STRONG_INLINE Packet8d pmin<Packet8d>(const Packet8d& a,
const Packet8d& b) {
- // Arguments are reversed to match NaN propagation behavior of std::min.
- return _mm512_min_pd(b, a);
+ return _mm512_min_pd(a, b);
}
template <>
EIGEN_STRONG_INLINE Packet16f pmax<Packet16f>(const Packet16f& a,
const Packet16f& b) {
- // Arguments are reversed to match NaN propagation behavior of std::max.
- return _mm512_max_ps(b, a);
+ return _mm512_max_ps(a, b);
}
template <>
EIGEN_STRONG_INLINE Packet8d pmax<Packet8d>(const Packet8d& a,
const Packet8d& b) {
- // Arguments are reversed to match NaN propagation behavior of std::max.
- return _mm512_max_pd(b, a);
+ return _mm512_max_pd(a, b);
}
template <>
@@ -465,21 +461,53 @@ EIGEN_STRONG_INLINE Packet16i ploadu<Packet16i>(const int* from) {
// {a0, a0 a1, a1, a2, a2, a3, a3, a4, a4, a5, a5, a6, a6, a7, a7}
template <>
EIGEN_STRONG_INLINE Packet16f ploaddup<Packet16f>(const float* from) {
- __m256i low_half = _mm256_load_si256(reinterpret_cast<const __m256i*>(from));
- __m512 even_elements = _mm512_castsi512_ps(_mm512_cvtepu32_epi64(low_half));
- __m512 pairs = _mm512_permute_ps(even_elements, _MM_SHUFFLE(2, 2, 0, 0));
- return pairs;
+ Packet8f lane0 = _mm256_broadcast_ps((const __m128*)(const void*)from);
+ // mimic an "inplace" permutation of the lower 128bits using a blend
+ lane0 = _mm256_blend_ps(
+ lane0, _mm256_castps128_ps256(_mm_permute_ps(
+ _mm256_castps256_ps128(lane0), _MM_SHUFFLE(1, 0, 1, 0))),
+ 15);
+ // then we can perform a consistent permutation on the global register to get
+ // everything in shape:
+ lane0 = _mm256_permute_ps(lane0, _MM_SHUFFLE(3, 3, 2, 2));
+
+ Packet8f lane1 = _mm256_broadcast_ps((const __m128*)(const void*)(from + 4));
+ // mimic an "inplace" permutation of the lower 128bits using a blend
+ lane1 = _mm256_blend_ps(
+ lane1, _mm256_castps128_ps256(_mm_permute_ps(
+ _mm256_castps256_ps128(lane1), _MM_SHUFFLE(1, 0, 1, 0))),
+ 15);
+ // then we can perform a consistent permutation on the global register to get
+ // everything in shape:
+ lane1 = _mm256_permute_ps(lane1, _MM_SHUFFLE(3, 3, 2, 2));
+
+#ifdef EIGEN_VECTORIZE_AVX512DQ
+ Packet16f res = _mm512_undefined_ps();
+ return _mm512_insertf32x8(res, lane0, 0);
+ return _mm512_insertf32x8(res, lane1, 1);
+ return res;
+#else
+ Packet16f res = _mm512_undefined_ps();
+ res = _mm512_insertf32x4(res, _mm256_extractf128_ps(lane0, 0), 0);
+ res = _mm512_insertf32x4(res, _mm256_extractf128_ps(lane0, 1), 1);
+ res = _mm512_insertf32x4(res, _mm256_extractf128_ps(lane1, 0), 2);
+ res = _mm512_insertf32x4(res, _mm256_extractf128_ps(lane1, 1), 3);
+ return res;
+#endif
}
// Loads 4 doubles from memory a returns the packet {a0, a0 a1, a1, a2, a2, a3,
// a3}
template <>
EIGEN_STRONG_INLINE Packet8d ploaddup<Packet8d>(const double* from) {
- __m512d x = _mm512_setzero_pd();
- x = _mm512_insertf64x2(x, _mm_loaddup_pd(&from[0]), 0);
- x = _mm512_insertf64x2(x, _mm_loaddup_pd(&from[1]), 1);
- x = _mm512_insertf64x2(x, _mm_loaddup_pd(&from[2]), 2);
- x = _mm512_insertf64x2(x, _mm_loaddup_pd(&from[3]), 3);
- return x;
+ Packet4d lane0 = _mm256_broadcast_pd((const __m128d*)(const void*)from);
+ lane0 = _mm256_permute_pd(lane0, 3 << 2);
+
+ Packet4d lane1 = _mm256_broadcast_pd((const __m128d*)(const void*)(from + 2));
+ lane1 = _mm256_permute_pd(lane1, 3 << 2);
+
+ Packet8d res = _mm512_undefined_pd();
+ res = _mm512_insertf64x4(res, lane0, 0);
+ return _mm512_insertf64x4(res, lane1, 1);
}
// Loads 4 floats from memory a returns the packet
@@ -497,11 +525,11 @@ EIGEN_STRONG_INLINE Packet16f ploadquad<Packet16f>(const float* from) {
// {a0, a0 a0, a0, a1, a1, a1, a1}
template <>
EIGEN_STRONG_INLINE Packet8d ploadquad<Packet8d>(const double* from) {
- __m128d tmp0 = _mm_load_pd1(from);
- __m256d lane0 = _mm256_broadcastsd_pd(tmp0);
- __m128d tmp1 = _mm_load_pd1(from + 1);
- __m256d lane1 = _mm256_broadcastsd_pd(tmp1);
- __m512d tmp = _mm512_undefined_pd();
+ Packet8d tmp = _mm512_undefined_pd();
+ Packet2d tmp0 = _mm_load_pd1(from);
+ Packet2d tmp1 = _mm_load_pd1(from + 1);
+ Packet4d lane0 = _mm256_broadcastsd_pd(tmp0);
+ Packet4d lane1 = _mm256_broadcastsd_pd(tmp1);
tmp = _mm512_insertf64x4(tmp, lane0, 0);
return _mm512_insertf64x4(tmp, lane1, 1);
}
@@ -632,8 +660,8 @@ EIGEN_STRONG_INLINE Packet8d pabs(const Packet8d& a) {
#ifdef EIGEN_VECTORIZE_AVX512DQ
// AVX512F does not define _mm512_extractf32x8_ps to extract _m256 from _m512
#define EIGEN_EXTRACT_8f_FROM_16f(INPUT, OUTPUT) \
- __m256 OUTPUT##_0 = _mm512_extractf32x8_ps(INPUT, 0); \
- __m256 OUTPUT##_1 = _mm512_extractf32x8_ps(INPUT, 1)
+ __m256 OUTPUT##_0 = _mm512_extractf32x8_ps(INPUT, 0) __m256 OUTPUT##_1 = \
+ _mm512_extractf32x8_ps(INPUT, 1)
#else
#define EIGEN_EXTRACT_8f_FROM_16f(INPUT, OUTPUT) \
__m256 OUTPUT##_0 = _mm256_insertf128_ps( \
@@ -723,7 +751,7 @@ vecs)
blend1 = _mm256_blend_ps(sum1, sum2, 0xcc);
blend2 = _mm256_blend_ps(sum3, sum4, 0xcc);
- final = _mm256_add_ps(final, _mm256_blend_ps(blend1, blend2, 0xf0));
+ final = padd(final, _mm256_blend_ps(blend1, blend2, 0xf0));
hsum1 = _mm256_hadd_ps(vecs8_0, vecs9_0);
hsum2 = _mm256_hadd_ps(vecs10_0, vecs11_0);
@@ -773,7 +801,7 @@ vecs)
blend1 = _mm256_blend_ps(sum1, sum2, 0xcc);
blend2 = _mm256_blend_ps(sum3, sum4, 0xcc);
- final_1 = _mm256_add_ps(final_1, _mm256_blend_ps(blend1, blend2, 0xf0));
+ final_1 = padd(final_1, _mm256_blend_ps(blend1, blend2, 0xf0));
__m512 final_output;
@@ -823,7 +851,7 @@ template<> EIGEN_STRONG_INLINE Packet8d preduxp<Packet8d>(const Packet8d* vecs)
tmp1 = _mm256_hadd_pd(vecs2_1, vecs3_1);
tmp1 = _mm256_add_pd(tmp1, _mm256_permute2f128_pd(tmp1, tmp1, 1));
- final_0 = _mm256_add_pd(final_0, _mm256_blend_pd(tmp0, tmp1, 0xC));
+ final_0 = padd(final_0, _mm256_blend_pd(tmp0, tmp1, 0xC));
tmp0 = _mm256_hadd_pd(vecs4_0, vecs5_0);
tmp0 = _mm256_add_pd(tmp0, _mm256_permute2f128_pd(tmp0, tmp0, 1));
@@ -839,7 +867,7 @@ template<> EIGEN_STRONG_INLINE Packet8d preduxp<Packet8d>(const Packet8d* vecs)
tmp1 = _mm256_hadd_pd(vecs6_1, vecs7_1);
tmp1 = _mm256_add_pd(tmp1, _mm256_permute2f128_pd(tmp1, tmp1, 1));
- final_1 = _mm256_add_pd(final_1, _mm256_blend_pd(tmp0, tmp1, 0xC));
+ final_1 = padd(final_1, _mm256_blend_pd(tmp0, tmp1, 0xC));
__m512d final_output = _mm512_insertf64x4(final_output, final_0, 0);
@@ -848,52 +876,55 @@ template<> EIGEN_STRONG_INLINE Packet8d preduxp<Packet8d>(const Packet8d* vecs)
template <>
EIGEN_STRONG_INLINE float predux<Packet16f>(const Packet16f& a) {
-#ifdef EIGEN_VECTORIZE_AVX512DQ
- __m256 lane0 = _mm512_extractf32x8_ps(a, 0);
- __m256 lane1 = _mm512_extractf32x8_ps(a, 1);
- Packet8f x = _mm256_add_ps(lane0, lane1);
- return predux<Packet8f>(x);
+ //#ifdef EIGEN_VECTORIZE_AVX512DQ
+#if 0
+ Packet8f lane0 = _mm512_extractf32x8_ps(a, 0);
+ Packet8f lane1 = _mm512_extractf32x8_ps(a, 1);
+ Packet8f sum = padd(lane0, lane1);
+ Packet8f tmp0 = _mm256_hadd_ps(sum, _mm256_permute2f128_ps(a, a, 1));
+ tmp0 = _mm256_hadd_ps(tmp0, tmp0);
+ return pfirst(_mm256_hadd_ps(tmp0, tmp0));
#else
- __m128 lane0 = _mm512_extractf32x4_ps(a, 0);
- __m128 lane1 = _mm512_extractf32x4_ps(a, 1);
- __m128 lane2 = _mm512_extractf32x4_ps(a, 2);
- __m128 lane3 = _mm512_extractf32x4_ps(a, 3);
- __m128 sum = _mm_add_ps(_mm_add_ps(lane0, lane1), _mm_add_ps(lane2, lane3));
+ Packet4f lane0 = _mm512_extractf32x4_ps(a, 0);
+ Packet4f lane1 = _mm512_extractf32x4_ps(a, 1);
+ Packet4f lane2 = _mm512_extractf32x4_ps(a, 2);
+ Packet4f lane3 = _mm512_extractf32x4_ps(a, 3);
+ Packet4f sum = padd(padd(lane0, lane1), padd(lane2, lane3));
sum = _mm_hadd_ps(sum, sum);
sum = _mm_hadd_ps(sum, _mm_permute_ps(sum, 1));
- return _mm_cvtss_f32(sum);
+ return pfirst(sum);
#endif
}
template <>
EIGEN_STRONG_INLINE double predux<Packet8d>(const Packet8d& a) {
- __m256d lane0 = _mm512_extractf64x4_pd(a, 0);
- __m256d lane1 = _mm512_extractf64x4_pd(a, 1);
- __m256d sum = _mm256_add_pd(lane0, lane1);
- __m256d tmp0 = _mm256_hadd_pd(sum, _mm256_permute2f128_pd(sum, sum, 1));
- return _mm_cvtsd_f64(_mm256_castpd256_pd128(_mm256_hadd_pd(tmp0, tmp0)));
+ Packet4d lane0 = _mm512_extractf64x4_pd(a, 0);
+ Packet4d lane1 = _mm512_extractf64x4_pd(a, 1);
+ Packet4d sum = padd(lane0, lane1);
+ Packet4d tmp0 = _mm256_hadd_pd(sum, _mm256_permute2f128_pd(sum, sum, 1));
+ return pfirst(_mm256_hadd_pd(tmp0, tmp0));
}
template <>
EIGEN_STRONG_INLINE Packet8f predux_downto4<Packet16f>(const Packet16f& a) {
#ifdef EIGEN_VECTORIZE_AVX512DQ
- __m256 lane0 = _mm512_extractf32x8_ps(a, 0);
- __m256 lane1 = _mm512_extractf32x8_ps(a, 1);
- return _mm256_add_ps(lane0, lane1);
+ Packet8f lane0 = _mm512_extractf32x8_ps(a, 0);
+ Packet8f lane1 = _mm512_extractf32x8_ps(a, 1);
+ return padd(lane0, lane1);
#else
- __m128 lane0 = _mm512_extractf32x4_ps(a, 0);
- __m128 lane1 = _mm512_extractf32x4_ps(a, 1);
- __m128 lane2 = _mm512_extractf32x4_ps(a, 2);
- __m128 lane3 = _mm512_extractf32x4_ps(a, 3);
- __m128 sum0 = _mm_add_ps(lane0, lane2);
- __m128 sum1 = _mm_add_ps(lane1, lane3);
+ Packet4f lane0 = _mm512_extractf32x4_ps(a, 0);
+ Packet4f lane1 = _mm512_extractf32x4_ps(a, 1);
+ Packet4f lane2 = _mm512_extractf32x4_ps(a, 2);
+ Packet4f lane3 = _mm512_extractf32x4_ps(a, 3);
+ Packet4f sum0 = padd(lane0, lane2);
+ Packet4f sum1 = padd(lane1, lane3);
return _mm256_insertf128_ps(_mm256_castps128_ps256(sum0), sum1, 1);
#endif
}
template <>
EIGEN_STRONG_INLINE Packet4d predux_downto4<Packet8d>(const Packet8d& a) {
- __m256d lane0 = _mm512_extractf64x4_pd(a, 0);
- __m256d lane1 = _mm512_extractf64x4_pd(a, 1);
- __m256d res = _mm256_add_pd(lane0, lane1);
+ Packet4d lane0 = _mm512_extractf64x4_pd(a, 0);
+ Packet4d lane1 = _mm512_extractf64x4_pd(a, 1);
+ Packet4d res = padd(lane0, lane1);
return res;
}
@@ -908,59 +939,58 @@ EIGEN_STRONG_INLINE float predux_mul<Packet16f>(const Packet16f& a) {
res = pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2)));
return pfirst(pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1))));
#else
- __m128 lane0 = _mm512_extractf32x4_ps(a, 0);
- __m128 lane1 = _mm512_extractf32x4_ps(a, 1);
- __m128 lane2 = _mm512_extractf32x4_ps(a, 2);
- __m128 lane3 = _mm512_extractf32x4_ps(a, 3);
- __m128 res = pmul(pmul(lane0, lane1), pmul(lane2, lane3));
+ Packet4f lane0 = _mm512_extractf32x4_ps(a, 0);
+ Packet4f lane1 = _mm512_extractf32x4_ps(a, 1);
+ Packet4f lane2 = _mm512_extractf32x4_ps(a, 2);
+ Packet4f lane3 = _mm512_extractf32x4_ps(a, 3);
+ Packet4f res = pmul(pmul(lane0, lane1), pmul(lane2, lane3));
res = pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2)));
return pfirst(pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1))));
#endif
}
template <>
EIGEN_STRONG_INLINE double predux_mul<Packet8d>(const Packet8d& a) {
- __m256d lane0 = _mm512_extractf64x4_pd(a, 0);
- __m256d lane1 = _mm512_extractf64x4_pd(a, 1);
- __m256d res = pmul(lane0, lane1);
+ Packet4d lane0 = _mm512_extractf64x4_pd(a, 0);
+ Packet4d lane1 = _mm512_extractf64x4_pd(a, 1);
+ Packet4d res = pmul(lane0, lane1);
res = pmul(res, _mm256_permute2f128_pd(res, res, 1));
return pfirst(pmul(res, _mm256_shuffle_pd(res, res, 1)));
}
template <>
EIGEN_STRONG_INLINE float predux_min<Packet16f>(const Packet16f& a) {
- __m128 lane0 = _mm512_extractf32x4_ps(a, 0);
- __m128 lane1 = _mm512_extractf32x4_ps(a, 1);
- __m128 lane2 = _mm512_extractf32x4_ps(a, 2);
- __m128 lane3 = _mm512_extractf32x4_ps(a, 3);
- __m128 res = _mm_min_ps(_mm_min_ps(lane0, lane1), _mm_min_ps(lane2, lane3));
+ Packet4f lane0 = _mm512_extractf32x4_ps(a, 0);
+ Packet4f lane1 = _mm512_extractf32x4_ps(a, 1);
+ Packet4f lane2 = _mm512_extractf32x4_ps(a, 2);
+ Packet4f lane3 = _mm512_extractf32x4_ps(a, 3);
+ Packet4f res = _mm_min_ps(_mm_min_ps(lane0, lane1), _mm_min_ps(lane2, lane3));
res = _mm_min_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2)));
return pfirst(_mm_min_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1))));
}
template <>
EIGEN_STRONG_INLINE double predux_min<Packet8d>(const Packet8d& a) {
- __m256d lane0 = _mm512_extractf64x4_pd(a, 0);
- __m256d lane1 = _mm512_extractf64x4_pd(a, 1);
- __m256d res = _mm256_min_pd(lane0, lane1);
+ Packet4d lane0 = _mm512_extractf64x4_pd(a, 0);
+ Packet4d lane1 = _mm512_extractf64x4_pd(a, 1);
+ Packet4d res = _mm256_min_pd(lane0, lane1);
res = _mm256_min_pd(res, _mm256_permute2f128_pd(res, res, 1));
return pfirst(_mm256_min_pd(res, _mm256_shuffle_pd(res, res, 1)));
}
template <>
EIGEN_STRONG_INLINE float predux_max<Packet16f>(const Packet16f& a) {
- __m128 lane0 = _mm512_extractf32x4_ps(a, 0);
- __m128 lane1 = _mm512_extractf32x4_ps(a, 1);
- __m128 lane2 = _mm512_extractf32x4_ps(a, 2);
- __m128 lane3 = _mm512_extractf32x4_ps(a, 3);
- __m128 res = _mm_max_ps(_mm_max_ps(lane0, lane1), _mm_max_ps(lane2, lane3));
+ Packet4f lane0 = _mm512_extractf32x4_ps(a, 0);
+ Packet4f lane1 = _mm512_extractf32x4_ps(a, 1);
+ Packet4f lane2 = _mm512_extractf32x4_ps(a, 2);
+ Packet4f lane3 = _mm512_extractf32x4_ps(a, 3);
+ Packet4f res = _mm_max_ps(_mm_max_ps(lane0, lane1), _mm_max_ps(lane2, lane3));
res = _mm_max_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2)));
return pfirst(_mm_max_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1))));
}
-
template <>
EIGEN_STRONG_INLINE double predux_max<Packet8d>(const Packet8d& a) {
- __m256d lane0 = _mm512_extractf64x4_pd(a, 0);
- __m256d lane1 = _mm512_extractf64x4_pd(a, 1);
- __m256d res = _mm256_max_pd(lane0, lane1);
+ Packet4d lane0 = _mm512_extractf64x4_pd(a, 0);
+ Packet4d lane1 = _mm512_extractf64x4_pd(a, 1);
+ Packet4d res = _mm256_max_pd(lane0, lane1);
res = _mm256_max_pd(res, _mm256_permute2f128_pd(res, res, 1));
return pfirst(_mm256_max_pd(res, _mm256_shuffle_pd(res, res, 1)));
}
diff --git a/eigen/Eigen/src/Core/arch/CUDA/Half.h b/eigen/Eigen/src/Core/arch/CUDA/Half.h
index 67518da..294c517 100644
--- a/eigen/Eigen/src/Core/arch/CUDA/Half.h
+++ b/eigen/Eigen/src/Core/arch/CUDA/Half.h
@@ -53,7 +53,7 @@ namespace half_impl {
// Make our own __half definition that is similar to CUDA's.
struct __half {
- EIGEN_DEVICE_FUNC __half() : x(0) {}
+ EIGEN_DEVICE_FUNC __half() {}
explicit EIGEN_DEVICE_FUNC __half(unsigned short raw) : x(raw) {}
unsigned short x;
};
@@ -386,18 +386,11 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(const half& a) {
return result;
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp(const half& a) {
-#if defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 530
- return half(hexp(a));
-#else
- return half(::expf(float(a)));
-#endif
-}
-EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half expm1(const half& a) {
- return half(numext::expm1(float(a)));
+ return half(::expf(float(a)));
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log(const half& a) {
#if defined(EIGEN_HAS_CUDA_FP16) && defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530
- return half(::hlog(a));
+ return Eigen::half(::hlog(a));
#else
return half(::logf(float(a)));
#endif
@@ -409,11 +402,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log10(const half& a) {
return half(::log10f(float(a)));
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sqrt(const half& a) {
-#if defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 530
- return half(hsqrt(a));
-#else
- return half(::sqrtf(float(a)));
-#endif
+ return half(::sqrtf(float(a)));
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half pow(const half& a, const half& b) {
return half(::powf(float(a), float(b)));
@@ -431,18 +420,10 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half tanh(const half& a) {
return half(::tanhf(float(a)));
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half floor(const half& a) {
-#if defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300
- return half(hfloor(a));
-#else
return half(::floorf(float(a)));
-#endif
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ceil(const half& a) {
-#if defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300
- return half(hceil(a));
-#else
return half(::ceilf(float(a)));
-#endif
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half (min)(const half& a, const half& b) {
@@ -493,9 +474,59 @@ template<> struct is_arithmetic<half> { enum { value = true }; };
} // end namespace internal
+} // end namespace Eigen
+
+namespace std {
+template<>
+struct numeric_limits<Eigen::half> {
+ static const bool is_specialized = true;
+ static const bool is_signed = true;
+ static const bool is_integer = false;
+ static const bool is_exact = false;
+ static const bool has_infinity = true;
+ static const bool has_quiet_NaN = true;
+ static const bool has_signaling_NaN = true;
+ static const float_denorm_style has_denorm = denorm_present;
+ static const bool has_denorm_loss = false;
+ static const std::float_round_style round_style = std::round_to_nearest;
+ static const bool is_iec559 = false;
+ static const bool is_bounded = false;
+ static const bool is_modulo = false;
+ static const int digits = 11;
+ static const int digits10 = 2;
+ //static const int max_digits10 = ;
+ static const int radix = 2;
+ static const int min_exponent = -13;
+ static const int min_exponent10 = -4;
+ static const int max_exponent = 16;
+ static const int max_exponent10 = 4;
+ static const bool traps = true;
+ static const bool tinyness_before = false;
+
+ static Eigen::half (min)() { return Eigen::half_impl::raw_uint16_to_half(0x400); }
+ static Eigen::half lowest() { return Eigen::half_impl::raw_uint16_to_half(0xfbff); }
+ static Eigen::half (max)() { return Eigen::half_impl::raw_uint16_to_half(0x7bff); }
+ static Eigen::half epsilon() { return Eigen::half_impl::raw_uint16_to_half(0x0800); }
+ static Eigen::half round_error() { return Eigen::half(0.5); }
+ static Eigen::half infinity() { return Eigen::half_impl::raw_uint16_to_half(0x7c00); }
+ static Eigen::half quiet_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7e00); }
+ static Eigen::half signaling_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7e00); }
+ static Eigen::half denorm_min() { return Eigen::half_impl::raw_uint16_to_half(0x1); }
+};
+}
+
+namespace Eigen {
+
template<> struct NumTraits<Eigen::half>
: GenericNumTraits<Eigen::half>
{
+ enum {
+ IsSigned = true,
+ IsInteger = false,
+ IsComplex = false,
+ RequireInitialization = false
+ };
+
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Eigen::half epsilon() {
return half_impl::raw_uint16_to_half(0x0800);
}
diff --git a/eigen/Eigen/src/Core/arch/CUDA/MathFunctions.h b/eigen/Eigen/src/Core/arch/CUDA/MathFunctions.h
index 987a529..0348b41 100644
--- a/eigen/Eigen/src/Core/arch/CUDA/MathFunctions.h
+++ b/eigen/Eigen/src/Core/arch/CUDA/MathFunctions.h
@@ -57,18 +57,6 @@ double2 pexp<double2>(const double2& a)
}
template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-float4 pexpm1<float4>(const float4& a)
-{
- return make_float4(expm1f(a.x), expm1f(a.y), expm1f(a.z), expm1f(a.w));
-}
-
-template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-double2 pexpm1<double2>(const double2& a)
-{
- return make_double2(expm1(a.x), expm1(a.y));
-}
-
-template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 psqrt<float4>(const float4& a)
{
return make_float4(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z), sqrtf(a.w));
diff --git a/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h b/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h
index 8c46af0..4dda631 100644
--- a/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h
+++ b/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h
@@ -167,10 +167,10 @@ template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double2 ploadu<double2>(const d
return make_double2(from[0], from[1]);
}
-template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float4 ploaddup<float4>(const float* from) {
+template<> EIGEN_STRONG_INLINE float4 ploaddup<float4>(const float* from) {
return make_float4(from[0], from[0], from[1], from[1]);
}
-template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double2 ploaddup<double2>(const double* from) {
+template<> EIGEN_STRONG_INLINE double2 ploaddup<double2>(const double* from) {
return make_double2(from[0], from[0]);
}
diff --git a/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h b/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h
index b9a125b..ae54225 100644
--- a/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h
+++ b/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h
@@ -34,7 +34,6 @@ template<> struct packet_traits<Eigen::half> : default_packet_traits
HasSqrt = 1,
HasRsqrt = 1,
HasExp = 1,
- HasExpm1 = 1,
HasLog = 1,
HasLog1p = 1
};
@@ -276,14 +275,6 @@ template<> __device__ EIGEN_STRONG_INLINE half2 plog1p<half2>(const half2& a) {
return __floats2half2_rn(r1, r2);
}
-template<> __device__ EIGEN_STRONG_INLINE half2 pexpm1<half2>(const half2& a) {
- float a1 = __low2float(a);
- float a2 = __high2float(a);
- float r1 = expm1f(a1);
- float r2 = expm1f(a2);
- return __floats2half2_rn(r1, r2);
-}
-
#if defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 530
template<> __device__ EIGEN_STRONG_INLINE
diff --git a/eigen/Eigen/src/Core/arch/NEON/PacketMath.h b/eigen/Eigen/src/Core/arch/NEON/PacketMath.h
index aede4a6..836fbc0 100644
--- a/eigen/Eigen/src/Core/arch/NEON/PacketMath.h
+++ b/eigen/Eigen/src/Core/arch/NEON/PacketMath.h
@@ -116,7 +116,7 @@ template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int32_t& from)
template<> EIGEN_STRONG_INLINE Packet4f plset<Packet4f>(const float& a)
{
- const float32_t f[] = {0, 1, 2, 3};
+ const float f[] = {0, 1, 2, 3};
Packet4f countdown = vld1q_f32(f);
return vaddq_f32(pset1<Packet4f>(a), countdown);
}
diff --git a/eigen/Eigen/src/Core/arch/SSE/PacketMath.h b/eigen/Eigen/src/Core/arch/SSE/PacketMath.h
index 03c8a2c..3832de1 100644
--- a/eigen/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/eigen/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -45,7 +45,7 @@ struct eigen_packet_wrapper
m_val = v;
return *this;
}
-
+
T m_val;
};
typedef eigen_packet_wrapper<__m128> Packet4f;
@@ -69,7 +69,7 @@ template<> struct is_arithmetic<__m128d> { enum { value = true }; };
#define vec2d_swizzle1(v,p,q) \
(_mm_castsi128_pd(_mm_shuffle_epi32( _mm_castpd_si128(v), ((q*2+1)<<6|(q*2)<<4|(p*2+1)<<2|(p*2)))))
-
+
#define vec4f_swizzle2(a,b,p,q,r,s) \
(_mm_shuffle_ps( (a), (b), ((s)<<6|(r)<<4|(q)<<2|(p))))
@@ -190,7 +190,7 @@ template<> EIGEN_STRONG_INLINE Packet4f pload1<Packet4f>(const float *from) {
return vec4f_swizzle1(_mm_load_ss(from),0,0,0,0);
}
#endif
-
+
template<> EIGEN_STRONG_INLINE Packet4f plset<Packet4f>(const float& a) { return _mm_add_ps(pset1<Packet4f>(a), _mm_set_ps(3,2,1,0)); }
template<> EIGEN_STRONG_INLINE Packet2d plset<Packet2d>(const double& a) { return _mm_add_pd(pset1<Packet2d>(a),_mm_set_pd(1,0)); }
template<> EIGEN_STRONG_INLINE Packet4i plset<Packet4i>(const int& a) { return _mm_add_epi32(pset1<Packet4i>(a),_mm_set_epi32(3,2,1,0)); }
@@ -250,34 +250,8 @@ template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f&
template<> EIGEN_STRONG_INLINE Packet2d pmadd(const Packet2d& a, const Packet2d& b, const Packet2d& c) { return _mm_fmadd_pd(a,b,c); }
#endif
-template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) {
-#if EIGEN_COMP_GNUC
- // There appears to be a bug in GCC, by which the optimizer may
- // flip the argument order in calls to _mm_min_ps, so we have to
- // resort to inline ASM here. This is supposed to be fixed in gcc6.3,
- // see also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867
- Packet4f res = b;
- asm("minps %[a], %[res]" : [res] "+x" (res) : [a] "x" (a));
- return res;
-#else
- // Arguments are reversed to match NaN propagation behavior of std::min.
- return _mm_min_ps(b, a);
-#endif
-}
-template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(const Packet2d& a, const Packet2d& b) {
-#if EIGEN_COMP_GNUC
- // There appears to be a bug in GCC, by which the optimizer may
- // flip the argument order in calls to _mm_min_pd, so we have to
- // resort to inline ASM here. This is supposed to be fixed in gcc6.3,
- // see also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867
- Packet2d res = b;
- asm("minpd %[a], %[res]" : [res] "+x" (res) : [a] "x" (a));
- return res;
-#else
- // Arguments are reversed to match NaN propagation behavior of std::min.
- return _mm_min_pd(b, a);
-#endif
-}
+template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_min_ps(a,b); }
+template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_min_pd(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b)
{
#ifdef EIGEN_VECTORIZE_SSE4_1
@@ -289,34 +263,8 @@ template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const
#endif
}
-template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) {
-#if EIGEN_COMP_GNUC
- // There appears to be a bug in GCC, by which the optimizer may
- // flip the argument order in calls to _mm_max_ps, so we have to
- // resort to inline ASM here. This is supposed to be fixed in gcc6.3,
- // see also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867
- Packet4f res = b;
- asm("maxps %[a], %[res]" : [res] "+x" (res) : [a] "x" (a));
- return res;
-#else
- // Arguments are reversed to match NaN propagation behavior of std::max.
- return _mm_max_ps(b, a);
-#endif
-}
-template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const Packet2d& b) {
-#if EIGEN_COMP_GNUC
- // There appears to be a bug in GCC, by which the optimizer may
- // flip the argument order in calls to _mm_max_pd, so we have to
- // resort to inline ASM here. This is supposed to be fixed in gcc6.3,
- // see also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867
- Packet2d res = b;
- asm("maxpd %[a], %[res]" : [res] "+x" (res) : [a] "x" (a));
- return res;
-#else
- // Arguments are reversed to match NaN propagation behavior of std::max.
- return _mm_max_pd(b, a);
-#endif
-}
+template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_max_ps(a,b); }
+template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_max_pd(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(const Packet4i& a, const Packet4i& b)
{
#ifdef EIGEN_VECTORIZE_SSE4_1
diff --git a/eigen/Eigen/src/Core/functors/NullaryFunctors.h b/eigen/Eigen/src/Core/functors/NullaryFunctors.h
index 6a30466..b03be02 100644
--- a/eigen/Eigen/src/Core/functors/NullaryFunctors.h
+++ b/eigen/Eigen/src/Core/functors/NullaryFunctors.h
@@ -44,16 +44,16 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
{
linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1)),
- m_interPacket(plset<Packet>(0)),
m_flip(numext::abs(high)<numext::abs(low))
{}
template<typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const {
+ typedef typename NumTraits<Scalar>::Real RealScalar;
if(m_flip)
- return (i==0)? m_low : (m_high - (m_size1-i)*m_step);
+ return (i==0)? m_low : (m_high - RealScalar(m_size1-i)*m_step);
else
- return (i==m_size1)? m_high : (m_low + i*m_step);
+ return (i==m_size1)? m_high : (m_low + RealScalar(i)*m_step);
}
template<typename IndexType>
@@ -63,7 +63,7 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
if(m_flip)
{
- Packet pi = padd(pset1<Packet>(Scalar(i-m_size1)),m_interPacket);
+ Packet pi = plset<Packet>(Scalar(i-m_size1));
Packet res = padd(pset1<Packet>(m_high), pmul(pset1<Packet>(m_step), pi));
if(i==0)
res = pinsertfirst(res, m_low);
@@ -71,7 +71,7 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
}
else
{
- Packet pi = padd(pset1<Packet>(Scalar(i)),m_interPacket);
+ Packet pi = plset<Packet>(Scalar(i));
Packet res = padd(pset1<Packet>(m_low), pmul(pset1<Packet>(m_step), pi));
if(i==m_size1-unpacket_traits<Packet>::size+1)
res = pinsertlast(res, m_high);
@@ -83,7 +83,6 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
const Scalar m_high;
const Index m_size1;
const Scalar m_step;
- const Packet m_interPacket;
const bool m_flip;
};
diff --git a/eigen/Eigen/src/Core/functors/UnaryFunctors.h b/eigen/Eigen/src/Core/functors/UnaryFunctors.h
index bfc0465..2e6a00f 100644
--- a/eigen/Eigen/src/Core/functors/UnaryFunctors.h
+++ b/eigen/Eigen/src/Core/functors/UnaryFunctors.h
@@ -264,26 +264,6 @@ struct functor_traits<scalar_exp_op<Scalar> > {
/** \internal
*
- * \brief Template functor to compute the exponential of a scalar - 1.
- *
- * \sa class CwiseUnaryOp, ArrayBase::expm1()
- */
-template<typename Scalar> struct scalar_expm1_op {
- EIGEN_EMPTY_STRUCT_CTOR(scalar_expm1_op)
- EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::expm1(a); }
- template <typename Packet>
- EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pexpm1(a); }
-};
-template <typename Scalar>
-struct functor_traits<scalar_expm1_op<Scalar> > {
- enum {
- PacketAccess = packet_traits<Scalar>::HasExpm1,
- Cost = functor_traits<scalar_exp_op<Scalar> >::Cost // TODO measure cost of expm1
- };
-};
-
-/** \internal
- *
* \brief Template functor to compute the logarithm of a scalar
*
* \sa class CwiseUnaryOp, ArrayBase::log()
@@ -698,13 +678,7 @@ struct functor_traits<scalar_ceil_op<Scalar> >
template<typename Scalar> struct scalar_isnan_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_isnan_op)
typedef bool result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const {
-#if defined(__SYCL_DEVICE_ONLY__)
- return numext::isnan(a);
-#else
- return (numext::isnan)(a);
-#endif
- }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return (numext::isnan)(a); }
};
template<typename Scalar>
struct functor_traits<scalar_isnan_op<Scalar> >
@@ -722,13 +696,7 @@ struct functor_traits<scalar_isnan_op<Scalar> >
template<typename Scalar> struct scalar_isinf_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_isinf_op)
typedef bool result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const {
-#if defined(__SYCL_DEVICE_ONLY__)
- return numext::isinf(a);
-#else
- return (numext::isinf)(a);
-#endif
- }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return (numext::isinf)(a); }
};
template<typename Scalar>
struct functor_traits<scalar_isinf_op<Scalar> >
@@ -746,13 +714,7 @@ struct functor_traits<scalar_isinf_op<Scalar> >
template<typename Scalar> struct scalar_isfinite_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_isfinite_op)
typedef bool result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const {
-#if defined(__SYCL_DEVICE_ONLY__)
- return numext::isfinite(a);
-#else
- return (numext::isfinite)(a);
-#endif
- }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return (numext::isfinite)(a); }
};
template<typename Scalar>
struct functor_traits<scalar_isfinite_op<Scalar> >
diff --git a/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
index ad38bcf..e844e37 100644
--- a/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
+++ b/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
@@ -269,10 +269,13 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
enum {
IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0,
LhsIsRowMajor = _ActualLhs::Flags&RowMajorBit ? 1 : 0,
- RhsIsRowMajor = _ActualRhs::Flags&RowMajorBit ? 1 : 0
+ RhsIsRowMajor = _ActualRhs::Flags&RowMajorBit ? 1 : 0,
+ SkipDiag = (UpLo&(UnitDiag|ZeroDiag))!=0
};
Index size = mat.cols();
+ if(SkipDiag)
+ size--;
Index depth = actualLhs.cols();
typedef internal::gemm_blocking_space<IsRowMajor ? RowMajor : ColMajor,typename Lhs::Scalar,typename Rhs::Scalar,
@@ -283,21 +286,23 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
internal::general_matrix_matrix_triangular_product<Index,
typename Lhs::Scalar, LhsIsRowMajor ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate,
typename Rhs::Scalar, RhsIsRowMajor ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate,
- IsRowMajor ? RowMajor : ColMajor, UpLo>
+ IsRowMajor ? RowMajor : ColMajor, UpLo&(Lower|Upper)>
::run(size, depth,
- &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &actualRhs.coeffRef(0,0), actualRhs.outerStride(),
- mat.data(), mat.outerStride(), actualAlpha, blocking);
+ &actualLhs.coeffRef(SkipDiag&&(UpLo&Lower)==Lower ? 1 : 0,0), actualLhs.outerStride(),
+ &actualRhs.coeffRef(0,SkipDiag&&(UpLo&Upper)==Upper ? 1 : 0), actualRhs.outerStride(),
+ mat.data() + (SkipDiag ? (bool(IsRowMajor) != ((UpLo&Lower)==Lower) ? 1 : mat.outerStride() ) : 0), mat.outerStride(), actualAlpha, blocking);
}
};
template<typename MatrixType, unsigned int UpLo>
template<typename ProductType>
-EIGEN_DEVICE_FUNC TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::_assignProduct(const ProductType& prod, const Scalar& alpha, bool beta)
+TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::_assignProduct(const ProductType& prod, const Scalar& alpha, bool beta)
{
+ EIGEN_STATIC_ASSERT((UpLo&UnitDiag)==0, WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED);
eigen_assert(derived().nestedExpression().rows() == prod.rows() && derived().cols() == prod.cols());
-
+
general_product_to_triangular_selector<MatrixType, ProductType, UpLo, internal::traits<ProductType>::InnerSize==1>::run(derived().nestedExpression().const_cast_derived(), prod, alpha, beta);
-
+
return derived();
}
diff --git a/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h b/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
index 5b7c15c..41e18ff 100644
--- a/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
+++ b/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
@@ -52,7 +52,7 @@ struct general_matrix_matrix_triangular_product<Index,Scalar,LhsStorageOrder,Con
static EIGEN_STRONG_INLINE void run(Index size, Index depth,const Scalar* lhs, Index lhsStride, \
const Scalar* rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha, level3_blocking<Scalar, Scalar>& blocking) \
{ \
- if (lhs==rhs) { \
+ if ( lhs==rhs && ((UpLo&(Lower|Upper)==UpLo)) ) { \
general_matrix_matrix_rankupdate<Index,Scalar,LhsStorageOrder,ConjugateLhs,ColMajor,UpLo> \
::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha,blocking); \
} else { \
diff --git a/eigen/Eigen/src/Core/products/GeneralMatrixVector.h b/eigen/Eigen/src/Core/products/GeneralMatrixVector.h
index 41d8242..3c1a7fc 100644
--- a/eigen/Eigen/src/Core/products/GeneralMatrixVector.h
+++ b/eigen/Eigen/src/Core/products/GeneralMatrixVector.h
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2008-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2008-2009 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
@@ -15,8 +15,10 @@ namespace Eigen {
namespace internal {
/* Optimized col-major matrix * vector product:
- * This algorithm processes the matrix per vertical panels,
- * which are then processed horizontaly per chunck of 8*PacketSize x 1 vertical segments.
+ * This algorithm processes 4 columns at onces that allows to both reduce
+ * the number of load/stores of the result by a factor 4 and to reduce
+ * the instruction dependency. Moreover, we know that all bands have the
+ * same alignment pattern.
*
* Mixing type logic: C += alpha * A * B
* | A | B |alpha| comments
@@ -25,7 +27,33 @@ namespace internal {
* |cplx |real |cplx | invalid, the caller has to do tmp: = A * B; C += alpha*tmp
* |cplx |real |real | optimal case, vectorization possible via real-cplx mul
*
+ * Accesses to the matrix coefficients follow the following logic:
+ *
+ * - if all columns have the same alignment then
+ * - if the columns have the same alignment as the result vector, then easy! (-> AllAligned case)
+ * - otherwise perform unaligned loads only (-> NoneAligned case)
+ * - otherwise
+ * - if even columns have the same alignment then
+ * // odd columns are guaranteed to have the same alignment too
+ * - if even or odd columns have the same alignment as the result, then
+ * // for a register size of 2 scalars, this is guarantee to be the case (e.g., SSE with double)
+ * - perform half aligned and half unaligned loads (-> EvenAligned case)
+ * - otherwise perform unaligned loads only (-> NoneAligned case)
+ * - otherwise, if the register size is 4 scalars (e.g., SSE with float) then
+ * - one over 4 consecutive columns is guaranteed to be aligned with the result vector,
+ * perform simple aligned loads for this column and aligned loads plus re-alignment for the other. (-> FirstAligned case)
+ * // this re-alignment is done by the palign function implemented for SSE in Eigen/src/Core/arch/SSE/PacketMath.h
+ * - otherwise,
+ * // if we get here, this means the register size is greater than 4 (e.g., AVX with floats),
+ * // we currently fall back to the NoneAligned case
+ *
* The same reasoning apply for the transposed case.
+ *
+ * The last case (PacketSize>4) could probably be improved by generalizing the FirstAligned case, but since we do not support AVX yet...
+ * One might also wonder why in the EvenAligned case we perform unaligned loads instead of using the aligned-loads plus re-alignment
+ * strategy as in the FirstAligned case. The reason is that we observed that unaligned loads on a 8 byte boundary are not too slow
+ * compared to unaligned loads on a 4 byte boundary.
+ *
*/
template<typename Index, typename LhsScalar, typename LhsMapper, bool ConjugateLhs, typename RhsScalar, typename RhsMapper, bool ConjugateRhs, int Version>
struct general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjugateLhs,RhsScalar,RhsMapper,ConjugateRhs,Version>
@@ -59,145 +87,238 @@ EIGEN_DONT_INLINE static void run(
template<typename Index, typename LhsScalar, typename LhsMapper, bool ConjugateLhs, typename RhsScalar, typename RhsMapper, bool ConjugateRhs, int Version>
EIGEN_DONT_INLINE void general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjugateLhs,RhsScalar,RhsMapper,ConjugateRhs,Version>::run(
Index rows, Index cols,
- const LhsMapper& alhs,
+ const LhsMapper& lhs,
const RhsMapper& rhs,
ResScalar* res, Index resIncr,
RhsScalar alpha)
{
EIGEN_UNUSED_VARIABLE(resIncr);
eigen_internal_assert(resIncr==1);
-
- // The following copy tells the compiler that lhs's attributes are not modified outside this function
- // This helps GCC to generate propoer code.
- LhsMapper lhs(alhs);
+ #ifdef _EIGEN_ACCUMULATE_PACKETS
+ #error _EIGEN_ACCUMULATE_PACKETS has already been defined
+ #endif
+ #define _EIGEN_ACCUMULATE_PACKETS(Alignment0,Alignment13,Alignment2) \
+ pstore(&res[j], \
+ padd(pload<ResPacket>(&res[j]), \
+ padd( \
+ padd(pcj.pmul(lhs0.template load<LhsPacket, Alignment0>(j), ptmp0), \
+ pcj.pmul(lhs1.template load<LhsPacket, Alignment13>(j), ptmp1)), \
+ padd(pcj.pmul(lhs2.template load<LhsPacket, Alignment2>(j), ptmp2), \
+ pcj.pmul(lhs3.template load<LhsPacket, Alignment13>(j), ptmp3)) )))
+
+ typedef typename LhsMapper::VectorMapper LhsScalars;
conj_helper<LhsScalar,RhsScalar,ConjugateLhs,ConjugateRhs> cj;
conj_helper<LhsPacket,RhsPacket,ConjugateLhs,ConjugateRhs> pcj;
+ if(ConjugateRhs)
+ alpha = numext::conj(alpha);
+
+ enum { AllAligned = 0, EvenAligned, FirstAligned, NoneAligned };
+ const Index columnsAtOnce = 4;
+ const Index peels = 2;
+ const Index LhsPacketAlignedMask = LhsPacketSize-1;
+ const Index ResPacketAlignedMask = ResPacketSize-1;
+// const Index PeelAlignedMask = ResPacketSize*peels-1;
+ const Index size = rows;
+
const Index lhsStride = lhs.stride();
- // TODO: for padded aligned inputs, we could enable aligned reads
- enum { LhsAlignment = Unaligned };
- const Index n8 = rows-8*ResPacketSize+1;
- const Index n4 = rows-4*ResPacketSize+1;
- const Index n3 = rows-3*ResPacketSize+1;
- const Index n2 = rows-2*ResPacketSize+1;
- const Index n1 = rows-1*ResPacketSize+1;
+ // How many coeffs of the result do we have to skip to be aligned.
+ // Here we assume data are at least aligned on the base scalar type.
+ Index alignedStart = internal::first_default_aligned(res,size);
+ Index alignedSize = ResPacketSize>1 ? alignedStart + ((size-alignedStart) & ~ResPacketAlignedMask) : 0;
+ const Index peeledSize = alignedSize - RhsPacketSize*peels - RhsPacketSize + 1;
+
+ const Index alignmentStep = LhsPacketSize>1 ? (LhsPacketSize - lhsStride % LhsPacketSize) & LhsPacketAlignedMask : 0;
+ Index alignmentPattern = alignmentStep==0 ? AllAligned
+ : alignmentStep==(LhsPacketSize/2) ? EvenAligned
+ : FirstAligned;
- // TODO: improve the following heuristic:
- const Index block_cols = cols<128 ? cols : (lhsStride*sizeof(LhsScalar)<32000?16:4);
- ResPacket palpha = pset1<ResPacket>(alpha);
+ // we cannot assume the first element is aligned because of sub-matrices
+ const Index lhsAlignmentOffset = lhs.firstAligned(size);
- for(Index j2=0; j2<cols; j2+=block_cols)
+ // find how many columns do we have to skip to be aligned with the result (if possible)
+ Index skipColumns = 0;
+ // if the data cannot be aligned (TODO add some compile time tests when possible, e.g. for floats)
+ if( (lhsAlignmentOffset < 0) || (lhsAlignmentOffset == size) || (UIntPtr(res)%sizeof(ResScalar)) )
{
- Index jend = numext::mini(j2+block_cols,cols);
- Index i=0;
- for(; i<n8; i+=ResPacketSize*8)
+ alignedSize = 0;
+ alignedStart = 0;
+ alignmentPattern = NoneAligned;
+ }
+ else if(LhsPacketSize > 4)
+ {
+ // TODO: extend the code to support aligned loads whenever possible when LhsPacketSize > 4.
+ // Currently, it seems to be better to perform unaligned loads anyway
+ alignmentPattern = NoneAligned;
+ }
+ else if (LhsPacketSize>1)
+ {
+ // eigen_internal_assert(size_t(firstLhs+lhsAlignmentOffset)%sizeof(LhsPacket)==0 || size<LhsPacketSize);
+
+ while (skipColumns<LhsPacketSize &&
+ alignedStart != ((lhsAlignmentOffset + alignmentStep*skipColumns)%LhsPacketSize))
+ ++skipColumns;
+ if (skipColumns==LhsPacketSize)
{
- ResPacket c0 = pset1<ResPacket>(ResScalar(0)),
- c1 = pset1<ResPacket>(ResScalar(0)),
- c2 = pset1<ResPacket>(ResScalar(0)),
- c3 = pset1<ResPacket>(ResScalar(0)),
- c4 = pset1<ResPacket>(ResScalar(0)),
- c5 = pset1<ResPacket>(ResScalar(0)),
- c6 = pset1<ResPacket>(ResScalar(0)),
- c7 = pset1<ResPacket>(ResScalar(0));
-
- for(Index j=j2; j<jend; j+=1)
- {
- RhsPacket b0 = pset1<RhsPacket>(rhs(j,0));
- c0 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*0,j),b0,c0);
- c1 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*1,j),b0,c1);
- c2 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*2,j),b0,c2);
- c3 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*3,j),b0,c3);
- c4 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*4,j),b0,c4);
- c5 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*5,j),b0,c5);
- c6 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*6,j),b0,c6);
- c7 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*7,j),b0,c7);
- }
- pstoreu(res+i+ResPacketSize*0, pmadd(c0,palpha,ploadu<ResPacket>(res+i+ResPacketSize*0)));
- pstoreu(res+i+ResPacketSize*1, pmadd(c1,palpha,ploadu<ResPacket>(res+i+ResPacketSize*1)));
- pstoreu(res+i+ResPacketSize*2, pmadd(c2,palpha,ploadu<ResPacket>(res+i+ResPacketSize*2)));
- pstoreu(res+i+ResPacketSize*3, pmadd(c3,palpha,ploadu<ResPacket>(res+i+ResPacketSize*3)));
- pstoreu(res+i+ResPacketSize*4, pmadd(c4,palpha,ploadu<ResPacket>(res+i+ResPacketSize*4)));
- pstoreu(res+i+ResPacketSize*5, pmadd(c5,palpha,ploadu<ResPacket>(res+i+ResPacketSize*5)));
- pstoreu(res+i+ResPacketSize*6, pmadd(c6,palpha,ploadu<ResPacket>(res+i+ResPacketSize*6)));
- pstoreu(res+i+ResPacketSize*7, pmadd(c7,palpha,ploadu<ResPacket>(res+i+ResPacketSize*7)));
+ // nothing can be aligned, no need to skip any column
+ alignmentPattern = NoneAligned;
+ skipColumns = 0;
}
- if(i<n4)
+ else
{
- ResPacket c0 = pset1<ResPacket>(ResScalar(0)),
- c1 = pset1<ResPacket>(ResScalar(0)),
- c2 = pset1<ResPacket>(ResScalar(0)),
- c3 = pset1<ResPacket>(ResScalar(0));
+ skipColumns = (std::min)(skipColumns,cols);
+ // note that the skiped columns are processed later.
+ }
- for(Index j=j2; j<jend; j+=1)
- {
- RhsPacket b0 = pset1<RhsPacket>(rhs(j,0));
- c0 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*0,j),b0,c0);
- c1 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*1,j),b0,c1);
- c2 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*2,j),b0,c2);
- c3 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*3,j),b0,c3);
- }
- pstoreu(res+i+ResPacketSize*0, pmadd(c0,palpha,ploadu<ResPacket>(res+i+ResPacketSize*0)));
- pstoreu(res+i+ResPacketSize*1, pmadd(c1,palpha,ploadu<ResPacket>(res+i+ResPacketSize*1)));
- pstoreu(res+i+ResPacketSize*2, pmadd(c2,palpha,ploadu<ResPacket>(res+i+ResPacketSize*2)));
- pstoreu(res+i+ResPacketSize*3, pmadd(c3,palpha,ploadu<ResPacket>(res+i+ResPacketSize*3)));
+ /* eigen_internal_assert( (alignmentPattern==NoneAligned)
+ || (skipColumns + columnsAtOnce >= cols)
+ || LhsPacketSize > size
+ || (size_t(firstLhs+alignedStart+lhsStride*skipColumns)%sizeof(LhsPacket))==0);*/
+ }
+ else if(Vectorizable)
+ {
+ alignedStart = 0;
+ alignedSize = size;
+ alignmentPattern = AllAligned;
+ }
- i+=ResPacketSize*4;
- }
- if(i<n3)
- {
- ResPacket c0 = pset1<ResPacket>(ResScalar(0)),
- c1 = pset1<ResPacket>(ResScalar(0)),
- c2 = pset1<ResPacket>(ResScalar(0));
+ const Index offset1 = (FirstAligned && alignmentStep==1)?3:1;
+ const Index offset3 = (FirstAligned && alignmentStep==1)?1:3;
- for(Index j=j2; j<jend; j+=1)
- {
- RhsPacket b0 = pset1<RhsPacket>(rhs(j,0));
- c0 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*0,j),b0,c0);
- c1 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*1,j),b0,c1);
- c2 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*2,j),b0,c2);
- }
- pstoreu(res+i+ResPacketSize*0, pmadd(c0,palpha,ploadu<ResPacket>(res+i+ResPacketSize*0)));
- pstoreu(res+i+ResPacketSize*1, pmadd(c1,palpha,ploadu<ResPacket>(res+i+ResPacketSize*1)));
- pstoreu(res+i+ResPacketSize*2, pmadd(c2,palpha,ploadu<ResPacket>(res+i+ResPacketSize*2)));
+ Index columnBound = ((cols-skipColumns)/columnsAtOnce)*columnsAtOnce + skipColumns;
+ for (Index i=skipColumns; i<columnBound; i+=columnsAtOnce)
+ {
+ RhsPacket ptmp0 = pset1<RhsPacket>(alpha*rhs(i, 0)),
+ ptmp1 = pset1<RhsPacket>(alpha*rhs(i+offset1, 0)),
+ ptmp2 = pset1<RhsPacket>(alpha*rhs(i+2, 0)),
+ ptmp3 = pset1<RhsPacket>(alpha*rhs(i+offset3, 0));
- i+=ResPacketSize*3;
- }
- if(i<n2)
+ // this helps a lot generating better binary code
+ const LhsScalars lhs0 = lhs.getVectorMapper(0, i+0), lhs1 = lhs.getVectorMapper(0, i+offset1),
+ lhs2 = lhs.getVectorMapper(0, i+2), lhs3 = lhs.getVectorMapper(0, i+offset3);
+
+ if (Vectorizable)
{
- ResPacket c0 = pset1<ResPacket>(ResScalar(0)),
- c1 = pset1<ResPacket>(ResScalar(0));
+ /* explicit vectorization */
+ // process initial unaligned coeffs
+ for (Index j=0; j<alignedStart; ++j)
+ {
+ res[j] = cj.pmadd(lhs0(j), pfirst(ptmp0), res[j]);
+ res[j] = cj.pmadd(lhs1(j), pfirst(ptmp1), res[j]);
+ res[j] = cj.pmadd(lhs2(j), pfirst(ptmp2), res[j]);
+ res[j] = cj.pmadd(lhs3(j), pfirst(ptmp3), res[j]);
+ }
- for(Index j=j2; j<jend; j+=1)
+ if (alignedSize>alignedStart)
{
- RhsPacket b0 = pset1<RhsPacket>(rhs(j,0));
- c0 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*0,j),b0,c0);
- c1 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+LhsPacketSize*1,j),b0,c1);
+ switch(alignmentPattern)
+ {
+ case AllAligned:
+ for (Index j = alignedStart; j<alignedSize; j+=ResPacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(Aligned,Aligned,Aligned);
+ break;
+ case EvenAligned:
+ for (Index j = alignedStart; j<alignedSize; j+=ResPacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(Aligned,Unaligned,Aligned);
+ break;
+ case FirstAligned:
+ {
+ Index j = alignedStart;
+ if(peels>1)
+ {
+ LhsPacket A00, A01, A02, A03, A10, A11, A12, A13;
+ ResPacket T0, T1;
+
+ A01 = lhs1.template load<LhsPacket, Aligned>(alignedStart-1);
+ A02 = lhs2.template load<LhsPacket, Aligned>(alignedStart-2);
+ A03 = lhs3.template load<LhsPacket, Aligned>(alignedStart-3);
+
+ for (; j<peeledSize; j+=peels*ResPacketSize)
+ {
+ A11 = lhs1.template load<LhsPacket, Aligned>(j-1+LhsPacketSize); palign<1>(A01,A11);
+ A12 = lhs2.template load<LhsPacket, Aligned>(j-2+LhsPacketSize); palign<2>(A02,A12);
+ A13 = lhs3.template load<LhsPacket, Aligned>(j-3+LhsPacketSize); palign<3>(A03,A13);
+
+ A00 = lhs0.template load<LhsPacket, Aligned>(j);
+ A10 = lhs0.template load<LhsPacket, Aligned>(j+LhsPacketSize);
+ T0 = pcj.pmadd(A00, ptmp0, pload<ResPacket>(&res[j]));
+ T1 = pcj.pmadd(A10, ptmp0, pload<ResPacket>(&res[j+ResPacketSize]));
+
+ T0 = pcj.pmadd(A01, ptmp1, T0);
+ A01 = lhs1.template load<LhsPacket, Aligned>(j-1+2*LhsPacketSize); palign<1>(A11,A01);
+ T0 = pcj.pmadd(A02, ptmp2, T0);
+ A02 = lhs2.template load<LhsPacket, Aligned>(j-2+2*LhsPacketSize); palign<2>(A12,A02);
+ T0 = pcj.pmadd(A03, ptmp3, T0);
+ pstore(&res[j],T0);
+ A03 = lhs3.template load<LhsPacket, Aligned>(j-3+2*LhsPacketSize); palign<3>(A13,A03);
+ T1 = pcj.pmadd(A11, ptmp1, T1);
+ T1 = pcj.pmadd(A12, ptmp2, T1);
+ T1 = pcj.pmadd(A13, ptmp3, T1);
+ pstore(&res[j+ResPacketSize],T1);
+ }
+ }
+ for (; j<alignedSize; j+=ResPacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(Aligned,Unaligned,Unaligned);
+ break;
+ }
+ default:
+ for (Index j = alignedStart; j<alignedSize; j+=ResPacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(Unaligned,Unaligned,Unaligned);
+ break;
+ }
}
- pstoreu(res+i+ResPacketSize*0, pmadd(c0,palpha,ploadu<ResPacket>(res+i+ResPacketSize*0)));
- pstoreu(res+i+ResPacketSize*1, pmadd(c1,palpha,ploadu<ResPacket>(res+i+ResPacketSize*1)));
- i+=ResPacketSize*2;
+ } // end explicit vectorization
+
+ /* process remaining coeffs (or all if there is no explicit vectorization) */
+ for (Index j=alignedSize; j<size; ++j)
+ {
+ res[j] = cj.pmadd(lhs0(j), pfirst(ptmp0), res[j]);
+ res[j] = cj.pmadd(lhs1(j), pfirst(ptmp1), res[j]);
+ res[j] = cj.pmadd(lhs2(j), pfirst(ptmp2), res[j]);
+ res[j] = cj.pmadd(lhs3(j), pfirst(ptmp3), res[j]);
}
- if(i<n1)
+ }
+
+ // process remaining first and last columns (at most columnsAtOnce-1)
+ Index end = cols;
+ Index start = columnBound;
+ do
+ {
+ for (Index k=start; k<end; ++k)
{
- ResPacket c0 = pset1<ResPacket>(ResScalar(0));
- for(Index j=j2; j<jend; j+=1)
+ RhsPacket ptmp0 = pset1<RhsPacket>(alpha*rhs(k, 0));
+ const LhsScalars lhs0 = lhs.getVectorMapper(0, k);
+
+ if (Vectorizable)
{
- RhsPacket b0 = pset1<RhsPacket>(rhs(j,0));
- c0 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+0,j),b0,c0);
+ /* explicit vectorization */
+ // process first unaligned result's coeffs
+ for (Index j=0; j<alignedStart; ++j)
+ res[j] += cj.pmul(lhs0(j), pfirst(ptmp0));
+ // process aligned result's coeffs
+ if (lhs0.template aligned<LhsPacket>(alignedStart))
+ for (Index i = alignedStart;i<alignedSize;i+=ResPacketSize)
+ pstore(&res[i], pcj.pmadd(lhs0.template load<LhsPacket, Aligned>(i), ptmp0, pload<ResPacket>(&res[i])));
+ else
+ for (Index i = alignedStart;i<alignedSize;i+=ResPacketSize)
+ pstore(&res[i], pcj.pmadd(lhs0.template load<LhsPacket, Unaligned>(i), ptmp0, pload<ResPacket>(&res[i])));
}
- pstoreu(res+i+ResPacketSize*0, pmadd(c0,palpha,ploadu<ResPacket>(res+i+ResPacketSize*0)));
- i+=ResPacketSize;
+
+ // process remaining scalars (or all if no explicit vectorization)
+ for (Index i=alignedSize; i<size; ++i)
+ res[i] += cj.pmul(lhs0(i), pfirst(ptmp0));
}
- for(;i<rows;++i)
+ if (skipColumns)
{
- ResScalar c0(0);
- for(Index j=j2; j<jend; j+=1)
- c0 += cj.pmul(lhs(i,j), rhs(j,0));
- res[i] += alpha*c0;
+ start = 0;
+ end = skipColumns;
+ skipColumns = 0;
}
- }
+ else
+ break;
+ } while(Vectorizable);
+ #undef _EIGEN_ACCUMULATE_PACKETS
}
/* Optimized row-major matrix * vector product:
@@ -242,160 +363,253 @@ EIGEN_DONT_INLINE static void run(
template<typename Index, typename LhsScalar, typename LhsMapper, bool ConjugateLhs, typename RhsScalar, typename RhsMapper, bool ConjugateRhs, int Version>
EIGEN_DONT_INLINE void general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,ConjugateLhs,RhsScalar,RhsMapper,ConjugateRhs,Version>::run(
Index rows, Index cols,
- const LhsMapper& alhs,
+ const LhsMapper& lhs,
const RhsMapper& rhs,
ResScalar* res, Index resIncr,
ResScalar alpha)
{
- // The following copy tells the compiler that lhs's attributes are not modified outside this function
- // This helps GCC to generate propoer code.
- LhsMapper lhs(alhs);
-
eigen_internal_assert(rhs.stride()==1);
+
+ #ifdef _EIGEN_ACCUMULATE_PACKETS
+ #error _EIGEN_ACCUMULATE_PACKETS has already been defined
+ #endif
+
+ #define _EIGEN_ACCUMULATE_PACKETS(Alignment0,Alignment13,Alignment2) {\
+ RhsPacket b = rhs.getVectorMapper(j, 0).template load<RhsPacket, Aligned>(0); \
+ ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Alignment0>(j), b, ptmp0); \
+ ptmp1 = pcj.pmadd(lhs1.template load<LhsPacket, Alignment13>(j), b, ptmp1); \
+ ptmp2 = pcj.pmadd(lhs2.template load<LhsPacket, Alignment2>(j), b, ptmp2); \
+ ptmp3 = pcj.pmadd(lhs3.template load<LhsPacket, Alignment13>(j), b, ptmp3); }
+
conj_helper<LhsScalar,RhsScalar,ConjugateLhs,ConjugateRhs> cj;
conj_helper<LhsPacket,RhsPacket,ConjugateLhs,ConjugateRhs> pcj;
- // TODO: fine tune the following heuristic. The rationale is that if the matrix is very large,
- // processing 8 rows at once might be counter productive wrt cache.
- const Index n8 = lhs.stride()*sizeof(LhsScalar)>32000 ? 0 : rows-7;
- const Index n4 = rows-3;
- const Index n2 = rows-1;
+ typedef typename LhsMapper::VectorMapper LhsScalars;
- // TODO: for padded aligned inputs, we could enable aligned reads
- enum { LhsAlignment = Unaligned };
+ enum { AllAligned=0, EvenAligned=1, FirstAligned=2, NoneAligned=3 };
+ const Index rowsAtOnce = 4;
+ const Index peels = 2;
+ const Index RhsPacketAlignedMask = RhsPacketSize-1;
+ const Index LhsPacketAlignedMask = LhsPacketSize-1;
+ const Index depth = cols;
+ const Index lhsStride = lhs.stride();
- Index i=0;
- for(; i<n8; i+=8)
+ // How many coeffs of the result do we have to skip to be aligned.
+ // Here we assume data are at least aligned on the base scalar type
+ // if that's not the case then vectorization is discarded, see below.
+ Index alignedStart = rhs.firstAligned(depth);
+ Index alignedSize = RhsPacketSize>1 ? alignedStart + ((depth-alignedStart) & ~RhsPacketAlignedMask) : 0;
+ const Index peeledSize = alignedSize - RhsPacketSize*peels - RhsPacketSize + 1;
+
+ const Index alignmentStep = LhsPacketSize>1 ? (LhsPacketSize - lhsStride % LhsPacketSize) & LhsPacketAlignedMask : 0;
+ Index alignmentPattern = alignmentStep==0 ? AllAligned
+ : alignmentStep==(LhsPacketSize/2) ? EvenAligned
+ : FirstAligned;
+
+ // we cannot assume the first element is aligned because of sub-matrices
+ const Index lhsAlignmentOffset = lhs.firstAligned(depth);
+ const Index rhsAlignmentOffset = rhs.firstAligned(rows);
+
+ // find how many rows do we have to skip to be aligned with rhs (if possible)
+ Index skipRows = 0;
+ // if the data cannot be aligned (TODO add some compile time tests when possible, e.g. for floats)
+ if( (sizeof(LhsScalar)!=sizeof(RhsScalar)) ||
+ (lhsAlignmentOffset < 0) || (lhsAlignmentOffset == depth) ||
+ (rhsAlignmentOffset < 0) || (rhsAlignmentOffset == rows) )
{
- ResPacket c0 = pset1<ResPacket>(ResScalar(0)),
- c1 = pset1<ResPacket>(ResScalar(0)),
- c2 = pset1<ResPacket>(ResScalar(0)),
- c3 = pset1<ResPacket>(ResScalar(0)),
- c4 = pset1<ResPacket>(ResScalar(0)),
- c5 = pset1<ResPacket>(ResScalar(0)),
- c6 = pset1<ResPacket>(ResScalar(0)),
- c7 = pset1<ResPacket>(ResScalar(0));
-
- Index j=0;
- for(; j+LhsPacketSize<=cols; j+=LhsPacketSize)
- {
- RhsPacket b0 = rhs.template load<RhsPacket, Unaligned>(j,0);
-
- c0 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+0,j),b0,c0);
- c1 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+1,j),b0,c1);
- c2 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+2,j),b0,c2);
- c3 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+3,j),b0,c3);
- c4 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+4,j),b0,c4);
- c5 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+5,j),b0,c5);
- c6 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+6,j),b0,c6);
- c7 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+7,j),b0,c7);
- }
- ResScalar cc0 = predux(c0);
- ResScalar cc1 = predux(c1);
- ResScalar cc2 = predux(c2);
- ResScalar cc3 = predux(c3);
- ResScalar cc4 = predux(c4);
- ResScalar cc5 = predux(c5);
- ResScalar cc6 = predux(c6);
- ResScalar cc7 = predux(c7);
- for(; j<cols; ++j)
- {
- RhsScalar b0 = rhs(j,0);
-
- cc0 += cj.pmul(lhs(i+0,j), b0);
- cc1 += cj.pmul(lhs(i+1,j), b0);
- cc2 += cj.pmul(lhs(i+2,j), b0);
- cc3 += cj.pmul(lhs(i+3,j), b0);
- cc4 += cj.pmul(lhs(i+4,j), b0);
- cc5 += cj.pmul(lhs(i+5,j), b0);
- cc6 += cj.pmul(lhs(i+6,j), b0);
- cc7 += cj.pmul(lhs(i+7,j), b0);
- }
- res[(i+0)*resIncr] += alpha*cc0;
- res[(i+1)*resIncr] += alpha*cc1;
- res[(i+2)*resIncr] += alpha*cc2;
- res[(i+3)*resIncr] += alpha*cc3;
- res[(i+4)*resIncr] += alpha*cc4;
- res[(i+5)*resIncr] += alpha*cc5;
- res[(i+6)*resIncr] += alpha*cc6;
- res[(i+7)*resIncr] += alpha*cc7;
+ alignedSize = 0;
+ alignedStart = 0;
+ alignmentPattern = NoneAligned;
}
- for(; i<n4; i+=4)
+ else if(LhsPacketSize > 4)
{
- ResPacket c0 = pset1<ResPacket>(ResScalar(0)),
- c1 = pset1<ResPacket>(ResScalar(0)),
- c2 = pset1<ResPacket>(ResScalar(0)),
- c3 = pset1<ResPacket>(ResScalar(0));
+ // TODO: extend the code to support aligned loads whenever possible when LhsPacketSize > 4.
+ alignmentPattern = NoneAligned;
+ }
+ else if (LhsPacketSize>1)
+ {
+ // eigen_internal_assert(size_t(firstLhs+lhsAlignmentOffset)%sizeof(LhsPacket)==0 || depth<LhsPacketSize);
- Index j=0;
- for(; j+LhsPacketSize<=cols; j+=LhsPacketSize)
+ while (skipRows<LhsPacketSize &&
+ alignedStart != ((lhsAlignmentOffset + alignmentStep*skipRows)%LhsPacketSize))
+ ++skipRows;
+ if (skipRows==LhsPacketSize)
{
- RhsPacket b0 = rhs.template load<RhsPacket, Unaligned>(j,0);
-
- c0 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+0,j),b0,c0);
- c1 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+1,j),b0,c1);
- c2 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+2,j),b0,c2);
- c3 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+3,j),b0,c3);
+ // nothing can be aligned, no need to skip any column
+ alignmentPattern = NoneAligned;
+ skipRows = 0;
}
- ResScalar cc0 = predux(c0);
- ResScalar cc1 = predux(c1);
- ResScalar cc2 = predux(c2);
- ResScalar cc3 = predux(c3);
- for(; j<cols; ++j)
+ else
{
- RhsScalar b0 = rhs(j,0);
-
- cc0 += cj.pmul(lhs(i+0,j), b0);
- cc1 += cj.pmul(lhs(i+1,j), b0);
- cc2 += cj.pmul(lhs(i+2,j), b0);
- cc3 += cj.pmul(lhs(i+3,j), b0);
+ skipRows = (std::min)(skipRows,Index(rows));
+ // note that the skiped columns are processed later.
}
- res[(i+0)*resIncr] += alpha*cc0;
- res[(i+1)*resIncr] += alpha*cc1;
- res[(i+2)*resIncr] += alpha*cc2;
- res[(i+3)*resIncr] += alpha*cc3;
+ /* eigen_internal_assert( alignmentPattern==NoneAligned
+ || LhsPacketSize==1
+ || (skipRows + rowsAtOnce >= rows)
+ || LhsPacketSize > depth
+ || (size_t(firstLhs+alignedStart+lhsStride*skipRows)%sizeof(LhsPacket))==0);*/
}
- for(; i<n2; i+=2)
+ else if(Vectorizable)
{
- ResPacket c0 = pset1<ResPacket>(ResScalar(0)),
- c1 = pset1<ResPacket>(ResScalar(0));
+ alignedStart = 0;
+ alignedSize = depth;
+ alignmentPattern = AllAligned;
+ }
- Index j=0;
- for(; j+LhsPacketSize<=cols; j+=LhsPacketSize)
- {
- RhsPacket b0 = rhs.template load<RhsPacket, Unaligned>(j,0);
+ const Index offset1 = (FirstAligned && alignmentStep==1)?3:1;
+ const Index offset3 = (FirstAligned && alignmentStep==1)?1:3;
- c0 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+0,j),b0,c0);
- c1 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i+1,j),b0,c1);
- }
- ResScalar cc0 = predux(c0);
- ResScalar cc1 = predux(c1);
- for(; j<cols; ++j)
+ Index rowBound = ((rows-skipRows)/rowsAtOnce)*rowsAtOnce + skipRows;
+ for (Index i=skipRows; i<rowBound; i+=rowsAtOnce)
+ {
+ // FIXME: what is the purpose of this EIGEN_ALIGN_DEFAULT ??
+ EIGEN_ALIGN_MAX ResScalar tmp0 = ResScalar(0);
+ ResScalar tmp1 = ResScalar(0), tmp2 = ResScalar(0), tmp3 = ResScalar(0);
+
+ // this helps the compiler generating good binary code
+ const LhsScalars lhs0 = lhs.getVectorMapper(i+0, 0), lhs1 = lhs.getVectorMapper(i+offset1, 0),
+ lhs2 = lhs.getVectorMapper(i+2, 0), lhs3 = lhs.getVectorMapper(i+offset3, 0);
+
+ if (Vectorizable)
{
- RhsScalar b0 = rhs(j,0);
+ /* explicit vectorization */
+ ResPacket ptmp0 = pset1<ResPacket>(ResScalar(0)), ptmp1 = pset1<ResPacket>(ResScalar(0)),
+ ptmp2 = pset1<ResPacket>(ResScalar(0)), ptmp3 = pset1<ResPacket>(ResScalar(0));
+
+ // process initial unaligned coeffs
+ // FIXME this loop get vectorized by the compiler !
+ for (Index j=0; j<alignedStart; ++j)
+ {
+ RhsScalar b = rhs(j, 0);
+ tmp0 += cj.pmul(lhs0(j),b); tmp1 += cj.pmul(lhs1(j),b);
+ tmp2 += cj.pmul(lhs2(j),b); tmp3 += cj.pmul(lhs3(j),b);
+ }
+
+ if (alignedSize>alignedStart)
+ {
+ switch(alignmentPattern)
+ {
+ case AllAligned:
+ for (Index j = alignedStart; j<alignedSize; j+=RhsPacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(Aligned,Aligned,Aligned);
+ break;
+ case EvenAligned:
+ for (Index j = alignedStart; j<alignedSize; j+=RhsPacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(Aligned,Unaligned,Aligned);
+ break;
+ case FirstAligned:
+ {
+ Index j = alignedStart;
+ if (peels>1)
+ {
+ /* Here we proccess 4 rows with with two peeled iterations to hide
+ * the overhead of unaligned loads. Moreover unaligned loads are handled
+ * using special shift/move operations between the two aligned packets
+ * overlaping the desired unaligned packet. This is *much* more efficient
+ * than basic unaligned loads.
+ */
+ LhsPacket A01, A02, A03, A11, A12, A13;
+ A01 = lhs1.template load<LhsPacket, Aligned>(alignedStart-1);
+ A02 = lhs2.template load<LhsPacket, Aligned>(alignedStart-2);
+ A03 = lhs3.template load<LhsPacket, Aligned>(alignedStart-3);
+
+ for (; j<peeledSize; j+=peels*RhsPacketSize)
+ {
+ RhsPacket b = rhs.getVectorMapper(j, 0).template load<RhsPacket, Aligned>(0);
+ A11 = lhs1.template load<LhsPacket, Aligned>(j-1+LhsPacketSize); palign<1>(A01,A11);
+ A12 = lhs2.template load<LhsPacket, Aligned>(j-2+LhsPacketSize); palign<2>(A02,A12);
+ A13 = lhs3.template load<LhsPacket, Aligned>(j-3+LhsPacketSize); palign<3>(A03,A13);
+
+ ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Aligned>(j), b, ptmp0);
+ ptmp1 = pcj.pmadd(A01, b, ptmp1);
+ A01 = lhs1.template load<LhsPacket, Aligned>(j-1+2*LhsPacketSize); palign<1>(A11,A01);
+ ptmp2 = pcj.pmadd(A02, b, ptmp2);
+ A02 = lhs2.template load<LhsPacket, Aligned>(j-2+2*LhsPacketSize); palign<2>(A12,A02);
+ ptmp3 = pcj.pmadd(A03, b, ptmp3);
+ A03 = lhs3.template load<LhsPacket, Aligned>(j-3+2*LhsPacketSize); palign<3>(A13,A03);
+
+ b = rhs.getVectorMapper(j+RhsPacketSize, 0).template load<RhsPacket, Aligned>(0);
+ ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Aligned>(j+LhsPacketSize), b, ptmp0);
+ ptmp1 = pcj.pmadd(A11, b, ptmp1);
+ ptmp2 = pcj.pmadd(A12, b, ptmp2);
+ ptmp3 = pcj.pmadd(A13, b, ptmp3);
+ }
+ }
+ for (; j<alignedSize; j+=RhsPacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(Aligned,Unaligned,Unaligned);
+ break;
+ }
+ default:
+ for (Index j = alignedStart; j<alignedSize; j+=RhsPacketSize)
+ _EIGEN_ACCUMULATE_PACKETS(Unaligned,Unaligned,Unaligned);
+ break;
+ }
+ tmp0 += predux(ptmp0);
+ tmp1 += predux(ptmp1);
+ tmp2 += predux(ptmp2);
+ tmp3 += predux(ptmp3);
+ }
+ } // end explicit vectorization
- cc0 += cj.pmul(lhs(i+0,j), b0);
- cc1 += cj.pmul(lhs(i+1,j), b0);
+ // process remaining coeffs (or all if no explicit vectorization)
+ // FIXME this loop get vectorized by the compiler !
+ for (Index j=alignedSize; j<depth; ++j)
+ {
+ RhsScalar b = rhs(j, 0);
+ tmp0 += cj.pmul(lhs0(j),b); tmp1 += cj.pmul(lhs1(j),b);
+ tmp2 += cj.pmul(lhs2(j),b); tmp3 += cj.pmul(lhs3(j),b);
}
- res[(i+0)*resIncr] += alpha*cc0;
- res[(i+1)*resIncr] += alpha*cc1;
+ res[i*resIncr] += alpha*tmp0;
+ res[(i+offset1)*resIncr] += alpha*tmp1;
+ res[(i+2)*resIncr] += alpha*tmp2;
+ res[(i+offset3)*resIncr] += alpha*tmp3;
}
- for(; i<rows; ++i)
+
+ // process remaining first and last rows (at most columnsAtOnce-1)
+ Index end = rows;
+ Index start = rowBound;
+ do
{
- ResPacket c0 = pset1<ResPacket>(ResScalar(0));
- Index j=0;
- for(; j+LhsPacketSize<=cols; j+=LhsPacketSize)
+ for (Index i=start; i<end; ++i)
{
- RhsPacket b0 = rhs.template load<RhsPacket,Unaligned>(j,0);
- c0 = pcj.pmadd(lhs.template load<LhsPacket,LhsAlignment>(i,j),b0,c0);
+ EIGEN_ALIGN_MAX ResScalar tmp0 = ResScalar(0);
+ ResPacket ptmp0 = pset1<ResPacket>(tmp0);
+ const LhsScalars lhs0 = lhs.getVectorMapper(i, 0);
+ // process first unaligned result's coeffs
+ // FIXME this loop get vectorized by the compiler !
+ for (Index j=0; j<alignedStart; ++j)
+ tmp0 += cj.pmul(lhs0(j), rhs(j, 0));
+
+ if (alignedSize>alignedStart)
+ {
+ // process aligned rhs coeffs
+ if (lhs0.template aligned<LhsPacket>(alignedStart))
+ for (Index j = alignedStart;j<alignedSize;j+=RhsPacketSize)
+ ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Aligned>(j), rhs.getVectorMapper(j, 0).template load<RhsPacket, Aligned>(0), ptmp0);
+ else
+ for (Index j = alignedStart;j<alignedSize;j+=RhsPacketSize)
+ ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Unaligned>(j), rhs.getVectorMapper(j, 0).template load<RhsPacket, Aligned>(0), ptmp0);
+ tmp0 += predux(ptmp0);
+ }
+
+ // process remaining scalars
+ // FIXME this loop get vectorized by the compiler !
+ for (Index j=alignedSize; j<depth; ++j)
+ tmp0 += cj.pmul(lhs0(j), rhs(j, 0));
+ res[i*resIncr] += alpha*tmp0;
}
- ResScalar cc0 = predux(c0);
- for(; j<cols; ++j)
+ if (skipRows)
{
- cc0 += cj.pmul(lhs(i,j), rhs(j,0));
+ start = 0;
+ end = skipRows;
+ skipRows = 0;
}
- res[i*resIncr] += alpha*cc0;
- }
+ else
+ break;
+ } while(Vectorizable);
+
+ #undef _EIGEN_ACCUMULATE_PACKETS
}
} // end namespace internal
diff --git a/eigen/Eigen/src/Core/products/SelfadjointProduct.h b/eigen/Eigen/src/Core/products/SelfadjointProduct.h
index 39c5b59..f038d68 100644
--- a/eigen/Eigen/src/Core/products/SelfadjointProduct.h
+++ b/eigen/Eigen/src/Core/products/SelfadjointProduct.h
@@ -120,7 +120,7 @@ struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,false>
template<typename MatrixType, unsigned int UpLo>
template<typename DerivedU>
-EIGEN_DEVICE_FUNC SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
+SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
::rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha)
{
selfadjoint_product_selector<MatrixType,DerivedU,UpLo>::run(_expression().const_cast_derived(), u.derived(), alpha);
diff --git a/eigen/Eigen/src/Core/products/SelfadjointRank2Update.h b/eigen/Eigen/src/Core/products/SelfadjointRank2Update.h
index d395888..2ae3641 100644
--- a/eigen/Eigen/src/Core/products/SelfadjointRank2Update.h
+++ b/eigen/Eigen/src/Core/products/SelfadjointRank2Update.h
@@ -57,7 +57,7 @@ template<bool Cond, typename T> struct conj_expr_if
template<typename MatrixType, unsigned int UpLo>
template<typename DerivedU, typename DerivedV>
-EIGEN_DEVICE_FUNC SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
+SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
::rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, const Scalar& alpha)
{
typedef internal::blas_traits<DerivedU> UBlasTraits;
diff --git a/eigen/Eigen/src/Core/util/BlasUtil.h b/eigen/Eigen/src/Core/util/BlasUtil.h
index b1791fb..6e6ee11 100644
--- a/eigen/Eigen/src/Core/util/BlasUtil.h
+++ b/eigen/Eigen/src/Core/util/BlasUtil.h
@@ -222,11 +222,6 @@ class blas_data_mapper {
return ploadt<Packet, AlignmentType>(&operator()(i, j));
}
- template <typename PacketT, int AlignmentT>
- EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketT load(Index i, Index j) const {
- return ploadt<PacketT, AlignmentT>(&operator()(i, j));
- }
-
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i, Index j) const {
return ploadt<HalfPacket, AlignmentType>(&operator()(i, j));
}
diff --git a/eigen/Eigen/src/Core/util/Constants.h b/eigen/Eigen/src/Core/util/Constants.h
index 5d37e5d..7587d68 100644
--- a/eigen/Eigen/src/Core/util/Constants.h
+++ b/eigen/Eigen/src/Core/util/Constants.h
@@ -25,10 +25,6 @@ const int Dynamic = -1;
*/
const int DynamicIndex = 0xffffff;
-/** This value means that the increment to go from one value to another in a sequence is not constant for each step.
- */
-const int UndefinedIncr = 0xfffffe;
-
/** This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm<int>().
* The value Infinity there means the L-infinity norm.
*/
diff --git a/eigen/Eigen/src/Core/util/DisableStupidWarnings.h b/eigen/Eigen/src/Core/util/DisableStupidWarnings.h
index 4431f2f..7559e12 100644
--- a/eigen/Eigen/src/Core/util/DisableStupidWarnings.h
+++ b/eigen/Eigen/src/Core/util/DisableStupidWarnings.h
@@ -4,6 +4,7 @@
#ifdef _MSC_VER
// 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p))
// 4101 - unreferenced local variable
+ // 4127 - conditional expression is constant
// 4181 - qualifier applied to reference type ignored
// 4211 - nonstandard extension used : redefined extern to static
// 4244 - 'argument' : conversion from 'type1' to 'type2', possible loss of data
@@ -19,7 +20,7 @@
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
#pragma warning( push )
#endif
- #pragma warning( disable : 4100 4101 4181 4211 4244 4273 4324 4503 4512 4522 4700 4714 4717 4800)
+ #pragma warning( disable : 4100 4101 4127 4181 4211 4244 4273 4324 4503 4512 4522 4700 4714 4717 4800)
#elif defined __INTEL_COMPILER
// 2196 - routine is both "inline" and "noinline" ("noinline" assumed)
@@ -41,9 +42,6 @@
#pragma clang diagnostic push
#endif
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
- #if __clang_major__ >= 3 && __clang_minor__ >= 5
- #pragma clang diagnostic ignored "-Wabsolute-value"
- #endif
#elif defined __GNUC__ && __GNUC__>=6
diff --git a/eigen/Eigen/src/Core/util/ForwardDeclarations.h b/eigen/Eigen/src/Core/util/ForwardDeclarations.h
index 1a48cff..ea10739 100644
--- a/eigen/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/eigen/Eigen/src/Core/util/ForwardDeclarations.h
@@ -83,7 +83,6 @@ template<typename ExpressionType> class ForceAlignedAccess;
template<typename ExpressionType> class SwapWrapper;
template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false> class Block;
-template<typename XprType, typename RowIndices, typename ColIndices> class IndexedView;
template<typename MatrixType, int Size=Dynamic> class VectorBlock;
template<typename MatrixType> class Transpose;
diff --git a/eigen/Eigen/src/Core/util/IndexedViewHelper.h b/eigen/Eigen/src/Core/util/IndexedViewHelper.h
deleted file mode 100644
index ab01c85..0000000
--- a/eigen/Eigen/src/Core/util/IndexedViewHelper.h
+++ /dev/null
@@ -1,187 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2017 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/.
-
-
-#ifndef EIGEN_INDEXED_VIEW_HELPER_H
-#define EIGEN_INDEXED_VIEW_HELPER_H
-
-namespace Eigen {
-
-/** \namespace Eigen::placeholders
- * \ingroup Core_Module
- *
- * Namespace containing symbolic placeholder and identifiers
- */
-namespace placeholders {
-
-namespace internal {
-struct symbolic_last_tag {};
-}
-
-/** \var last
- * \ingroup Core_Module
- *
- * Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last element/row/columns
- * of the underlying vector or matrix once passed to DenseBase::operator()(const RowIndices&, const ColIndices&).
- *
- * This symbolic placeholder support standard arithmetic operation.
- *
- * A typical usage example would be:
- * \code
- * using namespace Eigen;
- * using Eigen::placeholders::last;
- * VectorXd v(n);
- * v(seq(2,last-2)).setOnes();
- * \endcode
- *
- * \sa end
- */
-static const Symbolic::SymbolExpr<internal::symbolic_last_tag> last;
-
-/** \var end
- * \ingroup Core_Module
- *
- * Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last+1 element/row/columns
- * of the underlying vector or matrix once passed to DenseBase::operator()(const RowIndices&, const ColIndices&).
- *
- * This symbolic placeholder support standard arithmetic operation.
- * It is essentially an alias to last+1
- *
- * \sa last
- */
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-static const auto end = last+1;
-#else
-// Using a FixedExpr<1> expression is important here to make sure the compiler
-// can fully optimize the computation starting indices with zero overhead.
-static const Symbolic::AddExpr<Symbolic::SymbolExpr<internal::symbolic_last_tag>,Symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > end(last+fix<1>());
-#endif
-
-} // end namespace placeholders
-
-namespace internal {
-
- // Replace symbolic last/end "keywords" by their true runtime value
-inline Index eval_expr_given_size(Index x, Index /* size */) { return x; }
-
-template<int N>
-FixedInt<N> eval_expr_given_size(FixedInt<N> x, Index /*size*/) { return x; }
-
-template<typename Derived>
-Index eval_expr_given_size(const Symbolic::BaseExpr<Derived> &x, Index size)
-{
- return x.derived().eval(placeholders::last=size-1);
-}
-
-// Extract increment/step at compile time
-template<typename T, typename EnableIf = void> struct get_compile_time_incr {
- enum { value = UndefinedIncr };
-};
-
-// Analogue of std::get<0>(x), but tailored for our needs.
-template<typename T>
-Index first(const T& x) { return x.first(); }
-
-// IndexedViewCompatibleType/makeIndexedViewCompatible turn an arbitrary object of type T into something usable by MatrixSlice
-// The generic implementation is a no-op
-template<typename T,int XprSize,typename EnableIf=void>
-struct IndexedViewCompatibleType {
- typedef T type;
-};
-
-template<typename T,typename Q>
-const T& makeIndexedViewCompatible(const T& x, Index /*size*/, Q) { return x; }
-
-//--------------------------------------------------------------------------------
-// Handling of a single Index
-//--------------------------------------------------------------------------------
-
-struct SingleRange {
- enum {
- SizeAtCompileTime = 1
- };
- SingleRange(Index val) : m_value(val) {}
- Index operator[](Index) const { return m_value; }
- Index size() const { return 1; }
- Index first() const { return m_value; }
- Index m_value;
-};
-
-template<> struct get_compile_time_incr<SingleRange> {
- enum { value = 1 }; // 1 or 0 ??
-};
-
-// Turn a single index into something that looks like an array (i.e., that exposes a .size(), and operatro[](int) methods)
-template<typename T, int XprSize>
-struct IndexedViewCompatibleType<T,XprSize,typename internal::enable_if<internal::is_integral<T>::value>::type> {
- // Here we could simply use Array, but maybe it's less work for the compiler to use
- // a simpler wrapper as SingleRange
- //typedef Eigen::Array<Index,1,1> type;
- typedef SingleRange type;
-};
-
-template<typename T, int XprSize>
-struct IndexedViewCompatibleType<T, XprSize, typename enable_if<Symbolic::is_symbolic<T>::value>::type> {
- typedef SingleRange type;
-};
-
-
-template<typename T>
-typename enable_if<Symbolic::is_symbolic<T>::value,SingleRange>::type
-makeIndexedViewCompatible(const T& id, Index size, SpecializedType) {
- return eval_expr_given_size(id,size);
-}
-
-//--------------------------------------------------------------------------------
-// Handling of all
-//--------------------------------------------------------------------------------
-
-struct all_t { all_t() {} };
-
-// Convert a symbolic 'all' into a usable range type
-template<int XprSize>
-struct AllRange {
- enum { SizeAtCompileTime = XprSize };
- AllRange(Index size = XprSize) : m_size(size) {}
- Index operator[](Index i) const { return i; }
- Index size() const { return m_size.value(); }
- Index first() const { return 0; }
- variable_if_dynamic<Index,XprSize> m_size;
-};
-
-template<int XprSize>
-struct IndexedViewCompatibleType<all_t,XprSize> {
- typedef AllRange<XprSize> type;
-};
-
-template<typename XprSizeType>
-inline AllRange<get_fixed_value<XprSizeType>::value> makeIndexedViewCompatible(all_t , XprSizeType size, SpecializedType) {
- return AllRange<get_fixed_value<XprSizeType>::value>(size);
-}
-
-template<int Size> struct get_compile_time_incr<AllRange<Size> > {
- enum { value = 1 };
-};
-
-} // end namespace internal
-
-
-namespace placeholders {
-
-/** \var all
- * \ingroup Core_Module
- * Can be used as a parameter to DenseBase::operator()(const RowIndices&, const ColIndices&) to index all rows or columns
- */
-static const Eigen::internal::all_t all;
-
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_INDEXED_VIEW_HELPER_H
diff --git a/eigen/Eigen/src/Core/util/IntegralConstant.h b/eigen/Eigen/src/Core/util/IntegralConstant.h
deleted file mode 100644
index 78a4705..0000000
--- a/eigen/Eigen/src/Core/util/IntegralConstant.h
+++ /dev/null
@@ -1,270 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2017 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/.
-
-
-#ifndef EIGEN_INTEGRAL_CONSTANT_H
-#define EIGEN_INTEGRAL_CONSTANT_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<int N> class FixedInt;
-template<int N> class VariableAndFixedInt;
-
-/** \internal
- * \class FixedInt
- *
- * This class embeds a compile-time integer \c N.
- *
- * It is similar to c++11 std::integral_constant<int,N> but with some additional features
- * such as:
- * - implicit conversion to int
- * - arithmetic and some bitwise operators: -, +, *, /, %, &, |
- * - c++98/14 compatibility with fix<N> and fix<N>() syntax to define integral constants.
- *
- * It is strongly discouraged to directly deal with this class FixedInt. Instances are expcected to
- * be created by the user using Eigen::fix<N> or Eigen::fix<N>(). In C++98-11, the former syntax does
- * not create a FixedInt<N> instance but rather a point to function that needs to be \em cleaned-up
- * using the generic helper:
- * \code
- * internal::cleanup_index_type<T>::type
- * internal::cleanup_index_type<T,DynamicKey>::type
- * \endcode
- * where T can a FixedInt<N>, a pointer to function FixedInt<N> (*)(), or numerous other integer-like representations.
- * \c DynamicKey is either Dynamic (default) or DynamicIndex and used to identify true compile-time values.
- *
- * For convenience, you can extract the compile-time value \c N in a generic way using the following helper:
- * \code
- * internal::get_fixed_value<T,DefaultVal>::value
- * \endcode
- * that will give you \c N if T equals FixedInt<N> or FixedInt<N> (*)(), and \c DefaultVal if T does not embed any compile-time value (e.g., T==int).
- *
- * \sa fix<N>, class VariableAndFixedInt
- */
-template<int N> class FixedInt
-{
-public:
- static const int value = N;
- operator int() const { return value; }
- FixedInt() {}
- FixedInt( VariableAndFixedInt<N> other) {
- EIGEN_ONLY_USED_FOR_DEBUG(other);
- eigen_internal_assert(int(other)==N);
- }
-
- FixedInt<-N> operator-() const { return FixedInt<-N>(); }
- template<int M>
- FixedInt<N+M> operator+( FixedInt<M>) const { return FixedInt<N+M>(); }
- template<int M>
- FixedInt<N-M> operator-( FixedInt<M>) const { return FixedInt<N-M>(); }
- template<int M>
- FixedInt<N*M> operator*( FixedInt<M>) const { return FixedInt<N*M>(); }
- template<int M>
- FixedInt<N/M> operator/( FixedInt<M>) const { return FixedInt<N/M>(); }
- template<int M>
- FixedInt<N%M> operator%( FixedInt<M>) const { return FixedInt<N%M>(); }
- template<int M>
- FixedInt<N|M> operator|( FixedInt<M>) const { return FixedInt<N|M>(); }
- template<int M>
- FixedInt<N&M> operator&( FixedInt<M>) const { return FixedInt<N&M>(); }
-
-#if EIGEN_HAS_CXX14
- // Needed in C++14 to allow fix<N>():
- FixedInt operator() () const { return *this; }
-
- VariableAndFixedInt<N> operator() (int val) const { return VariableAndFixedInt<N>(val); }
-#else
- FixedInt ( FixedInt<N> (*)() ) {}
-#endif
-
-#if EIGEN_HAS_CXX11
- FixedInt(std::integral_constant<int,N>) {}
-#endif
-};
-
-/** \internal
- * \class VariableAndFixedInt
- *
- * This class embeds both a compile-time integer \c N and a runtime integer.
- * Both values are supposed to be equal unless the compile-time value \c N has a special
- * value meaning that the runtime-value should be used. Depending on the context, this special
- * value can be either Eigen::Dynamic (for positive quantities) or Eigen::DynamicIndex (for
- * quantities that can be negative).
- *
- * It is the return-type of the function Eigen::fix<N>(int), and most of the time this is the only
- * way it is used. It is strongly discouraged to directly deal with instances of VariableAndFixedInt.
- * Indeed, in order to write generic code, it is the responsibility of the callee to properly convert
- * it to either a true compile-time quantity (i.e. a FixedInt<N>), or to a runtime quantity (e.g., an Index)
- * using the following generic helper:
- * \code
- * internal::cleanup_index_type<T>::type
- * internal::cleanup_index_type<T,DynamicKey>::type
- * \endcode
- * where T can be a template instantiation of VariableAndFixedInt or numerous other integer-like representations.
- * \c DynamicKey is either Dynamic (default) or DynamicIndex and used to identify true compile-time values.
- *
- * For convenience, you can also extract the compile-time value \c N using the following helper:
- * \code
- * internal::get_fixed_value<T,DefaultVal>::value
- * \endcode
- * that will give you \c N if T equals VariableAndFixedInt<N>, and \c DefaultVal if T does not embed any compile-time value (e.g., T==int).
- *
- * \sa fix<N>(int), class FixedInt
- */
-template<int N> class VariableAndFixedInt
-{
-public:
- static const int value = N;
- operator int() const { return m_value; }
- VariableAndFixedInt(int val) { m_value = val; }
-protected:
- int m_value;
-};
-
-template<typename T, int Default=Dynamic> struct get_fixed_value {
- static const int value = Default;
-};
-
-template<int N,int Default> struct get_fixed_value<FixedInt<N>,Default> {
- static const int value = N;
-};
-
-#if !EIGEN_HAS_CXX14
-template<int N,int Default> struct get_fixed_value<FixedInt<N> (*)(),Default> {
- static const int value = N;
-};
-#endif
-
-template<int N,int Default> struct get_fixed_value<VariableAndFixedInt<N>,Default> {
- static const int value = N ;
-};
-
-template<typename T, int N, int Default>
-struct get_fixed_value<variable_if_dynamic<T,N>,Default> {
- static const int value = N;
-};
-
-template<typename T> EIGEN_DEVICE_FUNC Index get_runtime_value(const T &x) { return x; }
-#if !EIGEN_HAS_CXX14
-template<int N> EIGEN_DEVICE_FUNC Index get_runtime_value(FixedInt<N> (*)()) { return N; }
-#endif
-
-// Cleanup integer/FixedInt/VariableAndFixedInt/etc types:
-
-// By default, no cleanup:
-template<typename T, int DynamicKey=Dynamic, typename EnableIf=void> struct cleanup_index_type { typedef T type; };
-
-// Convert any integral type (e.g., short, int, unsigned int, etc.) to Eigen::Index
-template<typename T, int DynamicKey> struct cleanup_index_type<T,DynamicKey,typename internal::enable_if<internal::is_integral<T>::value>::type> { typedef Index type; };
-
-#if !EIGEN_HAS_CXX14
-// In c++98/c++11, fix<N> is a pointer to function that we better cleanup to a true FixedInt<N>:
-template<int N, int DynamicKey> struct cleanup_index_type<FixedInt<N> (*)(), DynamicKey> { typedef FixedInt<N> type; };
-#endif
-
-// If VariableAndFixedInt does not match DynamicKey, then we turn it to a pure compile-time value:
-template<int N, int DynamicKey> struct cleanup_index_type<VariableAndFixedInt<N>, DynamicKey> { typedef FixedInt<N> type; };
-// If VariableAndFixedInt matches DynamicKey, then we turn it to a pure runtime-value (aka Index):
-template<int DynamicKey> struct cleanup_index_type<VariableAndFixedInt<DynamicKey>, DynamicKey> { typedef Index type; };
-
-#if EIGEN_HAS_CXX11
-template<int N, int DynamicKey> struct cleanup_index_type<std::integral_constant<int,N>, DynamicKey> { typedef FixedInt<N> type; };
-#endif
-
-} // end namespace internal
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-
-#if EIGEN_HAS_CXX14
-template<int N>
-static const internal::FixedInt<N> fix{};
-#else
-template<int N>
-inline internal::FixedInt<N> fix() { return internal::FixedInt<N>(); }
-
-// The generic typename T is mandatory. Otherwise, a code like fix<N> could refer to either the function above or this next overload.
-// This way a code like fix<N> can only refer to the previous function.
-template<int N,typename T>
-inline internal::VariableAndFixedInt<N> fix(T val) { return internal::VariableAndFixedInt<N>(val); }
-#endif
-
-#else // EIGEN_PARSED_BY_DOXYGEN
-
-/** \var fix<N>()
- * \ingroup Core_Module
- *
- * This \em identifier permits to construct an object embedding a compile-time integer \c N.
- *
- * \tparam N the compile-time integer value
- *
- * It is typically used in conjunction with the Eigen::seq and Eigen::seqN functions to pass compile-time values to them:
- * \code
- * seqN(10,fix<4>,fix<-3>) // <=> [10 7 4 1]
- * \endcode
- *
- * See also the function fix(int) to pass both a compile-time and runtime value.
- *
- * In c++14, it is implemented as:
- * \code
- * template<int N> static const internal::FixedInt<N> fix{};
- * \endcode
- * where internal::FixedInt<N> is an internal template class similar to
- * <a href="http://en.cppreference.com/w/cpp/types/integral_constant">\c std::integral_constant </a><tt> <int,N> </tt>
- * Here, \c fix<N> is thus an object of type \c internal::FixedInt<N>.
- *
- * In c++98/11, it is implemented as a function:
- * \code
- * template<int N> inline internal::FixedInt<N> fix();
- * \endcode
- * Here internal::FixedInt<N> is thus a pointer to function.
- *
- * If for some reason you want a true object in c++98 then you can write: \code fix<N>() \endcode which is also valid in c++14.
- *
- * \sa fix<N>(int), seq, seqN
- */
-template<int N>
-static const auto fix();
-
-/** \fn fix<N>(int)
- * \ingroup Core_Module
- *
- * This function returns an object embedding both a compile-time integer \c N, and a fallback runtime value \a val.
- *
- * \tparam N the compile-time integer value
- * \param val the fallback runtime integer value
- *
- * This function is a more general version of the \ref fix identifier/function that can be used in template code
- * where the compile-time value could turn out to actually mean "undefined at compile-time". For positive integers
- * such as a size or a dimension, this case is identified by Eigen::Dynamic, whereas runtime signed integers
- * (e.g., an increment/stride) are identified as Eigen::DynamicIndex. In such a case, the runtime value \a val
- * will be used as a fallback.
- *
- * A typical use case would be:
- * \code
- * template<typename Derived> void foo(const MatrixBase<Derived> &mat) {
- * const int N = Derived::RowsAtCompileTime==Dynamic ? Dynamic : Derived::RowsAtCompileTime/2;
- * const int n = mat.rows()/2;
- * ... mat( seqN(0,fix<N>(n) ) ...;
- * }
- * \endcode
- * In this example, the function Eigen::seqN knows that the second argument is expected to be a size.
- * If the passed compile-time value N equals Eigen::Dynamic, then the proxy object returned by fix will be dissmissed, and converted to an Eigen::Index of value \c n.
- * Otherwise, the runtime-value \c n will be dissmissed, and the returned ArithmeticSequence will be of the exact same type as <tt> seqN(0,fix<N>) </tt>.
- *
- * \sa fix, seqN, class ArithmeticSequence
- */
-template<int N>
-static const auto fix(int val);
-
-#endif // EIGEN_PARSED_BY_DOXYGEN
-
-} // end namespace Eigen
-
-#endif // EIGEN_INTEGRAL_CONSTANT_H
diff --git a/eigen/Eigen/src/Core/util/Macros.h b/eigen/Eigen/src/Core/util/Macros.h
index 14ec87d..38d6ddb 100644
--- a/eigen/Eigen/src/Core/util/Macros.h
+++ b/eigen/Eigen/src/Core/util/Macros.h
@@ -13,7 +13,7 @@
#define EIGEN_WORLD_VERSION 3
#define EIGEN_MAJOR_VERSION 3
-#define EIGEN_MINOR_VERSION 90
+#define EIGEN_MINOR_VERSION 4
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
@@ -23,7 +23,7 @@
/// \internal EIGEN_COMP_GNUC set to 1 for all compilers compatible with GCC
#ifdef __GNUC__
- #define EIGEN_COMP_GNUC (__GNUC__*10+__GNUC_MINOR__)
+ #define EIGEN_COMP_GNUC 1
#else
#define EIGEN_COMP_GNUC 0
#endif
@@ -349,14 +349,6 @@
# define __has_feature(x) 0
#endif
-// Some old compilers do not support template specializations like:
-// template<typename T,int N> void foo(const T x[N]);
-#if !( EIGEN_COMP_CLANG && ((EIGEN_COMP_CLANG<309) || defined(__apple_build_version__)) || EIGEN_COMP_GNUC_STRICT && EIGEN_COMP_GNUC<49)
-#define EIGEN_HAS_STATIC_ARRAY_TEMPLATE 1
-#else
-#define EIGEN_HAS_STATIC_ARRAY_TEMPLATE 0
-#endif
-
// Upperbound on the C++ version to use.
// Expected values are 03, 11, 14, 17, etc.
// By default, let's use an arbitrarily large C++ version.
@@ -370,11 +362,6 @@
#define EIGEN_HAS_CXX11 0
#endif
-#if EIGEN_MAX_CPP_VER>=14 && (defined(__cplusplus) && (__cplusplus > 201103L) || EIGEN_COMP_MSVC >= 1910)
-#define EIGEN_HAS_CXX14 1
-#else
-#define EIGEN_HAS_CXX14 0
-#endif
// Do we support r-value references?
#ifndef EIGEN_HAS_RVALUE_REFERENCES
@@ -393,8 +380,7 @@
#if EIGEN_MAX_CPP_VER>=11 && \
((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) \
|| (defined(__GNUC__) && defined(_GLIBCXX_USE_C99)) \
- || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) \
- || (EIGEN_COMP_MSVC >= 1900) || defined(__SYCL_DEVICE_ONLY__))
+ || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)))
#define EIGEN_HAS_C99_MATH 1
#else
#define EIGEN_HAS_C99_MATH 0
@@ -413,12 +399,10 @@
// Does the compiler support variadic templates?
#ifndef EIGEN_HAS_VARIADIC_TEMPLATES
#if EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) \
- && (!defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000) )
+ && ( !defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000) )
// ^^ Disable the use of variadic templates when compiling with versions of nvcc older than 8.0 on ARM devices:
// this prevents nvcc from crashing when compiling Eigen on Tegra X1
#define EIGEN_HAS_VARIADIC_TEMPLATES 1
-#elif EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) && defined(__SYCL_DEVICE_ONLY__)
-#define EIGEN_HAS_VARIADIC_TEMPLATES 1
#else
#define EIGEN_HAS_VARIADIC_TEMPLATES 0
#endif
@@ -427,14 +411,13 @@
// Does the compiler fully support const expressions? (as in c++14)
#ifndef EIGEN_HAS_CONSTEXPR
-#if defined(__CUDACC__)
+#ifdef __CUDACC__
// Const expressions are supported provided that c++11 is enabled and we're using either clang or nvcc 7.5 or above
#if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && defined(__CUDACC_VER__) && (EIGEN_COMP_CLANG || __CUDACC_VER__ >= 70500))
#define EIGEN_HAS_CONSTEXPR 1
#endif
#elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (defined(__cplusplus) && __cplusplus >= 201402L) || \
- (EIGEN_GNUC_AT_LEAST(4,8) && (__cplusplus > 199711L)) || \
- (EIGEN_COMP_CLANG >= 306 && (__cplusplus > 199711L)))
+ (EIGEN_GNUC_AT_LEAST(4,8) && (__cplusplus > 199711L)))
#define EIGEN_HAS_CONSTEXPR 1
#endif
@@ -542,8 +525,8 @@
// - static is not very good because it prevents definitions from different object files to be merged.
// So static causes the resulting linked executable to be bloated with multiple copies of the same function.
// - inline is not perfect either as it unwantedly hints the compiler toward inlining the function.
-#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_DEVICE_FUNC
-#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_DEVICE_FUNC inline
+#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS inline
#ifdef NDEBUG
# ifndef EIGEN_NO_DEBUG
@@ -641,14 +624,6 @@ namespace Eigen {
#endif
-#if EIGEN_COMP_MSVC
- // NOTE MSVC often gives C4127 warnings with compiletime if statements. See bug 1362.
- // This workaround is ugly, but it does the job.
-# define EIGEN_CONST_CONDITIONAL(cond) (void)0, cond
-#else
-# define EIGEN_CONST_CONDITIONAL(cond) cond
-#endif
-
//------------------------------------------------------------------------------------------
// Static and dynamic alignment control
//
@@ -878,8 +853,7 @@ namespace Eigen {
typedef typename Eigen::internal::ref_selector<Derived>::type Nested; \
typedef typename Eigen::internal::traits<Derived>::StorageKind StorageKind; \
typedef typename Eigen::internal::traits<Derived>::StorageIndex StorageIndex; \
- enum CompileTimeTraits \
- { RowsAtCompileTime = Eigen::internal::traits<Derived>::RowsAtCompileTime, \
+ enum { RowsAtCompileTime = Eigen::internal::traits<Derived>::RowsAtCompileTime, \
ColsAtCompileTime = Eigen::internal::traits<Derived>::ColsAtCompileTime, \
Flags = Eigen::internal::traits<Derived>::Flags, \
SizeAtCompileTime = Base::SizeAtCompileTime, \
diff --git a/eigen/Eigen/src/Core/util/Memory.h b/eigen/Eigen/src/Core/util/Memory.h
index 7d90534..c634d7e 100644
--- a/eigen/Eigen/src/Core/util/Memory.h
+++ b/eigen/Eigen/src/Core/util/Memory.h
@@ -63,7 +63,7 @@ namespace Eigen {
namespace internal {
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC
inline void throw_std_bad_alloc()
{
#ifdef EIGEN_EXCEPTIONS
@@ -114,7 +114,7 @@ inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t =
void *previous_aligned = static_cast<char *>(original)+previous_offset;
if(aligned!=previous_aligned)
std::memmove(aligned, previous_aligned, size);
-
+
*(reinterpret_cast<void**>(aligned) - 1) = original;
return aligned;
}
@@ -142,7 +142,7 @@ EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed()
{
eigen_assert(is_malloc_allowed() && "heap allocation is forbidden (EIGEN_RUNTIME_NO_MALLOC is defined and g_is_malloc_allowed is false)");
}
-#else
+#else
EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed()
{}
#endif
@@ -471,8 +471,8 @@ EIGEN_DEVICE_FUNC inline Index first_default_aligned(const Scalar* array, Index
}
/** \internal Returns the smallest integer multiple of \a base and greater or equal to \a size
- */
-template<typename Index>
+ */
+template<typename Index>
inline Index first_multiple(Index size, Index base)
{
return ((size+base-1)/base)*base;
@@ -502,7 +502,7 @@ template<typename T> struct smart_copy_helper<T,false> {
{ std::copy(start, end, target); }
};
-// intelligent memmove. falls back to std::memmove for POD types, uses std::copy otherwise.
+// intelligent memmove. falls back to std::memmove for POD types, uses std::copy otherwise.
template<typename T, bool UseMemmove> struct smart_memmove_helper;
template<typename T> void smart_memmove(const T* start, const T* end, T* target)
@@ -522,15 +522,15 @@ template<typename T> struct smart_memmove_helper<T,true> {
template<typename T> struct smart_memmove_helper<T,false> {
static inline void run(const T* start, const T* end, T* target)
- {
+ {
if (UIntPtr(target) < UIntPtr(start))
{
std::copy(start, end, target);
}
- else
+ else
{
std::ptrdiff_t count = (std::ptrdiff_t(end)-std::ptrdiff_t(start)) / sizeof(T);
- std::copy_backward(start, end, target + count);
+ std::copy_backward(start, end, target + count);
}
}
};
@@ -603,7 +603,7 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
{
std::swap(a.ptr(),b.ptr());
}
-
+
} // end namespace internal
/** \internal
@@ -622,7 +622,7 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
* The underlying stack allocation function can controlled with the EIGEN_ALLOCA preprocessor token.
*/
#ifdef EIGEN_ALLOCA
-
+
#if EIGEN_DEFAULT_ALIGN_BYTES>0
// We always manually re-align the result of EIGEN_ALLOCA.
// If alloca is already aligned, the compiler should be smart enough to optimize away the re-alignment.
@@ -645,7 +645,7 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
Eigen::internal::check_size_for_overflow<TYPE>(SIZE); \
TYPE* NAME = (BUFFER)!=0 ? BUFFER : reinterpret_cast<TYPE*>(Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE)); \
Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,true)
-
+
#endif
@@ -701,7 +701,7 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
* Example:
* \code
* // Matrix4f requires 16 bytes alignment:
-* std::map< int, Matrix4f, std::less<int>,
+* std::map< int, Matrix4f, std::less<int>,
* aligned_allocator<std::pair<const int, Matrix4f> > > my_map_mat4;
* // Vector3f does not require 16 bytes alignment, no need to use Eigen's allocator:
* std::map< int, Vector3f > my_map_vec3;
diff --git a/eigen/Eigen/src/Core/util/Meta.h b/eigen/Eigen/src/Core/util/Meta.h
index 8de6055..7f63707 100644
--- a/eigen/Eigen/src/Core/util/Meta.h
+++ b/eigen/Eigen/src/Core/util/Meta.h
@@ -97,22 +97,17 @@ 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 }; };
-#if EIGEN_HAS_CXX11
-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 }; };
-#endif
-
+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 }; };
template <typename T> struct add_const { typedef const T type; };
template <typename T> struct add_const<T&> { typedef T& type; };
@@ -284,59 +279,6 @@ protected:
};
/** \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
@@ -433,10 +375,10 @@ struct meta_no { char a[2]; };
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(...);
+ template <typename C> static meta_yes testFunctor(typename C::ReturnType const *);
+ template <typename C> static meta_no testFunctor(...);
- enum { value = sizeof(testFunctor<T>(static_cast<T*>(0))) == sizeof(meta_yes) };
+ enum { value = sizeof(testFunctor<T>(0)) == sizeof(meta_yes) };
};
template<typename T> const T* return_ptr();
diff --git a/eigen/Eigen/src/Core/util/SymbolicIndex.h b/eigen/Eigen/src/Core/util/SymbolicIndex.h
deleted file mode 100644
index bb6349e..0000000
--- a/eigen/Eigen/src/Core/util/SymbolicIndex.h
+++ /dev/null
@@ -1,300 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2017 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/.
-
-#ifndef EIGEN_SYMBOLIC_INDEX_H
-#define EIGEN_SYMBOLIC_INDEX_H
-
-namespace Eigen {
-
-/** \namespace Eigen::Symbolic
- * \ingroup Core_Module
- *
- * This namespace defines a set of classes and functions to build and evaluate symbolic expressions of scalar type Index.
- * Here is a simple example:
- *
- * \code
- * // First step, defines symbols:
- * struct x_tag {}; static const Symbolic::SymbolExpr<x_tag> x;
- * struct y_tag {}; static const Symbolic::SymbolExpr<y_tag> y;
- * struct z_tag {}; static const Symbolic::SymbolExpr<z_tag> z;
- *
- * // Defines an expression:
- * auto expr = (x+3)/y+z;
- *
- * // And evaluate it: (c++14)
- * std::cout << expr.eval(x=6,y=3,z=-13) << "\n";
- *
- * // In c++98/11, only one symbol per expression is supported for now:
- * auto expr98 = (3-x)/2;
- * std::cout << expr98.eval(x=6) << "\n";
- * \endcode
- *
- * It is currently only used internally to define and minipulate the placeholders::last and placeholders::end symbols in Eigen::seq and Eigen::seqN.
- *
- */
-namespace Symbolic {
-
-template<typename Tag> class Symbol;
-template<typename Arg0> class NegateExpr;
-template<typename Arg1,typename Arg2> class AddExpr;
-template<typename Arg1,typename Arg2> class ProductExpr;
-template<typename Arg1,typename Arg2> class QuotientExpr;
-
-// A simple wrapper around an integral value to provide the eval method.
-// We could also use a free-function symbolic_eval...
-template<typename IndexType=Index>
-class ValueExpr {
-public:
- ValueExpr(IndexType val) : m_value(val) {}
- template<typename T>
- IndexType eval_impl(const T&) const { return m_value; }
-protected:
- IndexType m_value;
-};
-
-// Specialization for compile-time value,
-// It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
-template<int N>
-class ValueExpr<internal::FixedInt<N> > {
-public:
- ValueExpr() {}
- template<typename T>
- Index eval_impl(const T&) const { return N; }
-};
-
-
-/** \class BaseExpr
- * \ingroup Core_Module
- * Common base class of any symbolic expressions
- */
-template<typename Derived>
-class BaseExpr
-{
-public:
- const Derived& derived() const { return *static_cast<const Derived*>(this); }
-
- /** Evaluate the expression given the \a values of the symbols.
- *
- * \param values defines the values of the symbols, it can either be a SymbolValue or a std::tuple of SymbolValue
- * as constructed by SymbolExpr::operator= operator.
- *
- */
- template<typename T>
- Index eval(const T& values) const { return derived().eval_impl(values); }
-
-#if EIGEN_HAS_CXX14
- template<typename... Types>
- Index eval(Types&&... values) const { return derived().eval_impl(std::make_tuple(values...)); }
-#endif
-
- NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); }
-
- AddExpr<Derived,ValueExpr<> > operator+(Index b) const
- { return AddExpr<Derived,ValueExpr<> >(derived(), b); }
- AddExpr<Derived,ValueExpr<> > operator-(Index a) const
- { return AddExpr<Derived,ValueExpr<> >(derived(), -a); }
- ProductExpr<Derived,ValueExpr<> > operator*(Index a) const
- { return ProductExpr<Derived,ValueExpr<> >(derived(),a); }
- QuotientExpr<Derived,ValueExpr<> > operator/(Index a) const
- { return QuotientExpr<Derived,ValueExpr<> >(derived(),a); }
-
- friend AddExpr<Derived,ValueExpr<> > operator+(Index a, const BaseExpr& b)
- { return AddExpr<Derived,ValueExpr<> >(b.derived(), a); }
- friend AddExpr<NegateExpr<Derived>,ValueExpr<> > operator-(Index a, const BaseExpr& b)
- { return AddExpr<NegateExpr<Derived>,ValueExpr<> >(-b.derived(), a); }
- friend ProductExpr<ValueExpr<>,Derived> operator*(Index a, const BaseExpr& b)
- { return ProductExpr<ValueExpr<>,Derived>(a,b.derived()); }
- friend QuotientExpr<ValueExpr<>,Derived> operator/(Index a, const BaseExpr& b)
- { return QuotientExpr<ValueExpr<>,Derived>(a,b.derived()); }
-
- template<int N>
- AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>) const
- { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<N> >()); }
- template<int N>
- AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N>) const
- { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
- template<int N>
- ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N>) const
- { return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
- template<int N>
- QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N>) const
- { return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
-
- template<int N>
- friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>, const BaseExpr& b)
- { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); }
- template<int N>
- friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N>, const BaseExpr& b)
- { return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); }
- template<int N>
- friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N>, const BaseExpr& b)
- { return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
- template<int N>
- friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N>, const BaseExpr& b)
- { return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
-
-#if (!EIGEN_HAS_CXX14)
- template<int N>
- AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N> (*)()) const
- { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<N> >()); }
- template<int N>
- AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N> (*)()) const
- { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
- template<int N>
- ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N> (*)()) const
- { return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
- template<int N>
- QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N> (*)()) const
- { return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
-
- template<int N>
- friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N> (*)(), const BaseExpr& b)
- { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); }
- template<int N>
- friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N> (*)(), const BaseExpr& b)
- { return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); }
- template<int N>
- friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N> (*)(), const BaseExpr& b)
- { return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
- template<int N>
- friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N> (*)(), const BaseExpr& b)
- { return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
-#endif
-
-
- template<typename OtherDerived>
- AddExpr<Derived,OtherDerived> operator+(const BaseExpr<OtherDerived> &b) const
- { return AddExpr<Derived,OtherDerived>(derived(), b.derived()); }
-
- template<typename OtherDerived>
- AddExpr<Derived,NegateExpr<OtherDerived> > operator-(const BaseExpr<OtherDerived> &b) const
- { return AddExpr<Derived,NegateExpr<OtherDerived> >(derived(), -b.derived()); }
-
- template<typename OtherDerived>
- ProductExpr<Derived,OtherDerived> operator*(const BaseExpr<OtherDerived> &b) const
- { return ProductExpr<Derived,OtherDerived>(derived(), b.derived()); }
-
- template<typename OtherDerived>
- QuotientExpr<Derived,OtherDerived> operator/(const BaseExpr<OtherDerived> &b) const
- { return QuotientExpr<Derived,OtherDerived>(derived(), b.derived()); }
-};
-
-template<typename T>
-struct is_symbolic {
- // BaseExpr has no conversion ctor, so we only have to check whether T can be staticaly cast to its base class BaseExpr<T>.
- enum { value = internal::is_convertible<T,BaseExpr<T> >::value };
-};
-
-// Specialization for functions, because is_convertible fails in this case.
-// Useful in c++98/11 mode when testing is_symbolic<decltype(fix<N>)>
-template<typename T>
-struct is_symbolic<T (*)()> {
- enum { value = false };
-};
-
-/** Represents the actual value of a symbol identified by its tag
- *
- * It is the return type of SymbolValue::operator=, and most of the time this is only way it is used.
- */
-template<typename Tag>
-class SymbolValue
-{
-public:
- /** Default constructor from the value \a val */
- SymbolValue(Index val) : m_value(val) {}
-
- /** \returns the stored value of the symbol */
- Index value() const { return m_value; }
-protected:
- Index m_value;
-};
-
-/** Expression of a symbol uniquely identified by the template parameter type \c tag */
-template<typename tag>
-class SymbolExpr : public BaseExpr<SymbolExpr<tag> >
-{
-public:
- /** Alias to the template parameter \c tag */
- typedef tag Tag;
-
- SymbolExpr() {}
-
- /** Associate the value \a val to the given symbol \c *this, uniquely identified by its \c Tag.
- *
- * The returned object should be passed to ExprBase::eval() to evaluate a given expression with this specified runtime-time value.
- */
- SymbolValue<Tag> operator=(Index val) const {
- return SymbolValue<Tag>(val);
- }
-
- Index eval_impl(const SymbolValue<Tag> &values) const { return values.value(); }
-
-#if EIGEN_HAS_CXX14
- // C++14 versions suitable for multiple symbols
- template<typename... Types>
- Index eval_impl(const std::tuple<Types...>& values) const { return std::get<SymbolValue<Tag> >(values).value(); }
-#endif
-};
-
-template<typename Arg0>
-class NegateExpr : public BaseExpr<NegateExpr<Arg0> >
-{
-public:
- NegateExpr(const Arg0& arg0) : m_arg0(arg0) {}
-
- template<typename T>
- Index eval_impl(const T& values) const { return -m_arg0.eval_impl(values); }
-protected:
- Arg0 m_arg0;
-};
-
-template<typename Arg0, typename Arg1>
-class AddExpr : public BaseExpr<AddExpr<Arg0,Arg1> >
-{
-public:
- AddExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
-
- template<typename T>
- Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) + m_arg1.eval_impl(values); }
-protected:
- Arg0 m_arg0;
- Arg1 m_arg1;
-};
-
-template<typename Arg0, typename Arg1>
-class ProductExpr : public BaseExpr<ProductExpr<Arg0,Arg1> >
-{
-public:
- ProductExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
-
- template<typename T>
- Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) * m_arg1.eval_impl(values); }
-protected:
- Arg0 m_arg0;
- Arg1 m_arg1;
-};
-
-template<typename Arg0, typename Arg1>
-class QuotientExpr : public BaseExpr<QuotientExpr<Arg0,Arg1> >
-{
-public:
- QuotientExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
-
- template<typename T>
- Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) / m_arg1.eval_impl(values); }
-protected:
- Arg0 m_arg0;
- Arg1 m_arg1;
-};
-
-} // end namespace Symbolic
-
-} // end namespace Eigen
-
-#endif // EIGEN_SYMBOLIC_INDEX_H
diff --git a/eigen/Eigen/src/Core/util/XprHelper.h b/eigen/Eigen/src/Core/util/XprHelper.h
index 4b337f2..ba5bd18 100644
--- a/eigen/Eigen/src/Core/util/XprHelper.h
+++ b/eigen/Eigen/src/Core/util/XprHelper.h
@@ -109,7 +109,6 @@ template<typename T, int Value> class variable_if_dynamic
EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return T(Value); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
};
@@ -120,7 +119,6 @@ template<typename T> class variable_if_dynamic<T, Dynamic>
public:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value) : m_value(value) {}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return m_value; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
};
@@ -673,7 +671,7 @@ bool is_same_dense(const T1 &, const T2 &, typename enable_if<!(has_direct_acces
// Internal helper defining the cost of a scalar division for the type T.
// The default heuristic can be specialized for each scalar type and architecture.
-template<typename T,bool Vectorized=false,typename EnableIf = void>
+template<typename T,bool Vectorized=false,typename EnaleIf = void>
struct scalar_div_cost {
enum { value = 8*NumTraits<T>::MulCost };
};
diff --git a/eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
index dbbd480..4fec8af 100644
--- a/eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
+++ b/eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
@@ -85,7 +85,7 @@ MatrixBase<Derived>::eigenvalues() const
* \sa SelfAdjointEigenSolver::eigenvalues(), MatrixBase::eigenvalues()
*/
template<typename MatrixType, unsigned int UpLo>
-EIGEN_DEVICE_FUNC inline typename SelfAdjointView<MatrixType, UpLo>::EigenvaluesReturnType
+inline typename SelfAdjointView<MatrixType, UpLo>::EigenvaluesReturnType
SelfAdjointView<MatrixType, UpLo>::eigenvalues() const
{
typedef typename SelfAdjointView<MatrixType, UpLo>::PlainObject PlainObject;
@@ -149,7 +149,7 @@ MatrixBase<Derived>::operatorNorm() const
* \sa eigenvalues(), MatrixBase::operatorNorm()
*/
template<typename MatrixType, unsigned int UpLo>
-EIGEN_DEVICE_FUNC inline typename SelfAdjointView<MatrixType, UpLo>::RealScalar
+inline typename SelfAdjointView<MatrixType, UpLo>::RealScalar
SelfAdjointView<MatrixType, UpLo>::operatorNorm() const
{
return eigenvalues().cwiseAbs().maxCoeff();
diff --git a/eigen/Eigen/src/Geometry/AlignedBox.h b/eigen/Eigen/src/Geometry/AlignedBox.h
index c902d8f..066eae4 100644
--- a/eigen/Eigen/src/Geometry/AlignedBox.h
+++ b/eigen/Eigen/src/Geometry/AlignedBox.h
@@ -63,7 +63,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
/** Default constructor initializing a null box. */
EIGEN_DEVICE_FUNC inline AlignedBox()
- { if (EIGEN_CONST_CONDITIONAL(AmbientDimAtCompileTime!=Dynamic)) setEmpty(); }
+ { if (AmbientDimAtCompileTime!=Dynamic) setEmpty(); }
/** Constructs a null box with \a _dim the dimension of the ambient space. */
EIGEN_DEVICE_FUNC inline explicit AlignedBox(Index _dim) : m_min(_dim), m_max(_dim)
diff --git a/eigen/Eigen/src/Geometry/ParametrizedLine.h b/eigen/Eigen/src/Geometry/ParametrizedLine.h
index 3929ca8..1e985d8 100644
--- a/eigen/Eigen/src/Geometry/ParametrizedLine.h
+++ b/eigen/Eigen/src/Geometry/ParametrizedLine.h
@@ -104,44 +104,7 @@ public:
template <int OtherOptions>
EIGEN_DEVICE_FUNC VectorType intersectionPoint(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const;
- /** Applies the transformation matrix \a mat to \c *this and returns a reference to \c *this.
- *
- * \param mat the Dim x Dim transformation matrix
- * \param traits specifies whether the matrix \a mat represents an #Isometry
- * or a more generic #Affine transformation. The default is #Affine.
- */
- template<typename XprType>
- EIGEN_DEVICE_FUNC inline ParametrizedLine& transform(const MatrixBase<XprType>& mat, TransformTraits traits = Affine)
- {
- if (traits==Affine)
- direction() = (mat * direction()).normalized();
- else if (traits==Isometry)
- direction() = mat * direction();
- else
- {
- eigen_assert(0 && "invalid traits value in ParametrizedLine::transform()");
- }
- origin() = mat * origin();
- return *this;
- }
-
- /** Applies the transformation \a t to \c *this and returns a reference to \c *this.
- *
- * \param t the transformation of dimension Dim
- * \param traits specifies whether the transformation \a t represents an #Isometry
- * or a more generic #Affine transformation. The default is #Affine.
- * Other kind of transformations are not supported.
- */
- template<int TrOptions>
- EIGEN_DEVICE_FUNC inline ParametrizedLine& transform(const Transform<Scalar,AmbientDimAtCompileTime,Affine,TrOptions>& t,
- TransformTraits traits = Affine)
- {
- transform(t.linear(), traits);
- origin() += t.translation();
- return *this;
- }
-
-/** \returns \c *this with scalar type casted to \a NewScalarType
+ /** \returns \c *this with scalar type casted to \a NewScalarType
*
* Note that if \a NewScalarType is equal to the current scalar type of \c *this
* then this function smartly returns a const reference to \c *this.
diff --git a/eigen/Eigen/src/Geometry/Quaternion.h b/eigen/Eigen/src/Geometry/Quaternion.h
index f6ef1bc..3e5a9ba 100644
--- a/eigen/Eigen/src/Geometry/Quaternion.h
+++ b/eigen/Eigen/src/Geometry/Quaternion.h
@@ -423,7 +423,7 @@ typedef Map<Quaternion<double>, Aligned> QuaternionMapAlignedd;
// Generic Quaternion * Quaternion product
// This product can be specialized for a given architecture via the Arch template argument.
namespace internal {
-template<int Arch, class Derived1, class Derived2, typename Scalar, int _Options> struct quat_product
+template<int Arch, class Derived1, class Derived2, typename Scalar> struct quat_product
{
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
return Quaternion<Scalar>
@@ -446,8 +446,7 @@ QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) c
EIGEN_STATIC_ASSERT((internal::is_same<typename Derived::Scalar, typename OtherDerived::Scalar>::value),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
return internal::quat_product<Architecture::Target, Derived, OtherDerived,
- typename internal::traits<Derived>::Scalar,
- EIGEN_PLAIN_ENUM_MIN(internal::traits<Derived>::Alignment, internal::traits<OtherDerived>::Alignment)>::run(*this, other);
+ typename internal::traits<Derived>::Scalar>::run(*this, other);
}
/** \sa operator*(Quaternion) */
@@ -672,7 +671,7 @@ EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar>
// Generic conjugate of a Quaternion
namespace internal {
-template<int Arch, class Derived, typename Scalar, int _Options> struct quat_conj
+template<int Arch, class Derived, typename Scalar> struct quat_conj
{
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived>& q){
return Quaternion<Scalar>(q.w(),-q.x(),-q.y(),-q.z());
@@ -691,8 +690,7 @@ EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar>
QuaternionBase<Derived>::conjugate() const
{
return internal::quat_conj<Architecture::Target, Derived,
- typename internal::traits<Derived>::Scalar,
- internal::traits<Derived>::Alignment>::run(*this);
+ typename internal::traits<Derived>::Scalar>::run(*this);
}
diff --git a/eigen/Eigen/src/Geometry/Transform.h b/eigen/Eigen/src/Geometry/Transform.h
index 2d36dfa..3f31ee4 100644
--- a/eigen/Eigen/src/Geometry/Transform.h
+++ b/eigen/Eigen/src/Geometry/Transform.h
@@ -335,7 +335,7 @@ public:
OtherModeIsAffineCompact = OtherMode == int(AffineCompact)
};
- if(EIGEN_CONST_CONDITIONAL(ModeIsAffineCompact == OtherModeIsAffineCompact))
+ if(ModeIsAffineCompact == OtherModeIsAffineCompact)
{
// We need the block expression because the code is compiled for all
// combinations of transformations and will trigger a compile time error
@@ -343,7 +343,7 @@ public:
m_matrix.template block<Dim,Dim+1>(0,0) = other.matrix().template block<Dim,Dim+1>(0,0);
makeAffine();
}
- else if(EIGEN_CONST_CONDITIONAL(OtherModeIsAffineCompact))
+ else if(OtherModeIsAffineCompact)
{
typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType;
internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix());
@@ -481,7 +481,7 @@ public:
TransformTimeDiagonalReturnType res;
res.linear().noalias() = a*b.linear();
res.translation().noalias() = a*b.translation();
- if (EIGEN_CONST_CONDITIONAL(Mode!=int(AffineCompact)))
+ if (Mode!=int(AffineCompact))
res.matrix().row(Dim) = b.matrix().row(Dim);
return res;
}
@@ -755,7 +755,7 @@ template<typename Scalar, int Dim, int Mode,int Options>
Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other)
{
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
- if (EIGEN_CONST_CONDITIONAL(Mode == int(AffineCompact)))
+ if (Mode == int(AffineCompact))
m_matrix << other.m11(), other.m21(), other.dx(),
other.m12(), other.m22(), other.dy();
else
@@ -801,7 +801,7 @@ Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator
{
check_template_params();
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
- if (EIGEN_CONST_CONDITIONAL(Mode == int(AffineCompact)))
+ if (Mode == int(AffineCompact))
m_matrix << other.m11(), other.m21(), other.dx(),
other.m12(), other.m22(), other.dy();
else
@@ -819,7 +819,7 @@ template<typename Scalar, int Dim, int Mode, int Options>
QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const
{
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
- if (EIGEN_CONST_CONDITIONAL(Mode == int(AffineCompact)))
+ if (Mode == int(AffineCompact))
return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
m_matrix.coeff(0,1), m_matrix.coeff(1,1),
m_matrix.coeff(0,2), m_matrix.coeff(1,2));
@@ -912,7 +912,7 @@ EIGEN_DEVICE_FUNC Transform<Scalar,Dim,Mode,Options>&
Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other)
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim))
- if(EIGEN_CONST_CONDITIONAL(int(Mode)==int(Projective)))
+ if(int(Mode)==int(Projective))
affine() += other * m_matrix.row(Dim);
else
translation() += other;
diff --git a/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h b/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h
index 1a86ff8..f68cab5 100644
--- a/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h
+++ b/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h
@@ -16,17 +16,23 @@ namespace Eigen {
namespace internal {
template<class Derived, class OtherDerived>
-struct quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned16>
+struct quat_product<Architecture::SSE, Derived, OtherDerived, float>
{
+ enum {
+ AAlignment = traits<Derived>::Alignment,
+ BAlignment = traits<OtherDerived>::Alignment,
+ ResAlignment = traits<Quaternion<float> >::Alignment
+ };
static inline Quaternion<float> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
{
Quaternion<float> res;
const __m128 mask = _mm_setr_ps(0.f,0.f,0.f,-0.f);
- __m128 a = _a.coeffs().template packet<Aligned16>(0);
- __m128 b = _b.coeffs().template packet<Aligned16>(0);
+ __m128 a = _a.coeffs().template packet<AAlignment>(0);
+ __m128 b = _b.coeffs().template packet<BAlignment>(0);
__m128 s1 = _mm_mul_ps(vec4f_swizzle1(a,1,2,0,2),vec4f_swizzle1(b,2,0,1,2));
__m128 s2 = _mm_mul_ps(vec4f_swizzle1(a,3,3,3,1),vec4f_swizzle1(b,0,1,2,1));
- pstore(&res.x(),
+ pstoret<float,Packet4f,ResAlignment>(
+ &res.x(),
_mm_add_ps(_mm_sub_ps(_mm_mul_ps(a,vec4f_swizzle1(b,3,3,3,3)),
_mm_mul_ps(vec4f_swizzle1(a,2,0,1,0),
vec4f_swizzle1(b,1,2,0,0))),
@@ -36,14 +42,17 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned16>
}
};
-template<class Derived, int Alignment>
-struct quat_conj<Architecture::SSE, Derived, float, Alignment>
+template<class Derived>
+struct quat_conj<Architecture::SSE, Derived, float>
{
+ enum {
+ ResAlignment = traits<Quaternion<float> >::Alignment
+ };
static inline Quaternion<float> run(const QuaternionBase<Derived>& q)
{
Quaternion<float> res;
const __m128 mask = _mm_setr_ps(-0.f,-0.f,-0.f,0.f);
- pstore(&res.x(), _mm_xor_ps(mask, q.coeffs().template packet<Alignment>(0)));
+ pstoret<float,Packet4f,ResAlignment>(&res.x(), _mm_xor_ps(mask, q.coeffs().template packet<traits<Derived>::Alignment>(0)));
return res;
}
};
@@ -52,6 +61,9 @@ struct quat_conj<Architecture::SSE, Derived, float, Alignment>
template<typename VectorLhs,typename VectorRhs>
struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
{
+ enum {
+ ResAlignment = traits<typename plain_matrix_type<VectorLhs>::type>::Alignment
+ };
static inline typename plain_matrix_type<VectorLhs>::type
run(const VectorLhs& lhs, const VectorRhs& rhs)
{
@@ -60,7 +72,7 @@ struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
__m128 mul1=_mm_mul_ps(vec4f_swizzle1(a,1,2,0,3),vec4f_swizzle1(b,2,0,1,3));
__m128 mul2=_mm_mul_ps(vec4f_swizzle1(a,2,0,1,3),vec4f_swizzle1(b,1,2,0,3));
typename plain_matrix_type<VectorLhs>::type res;
- pstore(&res.x(),_mm_sub_ps(mul1,mul2));
+ pstoret<float,Packet4f,ResAlignment>(&res.x(),_mm_sub_ps(mul1,mul2));
return res;
}
};
@@ -68,9 +80,14 @@ struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
-template<class Derived, class OtherDerived, int Alignment>
-struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
+template<class Derived, class OtherDerived>
+struct quat_product<Architecture::SSE, Derived, OtherDerived, double>
{
+ enum {
+ BAlignment = traits<OtherDerived>::Alignment,
+ ResAlignment = traits<Quaternion<double> >::Alignment
+ };
+
static inline Quaternion<double> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
{
const Packet2d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0));
@@ -78,8 +95,8 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
Quaternion<double> res;
const double* a = _a.coeffs().data();
- Packet2d b_xy = _b.coeffs().template packet<Alignment>(0);
- Packet2d b_zw = _b.coeffs().template packet<Alignment>(2);
+ Packet2d b_xy = _b.coeffs().template packet<BAlignment>(0);
+ Packet2d b_zw = _b.coeffs().template packet<BAlignment>(2);
Packet2d a_xx = pset1<Packet2d>(a[0]);
Packet2d a_yy = pset1<Packet2d>(a[1]);
Packet2d a_zz = pset1<Packet2d>(a[2]);
@@ -97,9 +114,9 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
t2 = psub(pmul(a_zz, b_xy), pmul(a_xx, b_zw));
#ifdef EIGEN_VECTORIZE_SSE3
EIGEN_UNUSED_VARIABLE(mask)
- pstore(&res.x(), _mm_addsub_pd(t1, preverse(t2)));
+ pstoret<double,Packet2d,ResAlignment>(&res.x(), _mm_addsub_pd(t1, preverse(t2)));
#else
- pstore(&res.x(), padd(t1, pxor(mask,preverse(t2))));
+ pstoret<double,Packet2d,ResAlignment>(&res.x(), padd(t1, pxor(mask,preverse(t2))));
#endif
/*
@@ -111,25 +128,28 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
t2 = padd(pmul(a_zz, b_zw), pmul(a_xx, b_xy));
#ifdef EIGEN_VECTORIZE_SSE3
EIGEN_UNUSED_VARIABLE(mask)
- pstore(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2)));
+ pstoret<double,Packet2d,ResAlignment>(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2)));
#else
- pstore(&res.z(), psub(t1, pxor(mask,preverse(t2))));
+ pstoret<double,Packet2d,ResAlignment>(&res.z(), psub(t1, pxor(mask,preverse(t2))));
#endif
return res;
}
};
-template<class Derived, int Alignment>
-struct quat_conj<Architecture::SSE, Derived, double, Alignment>
+template<class Derived>
+struct quat_conj<Architecture::SSE, Derived, double>
{
+ enum {
+ ResAlignment = traits<Quaternion<double> >::Alignment
+ };
static inline Quaternion<double> run(const QuaternionBase<Derived>& q)
{
Quaternion<double> res;
const __m128d mask0 = _mm_setr_pd(-0.,-0.);
const __m128d mask2 = _mm_setr_pd(-0.,0.);
- pstore(&res.x(), _mm_xor_pd(mask0, q.coeffs().template packet<Alignment>(0)));
- pstore(&res.z(), _mm_xor_pd(mask2, q.coeffs().template packet<Alignment>(2)));
+ pstoret<double,Packet2d,ResAlignment>(&res.x(), _mm_xor_pd(mask0, q.coeffs().template packet<traits<Derived>::Alignment>(0)));
+ pstoret<double,Packet2d,ResAlignment>(&res.z(), _mm_xor_pd(mask2, q.coeffs().template packet<traits<Derived>::Alignment>(2)));
return res;
}
};
diff --git a/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
index 358444a..facdaf8 100644
--- a/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
+++ b/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
@@ -152,13 +152,28 @@ class LeastSquareDiagonalPreconditioner : public DiagonalPreconditioner<_Scalar>
{
// Compute the inverse squared-norm of each column of mat
m_invdiag.resize(mat.cols());
- for(Index j=0; j<mat.outerSize(); ++j)
+ if(MatType::IsRowMajor)
{
- RealScalar sum = mat.innerVector(j).squaredNorm();
- if(sum>0)
- m_invdiag(j) = RealScalar(1)/sum;
- else
- m_invdiag(j) = RealScalar(1);
+ m_invdiag.setZero();
+ for(Index j=0; j<mat.outerSize(); ++j)
+ {
+ for(typename MatType::InnerIterator it(mat,j); it; ++it)
+ m_invdiag(it.index()) += numext::abs2(it.value());
+ }
+ for(Index j=0; j<mat.cols(); ++j)
+ if(numext::real(m_invdiag(j))>RealScalar(0))
+ m_invdiag(j) = RealScalar(1)/numext::real(m_invdiag(j));
+ }
+ else
+ {
+ for(Index j=0; j<mat.outerSize(); ++j)
+ {
+ RealScalar sum = mat.innerVector(j).squaredNorm();
+ if(sum>RealScalar(0))
+ m_invdiag(j) = RealScalar(1)/sum;
+ else
+ m_invdiag(j) = RealScalar(1);
+ }
}
Base::m_isInitialized = true;
return *this;
diff --git a/eigen/Eigen/src/Jacobi/Jacobi.h b/eigen/Eigen/src/Jacobi/Jacobi.h
index d25af8e..c30326e 100644
--- a/eigen/Eigen/src/Jacobi/Jacobi.h
+++ b/eigen/Eigen/src/Jacobi/Jacobi.h
@@ -302,8 +302,12 @@ template<typename VectorX, typename VectorY, typename OtherScalar>
void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x, DenseBase<VectorY>& xpr_y, const JacobiRotation<OtherScalar>& j)
{
typedef typename VectorX::Scalar Scalar;
- enum { PacketSize = packet_traits<Scalar>::size };
+ enum {
+ PacketSize = packet_traits<Scalar>::size,
+ OtherPacketSize = packet_traits<OtherScalar>::size
+ };
typedef typename packet_traits<Scalar>::type Packet;
+ typedef typename packet_traits<OtherScalar>::type OtherPacket;
eigen_assert(xpr_x.size() == xpr_y.size());
Index size = xpr_x.size();
Index incrx = xpr_x.derived().innerStride();
@@ -321,6 +325,7 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
if(VectorX::SizeAtCompileTime == Dynamic &&
(VectorX::Flags & VectorY::Flags & PacketAccessBit) &&
+ (PacketSize == OtherPacketSize) &&
((incrx==1 && incry==1) || PacketSize == 1))
{
// both vectors are sequentially stored in memory => vectorization
@@ -329,9 +334,10 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
Index alignedStart = internal::first_default_aligned(y, size);
Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize;
- const Packet pc = pset1<Packet>(c);
- const Packet ps = pset1<Packet>(s);
- conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex,false> pcj;
+ const OtherPacket pc = pset1<OtherPacket>(c);
+ const OtherPacket ps = pset1<OtherPacket>(s);
+ conj_helper<OtherPacket,Packet,NumTraits<OtherScalar>::IsComplex,false> pcj;
+ conj_helper<OtherPacket,Packet,false,false> pm;
for(Index i=0; i<alignedStart; ++i)
{
@@ -350,8 +356,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
{
Packet xi = pload<Packet>(px);
Packet yi = pload<Packet>(py);
- pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
- pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
+ pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
+ pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
px += PacketSize;
py += PacketSize;
}
@@ -365,10 +371,10 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
Packet xi1 = ploadu<Packet>(px+PacketSize);
Packet yi = pload <Packet>(py);
Packet yi1 = pload <Packet>(py+PacketSize);
- pstoreu(px, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
- pstoreu(px+PacketSize, padd(pmul(pc,xi1),pcj.pmul(ps,yi1)));
- pstore (py, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
- pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pmul(ps,xi1)));
+ pstoreu(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
+ pstoreu(px+PacketSize, padd(pm.pmul(pc,xi1),pcj.pmul(ps,yi1)));
+ pstore (py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
+ pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pm.pmul(ps,xi1)));
px += Peeling*PacketSize;
py += Peeling*PacketSize;
}
@@ -376,8 +382,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
{
Packet xi = ploadu<Packet>(x+peelingEnd);
Packet yi = pload <Packet>(y+peelingEnd);
- pstoreu(x+peelingEnd, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
- pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
+ pstoreu(x+peelingEnd, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
+ pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
}
}
@@ -393,19 +399,21 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
/*** fixed-size vectorized path ***/
else if(VectorX::SizeAtCompileTime != Dynamic &&
(VectorX::Flags & VectorY::Flags & PacketAccessBit) &&
+ (PacketSize == OtherPacketSize) &&
(EIGEN_PLAIN_ENUM_MIN(evaluator<VectorX>::Alignment, evaluator<VectorY>::Alignment)>0)) // FIXME should be compared to the required alignment
{
- const Packet pc = pset1<Packet>(c);
- const Packet ps = pset1<Packet>(s);
- conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex,false> pcj;
+ const OtherPacket pc = pset1<OtherPacket>(c);
+ const OtherPacket ps = pset1<OtherPacket>(s);
+ conj_helper<OtherPacket,Packet,NumTraits<OtherPacket>::IsComplex,false> pcj;
+ conj_helper<OtherPacket,Packet,false,false> pm;
Scalar* EIGEN_RESTRICT px = x;
Scalar* EIGEN_RESTRICT py = y;
for(Index i=0; i<size; i+=PacketSize)
{
Packet xi = pload<Packet>(px);
Packet yi = pload<Packet>(py);
- pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
- pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
+ pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
+ pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
px += PacketSize;
py += PacketSize;
}
diff --git a/eigen/Eigen/src/LU/FullPivLU.h b/eigen/Eigen/src/LU/FullPivLU.h
index ec61086..03b6af7 100644
--- a/eigen/Eigen/src/LU/FullPivLU.h
+++ b/eigen/Eigen/src/LU/FullPivLU.h
@@ -411,9 +411,11 @@ template<typename _MatrixType> class FullPivLU
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename RhsType, typename DstType>
+ EIGEN_DEVICE_FUNC
void _solve_impl(const RhsType &rhs, DstType &dst) const;
template<bool Conjugate, typename RhsType, typename DstType>
+ EIGEN_DEVICE_FUNC
void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
#endif
diff --git a/eigen/Eigen/src/QR/ColPivHouseholderQR.h b/eigen/Eigen/src/QR/ColPivHouseholderQR.h
index d35395d..a7b47d5 100644
--- a/eigen/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/eigen/Eigen/src/QR/ColPivHouseholderQR.h
@@ -416,6 +416,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename RhsType, typename DstType>
+ EIGEN_DEVICE_FUNC
void _solve_impl(const RhsType &rhs, DstType &dst) const;
#endif
@@ -505,8 +506,8 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
m_colNormsUpdated.coeffRef(k) = m_colNormsDirect.coeffRef(k);
}
- RealScalar threshold_helper = numext::abs2<Scalar>(m_colNormsUpdated.maxCoeff() * NumTraits<Scalar>::epsilon()) / RealScalar(rows);
- RealScalar norm_downdate_threshold = numext::sqrt(NumTraits<Scalar>::epsilon());
+ RealScalar threshold_helper = numext::abs2<RealScalar>(m_colNormsUpdated.maxCoeff() * NumTraits<RealScalar>::epsilon()) / RealScalar(rows);
+ RealScalar norm_downdate_threshold = numext::sqrt(NumTraits<RealScalar>::epsilon());
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
m_maxpivot = RealScalar(0);
@@ -552,12 +553,12 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
// http://www.netlib.org/lapack/lawnspdf/lawn176.pdf
// and used in LAPACK routines xGEQPF and xGEQP3.
// See lines 278-297 in http://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html
- if (m_colNormsUpdated.coeffRef(j) != 0) {
+ if (m_colNormsUpdated.coeffRef(j) != RealScalar(0)) {
RealScalar temp = abs(m_qr.coeffRef(k, j)) / m_colNormsUpdated.coeffRef(j);
temp = (RealScalar(1) + temp) * (RealScalar(1) - temp);
- temp = temp < 0 ? 0 : temp;
- RealScalar temp2 = temp * numext::abs2<Scalar>(m_colNormsUpdated.coeffRef(j) /
- m_colNormsDirect.coeffRef(j));
+ temp = temp < RealScalar(0) ? RealScalar(0) : temp;
+ RealScalar temp2 = temp * numext::abs2<RealScalar>(m_colNormsUpdated.coeffRef(j) /
+ m_colNormsDirect.coeffRef(j));
if (temp2 <= norm_downdate_threshold) {
// The updated norm has become too inaccurate so re-compute the column
// norm directly.
diff --git a/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h b/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h
index 13b61fc..34c637b 100644
--- a/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h
+++ b/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h
@@ -367,7 +367,7 @@ class CompleteOrthogonalDecomposition {
#ifndef EIGEN_PARSED_BY_DOXYGEN
template <typename RhsType, typename DstType>
- void _solve_impl(const RhsType& rhs, DstType& dst) const;
+ EIGEN_DEVICE_FUNC void _solve_impl(const RhsType& rhs, DstType& dst) const;
#endif
protected:
diff --git a/eigen/Eigen/src/QR/FullPivHouseholderQR.h b/eigen/Eigen/src/QR/FullPivHouseholderQR.h
index c31e47c..e489bdd 100644
--- a/eigen/Eigen/src/QR/FullPivHouseholderQR.h
+++ b/eigen/Eigen/src/QR/FullPivHouseholderQR.h
@@ -392,21 +392,22 @@ template<typename _MatrixType> class FullPivHouseholderQR
* diagonal coefficient of U.
*/
RealScalar maxPivot() const { return m_maxpivot; }
-
+
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename RhsType, typename DstType>
+ EIGEN_DEVICE_FUNC
void _solve_impl(const RhsType &rhs, DstType &dst) const;
#endif
protected:
-
+
static void check_template_parameters()
{
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
}
-
+
void computeInPlace();
-
+
MatrixType m_qr;
HCoeffsType m_hCoeffs;
IntDiagSizeVectorType m_rows_transpositions;
diff --git a/eigen/Eigen/src/QR/HouseholderQR.h b/eigen/Eigen/src/QR/HouseholderQR.h
index 762b21c..3513d99 100644
--- a/eigen/Eigen/src/QR/HouseholderQR.h
+++ b/eigen/Eigen/src/QR/HouseholderQR.h
@@ -204,27 +204,28 @@ template<typename _MatrixType> class HouseholderQR
inline Index rows() const { return m_qr.rows(); }
inline Index cols() const { return m_qr.cols(); }
-
+
/** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
*
* For advanced uses only.
*/
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
-
+
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename RhsType, typename DstType>
+ EIGEN_DEVICE_FUNC
void _solve_impl(const RhsType &rhs, DstType &dst) const;
#endif
protected:
-
+
static void check_template_parameters()
{
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
}
void computeInPlace();
-
+
MatrixType m_qr;
HCoeffsType m_hCoeffs;
RowVectorType m_temp;
diff --git a/eigen/Eigen/src/SVD/BDCSVD.h b/eigen/Eigen/src/SVD/BDCSVD.h
index 25fca6f..d7a4271 100644
--- a/eigen/Eigen/src/SVD/BDCSVD.h
+++ b/eigen/Eigen/src/SVD/BDCSVD.h
@@ -77,6 +77,7 @@ public:
typedef _MatrixType MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef typename NumTraits<RealScalar>::Literal Literal;
enum {
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
@@ -259,7 +260,7 @@ BDCSVD<MatrixType>& BDCSVD<MatrixType>::compute(const MatrixType& matrix, unsign
//**** step 0 - Copy the input matrix and apply scaling to reduce over/under-flows
RealScalar scale = matrix.cwiseAbs().maxCoeff();
- if(scale==RealScalar(0)) scale = RealScalar(1);
+ if(scale==Literal(0)) scale = Literal(1);
MatrixX copy;
if (m_isTranspose) copy = matrix.adjoint()/scale;
else copy = matrix/scale;
@@ -351,13 +352,13 @@ void BDCSVD<MatrixType>::structured_update(Block<MatrixXr,Dynamic,Dynamic> A, co
Index k1=0, k2=0;
for(Index j=0; j<n; ++j)
{
- if( (A.col(j).head(n1).array()!=0).any() )
+ if( (A.col(j).head(n1).array()!=Literal(0)).any() )
{
A1.col(k1) = A.col(j).head(n1);
B1.row(k1) = B.row(j);
++k1;
}
- if( (A.col(j).tail(n2).array()!=0).any() )
+ if( (A.col(j).tail(n2).array()!=Literal(0)).any() )
{
A2.col(k2) = A.col(j).tail(n2);
B2.row(k2) = B.row(j);
@@ -449,11 +450,11 @@ void BDCSVD<MatrixType>::divide (Index firstCol, Index lastCol, Index firstRowW,
l = m_naiveU.row(1).segment(firstCol, k);
f = m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1);
}
- if (m_compV) m_naiveV(firstRowW+k, firstColW) = 1;
+ if (m_compV) m_naiveV(firstRowW+k, firstColW) = Literal(1);
if (r0<considerZero)
{
- c0 = 1;
- s0 = 0;
+ c0 = Literal(1);
+ s0 = Literal(0);
}
else
{
@@ -574,7 +575,7 @@ void BDCSVD<MatrixType>::computeSVDofM(Index firstCol, Index n, MatrixXr& U, Vec
ArrayRef col0 = m_computed.col(firstCol).segment(firstCol, n);
m_workspace.head(n) = m_computed.block(firstCol, firstCol, n, n).diagonal();
ArrayRef diag = m_workspace.head(n);
- diag(0) = 0;
+ diag(0) = Literal(0);
// Allocate space for singular values and vectors
singVals.resize(n);
@@ -590,7 +591,7 @@ void BDCSVD<MatrixType>::computeSVDofM(Index firstCol, Index n, MatrixXr& U, Vec
// but others are interleaved and we must ignore them at this stage.
// To this end, let's compute a permutation skipping them:
Index actual_n = n;
- while(actual_n>1 && diag(actual_n-1)==0) --actual_n;
+ while(actual_n>1 && diag(actual_n-1)==Literal(0)) --actual_n;
Index m = 0; // size of the deflated problem
for(Index k=0;k<actual_n;++k)
if(abs(col0(k))>considerZero)
@@ -691,7 +692,7 @@ template <typename MatrixType>
typename BDCSVD<MatrixType>::RealScalar BDCSVD<MatrixType>::secularEq(RealScalar mu, const ArrayRef& col0, const ArrayRef& diag, const IndicesRef &perm, const ArrayRef& diagShifted, RealScalar shift)
{
Index m = perm.size();
- RealScalar res = 1;
+ RealScalar res = Literal(1);
for(Index i=0; i<m; ++i)
{
Index j = perm(i);
@@ -710,16 +711,16 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
Index n = col0.size();
Index actual_n = n;
- while(actual_n>1 && col0(actual_n-1)==0) --actual_n;
+ while(actual_n>1 && col0(actual_n-1)==Literal(0)) --actual_n;
for (Index k = 0; k < n; ++k)
{
- if (col0(k) == 0 || actual_n==1)
+ if (col0(k) == Literal(0) || actual_n==1)
{
// if col0(k) == 0, then entry is deflated, so singular value is on diagonal
// if actual_n==1, then the deflated problem is already diagonalized
singVals(k) = k==0 ? col0(0) : diag(k);
- mus(k) = 0;
+ mus(k) = Literal(0);
shifts(k) = k==0 ? col0(0) : diag(k);
continue;
}
@@ -733,13 +734,13 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
{
// Skip deflated singular values
Index l = k+1;
- while(col0(l)==0) { ++l; eigen_internal_assert(l<actual_n); }
+ while(col0(l)==Literal(0)) { ++l; eigen_internal_assert(l<actual_n); }
right = diag(l);
}
// first decide whether it's closer to the left end or the right end
- RealScalar mid = left + (right-left) / 2;
- RealScalar fMid = secularEq(mid, col0, diag, perm, diag, 0);
+ RealScalar mid = left + (right-left) / Literal(2);
+ RealScalar fMid = secularEq(mid, col0, diag, perm, diag, Literal(0));
#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
std::cout << right-left << "\n";
std::cout << "fMid = " << fMid << " " << secularEq(mid-left, col0, diag, perm, diag-left, left) << " " << secularEq(mid-right, col0, diag, perm, diag-right, right) << "\n";
@@ -755,7 +756,7 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
<< " " << secularEq(0.8*(left+right), col0, diag, perm, diag, 0)
<< " " << secularEq(0.9*(left+right), col0, diag, perm, diag, 0) << "\n";
#endif
- RealScalar shift = (k == actual_n-1 || fMid > 0) ? left : right;
+ RealScalar shift = (k == actual_n-1 || fMid > Literal(0)) ? left : right;
// measure everything relative to shift
Map<ArrayXr> diagShifted(m_workspace.data()+4*n, n);
@@ -785,13 +786,13 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
// rational interpolation: fit a function of the form a / mu + b through the two previous
// iterates and use its zero to compute the next iterate
- bool useBisection = fPrev*fCur>0;
- while (fCur!=0 && abs(muCur - muPrev) > 8 * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(muCur), abs(muPrev)) && abs(fCur - fPrev)>NumTraits<RealScalar>::epsilon() && !useBisection)
+ bool useBisection = fPrev*fCur>Literal(0);
+ while (fCur!=Literal(0) && abs(muCur - muPrev) > Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(muCur), abs(muPrev)) && abs(fCur - fPrev)>NumTraits<RealScalar>::epsilon() && !useBisection)
{
++m_numIters;
// Find a and b such that the function f(mu) = a / mu + b matches the current and previous samples.
- RealScalar a = (fCur - fPrev) / (1/muCur - 1/muPrev);
+ RealScalar a = (fCur - fPrev) / (Literal(1)/muCur - Literal(1)/muPrev);
RealScalar b = fCur - a / muCur;
// And find mu such that f(mu)==0:
RealScalar muZero = -a/b;
@@ -803,8 +804,8 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
fCur = fZero;
- if (shift == left && (muCur < 0 || muCur > right - left)) useBisection = true;
- if (shift == right && (muCur < -(right - left) || muCur > 0)) useBisection = true;
+ if (shift == left && (muCur < Literal(0) || muCur > right - left)) useBisection = true;
+ if (shift == right && (muCur < -(right - left) || muCur > Literal(0))) useBisection = true;
if (abs(fCur)>abs(fPrev)) useBisection = true;
}
@@ -841,13 +842,13 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
std::cout << k << " : " << fLeft << " * " << fRight << " == " << fLeft * fRight << " ; " << left << " - " << right << " -> " << leftShifted << " " << rightShifted << " shift=" << shift << "\n";
}
#endif
- eigen_internal_assert(fLeft * fRight < 0);
+ eigen_internal_assert(fLeft * fRight < Literal(0));
- while (rightShifted - leftShifted > 2 * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(leftShifted), abs(rightShifted)))
+ while (rightShifted - leftShifted > Literal(2) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(leftShifted), abs(rightShifted)))
{
- RealScalar midShifted = (leftShifted + rightShifted) / 2;
+ RealScalar midShifted = (leftShifted + rightShifted) / Literal(2);
fMid = secularEq(midShifted, col0, diag, perm, diagShifted, shift);
- if (fLeft * fMid < 0)
+ if (fLeft * fMid < Literal(0))
{
rightShifted = midShifted;
}
@@ -858,7 +859,7 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
}
}
- muCur = (leftShifted + rightShifted) / 2;
+ muCur = (leftShifted + rightShifted) / Literal(2);
}
singVals[k] = shift + muCur;
@@ -892,8 +893,8 @@ void BDCSVD<MatrixType>::perturbCol0
// The offset permits to skip deflated entries while computing zhat
for (Index k = 0; k < n; ++k)
{
- if (col0(k) == 0) // deflated
- zhat(k) = 0;
+ if (col0(k) == Literal(0)) // deflated
+ zhat(k) = Literal(0);
else
{
// see equation (3.6)
@@ -918,7 +919,7 @@ void BDCSVD<MatrixType>::perturbCol0
std::cout << "zhat(" << k << ") = sqrt( " << prod << ") ; " << (singVals(last) + dk) << " * " << mus(last) + shifts(last) << " - " << dk << "\n";
#endif
RealScalar tmp = sqrt(prod);
- zhat(k) = col0(k) > 0 ? tmp : -tmp;
+ zhat(k) = col0(k) > Literal(0) ? tmp : -tmp;
}
}
}
@@ -934,7 +935,7 @@ void BDCSVD<MatrixType>::computeSingVecs
for (Index k = 0; k < n; ++k)
{
- if (zhat(k) == 0)
+ if (zhat(k) == Literal(0))
{
U.col(k) = VectorType::Unit(n+1, k);
if (m_compV) V.col(k) = VectorType::Unit(n, k);
@@ -947,7 +948,7 @@ void BDCSVD<MatrixType>::computeSingVecs
Index i = perm(l);
U(i,k) = zhat(i)/(((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k]));
}
- U(n,k) = 0;
+ U(n,k) = Literal(0);
U.col(k).normalize();
if (m_compV)
@@ -958,7 +959,7 @@ void BDCSVD<MatrixType>::computeSingVecs
Index i = perm(l);
V(i,k) = diag(i) * zhat(i) / (((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k]));
}
- V(0,k) = -1;
+ V(0,k) = Literal(-1);
V.col(k).normalize();
}
}
@@ -980,14 +981,14 @@ void BDCSVD<MatrixType>::deflation43(Index firstCol, Index shift, Index i, Index
RealScalar c = m_computed(start, start);
RealScalar s = m_computed(start+i, start);
RealScalar r = sqrt(numext::abs2(c) + numext::abs2(s));
- if (r == 0)
+ if (r == Literal(0))
{
- m_computed(start+i, start+i) = 0;
+ m_computed(start+i, start+i) = Literal(0);
return;
}
m_computed(start,start) = r;
- m_computed(start+i, start) = 0;
- m_computed(start+i, start+i) = 0;
+ m_computed(start+i, start) = Literal(0);
+ m_computed(start+i, start+i) = Literal(0);
JacobiRotation<RealScalar> J(c/r,-s/r);
if (m_compU) m_naiveU.middleRows(firstCol, size+1).applyOnTheRight(firstCol, firstCol+i, J);
@@ -1020,7 +1021,7 @@ void BDCSVD<MatrixType>::deflation44(Index firstColu , Index firstColm, Index fi
<< m_computed(firstColm + i+1, firstColm+i+1) << " "
<< m_computed(firstColm + i+2, firstColm+i+2) << "\n";
#endif
- if (r==0)
+ if (r==Literal(0))
{
m_computed(firstColm + i, firstColm + i) = m_computed(firstColm + j, firstColm + j);
return;
@@ -1029,7 +1030,7 @@ void BDCSVD<MatrixType>::deflation44(Index firstColu , Index firstColm, Index fi
s/=r;
m_computed(firstColm + i, firstColm) = r;
m_computed(firstColm + j, firstColm + j) = m_computed(firstColm + i, firstColm + i);
- m_computed(firstColm + j, firstColm) = 0;
+ m_computed(firstColm + j, firstColm) = Literal(0);
JacobiRotation<RealScalar> J(c,-s);
if (m_compU) m_naiveU.middleRows(firstColu, size+1).applyOnTheRight(firstColu + i, firstColu + j, J);
@@ -1053,7 +1054,7 @@ void BDCSVD<MatrixType>::deflation(Index firstCol, Index lastCol, Index k, Index
const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
RealScalar maxDiag = diag.tail((std::max)(Index(1),length-1)).cwiseAbs().maxCoeff();
RealScalar epsilon_strict = numext::maxi<RealScalar>(considerZero,NumTraits<RealScalar>::epsilon() * maxDiag);
- RealScalar epsilon_coarse = 8 * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(col0.cwiseAbs().maxCoeff(), maxDiag);
+ RealScalar epsilon_coarse = Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(col0.cwiseAbs().maxCoeff(), maxDiag);
#ifdef EIGEN_BDCSVD_SANITY_CHECKS
assert(m_naiveU.allFinite());
@@ -1081,7 +1082,7 @@ void BDCSVD<MatrixType>::deflation(Index firstCol, Index lastCol, Index k, Index
#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
std::cout << "deflation 4.2, set z(" << i << ") to zero because " << abs(col0(i)) << " < " << epsilon_strict << " (diag(" << i << ")=" << diag(i) << ")\n";
#endif
- col0(i) = 0;
+ col0(i) = Literal(0);
}
//condition 4.3
diff --git a/eigen/Eigen/src/SVD/SVDBase.h b/eigen/Eigen/src/SVD/SVDBase.h
index 4294147..cc90a3b 100644
--- a/eigen/Eigen/src/SVD/SVDBase.h
+++ b/eigen/Eigen/src/SVD/SVDBase.h
@@ -212,6 +212,7 @@ public:
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename RhsType, typename DstType>
+ EIGEN_DEVICE_FUNC
void _solve_impl(const RhsType &rhs, DstType &dst) const;
#endif
diff --git a/eigen/Eigen/src/SVD/UpperBidiagonalization.h b/eigen/Eigen/src/SVD/UpperBidiagonalization.h
index 0b14608..11ac847 100644
--- a/eigen/Eigen/src/SVD/UpperBidiagonalization.h
+++ b/eigen/Eigen/src/SVD/UpperBidiagonalization.h
@@ -159,6 +159,8 @@ void upperbidiagonalization_blocked_helper(MatrixType& A,
traits<MatrixType>::Flags & RowMajorBit> > Y)
{
typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef typename NumTraits<RealScalar>::Literal Literal;
enum { StorageOrder = traits<MatrixType>::Flags & RowMajorBit };
typedef InnerStride<int(StorageOrder) == int(ColMajor) ? 1 : Dynamic> ColInnerStride;
typedef InnerStride<int(StorageOrder) == int(ColMajor) ? Dynamic : 1> RowInnerStride;
@@ -263,7 +265,7 @@ void upperbidiagonalization_blocked_helper(MatrixType& A,
SubMatType A10( A.block(bs,0, brows-bs,bs) );
SubMatType A01( A.block(0,bs, bs,bcols-bs) );
Scalar tmp = A01(bs-1,0);
- A01(bs-1,0) = 1;
+ A01(bs-1,0) = Literal(1);
A11.noalias() -= A10 * Y.topLeftCorner(bcols,bs).bottomRows(bcols-bs).adjoint();
A11.noalias() -= X.topLeftCorner(brows,bs).bottomRows(brows-bs) * A01;
A01(bs-1,0) = tmp;
diff --git a/eigen/Eigen/src/SparseCore/SparseCompressedBase.h b/eigen/Eigen/src/SparseCore/SparseCompressedBase.h
index e0b3c22..5ccb466 100644
--- a/eigen/Eigen/src/SparseCore/SparseCompressedBase.h
+++ b/eigen/Eigen/src/SparseCore/SparseCompressedBase.h
@@ -185,14 +185,6 @@ class SparseCompressedBase<Derived>::InnerIterator
}
inline InnerIterator& operator++() { m_id++; return *this; }
- inline InnerIterator& operator+=(Index i) { m_id += i ; return *this; }
-
- inline InnerIterator operator+(Index i)
- {
- InnerIterator result = *this;
- result += i;
- return result;
- }
inline const Scalar& value() const { return m_values[m_id]; }
inline Scalar& valueRef() { return const_cast<Scalar&>(m_values[m_id]); }
@@ -253,14 +245,6 @@ class SparseCompressedBase<Derived>::ReverseInnerIterator
}
inline ReverseInnerIterator& operator--() { --m_id; return *this; }
- inline ReverseInnerIterator& operator-=(Index i) { m_id -= i; return *this; }
-
- inline ReverseInnerIterator operator-(Index i)
- {
- ReverseInnerIterator result = *this;
- result -= i;
- return result;
- }
inline const Scalar& value() const { return m_values[m_id-1]; }
inline Scalar& valueRef() { return const_cast<Scalar&>(m_values[m_id-1]); }
diff --git a/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
index c41c07a..e315e35 100644
--- a/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
+++ b/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
@@ -212,7 +212,8 @@ public:
enum {
CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
- Flags = XprType::Flags
+ // Expose storage order of the sparse expression
+ Flags = (XprType::Flags & ~RowMajorBit) | (int(Rhs::Flags)&RowMajorBit)
};
explicit binary_evaluator(const XprType& xpr)
@@ -299,7 +300,8 @@ public:
enum {
CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
- Flags = XprType::Flags
+ // Expose storage order of the sparse expression
+ Flags = (XprType::Flags & ~RowMajorBit) | (int(Lhs::Flags)&RowMajorBit)
};
explicit binary_evaluator(const XprType& xpr)
@@ -531,7 +533,8 @@ public:
enum {
CoeffReadCost = evaluator<LhsArg>::CoeffReadCost + evaluator<RhsArg>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
- Flags = XprType::Flags
+ // Expose storage order of the sparse expression
+ Flags = (XprType::Flags & ~RowMajorBit) | (int(RhsArg::Flags)&RowMajorBit)
};
explicit sparse_conjunction_evaluator(const XprType& xpr)
@@ -605,7 +608,8 @@ public:
enum {
CoeffReadCost = evaluator<LhsArg>::CoeffReadCost + evaluator<RhsArg>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
- Flags = XprType::Flags
+ // Expose storage order of the sparse expression
+ Flags = (XprType::Flags & ~RowMajorBit) | (int(LhsArg::Flags)&RowMajorBit)
};
explicit sparse_conjunction_evaluator(const XprType& xpr)
diff --git a/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h b/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h
index 9e39be7..5ab64f1 100644
--- a/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h
+++ b/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h
@@ -47,6 +47,7 @@ template<typename MatrixType, unsigned int _Mode> class SparseSelfAdjointView
enum {
Mode = _Mode,
+ TransposeMode = ((Mode & Upper) ? Lower : 0) | ((Mode & Lower) ? Upper : 0),
RowsAtCompileTime = internal::traits<SparseSelfAdjointView>::RowsAtCompileTime,
ColsAtCompileTime = internal::traits<SparseSelfAdjointView>::ColsAtCompileTime
};
@@ -368,7 +369,7 @@ struct generic_product_impl<Lhs, RhsView, DenseShape, SparseSelfAdjointShape, Pr
// transpose everything
Transpose<Dest> dstT(dst);
- internal::sparse_selfadjoint_time_dense_product<RhsView::Mode>(rhsNested.transpose(), lhsNested.transpose(), dstT, alpha);
+ internal::sparse_selfadjoint_time_dense_product<RhsView::TransposeMode>(rhsNested.transpose(), lhsNested.transpose(), dstT, alpha);
}
};
diff --git a/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h b/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h
index 9568cc1..91c09ab 100644
--- a/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h
+++ b/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h
@@ -320,7 +320,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
*
* \sa umfpackControl()
*/
- void printUmfpackControl()
+ void umfpackReportControl()
{
umfpack_report_control(m_control.data(), Scalar());
}
@@ -329,7 +329,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
*
* \sa analyzePattern(), compute()
*/
- void printUmfpackInfo()
+ void umfpackReportInfo()
{
eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
umfpack_report_info(m_control.data(), m_umfpackInfo.data(), Scalar());
@@ -339,7 +339,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
*
* \sa analyzePattern(), compute()
*/
- void printUmfpackStatus() {
+ void umfpackReportStatus() {
eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
umfpack_report_status(m_control.data(), m_fact_errorCode, Scalar());
}
diff --git a/eigen/Eigen/src/misc/lapacke.h b/eigen/Eigen/src/misc/lapacke.h
index 3d8e24f..8c7e79b 100644
--- a/eigen/Eigen/src/misc/lapacke.h
+++ b/eigen/Eigen/src/misc/lapacke.h
@@ -43,6 +43,10 @@
#include "lapacke_config.h"
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
#include <stdlib.h>
#ifndef lapack_int
@@ -104,11 +108,6 @@ lapack_complex_double lapack_make_complex_double( double re, double im );
#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
#ifndef LAPACKE_malloc
#define LAPACKE_malloc( size ) malloc( size )
#endif
diff --git a/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h
index 43615bd..ebaa3f1 100644
--- a/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h
+++ b/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h
@@ -10,7 +10,6 @@ typedef CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived> Inverse
typedef CwiseUnaryOp<internal::scalar_boolean_not_op<Scalar>, const Derived> BooleanNotReturnType;
typedef CwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived> ExpReturnType;
-typedef CwiseUnaryOp<internal::scalar_expm1_op<Scalar>, const Derived> Expm1ReturnType;
typedef CwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived> LogReturnType;
typedef CwiseUnaryOp<internal::scalar_log1p_op<Scalar>, const Derived> Log1pReturnType;
typedef CwiseUnaryOp<internal::scalar_log10_op<Scalar>, const Derived> Log10ReturnType;
@@ -91,20 +90,6 @@ exp() const
return ExpReturnType(derived());
}
-/** \returns an expression of the coefficient-wise exponential of *this minus 1.
- *
- * In exact arithmetic, \c x.expm1() is equivalent to \c x.exp() - 1,
- * however, with finite precision, this function is much more accurate when \c x is close to zero.
- *
- * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_expm1">Math functions</a>, exp()
- */
-EIGEN_DEVICE_FUNC
-inline const Expm1ReturnType
-expm1() const
-{
- return Expm1ReturnType(derived());
-}
-
/** \returns an expression of the coefficient-wise logarithm of *this.
*
* This function computes the coefficient-wise logarithm. The function MatrixBase::log() in the
@@ -113,7 +98,7 @@ expm1() const
* Example: \include Cwise_log.cpp
* Output: \verbinclude Cwise_log.out
*
- * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_log">Math functions</a>, log()
+ * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_log">Math functions</a>, exp()
*/
EIGEN_DEVICE_FUNC
inline const LogReturnType
diff --git a/eigen/Eigen/src/plugins/BlockMethods.h b/eigen/Eigen/src/plugins/BlockMethods.h
index 5caf144..ac35a00 100644
--- a/eigen/Eigen/src/plugins/BlockMethods.h
+++ b/eigen/Eigen/src/plugins/BlockMethods.h
@@ -42,116 +42,66 @@ template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBloc
#endif // not EIGEN_PARSED_BY_DOXYGEN
-/// \returns an expression of a block in \c *this with either dynamic or fixed sizes.
+/// \returns a dynamic-size expression of a block in *this.
///
-/// \param startRow the first row in the block
-/// \param startCol the first column in the block
-/// \param blockRows number of rows in the block, specified at either run-time or compile-time
-/// \param blockCols number of columns in the block, specified at either run-time or compile-time
-/// \tparam NRowsType the type of the value handling the number of rows in the block, typically Index.
-/// \tparam NColsType the type of the value handling the number of columns in the block, typically Index.
+/// \param startRow the first row in the block
+/// \param startCol the first column in the block
+/// \param blockRows the number of rows in the block
+/// \param blockCols the number of columns in the block
///
-/// Example using runtime (aka dynamic) sizes: \include MatrixBase_block_int_int_int_int.cpp
+/// Example: \include MatrixBase_block_int_int_int_int.cpp
/// Output: \verbinclude MatrixBase_block_int_int_int_int.out
///
-/// \newin{3.4}:
-///
-/// The number of rows \a blockRows and columns \a blockCols can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments. In the later case, \c n plays the role of a runtime fallback value in case \c N equals Eigen::Dynamic.
-/// Here is an example with a fixed number of rows \c NRows and dynamic number of columns \c cols:
-/// \code
-/// mat.block(i,j,fix<NRows>,cols)
-/// \endcode
-///
-/// This function thus fully covers the features offered by the following overloads block<NRows,NCols>(Index, Index),
-/// and block<NRows,NCols>(Index, Index, Index, Index) that are thus obsolete. Indeed, this generic version avoids
-/// redundancy, it preserves the argument order, and prevents the need to rely on the template keyword in templated code.
-///
-/// but with less redundancy and more consistency as it does not modify the argument order
-/// and seamlessly enable hybrid fixed/dynamic sizes.
-///
-/// \note Even in the case that the returned expression has dynamic size, in the case
+/// \note Even though the returned expression has dynamic size, in the case
/// when it is applied to a fixed-size matrix, it inherits a fixed maximal size,
/// which means that evaluating it does not cause a dynamic memory allocation.
///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa class Block, fix, fix<N>(int)
+/// \sa class Block, block(Index,Index)
///
-template<typename NRowsType, typename NColsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline typename FixedBlockXpr<...,...>::Type
-#endif
-block(Index startRow, Index startCol, NRowsType blockRows, NColsType blockCols)
+inline BlockXpr block(Index startRow, Index startCol, Index blockRows, Index blockCols)
{
- return typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type(
- derived(), startRow, startCol, internal::get_runtime_value(blockRows), internal::get_runtime_value(blockCols));
+ return BlockXpr(derived(), startRow, startCol, blockRows, blockCols);
}
-/// This is the const version of block(Index,Index,NRowsType,NColsType)
-template<typename NRowsType, typename NColsType>
+/// This is the const version of block(Index,Index,Index,Index). */
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline const typename ConstFixedBlockXpr<...,...>::Type
-#endif
-block(Index startRow, Index startCol, NRowsType blockRows, NColsType blockCols) const
+inline const ConstBlockXpr block(Index startRow, Index startCol, Index blockRows, Index blockCols) const
{
- return typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type(
- derived(), startRow, startCol, internal::get_runtime_value(blockRows), internal::get_runtime_value(blockCols));
+ return ConstBlockXpr(derived(), startRow, startCol, blockRows, blockCols);
}
-/// \returns a expression of a top-right corner of \c *this with either dynamic or fixed sizes.
+
+/// \returns a dynamic-size expression of a top-right corner of *this.
///
/// \param cRows the number of rows in the corner
/// \param cCols the number of columns in the corner
-/// \tparam NRowsType the type of the value handling the number of rows in the block, typically Index.
-/// \tparam NColsType the type of the value handling the number of columns in the block, typically Index.
///
-/// Example with dynamic sizes: \include MatrixBase_topRightCorner_int_int.cpp
+/// Example: \include MatrixBase_topRightCorner_int_int.cpp
/// Output: \verbinclude MatrixBase_topRightCorner_int_int.out
///
-/// The number of rows \a blockRows and columns \a blockCols can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments. See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NRowsType, typename NColsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline typename FixedBlockXpr<...,...>::Type
-#endif
-topRightCorner(NRowsType cRows, NColsType cCols)
+inline BlockXpr topRightCorner(Index cRows, Index cCols)
{
- return typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, cols() - internal::get_runtime_value(cCols), internal::get_runtime_value(cRows), internal::get_runtime_value(cCols));
+ return BlockXpr(derived(), 0, cols() - cCols, cRows, cCols);
}
-/// This is the const version of topRightCorner(NRowsType, NColsType).
-template<typename NRowsType, typename NColsType>
+/// This is the const version of topRightCorner(Index, Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline const typename ConstFixedBlockXpr<...,...>::Type
-#endif
-topRightCorner(NRowsType cRows, NColsType cCols) const
+inline const ConstBlockXpr topRightCorner(Index cRows, Index cCols) const
{
- return typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, cols() - internal::get_runtime_value(cCols), internal::get_runtime_value(cRows), internal::get_runtime_value(cCols));
+ return ConstBlockXpr(derived(), 0, cols() - cCols, cRows, cCols);
}
-/// \returns an expression of a fixed-size top-right corner of \c *this.
+/// \returns an expression of a fixed-size top-right corner of *this.
///
/// \tparam CRows the number of rows in the corner
/// \tparam CCols the number of columns in the corner
@@ -178,7 +128,7 @@ inline const typename ConstFixedBlockXpr<CRows,CCols>::Type topRightCorner() con
return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), 0, cols() - CCols);
}
-/// \returns an expression of a top-right corner of \c *this.
+/// \returns an expression of a top-right corner of *this.
///
/// \tparam CRows number of rows in corner as specified at compile-time
/// \tparam CCols number of columns in corner as specified at compile-time
@@ -212,51 +162,32 @@ inline const typename ConstFixedBlockXpr<CRows,CCols>::Type topRightCorner(Index
-/// \returns an expression of a top-left corner of \c *this with either dynamic or fixed sizes.
+/// \returns a dynamic-size expression of a top-left corner of *this.
///
/// \param cRows the number of rows in the corner
/// \param cCols the number of columns in the corner
-/// \tparam NRowsType the type of the value handling the number of rows in the block, typically Index.
-/// \tparam NColsType the type of the value handling the number of columns in the block, typically Index.
///
/// Example: \include MatrixBase_topLeftCorner_int_int.cpp
/// Output: \verbinclude MatrixBase_topLeftCorner_int_int.out
///
-/// The number of rows \a blockRows and columns \a blockCols can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments. See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NRowsType, typename NColsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline typename FixedBlockXpr<...,...>::Type
-#endif
-topLeftCorner(NRowsType cRows, NColsType cCols)
+inline BlockXpr topLeftCorner(Index cRows, Index cCols)
{
- return typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, 0, internal::get_runtime_value(cRows), internal::get_runtime_value(cCols));
+ return BlockXpr(derived(), 0, 0, cRows, cCols);
}
/// This is the const version of topLeftCorner(Index, Index).
-template<typename NRowsType, typename NColsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline const typename ConstFixedBlockXpr<...,...>::Type
-#endif
-topLeftCorner(NRowsType cRows, NColsType cCols) const
+inline const ConstBlockXpr topLeftCorner(Index cRows, Index cCols) const
{
- return typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, 0, internal::get_runtime_value(cRows), internal::get_runtime_value(cCols));
+ return ConstBlockXpr(derived(), 0, 0, cRows, cCols);
}
-/// \returns an expression of a fixed-size top-left corner of \c *this.
+/// \returns an expression of a fixed-size top-left corner of *this.
///
/// The template parameters CRows and CCols are the number of rows and columns in the corner.
///
@@ -265,7 +196,7 @@ topLeftCorner(NRowsType cRows, NColsType cCols) const
///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int CRows, int CCols>
EIGEN_DEVICE_FUNC
@@ -282,7 +213,7 @@ inline const typename ConstFixedBlockXpr<CRows,CCols>::Type topLeftCorner() cons
return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), 0, 0);
}
-/// \returns an expression of a top-left corner of \c *this.
+/// \returns an expression of a top-left corner of *this.
///
/// \tparam CRows number of rows in corner as specified at compile-time
/// \tparam CCols number of columns in corner as specified at compile-time
@@ -316,53 +247,32 @@ inline const typename ConstFixedBlockXpr<CRows,CCols>::Type topLeftCorner(Index
-/// \returns an expression of a bottom-right corner of \c *this with either dynamic or fixed sizes.
+/// \returns a dynamic-size expression of a bottom-right corner of *this.
///
/// \param cRows the number of rows in the corner
/// \param cCols the number of columns in the corner
-/// \tparam NRowsType the type of the value handling the number of rows in the block, typically Index.
-/// \tparam NColsType the type of the value handling the number of columns in the block, typically Index.
///
/// Example: \include MatrixBase_bottomRightCorner_int_int.cpp
/// Output: \verbinclude MatrixBase_bottomRightCorner_int_int.out
///
-/// The number of rows \a blockRows and columns \a blockCols can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments. See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NRowsType, typename NColsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline typename FixedBlockXpr<...,...>::Type
-#endif
-bottomRightCorner(NRowsType cRows, NColsType cCols)
+inline BlockXpr bottomRightCorner(Index cRows, Index cCols)
{
- return typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
- (derived(), rows() - internal::get_runtime_value(cRows), cols() - internal::get_runtime_value(cCols),
- internal::get_runtime_value(cRows), internal::get_runtime_value(cCols));
+ return BlockXpr(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
}
-/// This is the const version of bottomRightCorner(NRowsType, NColsType).
-template<typename NRowsType, typename NColsType>
+/// This is the const version of bottomRightCorner(Index, Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline const typename ConstFixedBlockXpr<...,...>::Type
-#endif
-bottomRightCorner(NRowsType cRows, NColsType cCols) const
+inline const ConstBlockXpr bottomRightCorner(Index cRows, Index cCols) const
{
- return typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
- (derived(), rows() - internal::get_runtime_value(cRows), cols() - internal::get_runtime_value(cCols),
- internal::get_runtime_value(cRows), internal::get_runtime_value(cCols));
+ return ConstBlockXpr(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
}
-/// \returns an expression of a fixed-size bottom-right corner of \c *this.
+/// \returns an expression of a fixed-size bottom-right corner of *this.
///
/// The template parameters CRows and CCols are the number of rows and columns in the corner.
///
@@ -371,7 +281,7 @@ bottomRightCorner(NRowsType cRows, NColsType cCols) const
///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int CRows, int CCols>
EIGEN_DEVICE_FUNC
@@ -388,7 +298,7 @@ inline const typename ConstFixedBlockXpr<CRows,CCols>::Type bottomRightCorner()
return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), rows() - CRows, cols() - CCols);
}
-/// \returns an expression of a bottom-right corner of \c *this.
+/// \returns an expression of a bottom-right corner of *this.
///
/// \tparam CRows number of rows in corner as specified at compile-time
/// \tparam CCols number of columns in corner as specified at compile-time
@@ -422,53 +332,32 @@ inline const typename ConstFixedBlockXpr<CRows,CCols>::Type bottomRightCorner(In
-/// \returns an expression of a bottom-left corner of \c *this with either dynamic or fixed sizes.
+/// \returns a dynamic-size expression of a bottom-left corner of *this.
///
/// \param cRows the number of rows in the corner
/// \param cCols the number of columns in the corner
-/// \tparam NRowsType the type of the value handling the number of rows in the block, typically Index.
-/// \tparam NColsType the type of the value handling the number of columns in the block, typically Index.
///
/// Example: \include MatrixBase_bottomLeftCorner_int_int.cpp
/// Output: \verbinclude MatrixBase_bottomLeftCorner_int_int.out
///
-/// The number of rows \a blockRows and columns \a blockCols can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments. See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NRowsType, typename NColsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline typename FixedBlockXpr<...,...>::Type
-#endif
-bottomLeftCorner(NRowsType cRows, NColsType cCols)
+inline BlockXpr bottomLeftCorner(Index cRows, Index cCols)
{
- return typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
- (derived(), rows() - internal::get_runtime_value(cRows), 0,
- internal::get_runtime_value(cRows), internal::get_runtime_value(cCols));
+ return BlockXpr(derived(), rows() - cRows, 0, cRows, cCols);
}
-/// This is the const version of bottomLeftCorner(NRowsType, NColsType).
-template<typename NRowsType, typename NColsType>
+/// This is the const version of bottomLeftCorner(Index, Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline typename ConstFixedBlockXpr<...,...>::Type
-#endif
-bottomLeftCorner(NRowsType cRows, NColsType cCols) const
+inline const ConstBlockXpr bottomLeftCorner(Index cRows, Index cCols) const
{
- return typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
- (derived(), rows() - internal::get_runtime_value(cRows), 0,
- internal::get_runtime_value(cRows), internal::get_runtime_value(cCols));
+ return ConstBlockXpr(derived(), rows() - cRows, 0, cRows, cCols);
}
-/// \returns an expression of a fixed-size bottom-left corner of \c *this.
+/// \returns an expression of a fixed-size bottom-left corner of *this.
///
/// The template parameters CRows and CCols are the number of rows and columns in the corner.
///
@@ -477,7 +366,7 @@ bottomLeftCorner(NRowsType cRows, NColsType cCols) const
///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int CRows, int CCols>
EIGEN_DEVICE_FUNC
@@ -494,7 +383,7 @@ inline const typename ConstFixedBlockXpr<CRows,CCols>::Type bottomLeftCorner() c
return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), rows() - CRows, 0);
}
-/// \returns an expression of a bottom-left corner of \c *this.
+/// \returns an expression of a bottom-left corner of *this.
///
/// \tparam CRows number of rows in corner as specified at compile-time
/// \tparam CCols number of columns in corner as specified at compile-time
@@ -528,50 +417,31 @@ inline const typename ConstFixedBlockXpr<CRows,CCols>::Type bottomLeftCorner(Ind
-/// \returns a block consisting of the top rows of \c *this.
+/// \returns a block consisting of the top rows of *this.
///
/// \param n the number of rows in the block
-/// \tparam NRowsType the type of the value handling the number of rows in the block, typically Index.
///
/// Example: \include MatrixBase_topRows_int.cpp
/// Output: \verbinclude MatrixBase_topRows_int.out
///
-/// The number of rows \a n can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments.
-/// See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NRowsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename NRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
-#else
-inline typename NRowsBlockXpr<...>::Type
-#endif
-topRows(NRowsType n)
+inline RowsBlockXpr topRows(Index n)
{
- return typename NRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
- (derived(), 0, 0, internal::get_runtime_value(n), cols());
+ return RowsBlockXpr(derived(), 0, 0, n, cols());
}
-/// This is the const version of topRows(NRowsType).
-template<typename NRowsType>
+/// This is the const version of topRows(Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstNRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
-#else
-inline const typename ConstNRowsBlockXpr<...>::Type
-#endif
-topRows(NRowsType n) const
+inline ConstRowsBlockXpr topRows(Index n) const
{
- return typename ConstNRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
- (derived(), 0, 0, internal::get_runtime_value(n), cols());
+ return ConstRowsBlockXpr(derived(), 0, 0, n, cols());
}
-/// \returns a block consisting of the top rows of \c *this.
+/// \returns a block consisting of the top rows of *this.
///
/// \tparam N the number of rows in the block as specified at compile-time
/// \param n the number of rows in the block as specified at run-time
@@ -584,7 +454,7 @@ topRows(NRowsType n) const
///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int N>
EIGEN_DEVICE_FUNC
@@ -603,50 +473,31 @@ inline typename ConstNRowsBlockXpr<N>::Type topRows(Index n = N) const
-/// \returns a block consisting of the bottom rows of \c *this.
+/// \returns a block consisting of the bottom rows of *this.
///
/// \param n the number of rows in the block
-/// \tparam NRowsType the type of the value handling the number of rows in the block, typically Index.
///
/// Example: \include MatrixBase_bottomRows_int.cpp
/// Output: \verbinclude MatrixBase_bottomRows_int.out
///
-/// The number of rows \a n can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments.
-/// See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NRowsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename NRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
-#else
-inline typename NRowsBlockXpr<...>::Type
-#endif
-bottomRows(NRowsType n)
+inline RowsBlockXpr bottomRows(Index n)
{
- return typename NRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
- (derived(), rows() - internal::get_runtime_value(n), 0, internal::get_runtime_value(n), cols());
+ return RowsBlockXpr(derived(), rows() - n, 0, n, cols());
}
-/// This is the const version of bottomRows(NRowsType).
-template<typename NRowsType>
+/// This is the const version of bottomRows(Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstNRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
-#else
-inline const typename ConstNRowsBlockXpr<...>::Type
-#endif
-bottomRows(NRowsType n) const
+inline ConstRowsBlockXpr bottomRows(Index n) const
{
- return typename ConstNRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
- (derived(), rows() - internal::get_runtime_value(n), 0, internal::get_runtime_value(n), cols());
+ return ConstRowsBlockXpr(derived(), rows() - n, 0, n, cols());
}
-/// \returns a block consisting of the bottom rows of \c *this.
+/// \returns a block consisting of the bottom rows of *this.
///
/// \tparam N the number of rows in the block as specified at compile-time
/// \param n the number of rows in the block as specified at run-time
@@ -659,7 +510,7 @@ bottomRows(NRowsType n) const
///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int N>
EIGEN_DEVICE_FUNC
@@ -678,51 +529,32 @@ inline typename ConstNRowsBlockXpr<N>::Type bottomRows(Index n = N) const
-/// \returns a block consisting of a range of rows of \c *this.
+/// \returns a block consisting of a range of rows of *this.
///
/// \param startRow the index of the first row in the block
/// \param n the number of rows in the block
-/// \tparam NRowsType the type of the value handling the number of rows in the block, typically Index.
///
/// Example: \include DenseBase_middleRows_int.cpp
/// Output: \verbinclude DenseBase_middleRows_int.out
///
-/// The number of rows \a n can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments.
-/// See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NRowsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename NRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
-#else
-inline typename NRowsBlockXpr<...>::Type
-#endif
-middleRows(Index startRow, NRowsType n)
+inline RowsBlockXpr middleRows(Index startRow, Index n)
{
- return typename NRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
- (derived(), startRow, 0, internal::get_runtime_value(n), cols());
+ return RowsBlockXpr(derived(), startRow, 0, n, cols());
}
-/// This is the const version of middleRows(Index,NRowsType).
-template<typename NRowsType>
+/// This is the const version of middleRows(Index,Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstNRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
-#else
-inline const typename ConstNRowsBlockXpr<...>::Type
-#endif
-middleRows(Index startRow, NRowsType n) const
+inline ConstRowsBlockXpr middleRows(Index startRow, Index n) const
{
- return typename ConstNRowsBlockXpr<internal::get_fixed_value<NRowsType>::value>::Type
- (derived(), startRow, 0, internal::get_runtime_value(n), cols());
+ return ConstRowsBlockXpr(derived(), startRow, 0, n, cols());
}
-/// \returns a block consisting of a range of rows of \c *this.
+/// \returns a block consisting of a range of rows of *this.
///
/// \tparam N the number of rows in the block as specified at compile-time
/// \param startRow the index of the first row in the block
@@ -736,7 +568,7 @@ middleRows(Index startRow, NRowsType n) const
///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int N>
EIGEN_DEVICE_FUNC
@@ -755,50 +587,31 @@ inline typename ConstNRowsBlockXpr<N>::Type middleRows(Index startRow, Index n =
-/// \returns a block consisting of the left columns of \c *this.
+/// \returns a block consisting of the left columns of *this.
///
/// \param n the number of columns in the block
-/// \tparam NColsType the type of the value handling the number of columns in the block, typically Index.
///
/// Example: \include MatrixBase_leftCols_int.cpp
/// Output: \verbinclude MatrixBase_leftCols_int.out
///
-/// The number of columns \a n can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments.
-/// See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NColsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename NColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline typename NColsBlockXpr<...>::Type
-#endif
-leftCols(NColsType n)
+inline ColsBlockXpr leftCols(Index n)
{
- return typename NColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, 0, rows(), internal::get_runtime_value(n));
+ return ColsBlockXpr(derived(), 0, 0, rows(), n);
}
-/// This is the const version of leftCols(NColsType).
-template<typename NColsType>
+/// This is the const version of leftCols(Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstNColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline const typename ConstNColsBlockXpr<...>::Type
-#endif
-leftCols(NColsType n) const
+inline ConstColsBlockXpr leftCols(Index n) const
{
- return typename ConstNColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, 0, rows(), internal::get_runtime_value(n));
+ return ConstColsBlockXpr(derived(), 0, 0, rows(), n);
}
-/// \returns a block consisting of the left columns of \c *this.
+/// \returns a block consisting of the left columns of *this.
///
/// \tparam N the number of columns in the block as specified at compile-time
/// \param n the number of columns in the block as specified at run-time
@@ -811,7 +624,7 @@ leftCols(NColsType n) const
///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int N>
EIGEN_DEVICE_FUNC
@@ -830,50 +643,31 @@ inline typename ConstNColsBlockXpr<N>::Type leftCols(Index n = N) const
-/// \returns a block consisting of the right columns of \c *this.
+/// \returns a block consisting of the right columns of *this.
///
/// \param n the number of columns in the block
-/// \tparam NColsType the type of the value handling the number of columns in the block, typically Index.
///
/// Example: \include MatrixBase_rightCols_int.cpp
/// Output: \verbinclude MatrixBase_rightCols_int.out
///
-/// The number of columns \a n can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments.
-/// See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NColsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename NColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline typename NColsBlockXpr<...>::Type
-#endif
-rightCols(NColsType n)
+inline ColsBlockXpr rightCols(Index n)
{
- return typename NColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, cols() - internal::get_runtime_value(n), rows(), internal::get_runtime_value(n));
+ return ColsBlockXpr(derived(), 0, cols() - n, rows(), n);
}
-/// This is the const version of rightCols(NColsType).
-template<typename NColsType>
+/// This is the const version of rightCols(Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstNColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline const typename ConstNColsBlockXpr<...>::Type
-#endif
-rightCols(NColsType n) const
+inline ConstColsBlockXpr rightCols(Index n) const
{
- return typename ConstNColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, cols() - internal::get_runtime_value(n), rows(), internal::get_runtime_value(n));
+ return ConstColsBlockXpr(derived(), 0, cols() - n, rows(), n);
}
-/// \returns a block consisting of the right columns of \c *this.
+/// \returns a block consisting of the right columns of *this.
///
/// \tparam N the number of columns in the block as specified at compile-time
/// \param n the number of columns in the block as specified at run-time
@@ -886,7 +680,7 @@ rightCols(NColsType n) const
///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int N>
EIGEN_DEVICE_FUNC
@@ -905,51 +699,32 @@ inline typename ConstNColsBlockXpr<N>::Type rightCols(Index n = N) const
-/// \returns a block consisting of a range of columns of \c *this.
+/// \returns a block consisting of a range of columns of *this.
///
/// \param startCol the index of the first column in the block
/// \param numCols the number of columns in the block
-/// \tparam NColsType the type of the value handling the number of columns in the block, typically Index.
///
/// Example: \include DenseBase_middleCols_int.cpp
/// Output: \verbinclude DenseBase_middleCols_int.out
///
-/// The number of columns \a n can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments.
-/// See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
-template<typename NColsType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename NColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline typename NColsBlockXpr<...>::Type
-#endif
-middleCols(Index startCol, NColsType numCols)
+inline ColsBlockXpr middleCols(Index startCol, Index numCols)
{
- return typename NColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, startCol, rows(), internal::get_runtime_value(numCols));
+ return ColsBlockXpr(derived(), 0, startCol, rows(), numCols);
}
-/// This is the const version of middleCols(Index,NColsType).
-template<typename NColsType>
+/// This is the const version of middleCols(Index,Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstNColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
-#else
-inline const typename ConstNColsBlockXpr<...>::Type
-#endif
-middleCols(Index startCol, NColsType numCols) const
+inline ConstColsBlockXpr middleCols(Index startCol, Index numCols) const
{
- return typename ConstNColsBlockXpr<internal::get_fixed_value<NColsType>::value>::Type
- (derived(), 0, startCol, rows(), internal::get_runtime_value(numCols));
+ return ConstColsBlockXpr(derived(), 0, startCol, rows(), numCols);
}
-/// \returns a block consisting of a range of columns of \c *this.
+/// \returns a block consisting of a range of columns of *this.
///
/// \tparam N the number of columns in the block as specified at compile-time
/// \param startCol the index of the first column in the block
@@ -963,7 +738,7 @@ middleCols(Index startCol, NColsType numCols) const
///
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int N>
EIGEN_DEVICE_FUNC
@@ -982,7 +757,7 @@ inline typename ConstNColsBlockXpr<N>::Type middleCols(Index startCol, Index n =
-/// \returns a fixed-size expression of a block of \c *this.
+/// \returns a fixed-size expression of a block in *this.
///
/// The template parameters \a NRows and \a NCols are the number of
/// rows and columns in the block.
@@ -993,18 +768,12 @@ inline typename ConstNColsBlockXpr<N>::Type middleCols(Index startCol, Index n =
/// Example: \include MatrixBase_block_int_int.cpp
/// Output: \verbinclude MatrixBase_block_int_int.out
///
-/// \note The usage of of this overload is discouraged from %Eigen 3.4, better used the generic
-/// block(Index,Index,NRowsType,NColsType), here is the one-to-one equivalence:
-/// \code
-/// mat.template block<NRows,NCols>(i,j) <--> mat.block(i,j,fix<NRows>,fix<NCols>)
-/// \endcode
-///
/// \note since block is a templated member, the keyword template has to be used
/// if the matrix type is also a template parameter: \code m.template block<3,3>(1,1); \endcode
///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int NRows, int NCols>
EIGEN_DEVICE_FUNC
@@ -1021,7 +790,7 @@ inline const typename ConstFixedBlockXpr<NRows,NCols>::Type block(Index startRow
return typename ConstFixedBlockXpr<NRows,NCols>::Type(derived(), startRow, startCol);
}
-/// \returns an expression of a block of \c *this.
+/// \returns an expression of a block in *this.
///
/// \tparam NRows number of rows in block as specified at compile-time
/// \tparam NCols number of columns in block as specified at compile-time
@@ -1038,19 +807,9 @@ inline const typename ConstFixedBlockXpr<NRows,NCols>::Type block(Index startRow
/// Example: \include MatrixBase_template_int_int_block_int_int_int_int.cpp
/// Output: \verbinclude MatrixBase_template_int_int_block_int_int_int_int.cpp
///
-/// \note The usage of of this overload is discouraged from %Eigen 3.4, better used the generic
-/// block(Index,Index,NRowsType,NColsType), here is the one-to-one complete equivalence:
-/// \code
-/// mat.template block<NRows,NCols>(i,j,rows,cols) <--> mat.block(i,j,fix<NRows>(rows),fix<NCols>(cols))
-/// \endcode
-/// If we known that, e.g., NRows==Dynamic and NCols!=Dynamic, then the equivalence becomes:
-/// \code
-/// mat.template block<Dynamic,NCols>(i,j,rows,NCols) <--> mat.block(i,j,rows,fix<NCols>)
-/// \endcode
-///
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
///
-/// \sa block(Index,Index,NRowsType,NColsType), class Block
+/// \sa class Block, block(Index,Index,Index,Index)
///
template<int NRows, int NCols>
inline typename FixedBlockXpr<NRows,NCols>::Type block(Index startRow, Index startCol,
@@ -1067,7 +826,7 @@ inline const typename ConstFixedBlockXpr<NRows,NCols>::Type block(Index startRow
return typename ConstFixedBlockXpr<NRows,NCols>::Type(derived(), startRow, startCol, blockRows, blockCols);
}
-/// \returns an expression of the \a i-th column of \c *this. Note that the numbering starts at 0.
+/// \returns an expression of the \a i-th column of *this. Note that the numbering starts at 0.
///
/// Example: \include MatrixBase_col.cpp
/// Output: \verbinclude MatrixBase_col.out
@@ -1088,7 +847,7 @@ inline ConstColXpr col(Index i) const
return ConstColXpr(derived(), i);
}
-/// \returns an expression of the \a i-th row of \c *this. Note that the numbering starts at 0.
+/// \returns an expression of the \a i-th row of *this. Note that the numbering starts at 0.
///
/// Example: \include MatrixBase_row.cpp
/// Output: \verbinclude MatrixBase_row.out
@@ -1109,153 +868,96 @@ inline ConstRowXpr row(Index i) const
return ConstRowXpr(derived(), i);
}
-/// \returns an expression of a segment (i.e. a vector block) in \c *this with either dynamic or fixed sizes.
+/// \returns a dynamic-size expression of a segment (i.e. a vector block) in *this.
///
/// \only_for_vectors
///
/// \param start the first coefficient in the segment
/// \param n the number of coefficients in the segment
-/// \tparam NType the type of the value handling the number of coefficients in the segment, typically Index.
///
/// Example: \include MatrixBase_segment_int_int.cpp
/// Output: \verbinclude MatrixBase_segment_int_int.out
///
-/// The number of coefficients \a n can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments.
-/// See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
-/// \note Even in the case that the returned expression has dynamic size, in the case
+/// \note Even though the returned expression has dynamic size, in the case
/// when it is applied to a fixed-size vector, it inherits a fixed maximal size,
/// which means that evaluating it does not cause a dynamic memory allocation.
///
-/// \sa block(Index,Index,NRowsType,NColsType), fix<N>, fix<N>(int), class Block
+/// \sa class Block, segment(Index)
///
-template<typename NType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename FixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
-#else
-inline typename FixedSegmentReturnType<...>::Type
-#endif
-segment(Index start, NType n)
+inline SegmentReturnType segment(Index start, Index n)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename FixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
- (derived(), start, internal::get_runtime_value(n));
+ return SegmentReturnType(derived(), start, n);
}
-/// This is the const version of segment(Index,NType).
-template<typename NType>
+/// This is the const version of segment(Index,Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstFixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
-#else
-inline const typename ConstFixedSegmentReturnType<...>::Type
-#endif
-segment(Index start, NType n) const
+inline ConstSegmentReturnType segment(Index start, Index n) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename ConstFixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
- (derived(), start, internal::get_runtime_value(n));
+ return ConstSegmentReturnType(derived(), start, n);
}
-/// \returns an expression of the first coefficients of \c *this with either dynamic or fixed sizes.
+/// \returns a dynamic-size expression of the first coefficients of *this.
///
/// \only_for_vectors
///
/// \param n the number of coefficients in the segment
-/// \tparam NType the type of the value handling the number of coefficients in the segment, typically Index.
///
/// Example: \include MatrixBase_start_int.cpp
/// Output: \verbinclude MatrixBase_start_int.out
///
-/// The number of coefficients \a n can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments.
-/// See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
-/// \note Even in the case that the returned expression has dynamic size, in the case
+/// \note Even though the returned expression has dynamic size, in the case
/// when it is applied to a fixed-size vector, it inherits a fixed maximal size,
/// which means that evaluating it does not cause a dynamic memory allocation.
///
/// \sa class Block, block(Index,Index)
///
-template<typename NType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename FixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
-#else
-inline typename FixedSegmentReturnType<...>::Type
-#endif
-head(NType n)
+inline SegmentReturnType head(Index n)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename FixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
- (derived(), 0, internal::get_runtime_value(n));
+ return SegmentReturnType(derived(), 0, n);
}
-/// This is the const version of head(NType).
-template<typename NType>
+/// This is the const version of head(Index).
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstFixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
-#else
-inline const typename ConstFixedSegmentReturnType<...>::Type
-#endif
-head(NType n) const
+inline ConstSegmentReturnType head(Index n) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename ConstFixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
- (derived(), 0, internal::get_runtime_value(n));
+ return ConstSegmentReturnType(derived(), 0, n);
}
-/// \returns an expression of a last coefficients of \c *this with either dynamic or fixed sizes.
+/// \returns a dynamic-size expression of the last coefficients of *this.
///
/// \only_for_vectors
///
/// \param n the number of coefficients in the segment
-/// \tparam NType the type of the value handling the number of coefficients in the segment, typically Index.
///
/// Example: \include MatrixBase_end_int.cpp
/// Output: \verbinclude MatrixBase_end_int.out
///
-/// The number of coefficients \a n can also be specified at compile-time by passing Eigen::fix<N>,
-/// or Eigen::fix<N>(n) as arguments.
-/// See \link block(Index,Index,NRowsType,NColsType) block() \endlink for the details.
-///
-/// \note Even in the case that the returned expression has dynamic size, in the case
+/// \note Even though the returned expression has dynamic size, in the case
/// when it is applied to a fixed-size vector, it inherits a fixed maximal size,
/// which means that evaluating it does not cause a dynamic memory allocation.
///
/// \sa class Block, block(Index,Index)
///
-template<typename NType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename FixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
-#else
-inline typename FixedSegmentReturnType<...>::Type
-#endif
-tail(NType n)
+inline SegmentReturnType tail(Index n)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename FixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
- (derived(), this->size() - internal::get_runtime_value(n), internal::get_runtime_value(n));
+ return SegmentReturnType(derived(), this->size() - n, n);
}
/// This is the const version of tail(Index).
-template<typename NType>
EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline const typename ConstFixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
-#else
-inline const typename ConstFixedSegmentReturnType<...>::Type
-#endif
-tail(NType n) const
+inline ConstSegmentReturnType tail(Index n) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename ConstFixedSegmentReturnType<internal::get_fixed_value<NType>::value>::Type
- (derived(), this->size() - internal::get_runtime_value(n), internal::get_runtime_value(n));
+ return ConstSegmentReturnType(derived(), this->size() - n, n);
}
/// \returns a fixed-size expression of a segment (i.e. a vector block) in \c *this
@@ -1272,7 +974,7 @@ tail(NType n) const
/// Example: \include MatrixBase_template_int_segment.cpp
/// Output: \verbinclude MatrixBase_template_int_segment.out
///
-/// \sa segment(Index,NType), class Block
+/// \sa class Block
///
template<int N>
EIGEN_DEVICE_FUNC
@@ -1291,7 +993,7 @@ inline typename ConstFixedSegmentReturnType<N>::Type segment(Index start, Index
return typename ConstFixedSegmentReturnType<N>::Type(derived(), start, n);
}
-/// \returns a fixed-size expression of the first coefficients of \c *this.
+/// \returns a fixed-size expression of the first coefficients of *this.
///
/// \only_for_vectors
///
@@ -1304,7 +1006,7 @@ inline typename ConstFixedSegmentReturnType<N>::Type segment(Index start, Index
/// Example: \include MatrixBase_template_int_start.cpp
/// Output: \verbinclude MatrixBase_template_int_start.out
///
-/// \sa head(NType), class Block
+/// \sa class Block
///
template<int N>
EIGEN_DEVICE_FUNC
@@ -1323,7 +1025,7 @@ inline typename ConstFixedSegmentReturnType<N>::Type head(Index n = N) const
return typename ConstFixedSegmentReturnType<N>::Type(derived(), 0, n);
}
-/// \returns a fixed-size expression of the last coefficients of \c *this.
+/// \returns a fixed-size expression of the last coefficients of *this.
///
/// \only_for_vectors
///
@@ -1336,7 +1038,7 @@ inline typename ConstFixedSegmentReturnType<N>::Type head(Index n = N) const
/// Example: \include MatrixBase_template_int_end.cpp
/// Output: \verbinclude MatrixBase_template_int_end.out
///
-/// \sa tail(NType), class Block
+/// \sa class Block
///
template<int N>
EIGEN_DEVICE_FUNC
diff --git a/eigen/Eigen/src/plugins/IndexedViewMethods.h b/eigen/Eigen/src/plugins/IndexedViewMethods.h
deleted file mode 100644
index 22c1666..0000000
--- a/eigen/Eigen/src/plugins/IndexedViewMethods.h
+++ /dev/null
@@ -1,267 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2017 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/.
-
-#if !defined(EIGEN_PARSED_BY_DOXYGEN)
-
-// This file is automatically included twice to generate const and non-const versions
-
-#ifndef EIGEN_INDEXED_VIEW_METHOD_2ND_PASS
-#define EIGEN_INDEXED_VIEW_METHOD_CONST const
-#define EIGEN_INDEXED_VIEW_METHOD_TYPE ConstIndexedViewType
-#else
-#define EIGEN_INDEXED_VIEW_METHOD_CONST
-#define EIGEN_INDEXED_VIEW_METHOD_TYPE IndexedViewType
-#endif
-
-#ifndef EIGEN_INDEXED_VIEW_METHOD_2ND_PASS
-protected:
-
-// define some aliases to ease readability
-
-template<typename Indices>
-struct IvcRowType : public internal::IndexedViewCompatibleType<Indices,RowsAtCompileTime> {};
-
-template<typename Indices>
-struct IvcColType : public internal::IndexedViewCompatibleType<Indices,ColsAtCompileTime> {};
-
-template<typename Indices>
-struct IvcType : public internal::IndexedViewCompatibleType<Indices,SizeAtCompileTime> {};
-
-typedef typename internal::IndexedViewCompatibleType<Index,1>::type IvcIndex;
-
-template<typename Indices>
-typename IvcRowType<Indices>::type
-ivcRow(const Indices& indices) const {
- return internal::makeIndexedViewCompatible(indices, internal::variable_if_dynamic<Index,RowsAtCompileTime>(derived().rows()),Specialized);
-}
-
-template<typename Indices>
-typename IvcColType<Indices>::type
-ivcCol(const Indices& indices) const {
- return internal::makeIndexedViewCompatible(indices, internal::variable_if_dynamic<Index,ColsAtCompileTime>(derived().cols()),Specialized);
-}
-
-template<typename Indices>
-typename IvcColType<Indices>::type
-ivcSize(const Indices& indices) const {
- return internal::makeIndexedViewCompatible(indices, internal::variable_if_dynamic<Index,SizeAtCompileTime>(derived().size()),Specialized);
-}
-
-template<typename RowIndices, typename ColIndices>
-struct valid_indexed_view_overload {
- // Here we use is_convertible to Index instead of is_integral in order to treat enums as Index.
- // In c++11 we could use is_integral<T> && is_enum<T> if is_convertible appears to be too permissive.
- enum { value = !(internal::is_convertible<RowIndices,Index>::value && internal::is_convertible<ColIndices,Index>::value) };
-};
-
-public:
-
-#endif
-
-template<typename RowIndices, typename ColIndices>
-struct EIGEN_INDEXED_VIEW_METHOD_TYPE {
- typedef IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,
- typename IvcRowType<RowIndices>::type,
- typename IvcColType<ColIndices>::type> type;
-};
-
-// This is the generic version
-
-template<typename RowIndices, typename ColIndices>
-typename internal::enable_if<valid_indexed_view_overload<RowIndices,ColIndices>::value
- && internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::ReturnAsIndexedView,
- typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type >::type
-operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- return typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type
- (derived(), ivcRow(rowIndices), ivcCol(colIndices));
-}
-
-// The following overload returns a Block<> object
-
-template<typename RowIndices, typename ColIndices>
-typename internal::enable_if<valid_indexed_view_overload<RowIndices,ColIndices>::value
- && internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::ReturnAsBlock,
- typename internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::BlockType>::type
-operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- typedef typename internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::BlockType BlockType;
- typename IvcRowType<RowIndices>::type actualRowIndices = ivcRow(rowIndices);
- typename IvcColType<ColIndices>::type actualColIndices = ivcCol(colIndices);
- return BlockType(derived(),
- internal::first(actualRowIndices),
- internal::first(actualColIndices),
- internal::size(actualRowIndices),
- internal::size(actualColIndices));
-}
-
-// The following overload returns a Scalar
-
-template<typename RowIndices, typename ColIndices>
-typename internal::enable_if<valid_indexed_view_overload<RowIndices,ColIndices>::value
- && internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::ReturnAsScalar,
- CoeffReturnType >::type
-operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- return Base::operator()(internal::eval_expr_given_size(rowIndices,rows()),internal::eval_expr_given_size(colIndices,cols()));
-}
-
-#if EIGEN_HAS_STATIC_ARRAY_TEMPLATE
-
-// The folowing three overloads are needed to handle raw Index[N] arrays.
-
-template<typename RowIndicesT, std::size_t RowIndicesN, typename ColIndices>
-IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],typename IvcColType<ColIndices>::type>
-operator()(const RowIndicesT (&rowIndices)[RowIndicesN], const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],typename IvcColType<ColIndices>::type>
- (derived(), rowIndices, ivcCol(colIndices));
-}
-
-template<typename RowIndices, typename ColIndicesT, std::size_t ColIndicesN>
-IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcRowType<RowIndices>::type, const ColIndicesT (&)[ColIndicesN]>
-operator()(const RowIndices& rowIndices, const ColIndicesT (&colIndices)[ColIndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcRowType<RowIndices>::type,const ColIndicesT (&)[ColIndicesN]>
- (derived(), ivcRow(rowIndices), colIndices);
-}
-
-template<typename RowIndicesT, std::size_t RowIndicesN, typename ColIndicesT, std::size_t ColIndicesN>
-IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN], const ColIndicesT (&)[ColIndicesN]>
-operator()(const RowIndicesT (&rowIndices)[RowIndicesN], const ColIndicesT (&colIndices)[ColIndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],const ColIndicesT (&)[ColIndicesN]>
- (derived(), rowIndices, colIndices);
-}
-
-#endif // EIGEN_HAS_STATIC_ARRAY_TEMPLATE
-
-// Overloads for 1D vectors/arrays
-
-template<typename Indices>
-typename internal::enable_if<
- IsRowMajor && (!(internal::get_compile_time_incr<typename IvcType<Indices>::type>::value==1 || internal::is_integral<Indices>::value)),
- IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,typename IvcType<Indices>::type> >::type
-operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,typename IvcType<Indices>::type>
- (derived(), IvcIndex(0), ivcCol(indices));
-}
-
-template<typename Indices>
-typename internal::enable_if<
- (!IsRowMajor) && (!(internal::get_compile_time_incr<typename IvcType<Indices>::type>::value==1 || internal::is_integral<Indices>::value)),
- IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcType<Indices>::type,IvcIndex> >::type
-operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcType<Indices>::type,IvcIndex>
- (derived(), ivcRow(indices), IvcIndex(0));
-}
-
-template<typename Indices>
-typename internal::enable_if<
- (internal::get_compile_time_incr<typename IvcType<Indices>::type>::value==1) && (!internal::is_integral<Indices>::value) && (!Symbolic::is_symbolic<Indices>::value),
- VectorBlock<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,internal::array_size<Indices>::value> >::type
-operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- typename IvcType<Indices>::type actualIndices = ivcSize(indices);
- return VectorBlock<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,internal::array_size<Indices>::value>
- (derived(), internal::first(actualIndices), internal::size(actualIndices));
-}
-
-template<typename IndexType>
-typename internal::enable_if<Symbolic::is_symbolic<IndexType>::value, CoeffReturnType >::type
-operator()(const IndexType& id) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- return Base::operator()(internal::eval_expr_given_size(id,size()));
-}
-
-#if EIGEN_HAS_STATIC_ARRAY_TEMPLATE
-
-template<typename IndicesT, std::size_t IndicesN>
-typename internal::enable_if<IsRowMajor,
- IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,const IndicesT (&)[IndicesN]> >::type
-operator()(const IndicesT (&indices)[IndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,const IndicesT (&)[IndicesN]>
- (derived(), IvcIndex(0), indices);
-}
-
-template<typename IndicesT, std::size_t IndicesN>
-typename internal::enable_if<!IsRowMajor,
- IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const IndicesT (&)[IndicesN],IvcIndex> >::type
-operator()(const IndicesT (&indices)[IndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const IndicesT (&)[IndicesN],IvcIndex>
- (derived(), indices, IvcIndex(0));
-}
-
-#endif // EIGEN_HAS_STATIC_ARRAY_TEMPLATE
-
-#undef EIGEN_INDEXED_VIEW_METHOD_CONST
-#undef EIGEN_INDEXED_VIEW_METHOD_TYPE
-
-#ifndef EIGEN_INDEXED_VIEW_METHOD_2ND_PASS
-#define EIGEN_INDEXED_VIEW_METHOD_2ND_PASS
-#include "IndexedViewMethods.h"
-#undef EIGEN_INDEXED_VIEW_METHOD_2ND_PASS
-#endif
-
-#else // EIGEN_PARSED_BY_DOXYGEN
-
-/**
- * \returns a generic submatrix view defined by the rows and columns indexed \a rowIndices and \a colIndices respectively.
- *
- * Each parameter must either be:
- * - An integer indexing a single row or column
- * - Eigen::all indexing the full set of respective rows or columns in increasing order
- * - An ArithmeticSequence as returned by the Eigen::seq and Eigen::seqN functions
- * - Any %Eigen's vector/array of integers or expressions
- * - Plain C arrays: \c int[N]
- * - And more generally any type exposing the following two member functions:
- * \code
- * <integral type> operator[](<integral type>) const;
- * <integral type> size() const;
- * \endcode
- * where \c <integral \c type> stands for any integer type compatible with Eigen::Index (i.e. \c std::ptrdiff_t).
- *
- * The last statement implies compatibility with \c std::vector, \c std::valarray, \c std::array, many of the Range-v3's ranges, etc.
- *
- * If the submatrix can be represented using a starting position \c (i,j) and positive sizes \c (rows,columns), then this
- * method will returns a Block object after extraction of the relevant information from the passed arguments. This is the case
- * when all arguments are either:
- * - An integer
- * - Eigen::all
- * - An ArithmeticSequence with compile-time increment strictly equal to 1, as returned by Eigen::seq(a,b), and Eigen::seqN(a,N).
- *
- * Otherwise a more general IndexedView<Derived,RowIndices',ColIndices'> object will be returned, after conversion of the inputs
- * to more suitable types \c RowIndices' and \c ColIndices'.
- *
- * For 1D vectors and arrays, you better use the operator()(const Indices&) overload, which behave the same way but taking a single parameter.
- *
- * \sa operator()(const Indices&), class Block, class IndexedView, DenseBase::block(Index,Index,Index,Index)
- */
-template<typename RowIndices, typename ColIndices>
-IndexedView_or_Block
-operator()(const RowIndices& rowIndices, const ColIndices& colIndices);
-
-/** This is an overload of operator()(const RowIndices&, const ColIndices&) for 1D vectors or arrays
- *
- * \only_for_vectors
- */
-template<typename Indices>
-IndexedView_or_VectorBlock
-operator()(const Indices& indices);
-
-#endif // EIGEN_PARSED_BY_DOXYGEN
diff --git a/eigen/bench/btl/actions/basic_actions.hh b/eigen/bench/btl/actions/basic_actions.hh
index 62442f0..a3333ea 100644
--- a/eigen/bench/btl/actions/basic_actions.hh
+++ b/eigen/bench/btl/actions/basic_actions.hh
@@ -6,7 +6,7 @@
#include "action_atv_product.hh"
#include "action_matrix_matrix_product.hh"
-#include "action_ata_product.hh"
+// #include "action_ata_product.hh"
#include "action_aat_product.hh"
#include "action_trisolve.hh"
diff --git a/eigen/bench/btl/libs/BLAS/blas_interface_impl.hh b/eigen/bench/btl/libs/BLAS/blas_interface_impl.hh
index 9e0a649..fc4ba2a 100644
--- a/eigen/bench/btl/libs/BLAS/blas_interface_impl.hh
+++ b/eigen/bench/btl/libs/BLAS/blas_interface_impl.hh
@@ -46,9 +46,9 @@ public :
BLAS_FUNC(gemm)(&notrans,&notrans,&N,&N,&N,&fone,A,&N,B,&N,&fzero,X,&N);
}
- static inline void ata_product(gene_matrix & A, gene_matrix & X, int N){
- BLAS_FUNC(syrk)(&lower,&trans,&N,&N,&fone,A,&N,&fzero,X,&N);
- }
+// static inline void ata_product(gene_matrix & A, gene_matrix & X, int N){
+// ssyrk_(&lower,&trans,&N,&N,&fone,A,&N,&fzero,X,&N);
+// }
static inline void aat_product(gene_matrix & A, gene_matrix & X, int N){
BLAS_FUNC(syrk)(&lower,&notrans,&N,&N,&fone,A,&N,&fzero,X,&N);
diff --git a/eigen/bench/btl/libs/BLAS/main.cpp b/eigen/bench/btl/libs/BLAS/main.cpp
index fd99149..564d55e 100644
--- a/eigen/bench/btl/libs/BLAS/main.cpp
+++ b/eigen/bench/btl/libs/BLAS/main.cpp
@@ -48,7 +48,7 @@ int main()
bench<Action_rot<blas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
bench<Action_matrix_matrix_product<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
- bench<Action_ata_product<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_ata_product<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
bench<Action_aat_product<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
bench<Action_trisolve<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
diff --git a/eigen/bench/btl/libs/STL/STL_interface.hh b/eigen/bench/btl/libs/STL/STL_interface.hh
index 16658c4..ef4cc92 100644
--- a/eigen/bench/btl/libs/STL/STL_interface.hh
+++ b/eigen/bench/btl/libs/STL/STL_interface.hh
@@ -78,18 +78,18 @@ public :
cible[i][j]=source[i][j];
}
- static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N)
- {
- real somme;
- for (int j=0;j<N;j++){
- for (int i=0;i<N;i++){
- somme=0.0;
- for (int k=0;k<N;k++)
- somme += A[i][k]*A[j][k];
- X[j][i]=somme;
- }
- }
- }
+// static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N)
+// {
+// real somme;
+// for (int j=0;j<N;j++){
+// for (int i=0;i<N;i++){
+// somme=0.0;
+// for (int k=0;k<N;k++)
+// somme += A[i][k]*A[j][k];
+// X[j][i]=somme;
+// }
+// }
+// }
static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N)
{
diff --git a/eigen/bench/btl/libs/blaze/blaze_interface.hh b/eigen/bench/btl/libs/blaze/blaze_interface.hh
index 7b418f6..ee15239 100644
--- a/eigen/bench/btl/libs/blaze/blaze_interface.hh
+++ b/eigen/bench/btl/libs/blaze/blaze_interface.hh
@@ -20,7 +20,6 @@
#include <blaze/Math.h>
#include <blaze/Blaze.h>
-#include <Eigen/Core>
// using namespace blaze;
#include <vector>
@@ -81,35 +80,35 @@ public :
}
}
- static EIGEN_DONT_INLINE void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
X = (A*B);
}
- static EIGEN_DONT_INLINE void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ static inline void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
X = (trans(A)*trans(B));
}
- static EIGEN_DONT_INLINE void ata_product(const gene_matrix & A, gene_matrix & X, int N){
+ static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N){
X = (trans(A)*A);
}
- static EIGEN_DONT_INLINE void aat_product(const gene_matrix & A, gene_matrix & X, int N){
+ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){
X = (A*trans(A));
}
- static EIGEN_DONT_INLINE void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
X = (A*B);
}
- static EIGEN_DONT_INLINE void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
X = (trans(A)*B);
}
- static EIGEN_DONT_INLINE void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){
+ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){
Y += coef * X;
}
- static EIGEN_DONT_INLINE void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){
+ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){
Y = a*X + b*Y;
}
diff --git a/eigen/bench/btl/libs/blaze/main.cpp b/eigen/bench/btl/libs/blaze/main.cpp
index ccae0cb..80e8f4e 100644
--- a/eigen/bench/btl/libs/blaze/main.cpp
+++ b/eigen/bench/btl/libs/blaze/main.cpp
@@ -30,9 +30,9 @@ int main()
bench<Action_matrix_vector_product<blaze_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
bench<Action_atv_product<blaze_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
- bench<Action_matrix_matrix_product<blaze_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
- bench<Action_ata_product<blaze_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
- bench<Action_aat_product<blaze_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_matrix_matrix_product<blaze_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_ata_product<blaze_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_aat_product<blaze_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
return 0;
}
diff --git a/eigen/bench/btl/libs/eigen3/eigen3_interface.hh b/eigen/bench/btl/libs/eigen3/eigen3_interface.hh
index 2e302d0..b821fd7 100644
--- a/eigen/bench/btl/libs/eigen3/eigen3_interface.hh
+++ b/eigen/bench/btl/libs/eigen3/eigen3_interface.hh
@@ -92,11 +92,9 @@ public :
X.noalias() = A.transpose()*B.transpose();
}
- static inline void ata_product(const gene_matrix & A, gene_matrix & X, int /*N*/){
- //X.noalias() = A.transpose()*A;
- X.template triangularView<Lower>().setZero();
- X.template selfadjointView<Lower>().rankUpdate(A.transpose());
- }
+// static inline void ata_product(const gene_matrix & A, gene_matrix & X, int /*N*/){
+// X.noalias() = A.transpose()*A;
+// }
static inline void aat_product(const gene_matrix & A, gene_matrix & X, int /*N*/){
X.template triangularView<Lower>().setZero();
diff --git a/eigen/bench/btl/libs/eigen3/main_matmat.cpp b/eigen/bench/btl/libs/eigen3/main_matmat.cpp
index 052810a..926fa2b 100644
--- a/eigen/bench/btl/libs/eigen3/main_matmat.cpp
+++ b/eigen/bench/btl/libs/eigen3/main_matmat.cpp
@@ -25,7 +25,7 @@ BTL_MAIN;
int main()
{
bench<Action_matrix_matrix_product<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
- bench<Action_ata_product<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_ata_product<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
bench<Action_aat_product<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
bench<Action_trmm<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
diff --git a/eigen/bench/perf_monitoring/gemm.cpp b/eigen/bench/perf_monitoring/gemm.cpp
deleted file mode 100644
index 804139d..0000000
--- a/eigen/bench/perf_monitoring/gemm.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "gemm_common.h"
-
-EIGEN_DONT_INLINE
-void gemm(const Mat &A, const Mat &B, Mat &C)
-{
- C.noalias() += A * B;
-}
-
-int main(int argc, char **argv)
-{
- return main_gemm(argc, argv, gemm);
-}
diff --git a/eigen/bench/perf_monitoring/changesets.txt b/eigen/bench/perf_monitoring/gemm/changesets.txt
index 960699c..af8eb9b 100644
--- a/eigen/bench/perf_monitoring/changesets.txt
+++ b/eigen/bench/perf_monitoring/gemm/changesets.txt
@@ -25,12 +25,13 @@ before-evaluators
#6742:0cbd6195e829 # merge default to tensors
#6747:853d2bafeb8f # Generalized the gebp apis
6765:71584fd55762 # Made the blocking computation aware of the l3 cache; Also optimized the blocking parameters to take into account the number of threads used for a computation
-6781:9cc5a931b2c6 # generalized gemv
-6792:f6e1daab600a # ensured that contractions that can be reduced to a matrix vector product
+#6781:9cc5a931b2c6 # generalized gemv
+#6792:f6e1daab600a # ensured that contractions that can be reduced to a matrix vector product
#6844:039efd86b75c # merge tensor
6845:7333ed40c6ef # change prefetching in gebp
#6856:b5be5e10eb7f # merge index conversion
-6893:c3a64aba7c70 # clean blocking size computation
+#6893:c3a64aba7c70 # clean blocking size computation
+#6898:6fb31ebe6492 # rotating kernel for ARM
6899:877facace746 # rotating kernel for ARM only
#6904:c250623ae9fa # result_of
6921:915f1b1fc158 # fix prefetching change for ARM
@@ -49,7 +50,6 @@ before-evaluators
7098:b6f1db9cf9ec # Bug 992: don't select a 3p GEMM path with non-vectorizable scalar types, this hits unsupported paths in symm/triangular products code
7591:09a8e2186610 # 3.3-alpha1
7650:b0f3c8f43025 # help clang inlining
-7708:dfc6ab9d9458 # Improve numerical accuracy in LLT and triangular solve by using true scalar divisions (instead of x * (1/y))
#8744:74b789ada92a # Improved the matrix multiplication blocking in the case where mr is not a power of 2 (e.g on Haswell CPUs)
8789:efcb912e4356 # Made the index type a template parameter to evaluateProductBlockingSizes. Use numext::mini and numext::maxi instead of std::min/std::max to compute blocking sizes
8972:81d53c711775 # Don't optimize the processing of the last rows of a matrix matrix product in cases that violate the assumptions made by the optimized code path
@@ -59,13 +59,3 @@ before-evaluators
9174:d228bc282ac9 # merge
9212:c90098affa7b # Fix performance regression introduced in changeset 8aad8f35c955
9213:9f1c14e4694b # Fix performance regression in dgemm introduced by changeset 81d53c711775
-9361:69d418c06999 # 3.3-beta2
-9583:bef509908b9d # 3.3-rc1
-9792:26667be4f70b # 3.3.0
-9942:b1d3eba60130 # Operators += and -= do not resize!
-9943:79bb9887afd4 # Ease compiler job to generate clean and efficient code in mat*vec
-9946:2213991340ea # Complete rewrite of column-major-matrix * vector product to deliver higher performance of modern CPU.
-9955:630471c3298c # Improve performance of row-major-dense-matrix * vector products for recent CPUs. (this is the next changeset fixing a typo)
-9975:2eeed9de710c # Revert vec/y to vec*(1/y) in row-major TRSM
-
-
diff --git a/eigen/bench/perf_monitoring/gemm_common.h b/eigen/bench/perf_monitoring/gemm/gemm.cpp
index 30dbc0d..614bd47 100644
--- a/eigen/bench/perf_monitoring/gemm_common.h
+++ b/eigen/bench/perf_monitoring/gemm/gemm.cpp
@@ -1,9 +1,8 @@
#include <iostream>
#include <fstream>
#include <vector>
-#include <string>
-#include "eigen_src/Eigen/Core"
-#include "../BenchTimer.h"
+#include <Eigen/Core>
+#include "../../BenchTimer.h"
using namespace Eigen;
#ifndef SCALAR
@@ -14,9 +13,14 @@ typedef SCALAR Scalar;
typedef Matrix<Scalar,Dynamic,Dynamic> Mat;
-template<typename Func>
EIGEN_DONT_INLINE
-double bench(long m, long n, long k, const Func& f)
+void gemm(const Mat &A, const Mat &B, Mat &C)
+{
+ C.noalias() += A * B;
+}
+
+EIGEN_DONT_INLINE
+double bench(long m, long n, long k)
{
Mat A(m,k);
Mat B(k,n);
@@ -40,25 +44,21 @@ double bench(long m, long n, long k, const Func& f)
long rep = std::max(1., std::min(100., up/flops) );
long tries = std::max(tm0, std::min(tm1, up/flops) );
- BENCH(t, tries, rep, f(A,B,C));
+ BENCH(t, tries, rep, gemm(A,B,C));
return 1e-9 * rep * flops / t.best();
}
-template<typename Func>
-int main_gemm(int argc, char **argv, const Func& f)
+int main(int argc, char **argv)
{
std::vector<double> results;
- std::string filename = std::string("gemm_settings.txt");
- if(argc>1)
- filename = std::string(argv[1]);
- std::ifstream settings(filename);
+ std::ifstream settings("gemm_settings.txt");
long m, n, k;
while(settings >> m >> n >> k)
{
//std::cerr << " Testing " << m << " " << n << " " << k << std::endl;
- results.push_back( bench(m, n, k, f) );
+ results.push_back( bench(m, n, k) );
}
std::cout << RowVectorXd::Map(results.data(), results.size());
diff --git a/eigen/bench/perf_monitoring/gemm_settings.txt b/eigen/bench/perf_monitoring/gemm/gemm_settings.txt
index 5c43e1c..5c43e1c 100644
--- a/eigen/bench/perf_monitoring/gemm_settings.txt
+++ b/eigen/bench/perf_monitoring/gemm/gemm_settings.txt
diff --git a/eigen/bench/perf_monitoring/lazy_gemm.cpp b/eigen/bench/perf_monitoring/gemm/lazy_gemm.cpp
index 7733060..6dc3701 100644
--- a/eigen/bench/perf_monitoring/lazy_gemm.cpp
+++ b/eigen/bench/perf_monitoring/gemm/lazy_gemm.cpp
@@ -84,10 +84,7 @@ int main(int argc, char **argv)
{
std::vector<double> results;
- std::string filename = std::string("lazy_gemm_settings.txt");
- if(argc>1)
- filename = std::string(argv[1]);
- std::ifstream settings(filename);
+ std::ifstream settings("lazy_gemm_settings.txt");
long m, n, k, t;
while(settings >> m >> n >> k >> t)
{
diff --git a/eigen/bench/perf_monitoring/lazy_gemm_settings.txt b/eigen/bench/perf_monitoring/gemm/lazy_gemm_settings.txt
index 407d5d4..407d5d4 100644
--- a/eigen/bench/perf_monitoring/lazy_gemm_settings.txt
+++ b/eigen/bench/perf_monitoring/gemm/lazy_gemm_settings.txt
diff --git a/eigen/bench/perf_monitoring/gemm/make_plot.sh b/eigen/bench/perf_monitoring/gemm/make_plot.sh
new file mode 100644
index 0000000..cd3214a
--- /dev/null
+++ b/eigen/bench/perf_monitoring/gemm/make_plot.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# base name of the bench
+# it reads $1.out
+# and generates $1.pdf
+WHAT=$1
+bench=$2
+
+header="rev "
+while read line
+do
+ if [ ! -z '$line' ]; then
+ header="$header \"$line\""
+ fi
+done < $bench"_settings.txt"
+
+echo $header > $WHAT.out.header
+cat $WHAT.out >> $WHAT.out.header
+
+
+echo "set title '$WHAT'" > $WHAT.gnuplot
+echo "set key autotitle columnhead outside " >> $WHAT.gnuplot
+echo "set xtics rotate 1" >> $WHAT.gnuplot
+
+echo "set term pdf color rounded enhanced fontscale 0.35 size 7in,5in" >> $WHAT.gnuplot
+echo set output "'"$WHAT.pdf"'" >> $WHAT.gnuplot
+
+col=`cat $bench"_settings.txt" | wc -l`
+echo "plot for [col=2:$col+1] '$WHAT.out.header' using 0:col:xticlabels(1) with lines" >> $WHAT.gnuplot
+echo " " >> $WHAT.gnuplot
+
+gnuplot -persist < $WHAT.gnuplot
+
+# generate a png file
+# convert -background white -density 120 -rotate 90 -resize 800 +dither -colors 256 -quality 0 $WHAT.ps -background white -flatten .$WHAT.png
+
+# clean
+rm $WHAT.out.header $WHAT.gnuplot \ No newline at end of file
diff --git a/eigen/bench/perf_monitoring/run.sh b/eigen/bench/perf_monitoring/gemm/run.sh
index 2087166..9d6ee40 100644
--- a/eigen/bench/perf_monitoring/run.sh
+++ b/eigen/bench/perf_monitoring/gemm/run.sh
@@ -1,22 +1,17 @@
#!/bin/bash
-# ./run.sh gemm gemm_settings.txt
-# ./run.sh lazy_gemm lazy_gemm_settings.txt
-# ./run.sh gemv gemv_settings.txt
-# ./run.sh trmv_up gemv_square_settings.txt
-# ...
+# ./run.sh gemm
+# ./run.sh lazy_gemm
# Examples of environment variables to be set:
# PREFIX="haswell-fma-"
# CXX_FLAGS="-mfma"
-# CXX=clang++
# Options:
# -up : enforce the recomputation of existing data, and keep best results as a merging strategy
# -s : recompute selected changesets only and keep bests
bench=$1
-settings_file=$2
if echo "$*" | grep '\-up' > /dev/null; then
update=true
@@ -30,16 +25,6 @@ else
selected=false
fi
-WORKING_DIR=${PREFIX:?"default"}
-
-if [ -z "$PREFIX" ]; then
- WORKING_DIR_PREFIX="$WORKING_DIR/"
-else
- WORKING_DIR_PREFIX="$WORKING_DIR/$PREFIX-"
-fi
-echo "WORKING_DIR_PREFIX=$WORKING_DIR_PREFIX"
-mkdir -p $WORKING_DIR
-
global_args="$*"
if [ $selected == true ]; then
@@ -60,7 +45,7 @@ else
cd ..
fi
-if [ -z "$CXX" ]; then
+if [ ! -z '$CXX' ]; then
CXX=g++
fi
@@ -103,7 +88,7 @@ function test_current
fi
res=$prev
count_rev=`echo $prev | wc -w`
- count_ref=`cat $settings_file | wc -l`
+ count_ref=`cat $bench"_settings.txt" | wc -l`
if echo "$global_args" | grep "$rev" > /dev/null; then
rev_found=true
else
@@ -112,9 +97,8 @@ function test_current
# echo $update et $selected et $rev_found because $rev et "$global_args"
# echo $count_rev et $count_ref
if [ $update == true ] || [ $count_rev != $count_ref ] || ([ $selected == true ] && [ $rev_found == true ]); then
- echo "RUN: $CXX -O3 -DNDEBUG -march=native $CXX_FLAGS -I eigen_src $bench.cpp -DSCALAR=$scalar -o $name"
- if $CXX -O3 -DNDEBUG -march=native $CXX_FLAGS -I eigen_src $bench.cpp -DSCALAR=$scalar -o $name; then
- curr=`./$name $settings_file`
+ if $CXX -O2 -DNDEBUG -march=native $CXX_FLAGS -I eigen_src $bench.cpp -DSCALAR=$scalar -o $name; then
+ curr=`./$name`
if [ $count_rev == $count_ref ]; then
echo "merge previous $prev"
echo "with new $curr"
@@ -133,9 +117,9 @@ function test_current
fi
}
-make_backup $WORKING_DIR_PREFIX"s"$bench
-make_backup $WORKING_DIR_PREFIX"d"$bench
-make_backup $WORKING_DIR_PREFIX"c"$bench
+make_backup $PREFIX"s"$bench
+make_backup $PREFIX"d"$bench
+make_backup $PREFIX"c"$bench
cut -f1 -d"#" < changesets.txt | grep -E '[[:alnum:]]' | while read rev
do
@@ -146,27 +130,27 @@ do
actual_rev=`hg identify | cut -f1 -d' '`
cd ..
- test_current $actual_rev float $WORKING_DIR_PREFIX"s"$bench
- test_current $actual_rev double $WORKING_DIR_PREFIX"d"$bench
- test_current $actual_rev "std::complex<double>" $WORKING_DIR_PREFIX"c"$bench
+ test_current $actual_rev float $PREFIX"s"$bench
+ test_current $actual_rev double $PREFIX"d"$bench
+ test_current $actual_rev "std::complex<double>" $PREFIX"c"$bench
fi
done
echo "Float:"
-cat $WORKING_DIR_PREFIX"s""$bench.out"
+cat $PREFIX"s""$bench.out"
echo " "
echo "Double:"
-cat $WORKING_DIR_PREFIX"d""$bench.out"
+cat $PREFIX"d""$bench.out"
echo ""
echo "Complex:"
-cat $WORKING_DIR_PREFIX"c""$bench.out"
+cat $PREFIX"c""$bench.out"
echo ""
-./make_plot.sh $WORKING_DIR_PREFIX"s"$bench $bench $settings_file
-./make_plot.sh $WORKING_DIR_PREFIX"d"$bench $bench $settings_file
-./make_plot.sh $WORKING_DIR_PREFIX"c"$bench $bench $settings_file
+./make_plot.sh $PREFIX"s"$bench $bench
+./make_plot.sh $PREFIX"d"$bench $bench
+./make_plot.sh $PREFIX"c"$bench $bench
diff --git a/eigen/bench/perf_monitoring/gemm_square_settings.txt b/eigen/bench/perf_monitoring/gemm_square_settings.txt
deleted file mode 100644
index 98474d1..0000000
--- a/eigen/bench/perf_monitoring/gemm_square_settings.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-8 8 8
-9 9 9
-12 12 12
-15 15 15
-16 16 16
-24 24 24
-102 102 102
-239 239 239
-240 240 240
-2400 2400 2400
-2463 2463 2463
diff --git a/eigen/bench/perf_monitoring/gemv.cpp b/eigen/bench/perf_monitoring/gemv.cpp
deleted file mode 100644
index 82e5ab9..0000000
--- a/eigen/bench/perf_monitoring/gemv.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "gemv_common.h"
-
-EIGEN_DONT_INLINE
-void gemv(const Mat &A, const Vec &B, Vec &C)
-{
- C.noalias() += A * B;
-}
-
-int main(int argc, char **argv)
-{
- return main_gemv(argc, argv, gemv);
-}
diff --git a/eigen/bench/perf_monitoring/gemv_common.h b/eigen/bench/perf_monitoring/gemv_common.h
deleted file mode 100644
index cc32577..0000000
--- a/eigen/bench/perf_monitoring/gemv_common.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#include <iostream>
-#include <fstream>
-#include <vector>
-#include <string>
-#include <functional>
-#include "eigen_src/Eigen/Core"
-#include "../BenchTimer.h"
-using namespace Eigen;
-
-#ifndef SCALAR
-#error SCALAR must be defined
-#endif
-
-typedef SCALAR Scalar;
-
-typedef Matrix<Scalar,Dynamic,Dynamic> Mat;
-typedef Matrix<Scalar,Dynamic,1> Vec;
-
-template<typename Func>
-EIGEN_DONT_INLINE
-double bench(long m, long n, Func &f)
-{
- Mat A(m,n);
- Vec B(n);
- Vec C(m);
- A.setRandom();
- B.setRandom();
- C.setRandom();
-
- BenchTimer t;
-
- double up = 1e8/sizeof(Scalar);
- double tm0 = 4, tm1 = 10;
- if(NumTraits<Scalar>::IsComplex)
- {
- up /= 4;
- tm0 = 2;
- tm1 = 4;
- }
-
- double flops = 2. * m * n;
- long rep = std::max(1., std::min(100., up/flops) );
- long tries = std::max(tm0, std::min(tm1, up/flops) );
-
- BENCH(t, tries, rep, f(A,B,C));
-
- return 1e-9 * rep * flops / t.best();
-}
-
-template<typename Func>
-int main_gemv(int argc, char **argv, Func& f)
-{
- std::vector<double> results;
-
- std::string filename = std::string("gemv_settings.txt");
- if(argc>1)
- filename = std::string(argv[1]);
- std::ifstream settings(filename);
- long m, n;
- while(settings >> m >> n)
- {
- //std::cerr << " Testing " << m << " " << n << std::endl;
- results.push_back( bench(m, n, f) );
- }
-
- std::cout << RowVectorXd::Map(results.data(), results.size());
-
- return 0;
-}
diff --git a/eigen/bench/perf_monitoring/gemv_settings.txt b/eigen/bench/perf_monitoring/gemv_settings.txt
deleted file mode 100644
index 21a5ee0..0000000
--- a/eigen/bench/perf_monitoring/gemv_settings.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-8 8
-9 9
-24 24
-239 239
-240 240
-2400 24
-24 2400
-24 240
-2400 2400
-4800 23
-23 4800
diff --git a/eigen/bench/perf_monitoring/gemv_square_settings.txt b/eigen/bench/perf_monitoring/gemv_square_settings.txt
deleted file mode 100644
index 5165759..0000000
--- a/eigen/bench/perf_monitoring/gemv_square_settings.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-8 8
-9 9
-12 12
-15 15
-16 16
-24 24
-53 53
-74 74
-102 102
-239 239
-240 240
-2400 2400
-2463 2463
diff --git a/eigen/bench/perf_monitoring/gemvt.cpp b/eigen/bench/perf_monitoring/gemvt.cpp
deleted file mode 100644
index fe94576..0000000
--- a/eigen/bench/perf_monitoring/gemvt.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "gemv_common.h"
-
-EIGEN_DONT_INLINE
-void gemv(const Mat &A, Vec &B, const Vec &C)
-{
- B.noalias() += A.transpose() * C;
-}
-
-int main(int argc, char **argv)
-{
- return main_gemv(argc, argv, gemv);
-}
diff --git a/eigen/bench/perf_monitoring/llt.cpp b/eigen/bench/perf_monitoring/llt.cpp
deleted file mode 100644
index d55b7d8..0000000
--- a/eigen/bench/perf_monitoring/llt.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "gemm_common.h"
-#include <Eigen/Cholesky>
-
-EIGEN_DONT_INLINE
-void llt(const Mat &A, const Mat &B, Mat &C)
-{
- C = A;
- C.diagonal().array() += 1000;
- Eigen::internal::llt_inplace<Mat::Scalar, Lower>::blocked(C);
-}
-
-int main(int argc, char **argv)
-{
- return main_gemm(argc, argv, llt);
-}
diff --git a/eigen/bench/perf_monitoring/make_plot.sh b/eigen/bench/perf_monitoring/make_plot.sh
deleted file mode 100644
index ca9fa96..0000000
--- a/eigen/bench/perf_monitoring/make_plot.sh
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/bin/bash
-
-# base name of the bench
-# it reads $1.out
-# and generates $1.pdf
-WHAT=$1
-bench=$2
-settings_file=$3
-
-header="rev "
-while read line
-do
- if [ ! -z '$line' ]; then
- header="$header \"$line\""
- fi
-done < $settings_file
-
-echo $header > $WHAT.out.header
-cat $WHAT.out >> $WHAT.out.header
-
-
-echo "set title '$WHAT'" > $WHAT.gnuplot
-echo "set key autotitle columnhead outside " >> $WHAT.gnuplot
-echo "set xtics rotate 1" >> $WHAT.gnuplot
-
-echo "set term pdf color rounded enhanced fontscale 0.35 size 7in,5in" >> $WHAT.gnuplot
-echo set output "'"$WHAT.pdf"'" >> $WHAT.gnuplot
-
-col=`cat $settings_file | wc -l`
-echo "plot for [col=2:$col+1] '$WHAT.out.header' using 0:col:xticlabels(1) with lines" >> $WHAT.gnuplot
-echo " " >> $WHAT.gnuplot
-
-gnuplot -persist < $WHAT.gnuplot
-
-# generate a png file (thumbnail)
-convert -colors 256 -background white -density 300 -resize 300 -quality 0 $WHAT.pdf -background white -flatten $WHAT.png
-
-# clean
-rm $WHAT.out.header $WHAT.gnuplot
-
-
-# generate html/svg graph
-
-echo " " > $WHAT.html
-cat resources/chart_header.html > $WHAT.html
-echo 'var customSettings = {"TITLE":"","SUBTITLE":"","XLABEL":"","YLABEL":""};' >> $WHAT.html
-# 'data' is an array of datasets (i.e. curves), each of which is an object of the form
-# {
-# key: <name of the curve>,
-# color: <optional color of the curve>,
-# values: [{
-# r: <revision number>,
-# v: <GFlops>
-# }]
-# }
-echo 'var data = [' >> $WHAT.html
-
-col=2
-while read line
-do
- if [ ! -z '$line' ]; then
- header="$header \"$line\""
- echo '{"key":"'$line'","values":[' >> $WHAT.html
- i=0
- while read line2
- do
- if [ ! -z '$line2' ]; then
- echo '{"r":'$i',"v":'`echo $line2 | cut -f $col -d ' '`'},' >> $WHAT.html
- fi
- ((i++))
- done < $WHAT.out
- echo ']},' >> $WHAT.html
- fi
- ((col++))
-done < $settings_file
-echo '];' >> $WHAT.html
-
-echo 'var changesets = [' >> $WHAT.html
-while read line2
-do
- if [ ! -z '$line2' ]; then
- echo '"'`echo $line2 | cut -f 1 -d ' '`'",' >> $WHAT.html
- fi
-done < $WHAT.out
-echo '];' >> $WHAT.html
-
-echo 'var changesets_count = [' >> $WHAT.html
-i=0
-while read line2
-do
- if [ ! -z '$line2' ]; then
- echo $i ',' >> $WHAT.html
- fi
- ((i++))
-done < $WHAT.out
-echo '];' >> $WHAT.html
-
-cat resources/chart_footer.html >> $WHAT.html
diff --git a/eigen/bench/perf_monitoring/resources/chart_footer.html b/eigen/bench/perf_monitoring/resources/chart_footer.html
deleted file mode 100644
index 8acc69f..0000000
--- a/eigen/bench/perf_monitoring/resources/chart_footer.html
+++ /dev/null
@@ -1,37 +0,0 @@
- /* setup the chart and its options */
- var chart = nv.models.lineChart()
- .color(d3.scale.category10().range())
- .margin({left: 75, bottom: 100})
- .forceX([0]).forceY([0]);
-
- chart.x(function(datum){ return datum.r; })
- .xAxis.options({
- axisLabel: customSettings.XLABEL || 'Changeset',
- tickFormat: d3.format('.0f')
- });
- chart.xAxis
- .tickValues(changesets_count)
- .tickFormat(function(d){return changesets[d]})
- .rotateLabels(-90);
-
- chart.y(function(datum){ return datum.v; })
- .yAxis.options({
- axisLabel: customSettings.YLABEL || 'GFlops'/*,
- tickFormat: function(val){ return d3.format('.0f')(val) + ' GFlops'; }*/
- });
-
- //chart.useInteractiveGuideline(true);
- d3.select('#chart').datum(data).call(chart);
- var plot = d3.select('#chart > g');
-
- /* setup the title */
- plot.append('text')
- .style('font-size', '24px')
- .attr('text-anchor', 'middle').attr('x', '50%').attr('y', '20px')
- .text(customSettings.TITLE || '');
-
- /* ensure the chart is responsive */
- nv.utils.windowResize(chart.update);
- </script>
- </body>
-</html> \ No newline at end of file
diff --git a/eigen/bench/perf_monitoring/resources/chart_header.html b/eigen/bench/perf_monitoring/resources/chart_header.html
deleted file mode 100644
index bb9ddff..0000000
--- a/eigen/bench/perf_monitoring/resources/chart_header.html
+++ /dev/null
@@ -1,46 +0,0 @@
-
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset='utf-8'>
- <style>.nvd3 .nv-axis line,.nvd3 .nv-axis path{fill:none;shape-rendering:crispEdges}.nv-brush .extent,.nvd3 .background path,.nvd3 .nv-axis line,.nvd3 .nv-axis path{shape-rendering:crispEdges}.nv-distx,.nv-disty,.nv-noninteractive,.nvd3 .nv-axis,.nvd3.nv-pie .nv-label,.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvtooltip,svg.nvd3-svg{display:block;-webkit-touch-callout:none;-khtml-user-select:none}.nvd3 .nv-axis{opacity:1}.nvd3 .nv-axis.nv-disabled,.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3 .nv-axis path{stroke:#000;stroke-opacity:.75}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{stroke:#e5e5e5}.nvd3 .nv-axis .zero line, .nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:transparent}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-discretebar .nv-groups rect,.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover,.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:transparent}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover,.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-markerLine{stroke:#000;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nv-force-node{stroke:#fff;stroke-width:1.5px}.nv-force-link{stroke:#999;stroke-opacity:.6}.nv-force-node text{stroke-width:0}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3 .nv-groups .nv-point.hover,.nvd3.nv-scatter .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}@media print{.nvd3 text{stroke-width:0;fill-opacity:1}}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;stroke:#fff;stroke-width:1px;stroke-opacity:1;fill-opacity:.7}.nvd3.nv-pie .hover path{fill-opacity:1}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-interactiveGuideLine,.nvtooltip{pointer-events:none}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvtooltip h3,.nvtooltip table td.key{font-weight:400}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;color:rgba(0,0,0,1);padding:1px;z-index:10000;font-family:Arial;font-size:13px;text-align:left;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip h3,.nvtooltip p{margin:0;text-align:center}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{padding:4px 14px;line-height:18px;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{padding:5px 14px}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key.total{font-weight:700}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table td.percent{color:#a9a9a9}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{vertical-align:middle;width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 line.nv-guideline{stroke:#ccc}</style>
- <style>
- * {
- box-sizing: border-box;
- }
- html, body {
- position: relative;
- height: 100%;
- width: 100%;
- border: 0;
- margin: 0;
- padding: 0;
- font-size: 0;
- }
- svg g {
- clip-path: none;
- }
- svg text {
- fill: #333;
- }
- .nv-axislabel {
- font-size: 16px !important;
- }
- .control {
- cursor: pointer;
- visibility: hidden;
- pointer-events: visible;
- }
- @media (min-width: 768px) {
- .control {
- visibility: visible;
- }
- }
- </style>
- <script src="s1.js"></script>
- <script src="s2.js"></script>
- </head>
- <body>
- <svg id='chart'></svg>
- <script type='text/javascript'>
- \ No newline at end of file
diff --git a/eigen/bench/perf_monitoring/resources/footer.html b/eigen/bench/perf_monitoring/resources/footer.html
deleted file mode 100644
index 81d8c88..0000000
--- a/eigen/bench/perf_monitoring/resources/footer.html
+++ /dev/null
@@ -1,3 +0,0 @@
-</table>
-</body>
-</html>
diff --git a/eigen/bench/perf_monitoring/resources/header.html b/eigen/bench/perf_monitoring/resources/header.html
deleted file mode 100644
index 1f22309..0000000
--- a/eigen/bench/perf_monitoring/resources/header.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Eigen performance monitoring</title>
-<style type="text/css">
-
-body
-{
- background:#fff;
-}
-th {
-
-}
-img
-{
- width:auto;
- box-shadow:0px 0px 20px #cecece;
- margin: 20px 20px 20px 20px;
- -moz-transform: scale(1);
- -moz-transition-duration: 0.4s;
- -webkit-transition-duration: 0.4s;
- -webkit-transform: scale(1);
-
- -ms-transform: scale(1);
- -ms-transition-duration: 0.4s;
-}
-img:hover
-{
-box-shadow: 5px 5px 20px #dcdcdc;
- -moz-transform: scale(1.1);
- -moz-transition-duration: 0.4s;
- -webkit-transition-duration: 0.4s;
- -webkit-transform: scale(1.1);
-
- -ms-transform: scale(1.1);
- -ms-transition-duration: 0.4s;
-
-}
-</style>
-</head>
-<body>
diff --git a/eigen/bench/perf_monitoring/resources/s1.js b/eigen/bench/perf_monitoring/resources/s1.js
deleted file mode 100644
index cfff2d3..0000000
--- a/eigen/bench/perf_monitoring/resources/s1.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++i<u;)(t=r[i].on)&&t.apply(this,arguments);return n}var e=[],r=new c;return t.on=function(t,i){var u,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,u=e.indexOf(o)).concat(e.slice(u+1)),r.remove(t)),i&&e.push(r.set(t,{on:i})),n)},t}function S(){ao.event.preventDefault()}function k(){for(var n,t=ao.event;n=t.sourceEvent;)t=n;return t}function N(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(i){try{var u=i.sourceEvent=ao.event;i.target=n,ao.event=i,t[i.type].apply(e,r)}finally{ao.event=u}}},t}function E(n){return ko(n,Co),n}function A(n){return"function"==typeof n?n:function(){return No(n,this)}}function C(n){return"function"==typeof n?n:function(){return Eo(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function i(){this.setAttribute(n,t)}function u(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ao.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?u:i}function L(n){return n.trim().replace(/\s+/g," ")}function q(n){return new RegExp("(?:^|\\s+)"+ao.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<i;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<i;)n[e](this,r)}n=T(n).map(D);var i=n.length;return"function"==typeof t?r:e}function D(n){var t=q(n);return function(e,r){if(i=e.classList)return r?i.add(n):i.remove(n);var i=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(i)||e.setAttribute("class",L(i+" "+n))):e.setAttribute("class",L(i.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function i(){this.style.setProperty(n,t,e)}function u(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?u:i}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function i(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?i:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e===zo&&t.documentElement.namespaceURI===zo?t.createElement(n):t.createElementNS(e,n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ao.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return Ao(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t<l;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function i(){var i=l(t,co(arguments));r.call(this),this.addEventListener(n,this[o]=i,i.$=e),i._=t}function u(){var t,e=new RegExp("^__on([^.]+)"+ao.requote(n)+"$");for(var r in this)if(t=r.match(e)){var i=this[r];this.removeEventListener(t[1],i,i.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),l=$;a>0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t<e&&(e=t.t),t=(n=t).n):t=n?n.n=t.n:oa=t.n;return aa=n,e}function Pn(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Un(n,t){var e=Math.pow(10,3*xo(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(l,a)),null!=(i=ya[e=n.charAt(++a)])&&(e=n.charAt(++a)),(u=A[e])&&(e=u(t,null==i?"e"===e?" ":"0":i)),o.push(e),l=a+1);return o.push(n.slice(l,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},i=e(r,n,t,0);if(i!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var u=null!=r.Z&&va!==Hn,o=new(u?Hn:va);return"j"in r?o.setFullYear(r.y,0,r.j):"W"in r||"U"in r?("w"in r||(r.w="W"in r?1:0),o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),u?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var i,u,o,a=0,l=t.length,c=e.length;l>a;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function $n(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Bn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function Wn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Jn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Gn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.y=Qn(+r[0]),e+r[0].length):-1}function Kn(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Qn(n){return n+(n>68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ft(){}function st(n,t,e){var r=e.s=n+t,i=r-n,u=r-i;e.t=n-u+(t-i)}function ht(n,t){n&&wa.hasOwnProperty(n.type)&&wa[n.type](n,t)}function pt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++i<u;)r=n[i],t.point(r[0],r[1],r[2]);t.lineEnd()}function gt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)pt(n[e],t,1);t.polygonEnd()}function vt(){function n(n,t){n*=Yo,t=t*Yo/2+Fo/4;var e=n-r,o=e>=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])<Uo&&xo(n[1]-t[1])<Uo}function St(n,t){n*=Yo;var e=Math.cos(t*=Yo);kt(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function kt(n,t,e){++Ea,Ca+=(n-Ca)/Ea,za+=(t-za)/Ea,La+=(e-La)/Ea}function Nt(){function n(n,i){n*=Yo;var u=Math.cos(i*=Yo),o=u*Math.cos(n),a=u*Math.sin(n),l=Math.sin(i),c=Math.atan2(Math.sqrt((c=e*l-r*a)*c+(c=r*o-t*l)*c+(c=t*a-e*o)*c),t*o+e*a+r*l);Aa+=c,qa+=c*(t+(t=o)),Ta+=c*(e+(e=a)),Ra+=c*(r+(r=l)),kt(t,e,r)}var t,e,r;ja.point=function(i,u){i*=Yo;var o=Math.cos(u*=Yo);t=o*Math.cos(i),e=o*Math.sin(i),r=Math.sin(u),ja.point=n,kt(t,e,r)}}function Et(){ja.point=St}function At(){function n(n,t){n*=Yo;var e=Math.cos(t*=Yo),o=e*Math.cos(n),a=e*Math.sin(n),l=Math.sin(t),c=i*l-u*a,f=u*o-r*l,s=r*a-i*o,h=Math.sqrt(c*c+f*f+s*s),p=r*o+i*a+u*l,g=h&&-nn(p)/h,v=Math.atan2(h,p);Da+=g*c,Pa+=g*f,Ua+=g*s,Aa+=v,qa+=v*(r+(r=o)),Ta+=v*(i+(i=a)),Ra+=v*(u+(u=l)),kt(r,i,u)}var t,e,r,i,u;ja.point=function(o,a){t=o,e=a,ja.point=n,o*=Yo;var l=Math.cos(a*=Yo);r=l*Math.cos(o),i=l*Math.sin(o),u=Math.sin(a),kt(r,i,u)},ja.lineEnd=function(){n(t,e),ja.lineEnd=Et,ja.point=St}}function Ct(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function zt(){return!0}function Lt(n,t,e,r,i){var u=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(wt(e,r)){i.lineStart();for(var a=0;t>a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r<t;)i.n=e=n[r],e.p=i,i=e;i.n=e=n[0],e.p=i}}function Tt(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Rt(n,t,e,r){return function(i,u){function o(t,e){var r=i(t,e);n(t=r[0],e=r[1])&&u.point(t,e)}function a(n,t){var e=i(n,t);d.point(e[0],e[1])}function l(){m.point=a,d.lineStart()}function c(){m.point=o,d.lineEnd()}function f(n,t){v.push([n,t]);var e=i(n,t);x.point(e[0],e[1])}function s(){x.lineStart(),v=[]}function h(){f(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),g.push(v),v=null,r)if(1&t){n=e[0];var i,r=n.length-1,o=-1;if(r>0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o<r;)u.point((i=n[o])[0],i[1]);u.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)<Uo?(n.point(e,r=(r+o)/2>0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)<Uo&&(e-=i*Uo),xo(u-a)<Uo&&(u-=a*Uo),r=Ft(e,r,u,o),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=u,r=o),i=a},lineEnd:function(){n.lineEnd(),e=r=NaN},clean:function(){return 2-t}}}function Ft(n,t,e,r){var i,u,o=Math.sin(n-e);return xo(o)>Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]<t[0]?Fo:-Fo;i=e*u/2,r.point(-u,i),r.point(0,i),r.point(u,i)}else r.point(t[0],t[1])}function Ot(n,t){var e=n[0],r=n[1],i=[Math.sin(e),-Math.cos(e),0],u=0,o=0;ka.reset();for(var a=0,l=t.length;l>a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)<Uo,C=A||Uo>E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)<Uo?k:N):k<=b[1]&&b[1]<=N:E>Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)<Uo?i>0?0:3:xo(r[0]-e)<Uo?i>0?2:1:xo(r[1]-t)<Uo?i>0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)<Uo||xo(r-h)<Uo?(r+h)/2:Math.atan2(_,b),E=n(N,k),A=E[0],C=E[1],z=A-t,L=C-e,q=M*z-m*L;(q*q/x>u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)<Uo?ce:(e.invert=function(n,t){var e=u-t;return[Math.atan2(n,e)/i,u-K(i)*Math.sqrt(n*n+e*e)]},e)}function Ne(n,t){return[n,Math.log(Math.tan(Fo/4+t/2))]}function Ee(n){var t,e=oe(n),r=e.scale,i=e.translate,u=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=i.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=u.apply(e,arguments);if(o===e){if(t=null==n){var a=Fo*r(),l=i();u([[l[0]-a,l[1]-a],[l[0]+a,l[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Ae(n,t){return[Math.log(Math.tan(Fo/4+t/2)),-n]}function Ce(n){return n[0]}function ze(n){return n[1]}function Le(n){for(var t=n.length,e=[0,1],r=2,i=2;t>i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)<Uo&&xo(r-l.circle.cy)<Uo;)u=l.P,a.unshift(l),je(l),l=u;a.unshift(l),Be(l);for(var c=o;c.circle&&xo(e-c.circle.x)<Uo&&xo(r-c.circle.cy)<Uo;)o=c.N,a.push(c),je(c),c=o;a.push(c),Be(c);var f,s=a.length;for(f=1;s>f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)<Uo&&g-i>Uo?{x:s,y:xo(t-s)<Uo?e:g}:xo(i-g)<Uo&&h-r>Uo?{x:xo(e-g)<Uo?t:h,y:g}:xo(r-h)<Uo&&i-p>Uo?{x:h,y:xo(t-h)<Uo?e:p}:xo(i-p)<Uo&&r-s>Uo?{x:xo(e-p)<Uo?t:s,y:p}:null),u.site,null)),++l)}function Ve(n,t){return t.angle-n.angle}function Xe(){rr(this),this.x=this.y=this.arc=this.site=this.cy=null}function $e(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,i=n.site,u=e.site;if(r!==u){var o=i.x,a=i.y,l=r.x-o,c=r.y-a,f=u.x-o,s=u.y-a,h=2*(l*s-c*f);if(!(h>=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.y<M.y||y.y===M.y&&y.x<=M.x){if(!M.L){m=M.P;break}M=M.L}else{if(!M.R){m=M;break}M=M.R}ll.insert(m,y),m||(al=y)}}}}function Be(n){var t=n.circle;t&&(t.P||(al=t.N),ll.remove(t),fl.push(t),rr(t),n.circle=null)}function We(n){for(var t,e=il,r=Yt(n[0][0],n[0][1],n[1][0],n[1][1]),i=e.length;i--;)t=e[i],(!Je(t,n)||!r(t)||xo(t.a.x-t.b.x)<Uo&&xo(t.a.y-t.b.y)<Uo)&&(t.a=t.b=null,e.splice(i,1))}function Je(n,t){var e=n.b;if(e)return!0;var r,i,u=n.a,o=t[0][0],a=t[1][0],l=t[0][1],c=t[1][1],f=n.l,s=n.r,h=f.x,p=f.y,g=s.x,v=s.y,d=(h+g)/2,y=(p+v)/2;if(v===p){if(o>d||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.y<l)return}else u={x:d,y:c};e={x:d,y:l}}}else if(r=(h-g)/(v-p),i=y-r*d,-1>r||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.y<l)return}else u={x:(c-i)/r,y:c};e={x:(l-i)/r,y:l}}else if(v>p){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.x<o)return}else u={x:a,y:r*a+i};e={x:o,y:r*o+i}}return n.a=u,n.b=e,!0}function Ge(n,t){this.l=n,this.r=t,this.a=this.b=null}function Ke(n,t,e,r){var i=new Ge(n,t);return il.push(i),e&&nr(i,n,t,e),r&&nr(i,t,n,r),ul[n.i].edges.push(new tr(i,n,t)),ul[t.i].edges.push(new tr(i,t,n)),i}function Qe(n,t,e){var r=new Ge(n,null);return r.a=t,r.b=e,il.push(r),r}function nr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function tr(n,t,e){var r=n.a,i=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(i.x-r.x,r.y-i.y):Math.atan2(r.x-i.x,i.y-r.y)}function er(){this._=null}function rr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function ir(n,t){var e=t,r=t.R,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ur(n,t){var e=t,r=t.L,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function or(n){for(;n.L;)n=n.L;return n}function ar(n,t){var e,r,i,u=n.sort(lr).pop();for(il=[],ul=new Array(n.length),ol=new er,ll=new er;;)if(i=al,u&&(!i||u.y<i.y||u.y===i.y&&u.x<i.x))u.x===e&&u.y===r||(ul[u.i]=new Ye(u),He(u),e=u.x,r=u.y),u=n.pop();else{if(!i)break;Fe(i.arc)}t&&(We(t),Ze(t));var o={cells:ul,edges:il};return ol=ll=il=ul=null,o}function lr(n,t){return t.y-n.y||t.x-n.x}function cr(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function fr(n){return n.x}function sr(n){return n.y}function hr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function pr(n,t,e,r,i,u){if(!n(t,e,r,i,u)){var o=.5*(e+i),a=.5*(r+u),l=t.nodes;l[0]&&pr(n,l[0],e,r,o,a),l[1]&&pr(n,l[1],o,r,i,a),l[2]&&pr(n,l[2],e,a,o,u),l[3]&&pr(n,l[3],o,a,i,u)}}function gr(n,t,e,r,i,u,o){var a,l=1/0;return function c(n,f,s,h,p){if(!(f>u||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return u<t.length&&(i=t.slice(u),a[o]?a[o]+=i:a[++o]=i),a.length<2?l[0]?(t=l[0].x,function(n){return t(n)+""}):function(){return t}:(t=l.length,function(n){for(var e,r=0;t>r;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,i*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Zo,this.translate=[n.e,n.f],this.scale=[r,u],this.skew=u?Math.atan2(i,u)*Zo:0}function Fr(n,t){return n[0]*t[0]+n[1]*t[1]}function Hr(n){var t=Math.sqrt(Fr(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Or(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ir(n){return n.length?n.pop()+",":""}function Yr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push("translate(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else(t[0]||t[1])&&e.push("translate("+t+")")}function Zr(n,t,e,r){n!==t?(n-t>180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i<u;)e[(t=r[i]).i]=t.x(n);return e.join("")}}function Br(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Wr(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Jr(n){for(var t=n.source,e=n.target,r=Kr(t,e),i=[t];t!==r;)t=t.parent,i.push(t);for(var u=i.length;e!==r;)i.splice(u,0,e),e=e.parent;return i}function Gr(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Kr(n,t){if(n===t)return n;for(var e=Gr(n),r=Gr(t),i=e.pop(),u=r.pop(),o=null;i===u;)o=i,i=e.pop(),u=r.pop();return o}function Qr(n){n.fixed|=2}function ni(n){n.fixed&=-7}function ti(n){n.fixed|=4,n.px=n.x,n.py=n.y}function ei(n){n.fixed&=-5}function ri(n,t,e){var r=0,i=0;if(n.charge=0,!n.leaf)for(var u,o=n.nodes,a=o.length,l=-1;++l<a;)u=o[l],null!=u&&(ri(u,t,e),n.charge+=u.charge,r+=u.charge*u.cx,i+=u.charge*u.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var c=t*e[n.point.index];n.charge+=n.pointCharge=c,r+=c*n.point.x,i+=c*n.point.y}n.cx=r/n.charge,n.cy=i/n.charge}function ii(n,t){return ao.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=fi,n}function ui(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(i=n.children)&&(r=i.length))for(var r,i;--r>=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++o<i;)e.push(u[o]);for(;null!=(n=r.pop());)t(n)}function ai(n){return n.children}function li(n){return n.value}function ci(n,t){return t.value-n.value}function fi(n){return ao.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function si(n){return n.x}function hi(n){return n.y}function pi(n,t,e){n.y0=t,n.y=e}function gi(n){return ao.range(n.length)}function vi(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function di(n){for(var t,e=1,r=0,i=n[0][1],u=n.length;u>e;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.r<r.r?Si(r,i=a):Si(r=l,i),o--):(wi(r,u),i=u,t(u))}var y=(f+s)/2,m=(h+p)/2,M=0;for(o=0;c>o;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u<o;)Ci(i[u],t,e,r)}function zi(n,t,e){var r=n.r+e.r,i=t.x-n.x,u=t.y-n.y;if(r&&(i||u)){var o=t.r+e.r,a=i*i+u*u;o*=o,r*=r;var l=.5+(r-o)/(2*a),c=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+l*i+c*u,e.y=n.y+l*u-c*i}else e.x=n.x+r,e.y=n.y}function Li(n,t){return n.parent==t.parent?1:2}function qi(n){var t=n.children;return t.length?t[0]:n.t}function Ti(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ri(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Di(n){for(var t,e=0,r=0,i=n.children,u=i.length;--u>=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)i.push(e(n[o-1],n[o])),u.push(r(t[o-1],t[o]));return function(t){var e=ao.bisect(n,t,1,a)-1;return u[e](i[e](t))}}function Wi(n,t,e,r){function i(){var i=Math.min(n.length,t.length)>2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++<f;)for(var h=s-1;h>0;h--)o.push(u(c)*h);for(c=0;o[c]<a;c++);for(f=o.length;o[f-1]>l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++o<a;)i.has(u=r[o])||i.set(u,n.push(u));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(u=n,o=0,t={t:"range",a:arguments},e):u},e.rangePoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=(l+c)/2,0):(c-l)/(n.length-1+a);return u=r(l+f*a/2,f),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=c=Math.round((l+c)/2),0):(c-l)/(n.length-1+a)|0;return u=r(l+Math.round(f*a/2+(c-l-(n.length-1+a)*f)/2),f),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=(s-f)/(n.length-a+2*l);return u=r(f+h*l,h),c&&u.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=Math.floor((s-f)/(n.length-a+2*l));return u=r(f+Math.round((s-f-(n.length-a)*h)/2),h),c&&u.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Yi(t.a[0])},e.copy=function(){return ou(n,t)},e.domain(n)}function au(n,t){function u(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ao.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ao.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(i).sort(e),u()):n},o.range=function(n){return arguments.length?(t=n,u()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[NaN,NaN]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return au(n,t)},u()}function lu(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(u*(t-n))))]}function i(){return u=e.length/(t-n),o=e.length-1,r}var u,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],i()):[n,t]},r.range=function(n){return arguments.length?(e=n,i()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s<h;)i.call(this,l=t[s],s)?f.push([+p.call(this,l,s),+g.call(this,l,s)]):f.length&&(o(),f=[]);return f.length&&o(),c.length?c.join(""):null}var e=Ce,r=ze,i=zt,u=xu,o=u.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(i=n,t):i},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?u=n:(u=Tl.get(n)||xu).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function xu(n){return n.length>1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("V",(r=n[t])[1],"H",r[0]);return i.join("")}function Su(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r=n[t])[0],"V",r[1]);return i.join("")}function ku(n,t){return n.length<4?xu(n):n[1]+Au(n.slice(1,-1),Cu(n,t))}function Nu(n,t){return n.length<3?bu(n):n[0]+Au((n.push(n[0]),n),Cu([n[n.length-2]].concat(n,[n[1]]),t))}function Eu(n,t){return n.length<3?xu(n):n[0]+Au(n,Cu(n,t))}function Au(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return xu(n);var e=n.length!=t.length,r="",i=n[0],u=n[1],o=t[0],a=o,l=1;if(e&&(r+="Q"+(u[0]-2*o[0]/3)+","+(u[1]-2*o[1]/3)+","+u[0]+","+u[1],i=n[1],l=2),t.length>1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c<t.length;c++,l++)u=n[l],a=t[c],r+="S"+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1]}if(e){var f=n[l];r+="Q"+(u[0]+2*a[0]/3)+","+(u[1]+2*a[1]/3)+","+f[0]+","+f[1]}return r}function Cu(n,t){for(var e,r=[],i=(1-t)/2,u=n[0],o=n[1],a=1,l=n.length;++a<l;)e=u,u=o,o=n[a],r.push([i*(o[0]-e[0]),i*(o[1]-e[1])]);return r}function zu(n){if(n.length<3)return xu(n);var t=1,e=n.length,r=n[0],i=r[0],u=r[1],o=[i,i,i,(r=n[1])[0]],a=[u,u,u,r[1]],l=[i,",",u,"L",Ru(Pl,o),",",Ru(Pl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Du(l,o,a);return n.pop(),l.push("L",r),l.join("")}function Lu(n){if(n.length<4)return xu(n);for(var t,e=[],r=-1,i=n.length,u=[0],o=[0];++r<3;)t=n[r],u.push(t[0]),o.push(t[1]);for(e.push(Ru(Pl,u)+","+Ru(Pl,o)),--r;++r<i;)t=n[r],u.shift(),u.push(t[0]),o.shift(),o.push(t[1]),Du(e,u,o);return e.join("")}function qu(n){for(var t,e,r=-1,i=n.length,u=i+4,o=[],a=[];++r<4;)e=n[r%i],o.push(e[0]),a.push(e[1]);for(t=[Ru(Pl,o),",",Ru(Pl,a)],--r;++r<u;)e=n[r%i],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Du(t,o,a);return t.join("")}function Tu(n,t){var e=n.length-1;if(e)for(var r,i,u=n[0][0],o=n[0][1],a=n[e][0]-u,l=n[e][1]-o,c=-1;++c<=e;)r=n[c],i=c/e,r[0]=t*r[0]+(1-t)*(u+i*a),r[1]=t*r[1]+(1-t)*(o+i*l);return zu(n)}function Ru(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Du(n,t,e){n.push("C",Ru(Rl,t),",",Ru(Rl,e),",",Ru(Dl,t),",",Ru(Dl,e),",",Ru(Pl,t),",",Ru(Pl,e))}function Pu(n,t){return(t[1]-n[1])/(t[0]-n[0])}function Uu(n){for(var t=0,e=n.length-1,r=[],i=n[0],u=n[1],o=r[0]=Pu(i,u);++t<e;)r[t]=(o+(o=Pu(i=u,u=n[t+1])))/2;return r[t]=o,r}function ju(n){for(var t,e,r,i,u=[],o=Uu(n),a=-1,l=n.length-1;++a<l;)t=Pu(n[a],n[a+1]),xo(t)<Uo?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,i=e*e+r*r,i>9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i<u;)t=n[i],e=t[0],r=t[1]-Io,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Ou(n){function t(t){function l(){v.push("M",a(n(y),s),f,c(n(d.reverse()),s),"Z")}for(var h,p,g,v=[],d=[],y=[],m=-1,M=t.length,x=En(e),b=En(i),_=e===r?function(){return p}:En(r),w=i===u?function(){return g}:En(u);++m<M;)o.call(this,h=t[m],m)?(d.push([p=+x.call(this,h,m),g=+b.call(this,h,m)]),y.push([+_.call(this,h,m),+w.call(this,h,m)])):d.length&&(l(),d=[],y=[]);return d.length&&l(),v.length?v.join(""):null}var e=Ce,r=Ce,i=0,u=ze,o=zt,a=xu,l=a.key,c=a,f="L",s=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(i=u=n,t):u},t.y0=function(n){return arguments.length?(i=n,t):i},t.y1=function(n){return arguments.length?(u=n,t):u},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(l="function"==typeof n?a=n:(a=Tl.get(n)||xu).key,c=a.reverse||a,f=a.closed?"M":"L",t):l},t.tension=function(n){return arguments.length?(s=n,t):s},t}function Iu(n){return n.radius}function Yu(n){return[n.x,n.y]}function Zu(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Io;return[e*Math.cos(r),e*Math.sin(r)]}}function Vu(){return 64}function Xu(){return"circle"}function $u(n){var t=Math.sqrt(n/Fo);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Bu(n){return function(){var t,e,r;(t=this[n])&&(r=t[e=t.active])&&(r.timer.c=null,r.timer.t=NaN,--t.count?delete t[e]:delete this[n],t.active+=.5,r.event&&r.event.interrupt.call(this,this.__data__,r.index))}}function Wu(n,t,e){return ko(n,Yl),n.namespace=t,n.id=e,n}function Ju(n,t,e,r){var i=n.id,u=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[u][i].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[u][i].tween.set(t,e)}))}function Gu(n){return null==n&&(n=""),function(){this.textContent=n}}function Ku(n){return null==n?"__transition__":"__transition_"+n+"__"}function Qu(n,t,e,r,i){function u(n){var t=v.delay;return f.t=t+l,n>=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]<Kl[u]/i?u-1:u]:[tc,Ki(n,e)[2]]}return r.invert=function(t){return io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,io(+e+1),t).length}var u=r.domain(),o=Yi(u),a=null==n?i(o,10):"number"==typeof n&&i(o,n);return a&&(n=a[0],t=a[1]),r.domain(Xi(u,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&e>r&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&e>r&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&r>e&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&r>e&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u<o;)if(null!=(r=n[u])&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=n[u])&&(e>r&&(e=r),r>i&&(i=r))}else{for(;++u<o;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=t.call(n,n[u],u))&&(e>r&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o<u;)i(e=+n[o])&&(r+=e);else for(;++o<u;)i(e=+t.call(n,n[o],o))&&(r+=e);return r},ao.mean=function(n,t){var e,u=0,o=n.length,a=-1,l=o;if(1===arguments.length)for(;++a<o;)i(e=r(n[a]))?u+=e:--l;else for(;++a<o;)i(e=r(t.call(n,n[a],a)))?u+=e:--l;return l?u/l:void 0},ao.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),i=+n[r-1],u=e-r;return u?i+u*(n[r]-i):i},ao.median=function(n,t){var u,o=[],a=n.length,l=-1;if(1===arguments.length)for(;++l<a;)i(u=r(n[l]))&&o.push(u);else for(;++l<a;)i(u=r(t.call(n,n[l],l)))&&o.push(u);return o.length?ao.quantile(o.sort(e),.5):void 0},ao.variance=function(n,t){var e,u,o=n.length,a=0,l=0,c=-1,f=0;if(1===arguments.length)for(;++c<o;)i(e=r(n[c]))&&(u=e-a,a+=u/++f,l+=u*(e-a));else for(;++c<o;)i(e=r(t.call(n,n[c],c)))&&(u=e-a,a+=u/++f,l+=u*(e-a));return f>1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t<e;)for(var i,u=-1,a=r[t]=new Array(i);++u<i;)a[u]=n[u][t];return r},ao.zip=function(){return ao.transpose(arguments)},ao.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ao.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ao.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ao.merge=function(n){for(var t,e,r,i=n.length,u=-1,o=0;++u<i;)o+=n[u].length;for(e=new Array(o);--i>=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)<t;)i.push(r/u);return i},ao.map=function(n,t){var e=new c;if(n instanceof c)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,i=-1,u=n.length;if(1===arguments.length)for(;++i<u;)e.set(i,n[i]);else for(;++i<u;)e.set(t.call(n,r=n[i],i),r)}else for(var o in n)e.set(o,n[o]);return e};var bo="__proto__",_o="\x00";l(c,{has:h,get:function(n){return this._[f(n)]},set:function(n,t){return this._[f(n)]=t},remove:p,keys:g,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:s(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t),this._[t])}}),ao.nest=function(){function n(t,o,a){if(a>=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p<g;)(h=d.get(l=v(f=o[p])))?h.push(f):d.set(l,[f]);return t?(f=t(),s=function(e,r){f.set(e,n(t,r,a))}):(f={},s=function(e,r){f[e]=n(t,r,a)}),d.forEach(s),f}function t(n,e){if(e>=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r<i;)n[e=arguments[r]]=M(n,t,t[e]);return n};var wo=["webkit","ms","moz","Moz","o","O"];ao.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o<a;){u.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var l=-1,c=r.length;++l<c;)(i=r[l])?(t.push(e=n.call(i,i.__data__,l,o)),e&&"__data__"in i&&(e.__data__=i.__data__)):t.push(null)}return E(u)},Co.selectAll=function(n){var t,e,r=[];n=C(n);for(var i=-1,u=this.length;++i<u;)for(var o=this[i],a=-1,l=o.length;++a<l;)(e=o[a])&&(r.push(t=co(n.call(e,e.__data__,a,i))),t.parentNode=e);return E(r)};var zo="http://www.w3.org/1999/xhtml",Lo={svg:"http://www.w3.org/2000/svg",xhtml:zo,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ao.ns={prefix:Lo,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++i<r;)if(!t.contains(n[i]))return!1}else for(t=e.getAttribute("class");++i<r;)if(!q(n[i]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},Co.style=function(n,e,r){var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++r<o;)(i=n[r])&&(y.has(d=t.call(i,i.__data__,r))?v[r]=i:y.set(d,i),m[r]=d);for(r=-1;++r<s;)(i=y.get(d=t.call(e,u=e[r],r)))?i!==!0&&(p[r]=i,i.__data__=u):g[r]=H(u),y.set(d,!0);for(r=-1;++r<o;)r in m&&y.get(m[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],u=e[r],i?(i.__data__=u,p[r]=i):g[r]=H(u);for(;s>r;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++u<o;)(i=r[u])&&(n[u]=i.__data__);return n}var a=Z([]),l=E([]),f=E([]);if("function"==typeof n)for(;++u<o;)e(r=this[u],n.call(r,r.parentNode.__data__,u));else for(;++u<o;)e(r=this[u],n);return l.enter=function(){return a},l.exit=function(){return f},l},Co.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},Co.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],i=r.length-1,u=r[i];--i>=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},Co.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},Co.call=function(n){var t=co(arguments);return n.apply(t[0]=this,t),this},Co.empty=function(){return!this.node()},Co.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++a<l;){r=(i=this[a]).update,o.push(t=[]),t.parentNode=i.parentNode;for(var c=-1,f=i.length;++c<f;)(u=i[c])?(t.push(r[c]=e=n.call(i.parentNode,u.__data__,c,a)),e.__data__=u.__data__):t.push(null)}return E(o)},qo.insert=function(n,t){return arguments.length<2&&(t=V(this)),Co.insert.call(this,n,t)},ao.select=function(t){var e;return"string"==typeof t?(e=[No(t,fo)],e.parentNode=fo.documentElement):(e=[t],e.parentNode=n(t)),E([e])},ao.selectAll=function(n){var t;return"string"==typeof n?(t=co(Eo(n,fo)),t.parentNode=fo.documentElement):(t=co(n),t.parentNode=null),E([t])},Co.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++<c;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}f=e+2;var r=n.charCodeAt(e+1);return 13===r?(i=!0,10===n.charCodeAt(e+2)&&++f):10===r&&(i=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;c>f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++r<i;)ht(e[r].geometry,t)}},wa={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){pt(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)pt(e[r],t,0)},Polygon:function(n,t){gt(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)gt(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,i=e.length;++r<i;)ht(e[r],t)}};ao.geo.area=function(n){return Sa=0,ao.geo.stream(n,Na),Sa};var Sa,ka=new ft,Na={sphere:function(){Sa+=4*Fo},point:b,lineStart:b,lineEnd:b,polygonStart:function(){ka.reset(),Na.lineStart=vt},polygonEnd:function(){var n=2*ka;Sa+=0>n?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var f,s,h,p,g,v,d,y,m,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=i,b.lineStart=u,b.lineEnd=o,m=0,Na.polygonStart()},polygonEnd:function(){Na.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>ka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t<f.length-h;++t)p.push(n[a[f[t]][2]]);return p}var e=Ce,r=ze;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ao.geom.polygon=function(n){return ko(n,rl),n};var rl=ao.geom.polygon.prototype=[];rl.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],i=0;++t<e;)n=r,r=this[t],i+=n[1]*r[0]-n[0]*r[1];return.5*i},rl.centroid=function(n){var t,e,r=-1,i=this.length,u=0,o=0,a=this[i-1];for(arguments.length||(n=-1/(6*this.area()));++r<i;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],u+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[u*n,o*n]},rl.clip=function(n){for(var t,e,r,i,u,o,a=De(n),l=-1,c=this.length-De(this),f=this[c-1];++l<c;){for(t=n.slice(),n.length=0,i=this[l],u=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Te(o,f,i)?(Te(u,f,i)||n.push(Re(u,o,f,i)),n.push(o)):Te(u,f,i)&&n.push(Re(u,o,f,i)),u=o;a&&n.push(n[0]),f=i}return n};var il,ul,ol,al,ll,cl=[],fl=[];Ye.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Ve),t.length},tr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},er.prototype={insert:function(n,t){var e,r,i;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=or(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(i=r.R,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.R&&(ir(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ur(this,r))):(i=r.L,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.L&&(ur(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ir(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,i=n.U,u=n.L,o=n.R;if(e=u?o?or(o):u:o,i?i.L===n?i.L=e:i.R=e:this._=e,u&&o?(r=e.C,e.C=n.C,e.L=u,u.U=e,e!==o?(i=e.U,e.U=n.U,n=e.R,i.L=n,e.R=o,o.U=e):(e.U=i,i=e,n=e.R)):(r=n.C,n=e),n&&(n.U=i),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===i.L){if(t=i.R,t.C&&(t.C=!1,i.C=!0,ir(this,i),t=i.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ur(this,t),t=i.R),t.C=i.C,i.C=t.R.C=!1,ir(this,i),n=this._;break}}else if(t=i.L,t.C&&(t.C=!1,i.C=!0,ur(this,i),t=i.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,ir(this,t),t=i.L),t.C=i.C,i.C=t.L.C=!1,ur(this,i),n=this._;break}t.C=!0,n=i,i=i.U}while(!n.C);n&&(n.C=!1)}}},ao.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],i=a[0][1],u=a[1][0],o=a[1][1];return ar(e(n),a).cells.forEach(function(e,a){var l=e.edges,c=e.site,f=t[a]=l.length?l.map(function(n){var t=n.start();return[t.x,t.y]}):c.x>=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l<c;)i=f,u=s,f=a[l].edge,s=f.l===o?f.r:f.l,r<u.i&&r<s.i&&cr(o,u,s)<0&&t.push([n[r],n[u.i],n[s.i]])}),t},t.x=function(n){return arguments.length?(u=En(r=n),t):r},t.y=function(n){return arguments.length?(o=En(i=n),t):i},t.clipExtent=function(n){return arguments.length?(a=null==n?sl:n,t):a===sl?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===sl?null:a&&a[1]},t)};var sl=[[-1e6,-1e6],[1e6,1e6]];ao.geom.delaunay=function(n){return ao.geom.voronoi().triangles(n)},ao.geom.quadtree=function(n,t,e,r,i){function u(n){function u(n,t,e,r,i,u,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var l=n.x,f=n.y;if(null!=l)if(xo(l-e)+xo(f-r)<.01)c(n,t,e,r,i,u,o,a);else{var s=n.point;n.x=n.y=n.point=null,c(n,s,l,f,i,u,o,a),c(n,t,e,r,i,u,o,a)}else n.x=e,n.y=r,n.point=t}else c(n,t,e,r,i,u,o,a)}function c(n,t,e,r,i,o,a,l){var c=.5*(i+a),f=.5*(o+l),s=e>=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.x<v&&(v=f.x),f.y<d&&(d=f.y),f.x>y&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p<g;)u(k,n[p],s[p],h[p],v,d,y,m);--p}else n.forEach(k.add);return s=h=n=f=null,k}var o,a=Ce,l=ze;return(o=arguments.length)?(a=fr,l=sr,3===o&&(i=e,r=t,e=t=0),u(n)):(u.x=function(n){return arguments.length?(a=n,u):a},u.y=function(n){return arguments.length?(l=n,u):l},u.extent=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],i=+n[1][1]),u):null==t?null:[[t,e],[r,i]]},u.size=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=e=0,r=+n[0],i=+n[1]),u):null==t?null:[r-t,i-e]},u)},ao.interpolateRgb=vr,ao.interpolateObject=dr,ao.interpolateNumber=yr,ao.interpolateString=mr;var hl=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,pl=new RegExp(hl.source,"g");ao.interpolate=Mr,ao.interpolators=[function(n,t){var e=typeof t;return("string"===e?ua.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?vr:mr:t instanceof an?vr:Array.isArray(t)?xr:"object"===e&&isNaN(t)?dr:yr)(n,t)}],ao.interpolateArray=xr;var gl=function(){return m},vl=ao.map({linear:gl,poly:Er,quad:function(){return Sr},cubic:function(){return kr},sin:function(){return Ar},exp:function(){return Cr},circle:function(){return zr},elastic:Lr,back:qr,bounce:function(){return Tr}}),dl=ao.map({"in":m,out:_r,"in-out":wr,"out-in":function(n){return wr(_r(n))}});ao.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Jr(n[e]));return t}},ao.layout.chord=function(){function n(){var n,c,s,h,p,g={},v=[],d=ao.range(u),y=[];for(e=[],r=[],n=0,h=-1;++h<u;){for(c=0,p=-1;++p<u;)c+=i[h][p];v.push(c),y.push(ao.range(u)),n+=c}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&y.forEach(function(n,t){n.sort(function(n,e){return a(i[t][n],i[t][e])})}),n=(Ho-f*u)/n,c=0,h=-1;++h<u;){for(s=c,p=-1;++p<u;){var m=d[h],M=y[m][p],x=i[m][M],b=c,_=c+=x*n;g[m+"-"+M]={index:m,subindex:M,startAngle:b,endAngle:_,value:x}}r[m]={index:m,startAngle:s,endAngle:c,value:v[m]},c+=f}for(h=-1;++h<u;)for(p=h-1;++p<u;){var w=g[h+"-"+p],S=g[p+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}l&&t()}function t(){e.sort(function(n,t){return l((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,i,u,o,a,l,c={},f=0;return c.matrix=function(n){return arguments.length?(u=(i=n)&&i.length,e=r=null,c):i},c.padding=function(n){return arguments.length?(f=n,e=r=null,c):f},c.sortGroups=function(n){return arguments.length?(o=n,e=r=null,c):o},c.sortSubgroups=function(n){return arguments.length?(a=n,e=null,c):a},c.sortChords=function(n){return arguments.length?(l=n,e&&t(),c):l},c.chords=function(){return e||n(),e},c.groups=function(){return r||n(),r},c},ao.layout.force=function(){function n(n){return function(t,e,r,i){if(t.point!==n){var u=t.cx-n.x,o=t.cy-n.y,a=i-e,l=u*u+o*o;if(l>a*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++l<f;)if(!isNaN(o=a[l][n]))return o;return Math.random()*r}var t,e,r,i=M.length,c=x.length,s=f[0],v=f[1];for(t=0;i>t;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++c<o;)n(a=u[c],e,l=a.value*r,i),e+=l}}function t(n){var e=n.children,r=0;if(e&&(i=e.length))for(var i,u=-1;++u<i;)r=Math.max(r,t(e[u]));return 1+r}function e(e,u){var o=r.call(this,e,u);return n(o[0],0,i[0],i[1]/t(o[0])),o}var r=ao.layout.hierarchy(),i=[1,1];return e.size=function(n){return arguments.length?(i=n,e):i},ii(e,r)},ao.layout.pie=function(){function n(o){var a,l=o.length,c=o.map(function(e,r){return+t.call(n,e,r)}),f=+("function"==typeof r?r.apply(this,arguments):r),s=("function"==typeof i?i.apply(this,arguments):i)-f,h=Math.min(Math.abs(s)/l,+("function"==typeof u?u.apply(this,arguments):u)),p=h*(0>s?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u<p;)o=l[u]=[],o.dx=s[u+1]-(o.x=s[u]),o.y=0;if(p>0)for(u=-1;++u<h;)a=c[u],a>=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.x<p.x&&(p=n),n.x>g.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++i<u;)r=(e=n[i]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(u>e&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0;if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++u<o;)i=n[u],i.x=a,i.y=c,i.dy=f,a+=i.dx=Math.min(e.x+e.dx-a,f?l(i.area/f):0);i.z=!0,i.dx+=e.x+e.dx-a,e.y+=f,e.dy-=f}else{for((r||f>e.dx)&&(f=e.dx);++u<o;)i=n[u],i.x=a,i.y=c,i.dx=f,c+=i.dy=Math.min(e.y+e.dy-c,f?l(i.area/f):0);i.z=!1,i.dy+=e.y+e.dy-c,e.x+=f,e.dx-=f}}function u(r){var i=o||a(r),u=i[0];return u.x=u.y=0,u.value?(u.dx=c[0],u.dy=c[1]):u.dx=u.dy=0,o&&a.revalue(u),n([u],u.dx*u.dy/u.value),(o?e:t)(u),h&&(o=i),i}var o,a=ao.layout.hierarchy(),l=Math.round,c=[1,1],f=null,s=Oi,h=!1,p="squarify",g=.5*(1+Math.sqrt(5));return u.size=function(n){return arguments.length?(c=n,u):c},u.padding=function(n){function t(t){var e=n.call(u,t,t.depth);return null==e?Oi(t):Ii(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Ii(t,n)}if(!arguments.length)return f;var r;return s=null==(f=n)?Oi:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,u},u.round=function(n){return arguments.length?(l=n?Math.round:Number,u):l!=Number},u.sticky=function(n){return arguments.length?(h=n,o=null,u):h},u.ratio=function(n){return arguments.length?(g=n,u):g},u.mode=function(n){return arguments.length?(p=n+"",u):p},ii(u,a)},ao.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++a<l;){u.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(e=c[f])&&Qu(e,f,i,r,o),t.push(e)}return Wu(u,i,r)},Co.interrupt=function(n){return this.each(null==n?Il:Bu(Ku(n)))};var Hl,Ol,Il=Bu(Ku()),Yl=[],Zl=0;Yl.call=Co.call,Yl.empty=Co.empty,Yl.node=Co.node,Yl.size=Co.size,ao.transition=function(n,t){return n&&n.transition?Hl?n.transition(t):n:ao.selection().transition(n)},ao.transition.prototype=Yl,Yl.select=function(n){var t,e,r,i=this.id,u=this.namespace,o=[];n=A(n);for(var a=-1,l=this.length;++a<l;){o.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(r=c[f])&&(e=n.call(r,r.__data__,f,a))?("__data__"in r&&(e.__data__=r.__data__),Qu(e,f,u,i,r[u][i]),t.push(e)):t.push(null)}return Wu(o,u,i)},Yl.selectAll=function(n){var t,e,r,i,u,o=this.id,a=this.namespace,l=[];n=C(n);for(var c=-1,f=this.length;++c<f;)for(var s=this[c],h=-1,p=s.length;++h<p;)if(r=s[h]){u=r[a][o],e=n.call(r,r.__data__,h,c),l.push(t=[]);for(var g=-1,v=e.length;++g<v;)(i=e[g])&&Qu(i,g,a,o,u),t.push(i)}return Wu(l,a,o)},Yl.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]<M[0])],L[1]=h[+(n[1]<M[1])]):M=null),E&&y(n,c,0)&&(r(k),t=!0),A&&y(n,f,1)&&(i(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function y(n,t,e){var r,i,u=Zi(t),l=u[0],c=u[1],f=L[e],v=e?h:s,d=v[1]-v[0];return C&&(l-=f,c-=d+f),r=(e?g:p)?Math.max(l,Math.min(c,n[e])):n[e],C?i=(r+=f)+d:(M&&(f=Math.max(l,Math.min(c,2*M[e]-r))),r>f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}();
diff --git a/eigen/bench/perf_monitoring/resources/s2.js b/eigen/bench/perf_monitoring/resources/s2.js
deleted file mode 100644
index 54eda2c..0000000
--- a/eigen/bench/perf_monitoring/resources/s2.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(){var a={};a.dev=!1,a.tooltip=a.tooltip||{},a.utils=a.utils||{},a.models=a.models||{},a.charts={},a.logs={},a.dom={},"undefined"!=typeof module&&"undefined"!=typeof exports&&"undefined"==typeof d3&&(d3=require("d3")),a.dispatch=d3.dispatch("render_start","render_end"),Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),a.dev&&(a.dispatch.on("render_start",function(b){a.logs.startTime=+new Date}),a.dispatch.on("render_end",function(b){a.logs.endTime=+new Date,a.logs.totalTime=a.logs.endTime-a.logs.startTime,a.log("total",a.logs.totalTime)})),a.log=function(){if(a.dev&&window.console&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(a.dev&&window.console&&"function"==typeof console.log&&Function.prototype.bind){var b=Function.prototype.bind.call(console.log,console);b.apply(console,arguments)}return arguments[arguments.length-1]},a.deprecated=function(a,b){console&&console.warn&&console.warn("nvd3 warning: `"+a+"` has been deprecated. ",b||"")},a.render=function(b){b=b||1,a.render.active=!0,a.dispatch.render_start();var c=function(){for(var d,e,f=0;b>f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.mutate(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.measure(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],h=!0,i=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(h=!1),d3.event.target.className.baseVal.match("nv-legend")&&(i=!0)),h&&(d-=c.left,e-=c.top),"mouseout"===d3.event.type||0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||i){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(j.nvPointerEventsClass)))return;return g.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void j.hidden(!0)}j.hidden(!1);var l="function"==typeof f.rangeBands,m=void 0;if(l){var n=d3.bisect(f.range(),d)-1;if(!(f.range()[n]+f.rangeBand()>=d))return g.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void j.hidden(!0);m=f.domain()[d3.bisect(f.range(),d)-1]}else m=f.invert(d);g.elementMousemove({mouseX:d,mouseY:e,pointXValue:m}),"dblclick"===d3.event.type&&g.elementDblclick({mouseX:d,mouseY:e,pointXValue:m}),"click"===d3.event.type&&g.elementClick({mouseX:d,mouseY:e,pointXValue:m}),"mousedown"===d3.event.type&&g.elementMouseDown({mouseX:d,mouseY:e,pointXValue:m}),"mouseup"===d3.event.type&&g.elementMouseUp({mouseX:d,mouseY:e,pointXValue:m})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),i&&(i.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("mousedown",m,!0).on("mouseup",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){h&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c={left:0,top:0},d=null,e=null,f=d3.scale.linear(),g=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick","elementMouseDown","elementMouseUp"),h=!0,i=null,j=a.models.tooltip(),k=window.ActiveXObject;return j.duration(0).hideDelay(0).hidden(!1),b.dispatch=g,b.tooltip=j,b.margin=function(a){return arguments.length?(c.top="undefined"!=typeof a.top?a.top:c.top,c.left="undefined"!=typeof a.left?a.left:c.left,b):c},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(f=a,b):f},b.showGuideLine=function(a){return arguments.length?(h=a,b):h},b.svgContainer=function(a){return arguments.length?(i=a,b):i},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},a.models.tooltip=function(){"use strict";function b(){if(!l||!l.node()){var a=[1];l=d3.select(document.body).selectAll(".nvtooltip").data(a),l.enter().append("div").attr("class","nvtooltip "+(i?i:"xy-tooltip")).attr("id",d).style("top",0).style("left",0).style("opacity",0).style("position","fixed").selectAll("div, table, td, tr").classed(q,!0).classed(q,!0),l.exit().remove()}}function c(){return n&&w(e)?(a.dom.write(function(){b();var a=u(e);a&&(l.node().innerHTML=a),y()}),c):void 0}var d="nvtooltip-"+Math.floor(1e5*Math.random()),e=null,f="w",g=25,h=0,i=null,j=!0,k=200,l=null,m={left:null,top:null},n=!0,o=100,p=!0,q="nv-pointer-events-none",r=function(a,b){return a},s=function(a){return a},t=function(a,b){return a},u=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(p){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(s(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).classed("total",function(a){return!!a.total}).html(function(a,b){return t(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return r(a.value,b)}),e.filter(function(a,b){return void 0!==a.percent}).append("td").classed("percent",!0).html(function(a,b){return"("+d3.format("%")(a.percent)+")"}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+="<div class='footer'>"+a.footer+"</div>"),f},v=function(){var a={left:null!==d3.event?d3.event.clientX:0,top:null!==d3.event?d3.event.clientY:0};if("none"!=getComputedStyle(document.body).transform){var b=document.body.getBoundingClientRect();a.left-=b.left,a.top-=b.top}return a},w=function(b){if(b&&b.series){if(a.utils.isArray(b.series))return!0;if(a.utils.isObject(b.series))return b.series=[b.series],!0}return!1},x=function(a){var b,c,d,e=l.node().offsetHeight,h=l.node().offsetWidth,i=document.documentElement.clientWidth,j=document.documentElement.clientHeight;switch(f){case"e":b=-h-g,c=-(e/2),a.left+b<0&&(b=g),(d=a.top+c)<0&&(c-=d),(d=a.top+c+e)>j&&(c-=d-j);break;case"w":b=g,c=-(e/2),a.left+b+h>i&&(b=-h-g),(d=a.top+c)<0&&(c-=d),(d=a.top+c+e)>j&&(c-=d-j);break;case"n":b=-(h/2)-5,c=g,a.top+c+e>j&&(c=-e-g),(d=a.left+b)<0&&(b-=d),(d=a.left+b+h)>i&&(b-=d-i);break;case"s":b=-(h/2),c=-e-g,a.top+c<0&&(c=g),(d=a.left+b)<0&&(b-=d),(d=a.left+b+h)>i&&(b-=d-i);break;case"center":b=-(h/2),c=-(e/2);break;default:b=0,c=0}return{left:b,top:c}},y=function(){a.dom.read(function(){var a=v(),b=x(a),c=a.left+b.left,d=a.top+b.top;if(j)l.interrupt().transition().delay(k).duration(0).style("opacity",0);else{var e="translate("+m.left+"px, "+m.top+"px)",f="translate("+Math.round(c)+"px, "+Math.round(d)+"px)",g=d3.interpolateString(e,f),h=l.style("opacity")<.1;l.interrupt().transition().duration(h?0:o).styleTween("transform",function(a){return g},"important").styleTween("-webkit-transform",function(a){return g}).style("-ms-transform",f).style("opacity",1)}m.left=c,m.top=d})};return c.nvPointerEventsClass=q,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{duration:{get:function(){return o},set:function(a){o=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return n},set:function(a){n=a}},hideDelay:{get:function(){return k},set:function(a){k=a}},contentGenerator:{get:function(){return u},set:function(a){u=a}},valueFormatter:{get:function(){return r},set:function(a){r=a}},headerFormatter:{get:function(){return s},set:function(a){s=a}},keyFormatter:{get:function(){return t},set:function(a){t=a}},headerEnabled:{get:function(){return p},set:function(a){p=a}},position:{get:function(){return v},set:function(a){v=a}},chartContainer:{get:function(){return document.body},set:function(b){a.deprecated("chartContainer","feature removed after 1.8.3")}},fixedTop:{get:function(){return null},set:function(b){a.deprecated("fixedTop","feature removed after 1.8.1")}},offset:{get:function(){return{left:0,top:0}},set:function(b){a.deprecated("offset","use chart.tooltip.distance() instead")}},hidden:{get:function(){return j},set:function(a){j!=a&&(j=!!a,c())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},node:{get:function(){return l.node()},set:function(a){}},id:{get:function(){return d},set:function(a){}}}),a.utils.initOptions(c),c},a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.isArray=Array.isArray,a.utils.isObject=function(a){return null!==a&&"object"==typeof a},a.utils.isFunction=function(a){return"function"==typeof a},a.utils.isDate=function(a){return"[object Date]"===toString.call(a)},a.utils.isNumber=function(a){return!isNaN(a)&&"number"==typeof a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(a.utils.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(b,c,d){c=c||function(a){return a.key},d=d||d3.scale.category20().range();var e=d.length;return function(f,g){var h=c(f);return a.utils.isFunction(b[h])?b[h]():void 0!==b[h]?b[h]:(e||(e=d.length),e-=1,d[e])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(b){if(a.utils.isFunction(b.style)&&a.utils.isFunction(b.text)){var c=parseInt(b.style("font-size").replace("px",""),10),d=b.text().length;return a.utils.NaNtoZero(d*c*.5)}return 0},a.utils.NaNtoZero=function(b){return!a.utils.isNumber(b)||isNaN(b)||null===b||b===1/0||b===-(1/0)?0:b},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(b){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;0===a.length?a.__rendered=!0:a.every(function(a){return!a.length})?a.__rendered=!0:a.__rendered=!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(c,d){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=a.utils.isArray(b[d]),f=a.utils.isObject(b[d]),g=a.utils.isObject(c[d]);f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(b){return b&&d3.map(b).forEach(function(b,c){a.utils.isFunction(this[b])&&this[b](c)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;e<c.length;e+=1){var f=c[e]&&c[e].values?c[e].values.length:0;d=f>d?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return Math.max(0,a.utils.sanitizeHeight(b,c)-d.top-d.bottom)},a.utils.availableWidth=function(b,c,d){return Math.max(0,a.utils.sanitizeWidth(b,c)-d.left-d.right)},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(null,c,e),i=a.utils.availableWidth(null,c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.utils.wrapTicks=function(a,b){a.each(function(){for(var a,c=d3.select(this),d=c.text().split(/\s+/).reverse(),e=[],f=0,g=1.1,h=c.attr("y"),i=parseFloat(c.attr("dy")),j=c.text(null).append("tspan").attr("x",0).attr("y",h).attr("dy",i+"em");a=d.pop();)e.push(a),j.text(e.join(" ")),j.node().getComputedTextLength()>b&&(e.pop(),j.text(e.join(" ")),e=[a],j=c.append("tspan").attr("x",0).attr("y",h).attr("dy",++f*g+i+"em").text(a))})},a.utils.arrayEquals=function(b,c){if(b===c)return!0;if(!b||!c)return!1;if(b.length!=c.length)return!1;for(var d=0,e=b.length;e>d;d++)if(b[d]instanceof Array&&c[d]instanceof Array){if(!a.arrayEquals(b[d],c[d]))return!1}else if(b[d]!=c[d])return!1;return!0},a.models.axis=function(){"use strict";function b(g){return t.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var q=g.selectAll("g.nv-wrap.nv-axis").data([b]),r=q.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),u=(r.append("g"),q.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),u.watchTransition(t,"axis").call(c),s=s||c.scale();var v=c.tickFormat();null==v&&(v=s.tickFormat());var w=u.selectAll("text.nv-axislabel").data([h||null]);w.exit().remove(),void 0!==p&&u.selectAll("g").select("text").style("font-size",p);var x,y,z;switch(c.orient()){case"top":w.enter().append("text").attr("class","nv-axislabel"),z=0,1===d.range().length?z=m?2*d.range()[0]+d.rangeBand():0:2===d.range().length?z=m?d.range()[0]+d.range()[1]+d.rangeBand():d.range()[1]:d.range().length>2&&(z=d.range()[d.range().length-1]+(d.range()[1]-d.range()[0])),w.attr("text-anchor","middle").attr("y",0).attr("x",z/2),i&&(y=q.selectAll("g.nv-axisMaxMin").data(d.domain()),y.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),y.exit().remove(),y.attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a,b){var c=v(a);return(""+c).match("NaN")?"":c}),y.watchTransition(t,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":x=o+36;var A=30,B=0,C=u.selectAll("g").select("text"),D="";if(j%360){C.attr("transform",""),C.each(function(a,b){var c=this.getBoundingClientRect(),d=c.width;B=c.height,d>A&&(A=d)}),D="rotate("+j+" 0,"+(B/2+c.tickPadding())+")";var E=Math.abs(Math.sin(j*Math.PI/180));x=(E?E*A:A)+30,C.attr("transform",D).style("text-anchor",j%360>0?"start":"end")}else l?C.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"}):C.attr("transform","translate(0,0)");w.enter().append("text").attr("class","nv-axislabel"),z=0,1===d.range().length?z=m?2*d.range()[0]+d.rangeBand():0:2===d.range().length?z=m?d.range()[0]+d.range()[1]+d.rangeBand():d.range()[1]:d.range().length>2&&(z=d.range()[d.range().length-1]+(d.range()[1]-d.range()[0])),w.attr("text-anchor","middle").attr("y",x).attr("x",z/2),i&&(y=q.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),y.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),y.exit().remove(),y.attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",D).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a,b){var c=v(a);return(""+c).match("NaN")?"":c}),y.watchTransition(t,"min-max bottom").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}));break;case"right":w.enter().append("text").attr("class","nv-axislabel"),w.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12-(o||0):-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(y=q.selectAll("g.nv-axisMaxMin").data(d.domain()),y.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),y.exit().remove(),y.attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a,b){var c=v(a);return(""+c).match("NaN")?"":c}),y.watchTransition(t,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":w.enter().append("text").attr("class","nv-axislabel"),w.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(y=q.selectAll("g.nv-axisMaxMin").data(d.domain()),y.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),y.exit().remove(),y.attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(s(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a,b){var c=v(a);return(""+c).match("NaN")?"":c}),y.watchTransition(t,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(w.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(u.selectAll("g").each(function(a,b){d3.select(this).select("text").attr("opacity",1),(d(a)<d.range()[1]+10||d(a)>d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&q.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var F=[];q.selectAll("g.nv-axisMaxMin").each(function(a,b){try{b?F.push(d(a)-this.getBoundingClientRect().width-4):F.push(d(a)+this.getBoundingClientRect().width+4)}catch(c){b?F.push(d(a)-4):F.push(d(a)+4)}}),u.selectAll("g").each(function(a,b){(d(a)<F[0]||d(a)>F[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}u.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),s=d.copy()}),t.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=void 0,q=250,r=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var s,t=a.utils.renderWatch(r,q);return b.axis=c,b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},fontSize:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return q},set:function(a){q=a,t.reset(q)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return E.reset(),l.each(function(b){var l=j-i.left-i.right,F=k-i.top-i.bottom;A=d3.select(this),a.utils.initSVG(A),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(d||[0,l],.1);var G=[];if(!e){var H,I,J=[];b.forEach(function(a,b){var c=p(a),d=r(a),e=s(a),f=t(a),g=v(a);g&&g.forEach(function(a,b){J.push(w(a,b,void 0))}),e&&J.push(e),c&&J.push(c),d&&J.push(d),f&&J.push(f)}),H=d3.min(J),I=d3.max(J),G=[H,I]}n.domain(e||G),n.range(f||[F,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);var K=A.selectAll("g.nv-wrap").data([b]);K.enter().append("g").attr("class","nvd3 nv-wrap");K.attr("transform","translate("+i.left+","+i.top+")");var L=K.selectAll(".nv-boxplot").data(function(a){return a}),M=L.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);L.attr("class","nv-boxplot").attr("transform",function(a,b,c){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),L.watchTransition(E,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*C/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),L.exit().remove(),M.each(function(a,b){var c=d3.select(this);[s,t].forEach(function(d){if(d(a)){var e=d===s?"low":"high";c.append("line").style("stroke",u(a)||z(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+e),c.append("line").style("stroke",u(a)||z(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+e)}})});var N=function(){return null===D?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},O=function(){return.45*m.rangeBand()-N()/2},P=function(){return.45*m.rangeBand()+N()/2};[s,t].forEach(function(a){var b=a===s?"low":"high",c=a===s?p:r;L.select("line.nv-boxplot-whisker.nv-boxplot-"+b).watchTransition(E,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b,c){return n(a(b))}).attr("x2",.45*m.rangeBand()).attr("y2",function(a,b){return n(c(a))}),L.select("line.nv-boxplot-tick.nv-boxplot-"+b).watchTransition(E,"nv-boxplot: boxplots").attr("x1",O).attr("y1",function(b,c){return n(a(b))}).attr("x2",P).attr("y2",function(b,c){return n(a(b))})}),[s,t].forEach(function(a){var b=a===s?"low":"high";M.selectAll(".nv-boxplot-"+b).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),B.elementMouseover({series:{key:a(b),color:u(b)||z(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),B.elementMouseout({series:{key:a(b),color:u(b)||z(b,d)},e:d3.event})}).on("mousemove",function(a,b){B.elementMousemove({e:d3.event})})}),M.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({key:o(a),value:o(a),series:[{key:"Q3",value:r(a),color:u(a)||z(a,b)},{key:"Q2",value:q(a),color:u(a)||z(a,b)},{key:"Q1",value:p(a),color:u(a)||z(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({key:o(a),value:o(a),series:[{key:"Q3",value:r(a),color:u(a)||z(a,b)},{key:"Q2",value:q(a),color:u(a)||z(a,b)},{key:"Q1",value:p(a),color:u(a)||z(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(a,b){B.elementMousemove({e:d3.event})}),L.select("rect.nv-boxplot-box").watchTransition(E,"nv-boxplot: boxes").attr("y",function(a,b){return n(r(a))}).attr("width",N).attr("x",O).attr("height",function(a,b){return Math.abs(n(r(a))-n(p(a)))||1}).style("fill",function(a,b){return u(a)||z(a,b)}).style("stroke",function(a,b){return u(a)||z(a,b)}),M.append("line").attr("class","nv-boxplot-median"),L.select("line.nv-boxplot-median").watchTransition(E,"nv-boxplot: boxplots line").attr("x1",O).attr("y1",function(a,b){return n(q(a))}).attr("x2",P).attr("y2",function(a,b){return n(q(a))});var Q=L.selectAll(".nv-boxplot-outlier").data(function(a){return v(a)||[]});Q.enter().append("circle").style("fill",function(a,b,c){return y(a,b,c)||z(a,c)}).style("stroke",function(a,b,c){return y(a,b,c)||z(a,c)}).style("z-index",9e3).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),B.elementMouseover({series:{key:x(a,b,c),color:y(a,b,c)||z(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),B.elementMouseout({series:{key:x(a,b,c),color:y(a,b,c)||z(a,c)},e:d3.event})}).on("mousemove",function(a,b){B.elementMousemove({e:d3.event})}),Q.attr("class","nv-boxplot-outlier"),Q.watchTransition(E,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a,b,c){return n(w(a,b,c))}).attr("r","3"),Q.exit().remove(),g=m.copy(),h=n.copy()}),E.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.label},p=function(a){return a.values.Q1},q=function(a){return a.values.Q2},r=function(a){return a.values.Q3},s=function(a){return a.values.whisker_low},t=function(a){return a.values.whisker_high},u=function(a){return a.color},v=function(a){return a.values.outliers},w=function(a,b,c){return a},x=function(a,b,c){return a},y=function(a,b,c){return void 0},z=a.utils.defaultColor(),A=null,B=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=250,D=null,E=a.utils.renderWatch(B,C);return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return D},set:function(a){D=a}},x:{get:function(){return o},set:function(a){o=a}},q1:{get:function(){return p},set:function(a){p=a}},q2:{get:function(){return q},set:function(a){q=a}},q3:{get:function(){return r},set:function(a){r=a}},wl:{get:function(){return s},set:function(a){s=a}},wh:{get:function(){return t},set:function(a){t=a}},itemColor:{get:function(){return u},set:function(a){u=a}},outliers:{get:function(){return v},set:function(a){v=a;}},outlierValue:{get:function(){return w},set:function(a){w=a}},outlierLabel:{get:function(){return x},set:function(a){x=a}},outlierColor:{get:function(){return y},set:function(a){y=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return d},set:function(a){d=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},y:{get:function(){return console.warn("BoxPlot 'y' chart option is deprecated. Please use model overrides instead."),{}},set:function(a){console.warn("BoxPlot 'y' chart option is deprecated. Please use model overrides instead.")}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return z},set:function(b){z=a.utils.getColor(b)}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!k||!k.length){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g");x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2===0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(a){p()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(a,b){var c=a.slice();a.sort(function(a,d){var e=c.indexOf(a),f=c.indexOf(d);return d3.descending(b[e],b[f])})}function c(e){return e.each(function(c,e){var s=p-d.left-d.right,x=q-d.top-d.bottom;r=d3.select(this),a.utils.initSVG(r);var y=g.call(this,c,e).slice(),z=h.call(this,c,e).slice(),A=i.call(this,c,e).slice().sort(d3.descending),B=j.call(this,c,e).slice(),C=k.call(this,c,e).slice(),D=l.call(this,c,e).slice(),E=m.call(this,c,e).slice(),F=n.call(this,c,e).slice();b(C,y),b(D,z),b(E,A),b(F,B),y.sort(d3.descending),z.sort(d3.descending),B.sort(d3.descending);var G=d3.scale.linear().domain(d3.extent(d3.merge([o,y]))).range(f?[s,0]:[0,s]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(G.range());this.__chart__=G;for(var H=(d3.min(y),d3.max(y),y[1],r.selectAll("g.nv-wrap.nv-bullet").data([c])),I=H.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),J=I.append("g"),K=H.select("g"),e=0,L=y.length;L>e;e++){var M="nv-range nv-range"+e;2>=e&&(M=M+" nv-range"+w[e]),J.append("rect").attr("class",M)}J.append("rect").attr("class","nv-measure"),H.attr("transform","translate("+d.left+","+d.top+")");for(var N=function(a){return Math.abs(G(a)-G(0))},O=function(a){return G(0>a?a:0)},e=0,L=y.length;L>e;e++){var P=y[e];K.select("rect.nv-range"+e).attr("height",x).attr("width",N(P)).attr("x",O(P)).datum(P)}K.select("rect.nv-measure").style("fill",t).attr("height",x/3).attr("y",x/3).attr("width",0>B?G(0)-G(B[0]):G(B[0])-G(0)).attr("x",O(B)).on("mouseover",function(){u.elementMouseover({value:B[0],label:F[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){u.elementMousemove({value:B[0],label:F[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){u.elementMouseout({value:B[0],label:F[0]||"Current",color:d3.select(this).style("fill")})});var Q=x/6,R=z.map(function(a,b){return{value:a,label:D[b]}});J.selectAll("path.nv-markerTriangle").data(R).enter().append("path").attr("class","nv-markerTriangle").attr("d","M0,"+Q+"L"+Q+","+-Q+" "+-Q+","+-Q+"Z").on("mouseover",function(a){u.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[G(a.value),x/2]})}).on("mousemove",function(a){u.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){u.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),K.selectAll("path.nv-markerTriangle").data(R).attr("transform",function(a){return"translate("+G(a.value)+","+x/2+")"});var S=A.map(function(a,b){return{value:a,label:E[b]}});J.selectAll("path.nv-markerLine").data(S).enter().append("line").attr("cursor","").attr("class","nv-markerLine").attr("x1",function(a){return G(a.value)}).attr("y1","2").attr("x2",function(a){return G(a.value)}).attr("y2",x-2).on("mouseover",function(a){u.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[G(a.value),x/2]})}).on("mousemove",function(a){u.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){u.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),K.selectAll("path.nv-markerLines").data(S).attr("transform",function(a){return"translate("+G(a.value)+","+x/2+")"}),H.selectAll(".nv-range").on("mouseover",function(a,b){var c=C[b]||v[b];u.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){u.elementMousemove({value:B[0],label:F[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=C[b]||v[b];u.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),c}var d={top:0,right:0,bottom:0,left:0},e="left",f=!1,g=function(a){return a.ranges},h=function(a){return a.markers?a.markers:[]},i=function(a){return a.markerLines?a.markerLines:[0]},j=function(a){return a.measures},k=function(a){return a.rangeLabels?a.rangeLabels:[]},l=function(a){return a.markerLabels?a.markerLabels:[]},m=function(a){return a.markerLineLabels?a.markerLineLabels:[]},n=function(a){return a.measureLabels?a.measureLabels:[]},o=[0],p=380,q=30,r=null,s=null,t=a.utils.getColor(["#1f77b4"]),u=d3.dispatch("elementMouseover","elementMouseout","elementMousemove"),v=["Maximum","Mean","Minimum"],w=["Max","Avg","Min"];return c.dispatch=u,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{ranges:{get:function(){return g},set:function(a){g=a}},markers:{get:function(){return h},set:function(a){h=a}},measures:{get:function(){return j},set:function(a){j=a}},forceX:{get:function(){return o},set:function(a){o=a}},width:{get:function(){return p},set:function(a){p=a}},height:{get:function(){return q},set:function(a){q=a}},tickFormat:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return d},set:function(a){d.top=void 0!==a.top?a.top:d.top,d.right=void 0!==a.right?a.right:d.right,d.bottom=void 0!==a.bottom?a.bottom:d.bottom,d.left=void 0!==a.left?a.left:d.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(c),c},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0]||0,u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch();return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(a){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(a){d()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),v?l.range(f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]):l.range(f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&(l.domain()[0]?l.domain([l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]):l.domain([-1,1])),m.domain()[0]===m.domain()[1]&&(m.domain()[0]?m.domain([m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]):m.domain([-1,1]));var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();var H=G.enter().append("g");G.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)});G.select(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),G.select(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(a,c){d3.select(b.container).style("cursor","ew-resize")}function E(a,b){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(a,c){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){aa.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=a.utils.availableWidth(o,L,m),N=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var O;z={};for(O in y)y[O]instanceof Array?z[O]=y[O].slice(0):z[O]=y[O]}var P=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var Q=l.filter(function(a){return!a.disabled}).map(function(a,b){var c=d3.extent(a.values,f.y());return c[0]<-.95&&(c[0]=-.95),[(c[0]-c[1])/(1+c[1]),(c[1]-c[0])/(1+c[0])]}),R=[d3.min(Q,function(a){return a[0]}),d3.max(Q,function(a){return a[1]})];f.yDomain(R)}F.domain([0,l[0].values.length-1]).range([0,M]).clamp(!0);var l=c(G.i,l),S=v?"none":"all",T=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),U=T.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),V=T.select("g");if(U.append("g").attr("class","nv-interactive"),U.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),U.append("g").attr("class","nv-y nv-axis"),U.append("g").attr("class","nv-background"),U.append("g").attr("class","nv-linesWrap").style("pointer-events",S),U.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),U.append("g").attr("class","nv-legendWrap"),U.append("g").attr("class","nv-controlsWrap"),q?(i.width(M),V.select(".nv-legendWrap").datum(l).call(i),i.height()>m.top&&(m.top=i.height(),N=a.utils.availableHeight(p,L,m)),V.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")):V.select(".nv-legendWrap").selectAll("*").remove(),u){var W=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),V.select(".nv-controlsWrap").datum(W).attr("transform","translate(0,"+-m.top+")").call(j)}else V.select(".nv-controlsWrap").selectAll("*").remove();T.attr("transform","translate("+m.left+","+m.top+")"),t&&V.select(".nv-y.nv-axis").attr("transform","translate("+M+",0)");var X=l.filter(function(a){return a.tempDisabled});T.select(".tempDisabled").remove(),X.length&&T.append("text").attr("class","tempDisabled").attr("x",M/2).attr("y","-.71em").style("text-anchor","end").text(X.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(M).height(N).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),T.select(".nv-interactive").call(k)),U.select(".nv-background").append("rect"),V.select(".nv-background rect").attr("width",M).attr("height",N),f.y(function(a){return a.display.y}).width(M).height(N).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Y=V.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Y.call(f),l.forEach(function(a,b){a.seriesIndex=b});var Z=l.filter(function(a){return!a.disabled&&!!B(a)}),$=V.select(".nv-avgLinesWrap").selectAll("line").data(Z,function(a){return a.key}),_=function(a){var b=e(B(a));return 0>b?0:b>N?N:b};$.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a,b){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",M).attr("y1",_).attr("y2",_),$.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>N?0:1}).attr("x1",0).attr("x2",M).attr("y1",_).attr("y2",_),$.exit().remove();var aa=Y.selectAll(".nv-indexLine").data([G]);aa.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(P),aa.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",N),r&&(g.scale(d)._ticks(a.utils.calcTicksX(M/70,l)).tickSize(-N,0),V.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),V.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(N/36,l)).tickSize(-M,0),V.select(".nv-y.nv-axis").call(h)),V.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a,c){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var m=b.yScale().invert(c.mouseY),o=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),p=.03*o,q=a.nearestValueIndex(j.map(function(a){return a.value}),m,p);null!==q&&(j[q].highlight=!0)}var r=g.tickFormat()(b.x()(d,e),e);k.tooltip.valueFormatter(function(a,b){return h.tickFormat()(a)}).data({value:r,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(a){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,aa.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b,c){if(!b.values)return b;var d=b.values[a];if(null==d)return b;var e=K(d,a);return-.95>e&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-e)/(1+e)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(a){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),t?o.range(g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]):o.range(g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g");C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b,c){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){var c=this;v.elementClick({data:a,index:b,color:d3.select(this).style("fill"),event:d3.event,element:c}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(0)),1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(i){return x.reset(),x.models(e),o&&x.models(f),p&&x.models(g),i.each(function(i){var m=d3.select(this);a.utils.initSVG(m);var u=a.utils.availableWidth(k,m,j),x=a.utils.availableHeight(l,m,j);if(b.update=function(){v.beforeUpdate(),m.transition().duration(w).call(b)},b.container=this,!(i&&i.length&&i.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),b;m.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var y=m.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([i]),z=y.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),A=z.append("defs"),B=y.select("g");z.append("g").attr("class","nv-x nv-axis"),z.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),z.append("g").attr("class","nv-barsWrap"),z.append("g").attr("class","nv-legendWrap"),B.attr("transform","translate("+j.left+","+j.top+")"),n?(h.width(u),B.select(".nv-legendWrap").datum(i).call(h),h.height()>j.top&&(j.top=h.height(),x=a.utils.availableHeight(l,m,j)),y.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")):B.select(".nv-legendWrap").selectAll("*").remove(),q&&B.select(".nv-y.nv-axis").attr("transform","translate("+u+",0)"),e.width(u).height(x);var C=B.select(".nv-barsWrap").datum(i.filter(function(a){return!a.disabled}));if(C.transition().call(e),A.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),B.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(r?2:1)).attr("height",16).attr("x",-c.rangeBand()/(r?1:2)),o){f.scale(c)._ticks(a.utils.calcTicksX(u/100,i)).tickSize(-x,0),B.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),B.select(".nv-x.nv-axis").call(f);var D=B.select(".nv-x.nv-axis").selectAll("g");r&&D.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"}),t&&D.selectAll(".tick text").attr("transform","rotate("+t+" 0,0)").style("text-anchor",t>0?"start":"end"),s&&B.selectAll(".tick text").call(a.utils.wrapTicks,b.xAxis.rangeBand())}p&&(g.scale(d)._ticks(a.utils.calcTicksY(x/36,i)).tickSize(-u,0),B.select(".nv-y.nv-axis").call(g)),B.select(".nv-zeroLine line").attr("x1",0).attr("x2",q?-u:u).attr("y1",d(0)).attr("y2",d(0))}),x.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.tooltip(),j={top:15,right:10,bottom:50,left:60},k=null,l=null,m=a.utils.getColor(),n=!1,o=!0,p=!0,q=!1,r=!1,s=!1,t=0,u=null,v=d3.dispatch("beforeUpdate","renderEnd"),w=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(q?"right":"left").tickFormat(d3.format(",.1f")),i.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var x=a.utils.renderWatch(v,w);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},i.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(a){i()}),b.dispatch=v,b.discretebar=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},showLegend:{get:function(){return n},set:function(a){n=a}},staggerLabels:{get:function(){return r},set:function(a){r=a}},rotateLabels:{get:function(){return t},set:function(a){t=a}},wrapLabels:{get:function(){return s},set:function(a){s=!!a}},showXAxis:{get:function(){return o},set:function(a){o=a}},showYAxis:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return u},set:function(a){u=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return w},set:function(a){w=a,x.reset(w),e.duration(w),f.duration(w),g.duration(w)}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),e.color(m),h.color(m)}},rightAlignYAxis:{get:function(){return q},set:function(a){q=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.focus=function(b){"use strict";function c(t){return s.reset(),s.models(b),m&&s.models(f),n&&s.models(g),t.each(function(s){function t(a){var b=+("e"==a),c=b?1:-1,d=y/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function u(){h.empty()||h.extent(p),D.data([h.empty()?d.domain():p]).each(function(a,b){var c=d(a[0])-d.range()[0],e=x-d(a[1]);d3.select(this).select(".left").attr("width",0>c?0:c),d3.select(this).select(".right").attr("x",d(a[1])).attr("width",0>e?0:e)})}function v(){p=h.empty()?null:h.extent();var a=h.empty()?d.domain():h.extent();Math.abs(a[0]-a[1])<=1||(r.brush({extent:a,brush:h}),u(),r.onBrush(a))}var w=d3.select(this);a.utils.initSVG(w);var x=a.utils.availableWidth(k,w,i),y=l-i.top-i.bottom;c.update=function(){0===q?w.call(c):w.transition().duration(q).call(c)},c.container=this,d=b.xScale(),e=b.yScale();var z=w.selectAll("g.nv-focus").data([s]),A=z.enter().append("g").attr("class","nvd3 nv-focus").append("g"),B=z.select("g");z.attr("transform","translate("+i.left+","+i.top+")"),A.append("g").attr("class","nv-background").append("rect"),A.append("g").attr("class","nv-x nv-axis"),A.append("g").attr("class","nv-y nv-axis"),A.append("g").attr("class","nv-contentWrap"),A.append("g").attr("class","nv-brushBackground"),A.append("g").attr("class","nv-x nv-brush"),o&&B.select(".nv-y.nv-axis").attr("transform","translate("+x+",0)"),B.select(".nv-background rect").attr("width",x).attr("height",y),b.width(x).height(y).color(s.map(function(a,b){return a.color||j(a,b)}).filter(function(a,b){return!s[b].disabled}));var C=B.select(".nv-contentWrap").datum(s.filter(function(a){return!a.disabled}));d3.transition(C).call(b),h.x(d).on("brush",function(){v()}),p&&h.extent(p);var D=B.select(".nv-brushBackground").selectAll("g").data([p||h.extent()]),E=D.enter().append("g");E.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",y),E.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",y);var F=B.select(".nv-x.nv-brush").call(h);F.selectAll("rect").attr("height",y),F.selectAll(".resize").append("path").attr("d",t),v(),B.select(".nv-background rect").attr("width",x).attr("height",y),m&&(f.scale(d)._ticks(a.utils.calcTicksX(x/100,s)).tickSize(-y,0),B.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),d3.transition(B.select(".nv-x.nv-axis")).call(f)),n&&(g.scale(e)._ticks(a.utils.calcTicksY(y/36,s)).tickSize(-x,0),d3.transition(B.select(".nv-y.nv-axis")).call(g)),B.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")")}),s.renderEnd("focus immediate"),c}var d,e,b=b||a.models.line(),f=a.models.axis(),g=a.models.axis(),h=d3.svg.brush(),i={top:10,right:0,bottom:30,left:0},j=a.utils.defaultColor(),k=null,l=70,m=!0,n=!1,o=!1,p=null,q=250,r=d3.dispatch("brush","onBrush","renderEnd");b.interactive(!1),b.pointActive(function(a){return!1});var s=a.utils.renderWatch(r,q);return c.dispatch=r,c.content=b,c.brush=h,c.xAxis=f,c.yAxis=g,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},brushExtent:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return q},set:function(a){q=a,s.reset(q),b.duration(q),f.duration(q),g.duration(q)}},color:{get:function(){return j},set:function(c){j=a.utils.getColor(c),b.color(j)}},interpolate:{get:function(){return b.interpolate()},set:function(a){b.interpolate(a)}},xTickFormat:{get:function(){return f.tickFormat()},set:function(a){f.tickFormat(a)}},yTickFormat:{get:function(){return g.tickFormat()},set:function(a){g.tickFormat(a)}},x:{get:function(){return b.x()},set:function(a){b.x(a)}},y:{get:function(){return b.y()},set:function(a){b.y(a)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(o?"right":"left")}}}),a.utils.inheritOptions(c,b),a.utils.initOptions(c),c},a.models.forceDirectedGraph=function(){"use strict";function b(g){return u.reset(),g.each(function(g){f=d3.select(this),a.utils.initSVG(f);var j=a.utils.availableWidth(d,f,c),u=a.utils.availableHeight(e,f,c);if(f.attr("width",j).attr("height",u),!(g&&g.links&&g.nodes))return a.utils.noData(b,f),b;f.selectAll(".nv-noData").remove(),f.selectAll("*").remove();var v=new Set;g.nodes.forEach(function(a){var b=Object.keys(a);b.forEach(function(a){v.add(a)})});var w=d3.layout.force().nodes(g.nodes).links(g.links).size([j,u]).linkStrength(k).friction(l).linkDistance(m).charge(n).gravity(o).theta(p).alpha(q).start(),x=f.selectAll(".link").data(g.links).enter().append("line").attr("class","nv-force-link").style("stroke-width",function(a){return Math.sqrt(a.value)}),y=f.selectAll(".node").data(g.nodes).enter().append("g").attr("class","nv-force-node").call(w.drag);y.append("circle").attr("r",r).style("fill",function(a){return h(a)}).on("mouseover",function(a){f.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.py),f.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.px);var b=h(a);a.series=[],v.forEach(function(c){a.series.push({color:b,key:c,value:a[c]})}),i.data(a).hidden(!1)}).on("mouseout",function(a){i.hidden(!0)}),i.headerFormatter(function(a){return"Node"}),t(x),s(y),w.on("tick",function(){x.attr("x1",function(a){return a.source.x}).attr("y1",function(a){return a.source.y}).attr("x2",function(a){return a.target.x}).attr("y2",function(a){return a.target.y}),y.attr("transform",function(a){return"translate("+a.x+", "+a.y+")"})})}),b}var c={top:2,right:0,bottom:2,left:0},d=400,e=32,f=null,g=d3.dispatch("renderEnd"),h=a.utils.getColor(["#000"]),i=a.models.tooltip(),j=null,k=.1,l=.9,m=30,n=-120,o=.1,p=.8,q=.1,r=5,s=function(a){},t=function(a){},u=a.utils.renderWatch(g);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},linkStrength:{get:function(){return k},set:function(a){k=a}},friction:{get:function(){return l},set:function(a){l=a}},linkDist:{get:function(){return m},set:function(a){m=a}},charge:{get:function(){return n},set:function(a){n=a}},gravity:{get:function(){return o},set:function(a){o=a}},theta:{get:function(){return p},set:function(a){p=a}},alpha:{get:function(){return q},set:function(a){q=a}},radius:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return getX},set:function(a){getX=d3.functor(a)}},y:{get:function(){return getY},set:function(a){getY=d3.functor(a)}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},noData:{get:function(){return j},set:function(a){j=a}},nodeExtras:{get:function(){return s},set:function(a){s=a}},linkExtras:{get:function(){return t},set:function(a){t=a}}}),b.dispatch=g,b.tooltip=i,a.utils.initOptions(b),b},a.models.furiousLegend=function(){"use strict";function b(r){function s(a,b){return"furious"!=q?"#000":o?a.disengaged?h(a,b):"#fff":o?void 0:a.disabled?h(a,b):"#fff"}function t(a,b){return o&&"furious"==q?a.disengaged?"#fff":h(a,b):a.disabled?"#fff":h(a,b)}return r.each(function(b){var r=d-c.left-c.right,u=d3.select(this);a.utils.initSVG(u);var v=u.selectAll("g.nv-legend").data([b]),w=(v.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v.select("g"));v.attr("transform","translate("+c.left+","+c.top+")");var x,y=w.selectAll(".nv-series").data(function(a){return"furious"!=q?a:a.filter(function(a){return o?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");if("classic"==q)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),x=y.select("circle");else if("furious"==q){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),x=y.select("rect"),z.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",s(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){p.legendMouseover(a,b)}).on("mouseout",function(a,b){p.legendMouseout(a,b)}).on("click",function(a,b){p.legendClick(a,b);var c=y.data();if(m){if("classic"==q)n?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==q)if(o)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!o){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}p.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=q||!o)&&(p.legendDblclick(a,b),m)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==q&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==q&&(a.userDisabled=a.disabled),p.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",s).text(function(a){return g(f(a))});var C;switch(q){case"furious":C=23;break;case"classic":C=20}if(j){var D=[];y.each(function(b,c){var d;if(g(f(b))&&g(f(b)).length>i){var e=g(f(b)).substring(0,i);d=d3.select(this).select("text").text(e+"..."),d3.select(this).append("svg:title").text(g(f(b)))}else d=d3.select(this).select("text");var h;try{if(h=d.node().getComputedTextLength(),0>=h)throw Error()}catch(j){h=a.utils.calcApproxTextWidth(d)}D.push(h+k)});for(var E=0,F=0,G=[];r>F&&E<D.length;)G[E]=D[E],F+=D[E++];for(0===E&&(E=1);F>r&&E>1;){G=[],E--;for(var H=0;H<D.length;H++)D[H]>(G[H%E]||0)&&(G[H%E]=D[H]);F=G.reduce(function(a,b,c,d){return a+b})}for(var I=[],J=0,K=0;E>J;J++)I[J]=K,K+=G[J];y.attr("transform",function(a,b){return"translate("+I[b%E]+","+(5+Math.floor(b/E)*C)+")"}),l?w.attr("transform","translate("+(d-c.right-F)+","+c.top+")"):w.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*C}else{var L,M=5,N=5,O=0;y.attr("transform",function(a,b){var e=d3.select(this).select("text").node().getComputedTextLength()+k;return L=N,d<c.left+c.right+L+e&&(N=L=5,M+=C),N+=e,N>O&&(O=N),"translate("+L+","+M+")"}),w.attr("transform","translate("+(d-c.right-O)+","+c.top+")"),e=c.top+c.bottom+M+15}"furious"==q&&x.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),x.style("fill",t).style("stroke",function(a,b){return a.color||h(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=function(a){return a},h=a.utils.getColor(),i=20,j=!0,k=28,l=!0,m=!0,n=!1,o=!1,p=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),q="classic";return b.dispatch=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},keyFormatter:{get:function(){return g},set:function(a){g=a}},align:{get:function(){return j},set:function(a){j=a}},rightAlign:{get:function(){return l},set:function(a){l=a}},maxKeyLength:{get:function(){return i},set:function(a){i=a}},padding:{get:function(){return k},set:function(a){k=a}},updateState:{get:function(){return m},set:function(a){m=a}},radioButtonMode:{get:function(){return n},set:function(a){n=a}},expanded:{get:function(){return o},set:function(a){o=a}},vers:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),r?l.range(e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]):l.range(e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&(l.domain()[0]?l.domain([l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]):l.domain([-1,1])),m.domain()[0]===m.domain()[1]&&(m.domain()[0]?m.domain([m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]):m.domain([-1,1]));var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this);a.utils.initSVG(w);var A=a.utils.availableWidth(n,w,l),B=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var C;v={};for(C in u)u[C]instanceof Array?v[C]=u[C].slice(0):v[C]=u[C]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var D=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),F=D.select("g");E.append("g").attr("class","nv-x nv-axis"),E.append("g").attr("class","nv-y nv-axis"),E.append("g").attr("class","nv-barsWrap"),E.append("g").attr("class","nv-legendWrap"),E.append("g").attr("class","nv-interactive"),p?(i.width(A),F.select(".nv-legendWrap").datum(k).call(i),i.height()>l.top&&(l.top=i.height(),B=a.utils.availableHeight(o,w,l)),D.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")):F.select(".nv-legendWrap").selectAll("*").remove(),D.attr("transform","translate("+l.left+","+l.top+")"),s&&F.select(".nv-y.nv-axis").attr("transform","translate("+A+",0)"),t&&(j.width(A).height(B).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),D.select(".nv-interactive").call(j)),f.width(A).height(B).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var G=F.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));G.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(A/100,k)).tickSize(-B,0),F.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),F.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(B/36,k)).tickSize(-A,0),F.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,l=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var j=g.values[e];void 0!==j&&(void 0===d&&(d=j),void 0===i&&(i=c.xScale()(c.x()(j,e))),l.push({key:g.key,value:c.y()(j,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var n=g.tickFormat()(c.x()(d,e));j.tooltip.valueFormatter(function(a,b){return h.tickFormat()(a)}).data({value:n,index:e,series:l})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(a){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a,d){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,D.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(a){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(a){k()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.legend=function(){"use strict";function b(r){function s(a,b){return"furious"!=q?"#000":o?a.disengaged?"#000":"#fff":o?void 0:(a.color||(a.color=h(a,b)),a.disabled?a.color:"#fff")}function t(a,b){return o&&"furious"==q&&a.disengaged?"#eee":a.color||h(a,b)}function u(a,b){return o&&"furious"==q?1:a.disabled?0:1}return r.each(function(b){var h=d-c.left-c.right,r=d3.select(this);a.utils.initSVG(r);var v=r.selectAll("g.nv-legend").data([b]),w=v.enter().append("g").attr("class","nvd3 nv-legend").append("g"),x=v.select("g");v.attr("transform","translate("+c.left+","+c.top+")");var y,z,A=x.selectAll(".nv-series").data(function(a){return"furious"!=q?a:a.filter(function(a){return o?!0:!a.disengaged})}),B=A.enter().append("g").attr("class","nv-series");switch(q){case"furious":z=23;break;case"classic":z=20}if("classic"==q)B.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),y=A.select(".nv-legend-symbol");else if("furious"==q){B.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),y=A.select(".nv-legend-symbol"),B.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var C=A.select(".nv-check-box");C.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",s(a,b))})}B.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var D=A.select("text.nv-legend-text");A.on("mouseover",function(a,b){p.legendMouseover(a,b)}).on("mouseout",function(a,b){p.legendMouseout(a,b)}).on("click",function(a,b){p.legendClick(a,b);var c=A.data();if(m){if("classic"==q)n?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==q)if(o)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!o){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}p.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=q||!o)&&(p.legendDblclick(a,b),m)){var c=A.data();c.forEach(function(a){a.disabled=!0,"furious"==q&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==q&&(a.userDisabled=a.disabled),p.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),A.classed("nv-disabled",function(a){return a.userDisabled}),A.exit().remove(),D.attr("fill",s).text(function(a){return g(f(a))});var E=0;if(j){var F=[];A.each(function(b,c){var d;if(g(f(b))&&g(f(b)).length>i){var e=g(f(b)).substring(0,i);d=d3.select(this).select("text").text(e+"..."),d3.select(this).append("svg:title").text(g(f(b)))}else d=d3.select(this).select("text");var h;try{if(h=d.node().getComputedTextLength(),0>=h)throw Error()}catch(j){h=a.utils.calcApproxTextWidth(d)}F.push(h+k)});var G=0,H=[];for(E=0;h>E&&G<F.length;)H[G]=F[G],E+=F[G++];for(0===G&&(G=1);E>h&&G>1;){H=[],G--;for(var I=0;I<F.length;I++)F[I]>(H[I%G]||0)&&(H[I%G]=F[I]);E=H.reduce(function(a,b,c,d){return a+b})}for(var J=[],K=0,L=0;G>K;K++)J[K]=L,L+=H[K];A.attr("transform",function(a,b){return"translate("+J[b%G]+","+(5+Math.floor(b/G)*z)+")"}),l?x.attr("transform","translate("+(d-c.right-E)+","+c.top+")"):x.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(F.length/G)*z}else{var M,N=5,O=5,P=0;A.attr("transform",function(a,b){var e=d3.select(this).select("text").node().getComputedTextLength()+k;return M=O,d<c.left+c.right+M+e&&(O=M=5,N+=z),O+=e,O>P&&(P=O),M+P>E&&(E=M+P),"translate("+M+","+N+")"}),x.attr("transform","translate("+(d-c.right-P)+","+c.top+")"),e=c.top+c.bottom+N+15}if("furious"==q){y.attr("width",function(a,b){return D[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),w.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var Q=x.select(".nv-legend-bg");Q.transition().duration(300).attr("x",-z).attr("width",E+z-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",o?1:0)}y.style("fill",t).style("fill-opacity",u).style("stroke",t)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=function(a){return a},h=a.utils.getColor(),i=20,j=!0,k=32,l=!0,m=!0,n=!1,o=!1,p=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),q="classic";return b.dispatch=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},keyFormatter:{get:function(){return g},set:function(a){g=a}},align:{get:function(){return j},set:function(a){j=a}},maxKeyLength:{get:function(){return i},set:function(a){i=a}},rightAlign:{get:function(){return l},set:function(a){l=a}},padding:{get:function(){return k},set:function(a){k=a}},updateState:{get:function(){return m},set:function(a){m=a}},radioButtonMode:{get:function(){return n},set:function(a){n=a}},expanded:{get:function(){return o},set:function(a){o=a}},vers:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(a,b){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(a,b){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return B.reset(),B.models(e),r&&B.models(f),s&&B.models(g),j.each(function(j){function y(){r&&L.select(".nv-focus .nv-x.nv-axis").transition().duration(A).call(f)}function B(){s&&L.select(".nv-focus .nv-y.nv-axis").transition().duration(A).call(g)}function E(a){var b=L.select(".nv-focus .nv-linesWrap").datum(j.filter(function(a){return!a.disabled}).map(function(b,c){return{key:b.key,area:b.area,classed:b.classed,values:b.values.filter(function(b,c){return e.x()(b,c)>=a[0]&&e.x()(b,c)<=a[1]}),disableTooltip:b.disableTooltip}}));b.transition().duration(A).call(e),y(),B()}var F=d3.select(this);a.utils.initSVG(F);var G=a.utils.availableWidth(n,F,l),H=a.utils.availableHeight(o,F,l)-(v?k.height():0);if(b.update=function(){0===A?F.call(b):F.transition().duration(A).call(b)},b.container=this,w.setter(D(j),b.update).getter(C(j)).update(),w.disabled=j.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)w[I]instanceof Array?x[I]=w[I].slice(0):x[I]=w[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,F),b;F.selectAll(".nv-noData").remove(),k.dispatch.on("onBrush",function(a){E(a)}),c=e.xScale(),d=e.yScale();var J=F.selectAll("g.nv-wrap.nv-lineChart").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),L=J.select("g");K.append("g").attr("class","nv-legendWrap");var M=K.append("g").attr("class","nv-focus");M.append("g").attr("class","nv-background").append("rect"),M.append("g").attr("class","nv-x nv-axis"),M.append("g").attr("class","nv-y nv-axis"),M.append("g").attr("class","nv-linesWrap"),M.append("g").attr("class","nv-interactive");K.append("g").attr("class","nv-focusWrap");p?(h.width(G),L.select(".nv-legendWrap").datum(j).call(h),"bottom"===q?J.select(".nv-legendWrap").attr("transform","translate(0,"+H+")"):"top"===q&&(h.height()>l.top&&(l.top=h.height(),H=a.utils.availableHeight(o,F,l)-(v?k.height():0)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")"))):L.select(".nv-legendWrap").selectAll("*").remove(),J.attr("transform","translate("+l.left+","+l.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),u&&(i.width(G).height(H).margin({left:l.left,top:l.top}).svgContainer(F).xScale(c),J.select(".nv-interactive").call(i)),L.select(".nv-focus .nv-background rect").attr("width",G).attr("height",H),e.width(G).height(H).color(j.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));if(r&&f.scale(c)._ticks(a.utils.calcTicksX(G/100,j)).tickSize(-H,0),s&&g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-G,0),L.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+H+")"),v){k.width(G),L.select(".nv-focusWrap").attr("transform","translate(0,"+(H+l.bottom+k.margin().top)+")").datum(j.filter(function(a){return!a.disabled})).call(k);var O=k.brush.empty()?k.xDomain():k.brush.extent();null!==O&&E(O)}else N.call(e),y(),B();h.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];z.stateChange(w),b.update()}),i.dispatch.on("elementMousemove",function(d){e.clearHighlights();var f,h,l,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled&&!a.disableTooltip}).forEach(function(g,i){var j=v?k.brush.empty()?k.xScale().domain():k.brush.extent():c.domain(),o=g.values.filter(function(a,b){return e.x()(a,b)>=j[0]&&e.x()(a,b)<=j[1]});h=a.interactiveBisect(o,d.pointXValue,e.x());var p=o[h],q=b.y()(p,h);null!==q&&e.highlightPoint(g.seriesIndex,h,!0),void 0!==p&&(void 0===f&&(f=p),void 0===l&&(l=b.xScale()(b.x()(p,h))),n.push({key:g.key,value:q,color:m(g,g.seriesIndex),data:p}))}),n.length>2){var o=b.yScale().invert(d.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=function(a,b){return null==a?"N/A":g.tickFormat()(a)};i.tooltip.valueFormatter(i.tooltip.valueFormatter()||s).data({value:b.x()(f,h),index:h,series:n})(),i.renderGuideLine(l)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(a){e.clearHighlights()}),z.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()})}),B.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k=a.models.focus(a.models.line()),l={top:30,right:20,bottom:50,left:60},m=a.utils.defaultColor(),n=null,o=null,p=!0,q="top",r=!0,s=!0,t=!1,u=!1,v=!1,w=a.utils.state(),x=null,y=null,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),A=250;f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),e.clipEdge(!0).duration(0),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.tooltip.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var B=a.utils.renderWatch(z,A),C=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},D=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.series.disableTooltip||j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){j.hidden(!0)}),b.dispatch=z,b.lines=e,b.legend=h,b.focus=k,b.xAxis=f,b.x2Axis=k.xAxis,b.yAxis=g,b.y2Axis=k.yAxis,b.interactiveLayer=i,b.tooltip=j,b.state=w,b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},legendPosition:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return y},set:function(a){y=a}},focusEnable:{get:function(){return v},set:function(a){v=a}},focusHeight:{get:function(){return k.height()},set:function(a){k.height(a)}},focusShowAxisX:{get:function(){return k.showXAxis()},set:function(a){k.showXAxis(a)}},focusShowAxisY:{get:function(){return k.showYAxis()},set:function(a){k.showYAxis(a)}},brushExtent:{get:function(){return k.brushExtent()},set:function(a){k.brushExtent(a)}},focusMargin:{get:function(){return k.margin},set:function(a){k.margin.top=void 0!==a.top?a.top:k.margin.top,k.margin.right=void 0!==a.right?a.right:k.margin.right,k.margin.bottom=void 0!==a.bottom?a.bottom:k.margin.bottom,k.margin.left=void 0!==a.left?a.left:k.margin.left}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return A},set:function(a){A=a,B.reset(A),e.duration(A),k.duration(A),f.duration(A),g.duration(A)}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),h.color(m),e.color(m),k.color(m)}},interpolate:{get:function(){return e.interpolate()},set:function(a){e.interpolate(a),k.interpolate(a)}},xTickFormat:{get:function(){return f.tickFormat()},set:function(a){f.tickFormat(a),k.xTickFormat(a)}},yTickFormat:{get:function(){return g.tickFormat()},set:function(a){g.tickFormat(a),k.yTickFormat(a)}},x:{get:function(){return e.x()},set:function(a){e.x(a),k.x(a)}},y:{get:function(){return e.y()},set:function(a){e.y(a),k.y(a)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=a,u&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){return a.models.lineChart().margin({bottom:30}).focusEnable(!0)},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=Z/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function R(){u.empty()||u.extent(I),ma.data([u.empty()?e.domain():I]).each(function(a,b){var c=e(a[0])-e.range()[0],d=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>c?0:c),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function S(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),R(),l.width(X).height(Y).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(X).height(Y).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=fa.select(".nv-focus .nv-barsWrap").datum(_.length?_.map(function(a,b){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=fa.select(".nv-focus .nv-linesWrap").datum(V(aa)?[{values:[]}]:aa.filter(function(a){return!a.disabled}).map(function(a,b){return{area:a.area,fillOpacity:a.fillOpacity,strokeWidth:a.strokeWidth,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=_.length&&!Q?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(X/100,v)).tickSize(-Y,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),fa.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),fa.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(Y/36,v)).tickSize(-X,0),q.scale(g)._ticks(a.utils.calcTicksY(Y/36,v)),Q?q.tickSize(aa.length?0:-X,0):q.tickSize(_.length?0:-X,0);var i=_.length?1:0,k=aa.length&&!V(aa)?1:0,m=Q?k:i,o=Q?i:k;fa.select(".nv-focus .nv-y1.nv-axis").style("opacity",m),fa.select(".nv-focus .nv-y2.nv-axis").style("opacity",o).attr("transform","translate("+d.range()[1]+",0)"),fa.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),fa.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var W=d3.select(this);a.utils.initSVG(W);var X=a.utils.availableWidth(y,W,w),Y=a.utils.availableHeight(z,W,w)-(E?H:0),Z=H-x.top-x.bottom;if(b.update=function(){W.transition().duration(L).call(b)},b.container=this,M.setter(U(v),b.update).getter(T(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var $;N={};for($ in M)M[$]instanceof Array?N[$]=M[$].slice(0):N[$]=M[$]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,W),b;W.selectAll(".nv-noData").remove();var _=v.filter(function(a){return!a.disabled&&a.bar}),aa=v.filter(function(a){return!a.bar});d=_.length&&!Q?l.xScale():j.xScale(),e=o.scale(),f=Q?j.yScale():l.yScale(),g=Q?l.yScale():j.yScale(),h=Q?k.yScale():m.yScale(),i=Q?m.yScale():k.yScale();var ba=v.filter(function(a){return!a.disabled&&(Q?!a.bar:a.bar)}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ca=v.filter(function(a){return!a.disabled&&(Q?a.bar:!a.bar)}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,X]),e.domain(d3.extent(d3.merge(ba.concat(ca)),function(a){return a.x})).range([0,X]);var da=W.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),ea=da.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),fa=da.select("g");ea.append("g").attr("class","nv-legendWrap");var ga=ea.append("g").attr("class","nv-focus");ga.append("g").attr("class","nv-x nv-axis"),ga.append("g").attr("class","nv-y1 nv-axis"),ga.append("g").attr("class","nv-y2 nv-axis"),ga.append("g").attr("class","nv-barsWrap"),ga.append("g").attr("class","nv-linesWrap");var ha=ea.append("g").attr("class","nv-context");if(ha.append("g").attr("class","nv-x nv-axis"),ha.append("g").attr("class","nv-y1 nv-axis"),ha.append("g").attr("class","nv-y2 nv-axis"),ha.append("g").attr("class","nv-barsWrap"),ha.append("g").attr("class","nv-linesWrap"),ha.append("g").attr("class","nv-brushBackground"),ha.append("g").attr("class","nv-x nv-brush"),D){var ia=t.align()?X/2:X,ja=t.align()?ia:0;t.width(ia),fa.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,Q?a.key=a.originalKey+(a.bar?P:O):a.key=a.originalKey+(a.bar?O:P),a})).call(t),t.height()>w.top&&(w.top=t.height(),Y=a.utils.availableHeight(z,W,w)-H),fa.select(".nv-legendWrap").attr("transform","translate("+ja+","+-w.top+")")}else fa.select(".nv-legendWrap").selectAll("*").remove();da.attr("transform","translate("+w.left+","+w.top+")"),fa.select(".nv-context").style("display",E?"initial":"none"),m.width(X).height(Z).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(X).height(Z).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ka=fa.select(".nv-context .nv-barsWrap").datum(_.length?_:[{values:[]}]),la=fa.select(".nv-context .nv-linesWrap").datum(V(aa)?[{values:[]}]:aa.filter(function(a){return!a.disabled}));fa.select(".nv-context").attr("transform","translate(0,"+(Y+w.bottom+x.top)+")"),ka.transition().call(m),la.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(X/100,v)).tickSize(-Z,0),fa.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),fa.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(Z/36).tickSize(-X,0),s.scale(i)._ticks(Z/36).tickSize(_.length?0:-X,0),fa.select(".nv-context .nv-y3.nv-axis").style("opacity",_.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),fa.select(".nv-context .nv-y2.nv-axis").style("opacity",aa.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),fa.select(".nv-context .nv-y1.nv-axis").transition().call(r),fa.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",S),I&&u.extent(I);var ma=fa.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),na=ma.enter().append("g");na.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",Z),na.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",Z);var oa=fa.select(".nv-x.nv-brush").call(u);oa.selectAll("rect").attr("height",Z),oa.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),S()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)",Q=!1;j.clipEdge(!0),k.interactive(!1),k.pointActive(function(a){return!1}),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var R=function(){return Q?{main:q,focus:s}:{main:p,focus:r}},S=function(){return Q?{main:p,focus:r}:{main:q,focus:s}},T=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},U=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},V=function(a){return a.every(function(a){return a.disabled})};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return S().main.tickFormat()(a,b)}).data(a).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(a){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return R().main.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(a){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(a){v()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},focusMargin:{get:function(){return x},set:function(a){x.top=void 0!==a.top?a.top:x.top,x.right=void 0!==a.right?a.right:x.right,x.bottom=void 0!==a.bottom?a.bottom:x.bottom,x.left=void 0!==a.left?a.left:x.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}},switchYAxisOrder:{get:function(){return Q},set:function(a){if(Q!==a){var b=p;p=q,q=b;var c=r;r=s,s=c}Q=a,p.orient("left"),q.orient("right"),r.orient("left"),s.orient("right")}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(F){return D.reset(),F.each(function(b){var F=k-j.left-j.right,G=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var H=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var I=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);I.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=H++,I[c]=b[c]):c>0&&I[c-1].nonStackable&&I[c].values.map(function(a,b){a.y0-=I[c-1].values[b].y,a.y1=a.y0+a.y})}),b=I}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b.length>0&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var J=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(J).map(function(a){return a.x})).rangeBands(f||[0,F],A),n.domain(e||d3.extent(d3.merge(J).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[G,0]),m.domain()[0]===m.domain()[1]&&(m.domain()[0]?m.domain([m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]):m.domain([-1,1])),n.domain()[0]===n.domain()[1]&&(n.domain()[0]?n.domain([n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]):n.domain([-1,1])),h=h||m,i=i||n;var K=p.selectAll("g.nv-wrap.nv-multibar").data([b]),L=K.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),M=L.append("defs"),N=L.append("g"),O=K.select("g");N.append("g").attr("class","nv-groups"),K.attr("transform","translate("+j.left+","+j.top+")"),M.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),K.select("#nv-edge-clip-"+o+" rect").attr("width",F).attr("height",G),O.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var P=K.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});P.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var Q=D.transition(P.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a,c,d){var e=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(e=i(a.y0)),e}).attr("height",0).remove();Q.delay&&Q.delay(function(a,b){var c=b*(z/(E+1))-b;return c}),P.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),P.style("stroke-opacity",1).style("fill-opacity",B);var R=P.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});R.exit().remove();R.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});R.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),C.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),C.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){C.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){var c=this;C.elementClick({data:a,index:b,color:d3.select(this).style("fill"),event:d3.event,element:c}),d3.event.stopPropagation()}).on("dblclick",function(a,b){C.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),R.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),R.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var S=R.watchTransition(D,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?S.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),0)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),0)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==H&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*H))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/H;return b.length!==H&&(e=m.rangeBand()/(2*H)),e}return m.rangeBand()}):S.attr("x",function(a,c){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(E=b[0].values.length)}),D.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=.75,C=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),D=a.utils.renderWatch(C,z),E=0;return b.dispatch=C,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},fillOpacity:{get:function(){return B},set:function(a){B=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,D.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(B){return G.reset(),G.models(e),s&&G.models(f),t&&G.models(g),B.each(function(B){var G=d3.select(this);a.utils.initSVG(G);var K=a.utils.availableWidth(m,G,l),L=a.utils.availableHeight(n,G,l);if(b.update=function(){0===E?G.call(b):G.transition().duration(E).call(b)},b.container=this,z.setter(J(B),b.update).getter(I(B)).update(),z.disabled=B.map(function(a){return!!a.disabled}),!A){var M;A={};for(M in z)z[M]instanceof Array?A[M]=z[M].slice(0):A[M]=z[M]}if(!(B&&B.length&&B.filter(function(a){return a.values.length}).length))return a.utils.noData(b,G),b;G.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=G.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([B]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),P=N.select("g");if(O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-barsWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),r?(i.width(K-D()),P.select(".nv-legendWrap").datum(B).call(i),i.height()>l.top&&(l.top=i.height(),L=a.utils.availableHeight(n,G,l)),P.select(".nv-legendWrap").attr("transform","translate("+D()+","+-l.top+")")):P.select(".nv-legendWrap").selectAll("*").remove(),p){var Q=[{key:q.grouped||"Grouped",disabled:e.stacked()},{key:q.stacked||"Stacked",disabled:!e.stacked()}];j.width(D()).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(Q).attr("transform","translate(0,"+-l.top+")").call(j)}else P.select(".nv-controlsWrap").selectAll("*").remove();N.attr("transform","translate("+l.left+","+l.top+")"),u&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),e.disabled(B.map(function(a){return a.disabled})).width(K).height(L).color(B.map(function(a,b){return a.color||o(a,b)}).filter(function(a,b){return!B[b].disabled}));var R=P.select(".nv-barsWrap").datum(B.filter(function(a){return!a.disabled}));if(R.call(e),s){f.scale(c)._ticks(a.utils.calcTicksX(K/100,B)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),P.select(".nv-x.nv-axis").call(f);var S=P.select(".nv-x.nv-axis > g").selectAll("g");if(S.selectAll("line, text").style("opacity",1),w){var T=function(a,b){return"translate("+a+","+b+")"},U=5,V=17;S.selectAll("text").attr("transform",function(a,b,c){return T(0,c%2==0?U:V)});var W=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;P.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return T(0,0===b||W%2!==0?V:U)})}x&&P.selectAll(".tick text").call(a.utils.wrapTicks,b.xAxis.rangeBand()),v&&S.filter(function(a,b){return b%Math.ceil(B[0].values.length/(K/100))!==0}).selectAll("text, line").style("opacity",0),y&&S.selectAll(".tick text").attr("transform","rotate("+y+" 0,0)").style("text-anchor",y>0?"start":"end"),P.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}t&&(g.scale(d)._ticks(a.utils.calcTicksY(L/36,B)).tickSize(-K,0),P.select(".nv-y.nv-axis").call(g)),F&&(h.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(G).xScale(c),N.select(".nv-interactive").call(h)),i.dispatch.on("stateChange",function(a){for(var c in a)z[c]=a[c];C.stateChange(z),b.update()}),j.dispatch.on("legendClick",function(a,c){if(a.disabled){switch(Q=Q.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case q.grouped:e.stacked(!1);break;case"Stacked":case q.stacked:e.stacked(!0)}z.stacked=e.stacked(),C.stateChange(z),b.update()}}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(B.forEach(function(b,c){b.disabled=a.disabled[c]}),z.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),z.stacked=a.stacked,H=a.stacked),b.update()}),F?(h.dispatch.on("elementMousemove",function(a){if(void 0!=a.pointXValue){var d,e,f,g,i=[];B.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(h,j){e=c.domain().indexOf(a.pointXValue);var k=h.values[e];void 0!==k&&(g=k.x,void 0===d&&(d=k),void 0===f&&(f=a.mouseX),i.push({key:h.key,value:b.y()(k,e),color:o(h,h.seriesIndex),data:h.values[e]}))}),h.tooltip.data({value:g,index:e,series:i})(),h.renderGuideLine(f)}}),h.dispatch.on("elementMouseout",function(a){h.tooltip.hidden(!0)})):(e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},k.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){k.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(a){k()}))}),G.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.interactiveGuideline(),i=a.models.legend(),j=a.models.legend(),k=a.models.tooltip(),l={top:30,right:20,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q={},r=!0,s=!0,t=!0,u=!1,v=!0,w=!1,x=!1,y=0,z=a.utils.state(),A=null,B=null,C=d3.dispatch("stateChange","changeState","renderEnd"),D=function(){return p?180:0},E=250,F=!1;z.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(u?"right":"left").tickFormat(d3.format(",.1f")),k.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),j.updateState(!1);var G=a.utils.renderWatch(C),H=!1,I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:H}}},J=function(a){return function(b){void 0!==b.stacked&&(H=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=C,b.multibar=e,b.legend=i,b.controls=j,b.xAxis=f,b.yAxis=g,b.state=z,b.tooltip=k,b.interactiveLayer=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return r},set:function(a){r=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return s},set:function(a){s=a}},showYAxis:{get:function(){return t},set:function(a){t=a}},defaultState:{get:function(){return A},set:function(a){A=a}},noData:{get:function(){return B},set:function(a){B=a}},reduceXTicks:{get:function(){return v},set:function(a){v=a}},rotateLabels:{get:function(){return y},set:function(a){y=a}},staggerLabels:{get:function(){return w},set:function(a){w=a}},wrapLabels:{get:function(){return x},set:function(a){x=!!a}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return E},set:function(a){E=a,e.duration(E),f.duration(E),g.duration(E),G.reset(E)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),i.color(o)}},rightAlignYAxis:{get:function(){return u},set:function(a){u=a,g.orient(u?"right":"left")}},useInteractiveGuideline:{get:function(){return F},set:function(a){F=a}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),i.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return F.reset(),m.each(function(b){var m=k-j.left-j.right,D=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var G=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(G).map(function(a){return a.x})).rangeBands(f||[0,D],A),p.domain(e||d3.extent(d3.merge(G).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),x&&!w?p.range(g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]):p.range(g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);var H=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),I=H.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),J=(I.append("defs"),I.append("g"));H.select("g");J.append("g").attr("class","nv-groups"),H.attr("transform","translate("+j.left+","+j.top+")");var K=H.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});K.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),K.exit().watchTransition(F,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),K.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),K.watchTransition(F,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",B);var L=K.selectAll("g.nv-bar").data(function(a){return a.values});L.exit().remove();var M=L.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});M.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),L.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),E.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),E.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){E.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){E.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){var c=this;E.elementClick({data:a,index:b,color:d3.select(this).style("fill"),event:d3.event,element:c}),d3.event.stopPropagation()}).on("dblclick",function(a,b){E.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(M.append("polyline"),L.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),M.append("text"),x&&!w?(L.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=C(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+C(Math.abs(d[1]))+"-"+C(Math.abs(d[0])):c+"±"+C(Math.abs(d))}),L.watchTransition(F,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):L.selectAll("text").text(""),y&&!w?(M.append("text").classed("nv-bar-label",!0),L.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),L.watchTransition(F,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):L.selectAll("text.nv-bar-label").text(""),L.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),L.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?L.watchTransition(F,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))||0}).attr("height",o.rangeBand()):L.watchTransition(F,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)||0}),h=o.copy(),i=p.copy()}),F.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=.75,C=d3.format(",.2f"),D=250,E=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),F=a.utils.renderWatch(E,D);return b.dispatch=E,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return C},set:function(a){C=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},fillOpacity:{get:function(){return B},set:function(a){B=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return D},set:function(a){D=a,F.reset(D)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)u[E]instanceof Array?v[E]=u[E].slice(0):v[E]=u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q?(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),h.height()>k.top&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")):H.select(".nv-legendWrap").selectAll("*").remove(),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}else H.select(".nv-controlsWrap").selectAll("*").remove();F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a,c){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(a){j()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function n(a){var b=2===j[a.seriesIndex].yAxis?E:D;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color,key:a.series.key},G.duration(0).headerFormatter(function(a,b){return C.tickFormat()(a,b)}).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}function H(a){var b=2===j[a.seriesIndex].yAxis?E:D;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color,key:a.series.key},G.duration(100).headerFormatter(function(a,b){return C.tickFormat()(a,b)}).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}function J(a){var b=2===j[a.seriesIndex].yAxis?E:D;a.point.x=A.x()(a.point),a.point.y=A.y()(a.point),G.duration(0).headerFormatter(function(a,b){return C.tickFormat()(a,b)}).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}function K(a){var b=2===j[a.data.series].yAxis?E:D;a.value=y.x()(a.data),a.series={value:y.y()(a.data),color:a.color,key:a.data.key},G.duration(0).headerFormatter(function(a,b){return C.tickFormat()(a,b)}).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}function L(){for(var a=0,b=I.length;b>a;a++){var c=I[a];try{c.clearHighlights()}catch(d){}}}function M(a,b,c){for(var d=0,e=I.length;e>d;d++){var f=I[d];try{f.highlightPoint(a,b,c)}catch(g){}}}var N=d3.select(this);a.utils.initSVG(N),b.update=function(){N.transition().call(b)},b.container=this;var O=a.utils.availableWidth(g,N,e),P=a.utils.availableHeight(h,N,e),Q=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),R=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),S=j.filter(function(a){return"scatter"==a.type&&1==a.yAxis}),T=j.filter(function(a){return"scatter"==a.type&&2==a.yAxis}),U=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),V=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),W=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),X=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,N),b;N.selectAll(".nv-noData").remove();var Y=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a,b){return{x:k(a),y:l(a)}})}),Z=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a,b){return{x:k(a),y:l(a)}})});r.domain(d3.extent(d3.merge(Y.concat(Z)),function(a){return a.x})).range([0,O]);var $=N.selectAll("g.wrap.multiChart").data([j]),_=$.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");_.append("g").attr("class","nv-x nv-axis"),_.append("g").attr("class","nv-y1 nv-axis"),_.append("g").attr("class","nv-y2 nv-axis"),_.append("g").attr("class","stack1Wrap"),_.append("g").attr("class","stack2Wrap"),_.append("g").attr("class","bars1Wrap"),_.append("g").attr("class","bars2Wrap"),_.append("g").attr("class","scatters1Wrap"),_.append("g").attr("class","scatters2Wrap"),_.append("g").attr("class","lines1Wrap"),_.append("g").attr("class","lines2Wrap"),_.append("g").attr("class","legendWrap"),_.append("g").attr("class","nv-interactive");var aa=$.select("g"),ba=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var ca=F.align()?O/2:O,da=F.align()?ca:0;F.width(ca),F.color(ba),aa.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":q),a})).call(F),F.height()>e.top&&(e.top=F.height(),P=a.utils.availableHeight(h,N,e)),aa.select(".legendWrap").attr("transform","translate("+da+","+-e.top+")")}else aa.select(".legendWrap").selectAll("*").remove();u.width(O).height(P).interpolate(m).color(ba.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),v.width(O).height(P).interpolate(m).color(ba.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),w.width(O).height(P).color(ba.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"scatter"==j[b].type})),x.width(O).height(P).color(ba.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"scatter"==j[b].type})),y.width(O).height(P).color(ba.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),z.width(O).height(P).color(ba.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),A.width(O).height(P).interpolate(m).color(ba.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),B.width(O).height(P).interpolate(m).color(ba.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),aa.attr("transform","translate("+e.left+","+e.top+")");var ea=aa.select(".lines1Wrap").datum(Q.filter(function(a){return!a.disabled})),fa=aa.select(".scatters1Wrap").datum(S.filter(function(a){return!a.disabled})),ga=aa.select(".bars1Wrap").datum(U.filter(function(a){return!a.disabled})),ha=aa.select(".stack1Wrap").datum(W.filter(function(a){return!a.disabled})),ia=aa.select(".lines2Wrap").datum(R.filter(function(a){return!a.disabled})),ja=aa.select(".scatters2Wrap").datum(T.filter(function(a){return!a.disabled})),ka=aa.select(".bars2Wrap").datum(V.filter(function(a){return!a.disabled})),la=aa.select(".stack2Wrap").datum(X.filter(function(a){return!a.disabled})),ma=W.length?W.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],na=X.length?X.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];s.domain(c||d3.extent(d3.merge(Y).concat(ma),function(a){return a.y})).range([0,P]),t.domain(d||d3.extent(d3.merge(Z).concat(na),function(a){return a.y})).range([0,P]),u.yDomain(s.domain()),w.yDomain(s.domain()),y.yDomain(s.domain()),A.yDomain(s.domain()),v.yDomain(t.domain()),x.yDomain(t.domain()),z.yDomain(t.domain()),B.yDomain(t.domain()),W.length&&d3.transition(ha).call(A),X.length&&d3.transition(la).call(B),U.length&&d3.transition(ga).call(y),V.length&&d3.transition(ka).call(z),Q.length&&d3.transition(ea).call(u),R.length&&d3.transition(ia).call(v),S.length&&d3.transition(fa).call(w),T.length&&d3.transition(ja).call(x),C._ticks(a.utils.calcTicksX(O/100,j)).tickSize(-P,0),aa.select(".nv-x.nv-axis").attr("transform","translate(0,"+P+")"),d3.transition(aa.select(".nv-x.nv-axis")).call(C),D._ticks(a.utils.calcTicksY(P/36,j)).tickSize(-O,0),d3.transition(aa.select(".nv-y1.nv-axis")).call(D),E._ticks(a.utils.calcTicksY(P/36,j)).tickSize(-O,0),d3.transition(aa.select(".nv-y2.nv-axis")).call(E),aa.select(".nv-y1.nv-axis").classed("nv-disabled",Y.length?!1:!0).attr("transform","translate("+r.range()[0]+",0)"),aa.select(".nv-y2.nv-axis").classed("nv-disabled",Z.length?!1:!0).attr("transform","translate("+r.range()[1]+",0)"),F.dispatch.on("stateChange",function(a){b.update()}),p&&(o.width(O).height(P).margin({left:e.left,top:e.top}).svgContainer(N).xScale(r),$.select(".nv-interactive").call(o)),p?(o.dispatch.on("elementMousemove",function(c){L();var d,e,g,h=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var k=r.domain(),l=i.values.filter(function(a,c){return b.x()(a,c)>=k[0]&&b.x()(a,c)<=k[1]});e=a.interactiveBisect(l,c.pointXValue,b.x());var m=l[e],n=b.y()(m,e);null!==n&&M(j,e,!0),void 0!==m&&(void 0===d&&(d=m),void 0===g&&(g=r(b.x()(m,e))),h.push({key:i.key,value:n,color:f(i,i.seriesIndex),data:m,yAxis:2==i.yAxis?E:D}))});var i=function(a,b){var c=h[b].yAxis;return null==a?"N/A":c.tickFormat()(a)};o.tooltip.headerFormatter(function(a,b){return C.tickFormat()(a,b)}).valueFormatter(o.tooltip.valueFormatter()||i).data({value:b.x()(d,e),index:e,series:h})(),o.renderGuideLine(g)}),o.dispatch.on("elementMouseout",function(a){L()})):(u.dispatch.on("elementMouseover.tooltip",n),v.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseout.tooltip",function(a){G.hidden(!0)}),v.dispatch.on("elementMouseout.tooltip",function(a){G.hidden(!0)}),w.dispatch.on("elementMouseover.tooltip",H),x.dispatch.on("elementMouseover.tooltip",H),w.dispatch.on("elementMouseout.tooltip",function(a){G.hidden(!0)}),x.dispatch.on("elementMouseout.tooltip",function(a){G.hidden(!0)}),A.dispatch.on("elementMouseover.tooltip",J),B.dispatch.on("elementMouseover.tooltip",J),A.dispatch.on("elementMouseout.tooltip",function(a){G.hidden(!0)}),B.dispatch.on("elementMouseout.tooltip",function(a){G.hidden(!0)}),y.dispatch.on("elementMouseover.tooltip",K),z.dispatch.on("elementMouseover.tooltip",K),y.dispatch.on("elementMouseout.tooltip",function(a){G.hidden(!0)}),z.dispatch.on("elementMouseout.tooltip",function(a){G.hidden(!0)}),y.dispatch.on("elementMousemove.tooltip",function(a){G()}),z.dispatch.on("elementMousemove.tooltip",function(a){G()}))}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="linear",n=!0,o=a.interactiveGuideline(),p=!1,q=" (right axis)",r=d3.scale.linear(),s=d3.scale.linear(),t=d3.scale.linear(),u=a.models.line().yScale(s),v=a.models.line().yScale(t),w=a.models.scatter().yScale(s),x=a.models.scatter().yScale(t),y=a.models.multiBar().stacked(!1).yScale(s),z=a.models.multiBar().stacked(!1).yScale(t),A=a.models.stackedArea().yScale(s),B=a.models.stackedArea().yScale(t),C=a.models.axis().scale(r).orient("bottom").tickPadding(5),D=a.models.axis().scale(s).orient("left"),E=a.models.axis().scale(t).orient("right"),F=a.models.legend().height(30),G=a.models.tooltip(),H=d3.dispatch(),I=[u,v,w,x,y,z,A,B];return b.dispatch=H,b.legend=F,b.lines1=u,b.lines2=v,b.scatters1=w,b.scatters2=x,b.bars1=y,b.bars2=z,b.stack1=A,b.stack2=B,b.xAxis=C,b.yAxis1=D,b.yAxis2=E,b.tooltip=G,b.interactiveLayer=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},legendRightAxisHint:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,u.x(a),v.x(a),w.x(a),x.x(a),y.x(a),z.x(a),A.x(a),B.x(a)}},y:{get:function(){return l},set:function(a){l=a,u.y(a),v.y(a),w.y(a),x.y(a),A.y(a),B.y(a),y.y(a),z.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,u.useVoronoi(a),v.useVoronoi(a),A.useVoronoi(a),B.useVoronoi(a)}},useInteractiveGuideline:{get:function(){return p},set:function(a){p=a,p&&(u.interactive(!1),u.useVoronoi(!1),v.interactive(!1),v.useVoronoi(!1),A.interactive(!1),A.useVoronoi(!1),B.interactive(!1),B.useVoronoi(!1),w.interactive(!1),x.interactive(!1))}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),v?l.range(e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]):l.range(e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&(l.domain()[0]?l.domain([l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]):l.domain([-1,1])),m.domain()[0]===m.domain()[1]&&(m.domain()[0]?m.domain([m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]):m.domain([-1,1]));var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(a,b){return x[0]}).attr("stroke",function(a,b){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(B){return A.reset(),B.each(function(b){function A(a){return x(o.map(function(b){if(isNaN(a.values[b.key])||isNaN(parseFloat(a.values[b.key]))||O){var c=l[b.key].domain(),d=l[b.key].range(),e=c[0]-(c[1]-c[0])/9;if(v.indexOf(b.key)<0){var f=d3.scale.linear().domain([e,c[1]]).range([j-12,d[1]]);l[b.key].brush.y(f),v.push(b.key)}if(isNaN(a.values[b.key])||isNaN(parseFloat(a.values[b.key])))return[k(b.key),l[b.key](e)]}return void 0!==U&&(v.length>0||O?(U.style("display","inline"),V.style("display","inline")):(U.style("display","none"),V.style("display","none"))),[k(b.key),l[b.key](a.values[b.key])]}))}function B(a){s.forEach(function(b){var c=l[b.dimension].brush.y().domain();b.hasOnlyNaN&&(b.extent[1]=(l[b.dimension].domain()[1]-c[0])*(b.extent[1]-b.extent[0])/(N[b.dimension]-b.extent[0])+c[0]),b.hasNaN&&(b.extent[0]=c[0]),a&&l[b.dimension].brush.extent(b.extent)}),e.select(".nv-brushBackground").each(function(a){d3.select(this).call(l[a.key].brush)}).selectAll("rect").attr("x",-8).attr("width",16),F()}function C(){q===!1&&(q=!0,B(!0))}function D(){$=p.filter(function(a){return!l[a].brush.empty()}),_=$.map(function(a){return l[a].brush.extent()}),s=[],$.forEach(function(a,b){s[b]={dimension:a,extent:_[b],hasNaN:!1,hasOnlyNaN:!1}}),t=[],c.style("display",function(a){var b=$.every(function(b,c){return(isNaN(a.values[b])||isNaN(parseFloat(a.values[b])))&&_[c][0]==l[b].brush.y().domain()[0]?!0:_[c][0]<=a.values[b]&&a.values[b]<=_[c][1]&&!isNaN(parseFloat(a.values[b]))});return b&&t.push(a),b?null:"none"}),F(),z.brush({filters:s,active:t})}function E(){var a=$.length>0?!0:!1;s.forEach(function(a){a.extent[0]===l[a.dimension].brush.y().domain()[0]&&v.indexOf(a.dimension)>=0&&(a.hasNaN=!0),a.extent[1]<l[a.dimension].domain()[0]&&(a.hasOnlyNaN=!0)}),z.brushEnd(t,a)}function F(){e.select(".nv-axis").each(function(a,b){var c=s.filter(function(b){return b.dimension==a.key});P[a.key]=l[a.key].domain(),0!=c.length&&q&&(P[a.key]=[],c[0].extent[1]>l[a.key].domain()[0]&&(P[a.key]=[c[0].extent[1]]),c[0].extent[0]>=l[a.key].domain()[0]&&P[a.key].push(c[0].extent[0])),d3.select(this).call(y.scale(l[a.key]).tickFormat(a.format).tickValues(P[a.key]))})}function G(a){u[a.key]=this.parentNode.__origin__=k(a.key),d.attr("visibility","hidden")}function H(a){u[a.key]=Math.min(i,Math.max(0,this.parentNode.__origin__+=d3.event.x)),c.attr("d",A),o.sort(function(a,b){return J(a.key)-J(b.key)}),o.forEach(function(a,b){return a.currentPosition=b}),k.domain(o.map(function(a){return a.key})),e.attr("transform",function(a){return"translate("+J(a.key)+")"})}function I(a,b){delete this.parentNode.__origin__,delete u[a.key],d3.select(this.parentNode).attr("transform","translate("+k(a.key)+")"),c.attr("d",A),d.attr("d",A).attr("visibility",null),z.dimensionsOrder(o)}function J(a){var b=u[a];return null==b?k(a):b}var K=d3.select(this);if(i=a.utils.availableWidth(g,K,f),j=a.utils.availableHeight(h,K,f),a.utils.initSVG(K),void 0===b[0].values){var L=[];b.forEach(function(a){var b={},c=Object.keys(a);c.forEach(function(c){"name"!==c&&(b[c]=a[c])}),L.push({key:a.name,values:b})}),b=L}var M=b.map(function(a){return a.values});0===t.length&&(t=b),p=n.sort(function(a,b){return a.currentPosition-b.currentPosition}).map(function(a){return a.key}),o=n.filter(function(a){return!a.disabled}),k.rangePoints([0,i],1).domain(o.map(function(a){return a.key}));var N={},O=!1,P=[];p.forEach(function(a){var b=d3.extent(M,function(b){return+b[a]}),c=b[0],d=b[1],e=!1;(isNaN(c)||isNaN(d))&&(e=!0,c=0,d=0),c===d&&(c-=1,d+=1);var f=s.filter(function(b){return b.dimension==a});0!==f.length&&(e?(c=l[a].domain()[0],d=l[a].domain()[1]):!f[0].hasOnlyNaN&&q?(c=c>f[0].extent[0]?f[0].extent[0]:c,d=d<f[0].extent[1]?f[0].extent[1]:d):f[0].hasNaN&&(d=d<f[0].extent[1]?f[0].extent[1]:d,N[a]=l[a].domain()[1],O=!0)),l[a]=d3.scale.linear().domain([c,d]).range([.9*(j-12),0]),v=[],l[a].brush=d3.svg.brush().y(l[a]).on("brushstart",C).on("brush",D).on("brushend",E)});var Q=K.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),R=Q.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),S=R.append("g"),T=Q.select("g");S.append("g").attr("class","nv-parallelCoordinates background"),S.append("g").attr("class","nv-parallelCoordinates foreground"),S.append("g").attr("class","nv-parallelCoordinates missingValuesline"),Q.attr("transform","translate("+f.left+","+f.top+")"),x.interpolate("cardinal").tension(w),y.orient("left");var U,V,W=d3.behavior.drag().on("dragstart",G).on("drag",H).on("dragend",I),X=k.range()[1]-k.range()[0];if(!isNaN(X)){var Y=[0+X/2,j-12,i-X/2,j-12];U=Q.select(".missingValuesline").selectAll("line").data([Y]),U.enter().append("line"),U.exit().remove(),U.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),V=Q.select(".missingValuesline").selectAll("text").data([m]),V.append("text").data([m]),V.enter().append("text"),V.exit().remove(),V.attr("y",j).attr("x",i-92-X/2).text(function(a){return a})}d=Q.select(".background").selectAll("path").data(b),d.enter().append("path"),d.exit().remove(),d.attr("d",A),c=Q.select(".foreground").selectAll("path").data(b),c.enter().append("path"),c.exit().remove(),c.attr("d",A).style("stroke-width",function(a,b){return isNaN(a.strokeWidth)&&(a.strokeWidth=1),a.strokeWidth}).attr("stroke",function(a,b){return a.color||r(a,b)}),c.on("mouseover",function(a,b){d3.select(this).classed("hover",!0).style("stroke-width",a.strokeWidth+2+"px").style("stroke-opacity",1),z.elementMouseover({label:a.name,color:a.color||r(a,b),values:a.values,dimensions:o})}),c.on("mouseout",function(a,b){d3.select(this).classed("hover",!1).style("stroke-width",a.strokeWidth+"px").style("stroke-opacity",.7),z.elementMouseout({label:a.name,index:b})}),c.on("mousemove",function(a,b){z.elementMousemove()}),c.on("click",function(a){z.elementClick({id:a.id})}),e=T.selectAll(".dimension").data(o);var Z=e.enter().append("g").attr("class","nv-parallelCoordinates dimension");e.attr("transform",function(a){return"translate("+k(a.key)+",0)"}),Z.append("g").attr("class","nv-axis"),Z.append("text").attr("class","nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").on("mouseover",function(a,b){z.elementMouseover({label:a.tooltip||a.key,color:a.color})}).on("mouseout",function(a,b){z.elementMouseout({label:a.tooltip})}).on("mousemove",function(a,b){z.elementMousemove()}).call(W),Z.append("g").attr("class","nv-brushBackground"),e.exit().remove(),e.select(".nv-label").text(function(a){return a.key}),B(q);var $=p.filter(function(a){return!l[a].brush.empty()}),_=$.map(function(a){return l[a].brush.extent()}),aa=t.slice(0);t=[],c.style("display",function(a){var b=$.every(function(b,c){return(isNaN(a.values[b])||isNaN(parseFloat(a.values[b])))&&_[c][0]==l[b].brush.y().domain()[0]?!0:_[c][0]<=a.values[b]&&a.values[b]<=_[c][1]&&!isNaN(parseFloat(a.values[b]))});return b&&t.push(a),b?null:"none"}),(s.length>0||!a.utils.arrayEquals(t,aa))&&z.activeChanged(t)}),b}var c,d,e,f={top:30,right:0,bottom:10,left:0},g=null,h=null,i=null,j=null,k=d3.scale.ordinal(),l={},m="undefined values",n=[],o=[],p=[],q=!0,r=a.utils.defaultColor(),s=[],t=[],u=[],v=[],w=1,x=d3.svg.line(),y=d3.svg.axis(),z=d3.dispatch("brushstart","brush","brushEnd","dimensionsOrder","stateChange","elementClick","elementMouseover","elementMouseout","elementMousemove","renderEnd","activeChanged"),A=a.utils.renderWatch(z);return b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},dimensionData:{get:function(){return n},set:function(a){n=a}},displayBrush:{get:function(){return q},set:function(a){q=a}},filters:{get:function(){return s},set:function(a){s=a}},active:{get:function(){return t},set:function(a){t=a}},lineTension:{get:function(){return w},set:function(a){w=a}},undefinedValuesLabel:{get:function(){return m},set:function(a){m=a}},dimensions:{get:function(){return n.map(function(a){return a.key})},set:function(b){a.deprecated("dimensions","use dimensionData instead"),0===n.length?b.forEach(function(a){n.push({key:a})}):b.forEach(function(a,b){n[b].key=a})}},dimensionNames:{get:function(){return n.map(function(a){return a.key})},set:function(b){a.deprecated("dimensionNames","use dimensionData instead"),p=[],0===n.length?b.forEach(function(a){n.push({key:a})}):b.forEach(function(a,b){n[b].key=a})}},dimensionFormats:{get:function(){return n.map(function(a){return a.format})},set:function(b){a.deprecated("dimensionFormats","use dimensionData instead"),0===n.length?b.forEach(function(a){n.push({format:a})}):b.forEach(function(a,b){n[b].format=a})}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},color:{get:function(){return r},set:function(b){r=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinatesChart=function(){"use strict";function b(e){return r.reset(),r.models(c),e.each(function(e){var j=d3.select(this);a.utils.initSVG(j);var o=a.utils.availableWidth(g,j,f),p=a.utils.availableHeight(h,j,f);if(b.update=function(){j.call(b)},b.container=this,k.setter(t(l),b.update).getter(s(l)).update(),k.disabled=l.map(function(a){return!!a.disabled}),l=l.map(function(a){return a.disabled=!!a.disabled,a}),l.forEach(function(a,b){a.originalPosition=isNaN(a.originalPosition)?b:a.originalPosition,a.currentPosition=isNaN(a.currentPosition)?b:a.currentPosition}),!n){var r;n={};for(r in k)k[r]instanceof Array?n[r]=k[r].slice(0):n[r]=k[r]}if(!e||!e.length)return a.utils.noData(b,j),b;j.selectAll(".nv-noData").remove();var u=j.selectAll("g.nv-wrap.nv-parallelCoordinatesChart").data([e]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinatesChart").append("g"),w=u.select("g");v.append("g").attr("class","nv-parallelCoordinatesWrap"),v.append("g").attr("class","nv-legendWrap"),w.select("rect").attr("width",o).attr("height",p>0?p:0),i?(d.width(o).color(function(a){return"rgb(188,190,192)"}),w.select(".nv-legendWrap").datum(l.sort(function(a,b){return a.originalPosition-b.originalPosition})).call(d),d.height()>f.top&&(f.top=d.height(),p=a.utils.availableHeight(h,j,f)),u.select(".nv-legendWrap").attr("transform","translate( 0 ,"+-f.top+")")):w.select(".nv-legendWrap").selectAll("*").remove(),u.attr("transform","translate("+f.left+","+f.top+")"),c.width(o).height(p).dimensionData(l).displayBrush(m);var x=w.select(".nv-parallelCoordinatesWrap ").datum(e);x.transition().call(c),c.dispatch.on("brushEnd",function(a,b){b?(m=!0,q.brushEnd(a)):m=!1}),d.dispatch.on("stateChange",function(a){for(var c in a)k[c]=a[c];q.stateChange(k),b.update()}),c.dispatch.on("dimensionsOrder",function(a){l.sort(function(a,b){return a.currentPosition-b.currentPosition});var b=!1;l.forEach(function(a,c){a.currentPosition=c,a.currentPosition!==a.originalPosition&&(b=!0)}),q.dimensionsOrder(l,b)}),q.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),k.disabled=a.disabled),b.update()})}),r.renderEnd("parraleleCoordinateChart immediate"),b}var c=a.models.parallelCoordinates(),d=a.models.legend(),e=a.models.tooltip(),f=(a.models.tooltip(),{top:0,right:0,bottom:0,left:0}),g=null,h=null,i=!0,j=a.utils.defaultColor(),k=a.utils.state(),l=[],m=!0,n=null,o=null,p="undefined",q=d3.dispatch("dimensionsOrder","brushEnd","stateChange","changeState","renderEnd"),r=a.utils.renderWatch(q),s=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},t=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.contentGenerator(function(a){var b='<table><thead><tr><td class="legend-color-guide"><div style="background-color:'+a.color+'"></div></td><td><strong>'+a.key+"</strong></td></tr></thead>";return 0!==a.series.length&&(b+='<tbody><tr><td height ="10px"></td></tr>',a.series.forEach(function(a){b=b+'<tr><td class="legend-color-guide"><div style="background-color:'+a.color+'"></div></td><td class="key">'+a.key+'</td><td class="value">'+a.value+"</td></tr>"}),b+="</tbody>"),b+="</table>"}),c.dispatch.on("elementMouseover.tooltip",function(a){var b={key:a.label,color:a.color,series:[]};a.values&&(Object.keys(a.values).forEach(function(c){var d=a.dimensions.filter(function(a){return a.key===c})[0];if(d){var e;e=isNaN(a.values[c])||isNaN(parseFloat(a.values[c]))?p:d.format(a.values[c]),b.series.push({idx:d.currentPosition,key:c,value:e,color:d.color})}}),b.series.sort(function(a,b){return a.idx-b.idx})),e.data(b).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(a){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e()}),b.dispatch=q,b.parallelCoordinates=c,b.legend=d,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},defaultState:{get:function(){return n},set:function(a){n=a}},dimensionData:{get:function(){return l},set:function(a){l=a}},displayBrush:{get:function(){return m},set:function(a){m=a}},noData:{get:function(){return o},set:function(a){o=a}},nanValue:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b),d.color(j),c.color(j)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(F){return E.reset(),F.each(function(b){function F(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return C[b](c(a))}}var G=d-c.left-c.right,H=e-c.top-c.bottom,I=Math.min(G,H)/2,J=[],K=[];if(i=d3.select(this),0===A.length)for(var L=I-I/5,M=y*I,N=0;N<b[0].length;N++)J.push(L),K.push(M);else r?(J=A.map(function(a){return(a.outer-a.outer/5)*I}),K=A.map(function(a){return(a.inner-a.inner/5)*I}),y=d3.min(A.map(function(a){return a.inner-a.inner/5}))):(J=A.map(function(a){return a.outer*I}),K=A.map(function(a){return a.inner*I}),y=d3.min(A.map(function(a){return a.inner})));a.utils.initSVG(i);var O=i.selectAll(".nv-wrap.nv-pie").data(b),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-pie nv-chart-"+h),Q=P.append("g"),R=O.select("g"),S=Q.append("g").attr("class","nv-pie");Q.append("g").attr("class","nv-pieLabels"),O.attr("transform","translate("+c.left+","+c.top+")"),R.select(".nv-pie").attr("transform","translate("+G/2+","+H/2+")"),R.select(".nv-pieLabels").attr("transform","translate("+G/2+","+H/2+")"),i.on("click",function(a,b){B.chartClick({data:a,index:b,pos:d3.event,id:h})}),C=[],D=[];for(var N=0;N<b[0].length;N++){var T=d3.svg.arc().outerRadius(J[N]),U=d3.svg.arc().outerRadius(J[N]+5);u!==!1&&(T.startAngle(u),U.startAngle(u)),w!==!1&&(T.endAngle(w),U.endAngle(w)),p&&(T.innerRadius(K[N]),U.innerRadius(K[N])),T.cornerRadius&&x&&(T.cornerRadius(x),U.cornerRadius(x)),C.push(T),D.push(U)}var V=d3.layout.pie().sort(null).value(function(a){return a.disabled?0:g(a)});V.padAngle&&v&&V.padAngle(v),p&&q&&(S.append("text").attr("class","nv-pie-title"),O.select(".nv-pie-title").style("text-anchor","middle").text(function(a){return q}).style("font-size",Math.min(G,H)*y*2/(q.length+2)+"px").attr("dy","0.35em").attr("transform",function(a,b){return"translate(0, "+s+")"}));var W=O.select(".nv-pie").selectAll(".nv-slice").data(V),X=O.select(".nv-pieLabels").selectAll(".nv-label").data(V);W.exit().remove(),X.exit().remove();var Y=W.enter().append("g");Y.attr("class","nv-slice"),Y.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),r&&d3.select(this).select("path").transition().duration(70).attr("d",D[b]),B.elementMouseover({data:a.data,index:b,color:d3.select(this).style("fill"),percent:(a.endAngle-a.startAngle)/(2*Math.PI)})}),Y.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),r&&d3.select(this).select("path").transition().duration(50).attr("d",C[b]),B.elementMouseout({data:a.data,index:b})}),Y.on("mousemove",function(a,b){B.elementMousemove({data:a.data,index:b})}),Y.on("click",function(a,b){var c=this;B.elementClick({data:a.data,index:b,color:d3.select(this).style("fill"),event:d3.event,element:c})}),Y.on("dblclick",function(a,b){B.elementDblClick({data:a.data,index:b,color:d3.select(this).style("fill")})}),W.attr("fill",function(a,b){return j(a.data,b)}),W.attr("stroke",function(a,b){return j(a.data,b)});Y.append("path").each(function(a){this._current=a});if(W.select("path").transition().duration(z).attr("d",function(a,b){return C[b](a)}).attrTween("d",F),l){for(var Z=[],N=0;N<b[0].length;N++)Z.push(C[N]),m?p&&(Z[N]=d3.svg.arc().outerRadius(C[N].outerRadius()),u!==!1&&Z[N].startAngle(u),w!==!1&&Z[N].endAngle(w)):p||Z[N].innerRadius(0);X.enter().append("g").classed("nv-label",!0).each(function(a,b){var c=d3.select(this);c.attr("transform",function(a,b){if(t){a.outerRadius=J[b]+10,a.innerRadius=J[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Z[b].centroid(a)+") rotate("+c+")"}return a.outerRadius=I+10,a.innerRadius=I+15,"translate("+Z[b].centroid(a)+")"}),c.append("rect").style("stroke","#fff").style("fill","#fff").attr("rx",3).attr("ry",3),c.append("text").style("text-anchor",t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")});var $={},_=14,aa=140,ba=function(a){return Math.floor(a[0]/aa)*aa+","+Math.floor(a[1]/_)*_},ca=function(a){return(a.endAngle-a.startAngle)/(2*Math.PI)};X.watchTransition(E,"pie labels").attr("transform",function(a,b){if(t){a.outerRadius=J[b]+10,a.innerRadius=J[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Z[b].centroid(a)+") rotate("+c+")"}a.outerRadius=I+10,a.innerRadius=I+15;var d=Z[b].centroid(a),e=ca(a);if(a.value&&e>=o){var f=ba(d);$[f]&&(d[1]-=_),$[ba(d)]=!0}return"translate("+d+")"}),X.select(".nv-label text").style("text-anchor",function(a,b){return t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle"}).text(function(a,b){var c=ca(a),d="";if(!a.value||o>c)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),E.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=250,A=[],B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=[],D=[],E=a.utils.renderWatch(B);return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return A},set:function(a){A=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},duration:{get:function(){return z},set:function(a){z=a,E.reset(z)}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return r.reset(),r.models(c),e.each(function(e){var i=d3.select(this);a.utils.initSVG(i);var l=a.utils.availableWidth(g,i,f),o=a.utils.availableHeight(h,i,f);if(b.update=function(){i.transition().call(b)},b.container=this,m.setter(t(e),b.update).getter(s(e)).update(),m.disabled=e.map(function(a){return!!a.disabled}),!n){var p;n={};for(p in m)m[p]instanceof Array?n[p]=m[p].slice(0):n[p]=m[p]}if(!e||!e.length)return a.utils.noData(b,i),b;i.selectAll(".nv-noData").remove();var r=i.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=r.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=r.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),j){if("top"===k)d.width(l).key(c.x()),r.select(".nv-legendWrap").datum(e).call(d),d.height()>f.top&&(f.top=d.height(),o=a.utils.availableHeight(h,i,f)),r.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===k){var w=a.models.legend().width();w>l/2&&(w=l/2),d.height(o).key(c.x()),d.width(w),l-=d.width(),r.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+l+",0)")}}else v.select(".nv-legendWrap").selectAll("*").remove();r.attr("transform","translate("+f.left+","+f.top+")"),c.width(l).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)m[c]=a[c];q.stateChange(m),b.update()}),q.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),m.disabled=a.disabled),b.update()})}),r.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!1,j=!0,k="top",l=a.utils.defaultColor(),m=a.utils.state(),n=null,o=null,p=250,q=d3.dispatch("stateChange","changeState","renderEnd");e.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var r=a.utils.renderWatch(q),s=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},t=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color,percent:a.percent},i||(delete a.percent,delete a.series.percent),e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(a){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(a){e()}),b.legend=d,b.dispatch=q,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},noData:{get:function(){return o},set:function(a){o=a}},showTooltipPercent:{get:function(){return i},set:function(a){i=a}},showLegend:{get:function(){return j},set:function(a){j=a}},legendPosition:{get:function(){return k},set:function(a){k=a}},defaultState:{get:function(){return n},set:function(a){n=a}},color:{get:function(){return l},set:function(a){l=a,d.color(l),c.color(l)}},duration:{get:function(){return p},set:function(a){p=a,r.reset(p),c.duration(p)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(a){var b,c;return b=i=i||{},c=a[0].series,b=b[c]=b[c]||{},c=a[1],b=b[c]=b[c]||{}}function c(a){var c,d,e=a[0],f=b(a),g=!1;for(c=1;c<arguments.length;c++)d=arguments[c],f[d]===e[d]&&f.hasOwnProperty(d)||(f[d]=e[d],g=!0);return g}function d(b){return U.reset(),b.each(function(b){function i(){if(T=!1,!z)return!1;if(P===!0){var c=d3.merge(b.map(function(b,c){return b.values.map(function(b,d){var e=s(b,d),f=t(b,d);return[a.utils.NaNtoZero(p(e))+1e-4*Math.random(),a.utils.NaNtoZero(q(f))+1e-4*Math.random(),c,d,b]}).filter(function(a,b){return A(a[4],b)})}));if(0==c.length)return!1;c.length<3&&(c.push([p.range()[0]-20,q.range()[0]-20,null,null]),c.push([p.range()[1]+20,q.range()[1]+20,null,null]),c.push([p.range()[0]-20,q.range()[0]+20,null,null]),c.push([p.range()[1]+20,q.range()[1]-20,null,null]));var d=d3.geom.polygon([[-10,-10],[-10,l+10],[k+10,l+10],[k+10,-10]]),e=d3.geom.voronoi(c).map(function(a,b){return{data:d.clip(a),series:c[b][2],point:c[b][3]}});_.select(".nv-point-paths").selectAll("path").remove();var f=_.select(".nv-point-paths").selectAll("path").data(e),g=f.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+n+"-"+b+")"});if(F&&g.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),E){_.select(".nv-point-clips").selectAll("*").remove();var h=_.select(".nv-point-clips").selectAll("clipPath").data(c);h.enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+n+"-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",G)}var i=function(a,c){if(T)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=m(d,a.series),e.x=s(e),e.y=t(e);var f=o.node().getBoundingClientRect(),g=window.pageYOffset||document.documentElement.scrollTop,h=window.pageXOffset||document.documentElement.scrollLeft,i={left:p(s(e,a.point))+f.left+h+j.left+10,top:q(t(e,a.point))+f.top+g+j.top+10};c({point:e,series:d,pos:i,relativePos:[p(s(e,a.point))+j.left,q(t(e,a.point))+j.top],seriesIndex:a.series,pointIndex:a.point})}};f.on("click",function(a){i(a,O.elementClick)}).on("dblclick",function(a){i(a,O.elementDblClick)}).on("mouseover",function(a){i(a,O.elementMouseover)}).on("mouseout",function(a,b){i(a,O.elementMouseout)})}else _.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(T||!b[a.series])return 0;var d=b[a.series],e=d.values[c],f=this;O.elementClick({point:e,series:d,pos:[p(s(e,c))+j.left,q(t(e,c))+j.top],relativePos:[p(s(e,c))+j.left,q(t(e,c))+j.top],seriesIndex:a.series,pointIndex:c,event:d3.event,element:f})}).on("dblclick",function(a,c){if(T||!b[a.series])return 0;var d=b[a.series],e=d.values[c];O.elementDblClick({point:e,series:d,pos:[p(s(e,c))+j.left,q(t(e,c))+j.top],relativePos:[p(s(e,c))+j.left,q(t(e,c))+j.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(T||!b[a.series])return 0;var d=b[a.series],e=d.values[c];O.elementMouseover({point:e,series:d,pos:[p(s(e,c))+j.left,q(t(e,c))+j.top],relativePos:[p(s(e,c))+j.left,q(t(e,c))+j.top],seriesIndex:a.series,pointIndex:c,color:m(a,c)})}).on("mouseout",function(a,c){if(T||!b[a.series])return 0;var d=b[a.series],e=d.values[c];O.elementMouseout({point:e,series:d,pos:[p(s(e,c))+j.left,q(t(e,c))+j.top],relativePos:[p(s(e,c))+j.left,q(t(e,c))+j.top],seriesIndex:a.series,pointIndex:c,color:m(a,c)})})}o=d3.select(this);var Q=a.utils.availableWidth(k,o,j),W=a.utils.availableHeight(l,o,j);a.utils.initSVG(o),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var X=d.yScale().name===d3.scale.log().name?!0:!1,Y=H&&I&&L?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:s(a,b),y:t(a,b),size:u(a,b)}})}));if(p.domain(H||d3.extent(Y.map(function(a){return a.x}).concat(w))),B&&b[0]?p.range(J||[(Q*C+Q)/(2*b[0].values.length),Q-Q*(1+C)/(2*b[0].values.length)]):p.range(J||[0,Q]),X){var Z=d3.min(Y.map(function(a){return 0!==a.y?a.y:void 0}));q.clamp(!0).domain(I||d3.extent(Y.map(function(a){return 0!==a.y?a.y:.1*Z}).concat(x))).range(K||[W,0])}else q.domain(I||d3.extent(Y.map(function(a){return a.y}).concat(x))).range(K||[W,0]);r.domain(L||d3.extent(Y.map(function(a){return a.size}).concat(y))).range(M||V),N=p.domain()[0]===p.domain()[1]||q.domain()[0]===q.domain()[1],p.domain()[0]===p.domain()[1]&&(p.domain()[0]?p.domain([p.domain()[0]-.01*p.domain()[0],p.domain()[1]+.01*p.domain()[1]]):p.domain([-1,1])),q.domain()[0]===q.domain()[1]&&(q.domain()[0]?q.domain([q.domain()[0]-.01*q.domain()[0],q.domain()[1]+.01*q.domain()[1]]):q.domain([-1,1])),isNaN(p.domain()[0])&&p.domain([-1,1]),isNaN(q.domain()[0])&&q.domain([-1,1]),e=e||p,f=f||q,g=g||r;var $=p(1)!==e(1)||q(1)!==f(1)||r(1)!==g(1),_=o.selectAll("g.nv-wrap.nv-scatter").data([b]),aa=_.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+n),ba=aa.append("defs"),ca=aa.append("g"),da=_.select("g");_.classed("nv-single-point",N),ca.append("g").attr("class","nv-groups"),ca.append("g").attr("class","nv-point-paths"),aa.append("g").attr("class","nv-point-clips"),_.attr("transform","translate("+j.left+","+j.top+")"),ba.append("clipPath").attr("id","nv-edge-clip-"+n).append("rect"),_.select("#nv-edge-clip-"+n+" rect").attr("width",Q).attr("height",W>0?W:0),da.attr("clip-path",D?"url(#nv-edge-clip-"+n+")":""),T=!0;var ea=_.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});ea.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),ea.exit().remove(),ea.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("nv-noninteractive",!z).classed("hover",function(a){return a.hover}),ea.watchTransition(U,"scatter: groups").style("fill",function(a,b){return m(a,b)}).style("stroke",function(a,b){return m(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var fa=ea.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return A(a[0],b)})});if(fa.enter().append("path").attr("class",function(a){return"nv-point nv-point-"+a[1]}).style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(b){return"translate("+a.utils.NaNtoZero(e(s(b[0],b[1])))+","+a.utils.NaNtoZero(f(t(b[0],b[1])))+")"}).attr("d",a.utils.symbol().type(function(a){return v(a[0])}).size(function(a){return r(u(a[0],a[1]))})),fa.exit().remove(),ea.exit().selectAll("path.nv-point").watchTransition(U,"scatter exit").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(p(s(b[0],b[1])))+","+a.utils.NaNtoZero(q(t(b[0],b[1])))+")"}).remove(),fa.filter(function(a){return $||c(a,"x","y")}).watchTransition(U,"scatter points").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(p(s(b[0],b[1])))+","+a.utils.NaNtoZero(q(t(b[0],b[1])))+")"}),fa.filter(function(a){return $||c(a,"shape","size")}).watchTransition(U,"scatter points").attr("d",a.utils.symbol().type(function(a){return v(a[0])}).size(function(a){return r(u(a[0],a[1]))})),S){var ga=ea.selectAll(".nv-label").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return A(a[0],b)})});ga.enter().append("text").style("fill",function(a,b){return a.color}).style("stroke-opacity",0).style("fill-opacity",1).attr("transform",function(b){var c=a.utils.NaNtoZero(e(s(b[0],b[1])))+Math.sqrt(r(u(b[0],b[1]))/Math.PI)+2;return"translate("+c+","+a.utils.NaNtoZero(f(t(b[0],b[1])))+")"}).text(function(a,b){return a[0].label}),ga.exit().remove(),ea.exit().selectAll("path.nv-label").watchTransition(U,"scatter exit").attr("transform",function(b){var c=a.utils.NaNtoZero(p(s(b[0],b[1])))+Math.sqrt(r(u(b[0],b[1]))/Math.PI)+2;return"translate("+c+","+a.utils.NaNtoZero(q(t(b[0],b[1])))+")"}).remove(),ga.each(function(a){d3.select(this).classed("nv-label",!0).classed("nv-label-"+a[1],!1).classed("hover",!1)}),ga.watchTransition(U,"scatter labels").attr("transform",function(b){var c=a.utils.NaNtoZero(p(s(b[0],b[1])))+Math.sqrt(r(u(b[0],b[1]))/Math.PI)+2;return"translate("+c+","+a.utils.NaNtoZero(q(t(b[0],b[1])))+")"})}R?(clearTimeout(h),h=setTimeout(i,R)):i(),e=p.copy(),f=q.copy(),g=r.copy()}),U.renderEnd("scatter immediate"),d}var e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=null,l=null,m=a.utils.defaultColor(),n=Math.floor(1e5*Math.random()),o=null,p=d3.scale.linear(),q=d3.scale.linear(),r=d3.scale.linear(),s=function(a){return a.x},t=function(a){return a.y},u=function(a){return a.size||1},v=function(a){return a.shape||"circle"},w=[],x=[],y=[],z=!0,A=function(a){return!a.notActive},B=!1,C=.1,D=!1,E=!0,F=!1,G=function(){return 25},H=null,I=null,J=null,K=null,L=null,M=null,N=!1,O=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),P=!0,Q=250,R=300,S=!1,T=!1,U=a.utils.renderWatch(O,Q),V=[16,256];return d.dispatch=O,d.options=a.utils.optionsFunc.bind(d),d._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){o.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){o.select(".nv-groups").selectAll(".nv-series-"+b).selectAll(".nv-point-"+c).classed("hover",d)})}},O.on("elementMouseover.point",function(a){z&&d._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),O.on("elementMouseout.point",function(a){z&&d._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),d._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},xScale:{get:function(){return p},set:function(a){p=a}},yScale:{get:function(){return q},set:function(a){q=a}},pointScale:{get:function(){return r},set:function(a){r=a}},xDomain:{get:function(){return H},set:function(a){H=a}},yDomain:{get:function(){return I},set:function(a){I=a}},pointDomain:{get:function(){return L},set:function(a){L=a}},xRange:{get:function(){return J},set:function(a){J=a}},yRange:{get:function(){return K},set:function(a){K=a}},pointRange:{get:function(){return M},set:function(a){M=a}},forceX:{get:function(){return w},set:function(a){w=a}},forceY:{get:function(){return x},set:function(a){x=a}},forcePoint:{get:function(){return y},set:function(a){y=a}},interactive:{get:function(){return z},set:function(a){z=a}},pointActive:{get:function(){return A},set:function(a){A=a}},padDataOuter:{get:function(){return C},set:function(a){C=a}},padData:{get:function(){return B},set:function(a){B=a}},clipEdge:{get:function(){return D},set:function(a){D=a}},clipVoronoi:{get:function(){return E},set:function(a){E=a}},clipRadius:{get:function(){return G},set:function(a){G=a}},showVoronoi:{get:function(){return F},set:function(a){F=a}},id:{get:function(){return n},set:function(a){n=a}},interactiveUpdateDelay:{get:function(){return R},set:function(a){R=a}},showLabels:{get:function(){return S},set:function(a){S=a}},x:{get:function(){return s},set:function(a){s=d3.functor(a)}},y:{get:function(){return t},set:function(a){t=d3.functor(a)}},pointSize:{get:function(){return u},set:function(a){u=d3.functor(a)}},pointShape:{get:function(){return v},set:function(a){v=d3.functor(a)}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return Q},set:function(a){Q=a,U.reset(Q)}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}},useVoronoi:{get:function(){return P},set:function(a){P=a,P===!1&&(E=!1)}}}),a.utils.initOptions(d),d},a.models.scatterChart=function(){"use strict";function b(z){return E.reset(),E.models(c),t&&E.models(d),u&&E.models(e),q&&E.models(g),r&&E.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var H=a.utils.availableWidth(k,m,j),I=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(G(z),b.update).getter(F(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var J;x={};for(J in w)w[J]instanceof Array?x[J]=w[J].slice(0):x[J]=w[J]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),E.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var K=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),L=K.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),M=L.append("g"),N=K.select("g");if(M.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),M.append("g").attr("class","nv-x nv-axis"),M.append("g").attr("class","nv-y nv-axis"),M.append("g").attr("class","nv-scatterWrap"),M.append("g").attr("class","nv-regressionLinesWrap"),M.append("g").attr("class","nv-distWrap"),M.append("g").attr("class","nv-legendWrap"),v&&N.select(".nv-y.nv-axis").attr("transform","translate("+H+",0)"),s){var O=H;f.width(O),K.select(".nv-legendWrap").datum(z).call(f),f.height()>j.top&&(j.top=f.height(),I=a.utils.availableHeight(l,m,j)),K.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}else N.select(".nv-legendWrap").selectAll("*").remove();K.attr("transform","translate("+j.left+","+j.top+")"),c.width(H).height(I).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})).showLabels(B),K.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),K.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var P=K.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});P.enter().append("g").attr("class","nv-regLines");var Q=P.selectAll(".nv-regLine").data(function(a){return[a]});Q.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),Q.filter(function(a){return a.intercept&&a.slope}).watchTransition(E,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a,b){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a,b){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a,b){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(H/100,z)).tickSize(-I,0),N.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(I/36,z)).tickSize(-H,0),N.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),M.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),N.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(I).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),M.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),N.select(".nv-distributionY").attr("transform","translate("+(v?H:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.relativePos[1]-I),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.relativePos[0]+g.size()),i.data(a).hidden(!1)}),C=o.copy(),D=p.copy()}),E.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250,B=!1;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var C,D,E=a.utils.renderWatch(y,A),F=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},G=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},showLabels:{get:function(){return B},set:function(a){B=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return t.reset(),k.each(function(b){var k=h-g.left-g.right,s=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[s,0]);var t=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");u.append("g"),t.select("g");t.attr("transform","translate("+g.left+","+g.top+")");var v=t.selectAll("path").data(function(a){return[a]});v.enter().append("path"),v.exit().remove(),v.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var w=t.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[q?e:null,q?d:null,r?f:null].filter(function(a){return null!=a})});w.enter().append("circle"),w.exit().remove(),w.attr("cx",function(a,b){return l(n(a,a.pointIndex))}).attr("cy",function(a,b){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a,b){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),t.renderEnd("sparkline immediate"),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]),q=!0,r=!0,s=d3.dispatch("renderEnd"),t=a.utils.renderWatch(s);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},showMinMaxPoints:{get:function(){return q},set:function(a){q=a}},showCurrentPoint:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),b.dispatch=s,a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return r.reset(),r.models(e),p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;f<a.length;f++)Math.abs(e.x()(a[f],f)-b)<c&&(c=Math.abs(e.x()(a[f],f)-b),d=f);return d}if(!j){var b=d3.mouse(this)[0]-f.left;i=[a(p,Math.round(c.invert(b)))],q()}}var s=d3.select(this);a.utils.initSVG(s);var t=a.utils.availableWidth(g,s,f),u=a.utils.availableHeight(h,s,f);if(b.update=function(){s.call(b)},b.container=this,!p||!p.length)return a.utils.noData(b,s),b;s.selectAll(".nv-noData").remove();var v=e.y()(p[p.length-1],p.length-1);c=e.xScale(),d=e.yScale();var w=s.selectAll("g.nv-wrap.nv-sparklineplus").data([p]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-sparklineplus"),y=x.append("g"),z=w.select("g");y.append("g").attr("class","nv-sparklineWrap"),y.append("g").attr("class","nv-valueWrap"),y.append("g").attr("class","nv-hoverArea"),w.attr("transform","translate("+f.left+","+f.top+")");var A=z.select(".nv-sparklineWrap");if(e.width(t).height(u),A.call(e),m){var B=z.select(".nv-valueWrap"),C=B.selectAll(".nv-currentValue").data([v]);C.enter().append("text").attr("class","nv-currentValue").attr("dx",o?-8:8).attr("dy",".9em").style("text-anchor",o?"end":"start"),C.attr("x",t+(o?f.right:0)).attr("y",n?function(a){return d(a)}:0).style("fill",e.color()(p[p.length-1],p.length-1)).text(l(v))}y.select(".nv-hoverArea").append("rect").on("mousemove",r).on("click",function(){j=!j}).on("mouseout",function(){i=[],q()}),z.select(".nv-hoverArea rect").attr("transform",function(a){return"translate("+-f.left+","+-f.top+")"}).attr("width",t+f.left+f.right).attr("height",u+f.top)}),r.renderEnd("sparklinePlus immediate"),b}var c,d,e=a.models.sparkline(),f={top:15,right:100,bottom:10,left:50},g=null,h=null,i=[],j=!1,k=d3.format(",r"),l=d3.format(",.2f"),m=!0,n=!0,o=!1,p=null,q=d3.dispatch("renderEnd"),r=a.utils.renderWatch(q);return b.dispatch=q,b.sparkline=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},xTickFormat:{get:function(){return k},set:function(a){k=a}},yTickFormat:{get:function(){return l},set:function(a){l=a}},showLastValue:{get:function(){return m},set:function(a){m=a}},alignValue:{get:function(){return n},set:function(a){n=a}},rightAlignValue:{get:function(){return o},set:function(a){o=a}},noData:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.stackedArea=function(){"use strict";function b(n){return v.reset(),v.models(s),n.each(function(n){var t=f-e.left-e.right,w=g-e.top-e.bottom;j=d3.select(this),a.utils.initSVG(j),c=s.xScale(),d=s.yScale();var x=n;n.forEach(function(a,b){a.seriesIndex=b,a.values=a.values.map(function(a,c){return a.index=c,a.seriesIndex=b,a})});var y=n.filter(function(a){return!a.disabled});n=d3.layout.stack().order(p).offset(o).values(function(a){return a.values}).x(k).y(l).out(function(a,b,c){a.display={y:c,y0:b}})(y);var z=j.selectAll("g.nv-wrap.nv-stackedarea").data([n]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedarea"),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-areaWrap"),C.append("g").attr("class","nv-scatterWrap"),z.attr("transform","translate("+e.left+","+e.top+")"),0==s.forceY().length&&s.forceY().push(0),s.width(t).height(w).x(k).y(function(a){return void 0!==a.display?a.display.y+a.display.y0:void 0}).color(n.map(function(a,b){return a.color=a.color||h(a,a.seriesIndex),a.color}));var E=D.select(".nv-scatterWrap").datum(n);E.call(s),B.append("clipPath").attr("id","nv-edge-clip-"+i).append("rect"),z.select("#nv-edge-clip-"+i+" rect").attr("width",t).attr("height",w),D.attr("clip-path",r?"url(#nv-edge-clip-"+i+")":"");var F=d3.svg.area().defined(m).x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y+a.display.y0)}).interpolate(q),G=d3.svg.area().defined(m).x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y0)}),H=D.select(".nv-areaWrap").selectAll("path.nv-area").data(function(a){return a});H.enter().append("path").attr("class",function(a,b){return"nv-area nv-area-"+b}).attr("d",function(a,b){return G(a.values,a.seriesIndex)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),u.areaMouseover({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),u.areaMouseout({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("click",function(a,b){d3.select(this).classed("hover",!1),u.areaClick({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}),H.exit().remove(),H.style("fill",function(a,b){return a.color||h(a,a.seriesIndex)}).style("stroke",function(a,b){return a.color||h(a,a.seriesIndex)}),H.watchTransition(v,"stackedArea path").attr("d",function(a,b){return F(a.values,b)}),s.dispatch.on("elementMouseover.area",function(a){D.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!0)}),s.dispatch.on("elementMouseout.area",function(a){D.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!1)}),b.d3_stackedOffset_stackPercent=function(a){var b,c,d,e=a.length,f=a[0].length,g=[];for(c=0;f>c;++c){for(b=0,d=0;b<x.length;b++)d+=l(x[b].values[c]);if(d)for(b=0;e>b;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),v.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m=function(a,b){return!isNaN(l(a,b))&&null!==l(a,b)},n="stack",o="zero",p="default",q="linear",r=!1,s=a.models.scatter(),t=250,u=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");s.pointSize(2.2).pointDomain([2.2,2.2]);var v=a.utils.renderWatch(u,t);return b.dispatch=u,b.scatter=s,s.dispatch.on("elementClick",function(){u.elementClick.apply(this,arguments)}),s.dispatch.on("elementMouseover",function(){u.elementMouseover.apply(this,arguments)}),s.dispatch.on("elementMouseout",function(){u.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(q=a,b):q},b.duration=function(a){return arguments.length?(t=a,v.reset(t),s.duration(t),b):t},b.dispatch=u,b.scatter=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},defined:{get:function(){return m},set:function(a){m=a}},clipEdge:{get:function(){return r},set:function(a){r=a}},offset:{get:function(){return o},set:function(a){o=a}},order:{get:function(){return p},set:function(a){p=a}},interpolate:{get:function(){return q},set:function(a){q=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return n},set:function(a){switch(n=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t),s.duration(t)}}}),a.utils.inheritOptions(b,s),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return J.reset(),J.models(e),s&&J.models(f),t&&J.models(g),k.each(function(k){function B(){s&&V.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+R+")").transition().duration(G).call(f)}function J(){if(t){if("expand"===e.style()||"stack_percent"===e.style()){var a=g.tickFormat();H&&a===N||(H=a),g.tickFormat(N)}else H&&(g.tickFormat(H),H=null);V.select(".nv-focus .nv-y.nv-axis").transition().duration(0).call(g)}}function O(a){var b=V.select(".nv-focus .nv-stackedWrap").datum(k.filter(function(a){return!a.disabled}).map(function(b,c){return{key:b.key,area:b.area,classed:b.classed,values:b.values.filter(function(b,c){return e.x()(b,c)>=a[0]&&e.x()(b,c)<=a[1]}),disableTooltip:b.disableTooltip}}));b.transition().duration(G).call(e),B(),J()}var P=d3.select(this);a.utils.initSVG(P);var Q=a.utils.availableWidth(n,P,m),R=a.utils.availableHeight(o,P,m)-(v?l.height():0);if(b.update=function(){P.transition().duration(G).call(b)},b.container=this,z.setter(M(k),b.update).getter(L(k)).update(),z.disabled=k.map(function(a){return!!a.disabled}),!A){var S;A={};for(S in z)z[S]instanceof Array?A[S]=z[S].slice(0):A[S]=z[S]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,P),b;P.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var T=P.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),U=T.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),V=T.select("g");U.append("g").attr("class","nv-legendWrap"),U.append("g").attr("class","nv-controlsWrap");var W=U.append("g").attr("class","nv-focus");W.append("g").attr("class","nv-background").append("rect"),W.append("g").attr("class","nv-x nv-axis"),W.append("g").attr("class","nv-y nv-axis"),W.append("g").attr("class","nv-stackedWrap"),W.append("g").attr("class","nv-interactive");U.append("g").attr("class","nv-focusWrap");if(r){var X=q?Q-D:Q;h.width(X),V.select(".nv-legendWrap").datum(k).call(h),h.height()>m.top&&(m.top=h.height(),R=a.utils.availableHeight(o,P,m)-(v?l.height():0)),V.select(".nv-legendWrap").attr("transform","translate("+(Q-X)+","+-m.top+")")}else V.select(".nv-legendWrap").selectAll("*").remove();if(q){var Y=[{key:F.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:F.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:F.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:F.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];D=E.length/3*260,Y=Y.filter(function(a){return-1!==E.indexOf(a.metaKey)}),i.width(D).color(["#444","#444","#444"]),V.select(".nv-controlsWrap").datum(Y).call(i),Math.max(i.height(),h.height())>m.top&&(m.top=Math.max(i.height(),h.height()),R=a.utils.availableHeight(o,P,m)),V.select(".nv-controlsWrap").attr("transform","translate(0,"+-m.top+")")}else V.select(".nv-controlsWrap").selectAll("*").remove();T.attr("transform","translate("+m.left+","+m.top+")"),u&&V.select(".nv-y.nv-axis").attr("transform","translate("+Q+",0)"),w&&(j.width(Q).height(R).margin({left:m.left,top:m.top}).svgContainer(P).xScale(c),T.select(".nv-interactive").call(j)),V.select(".nv-focus .nv-background rect").attr("width",Q).attr("height",R),e.width(Q).height(R).color(k.map(function(a,b){return a.color||p(a,b)}).filter(function(a,b){return!k[b].disabled}));var Z=V.select(".nv-focus .nv-stackedWrap").datum(k.filter(function(a){return!a.disabled}));if(s&&f.scale(c)._ticks(a.utils.calcTicksX(Q/100,k)).tickSize(-R,0),t){var $;$="wiggle"===e.offset()?0:a.utils.calcTicksY(R/36,k),g.scale(d)._ticks($).tickSize(-Q,0)}if(v){l.width(Q),V.select(".nv-focusWrap").attr("transform","translate(0,"+(R+m.bottom+l.margin().top)+")").datum(k.filter(function(a){return!a.disabled})).call(l);var _=l.brush.empty()?l.xDomain():l.brush.extent();null!==_&&O(_)}else Z.transition().call(e),B(),J();e.dispatch.on("areaClick.toggle",function(a){1===k.filter(function(a){return!a.disabled}).length?k.forEach(function(a){a.disabled=!1}):k.forEach(function(b,c){b.disabled=c!=a.seriesIndex}),z.disabled=k.map(function(a){return!!a.disabled}),C.stateChange(z),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)z[c]=a[c];C.stateChange(z),b.update()}),i.dispatch.on("legendClick",function(a,c){a.disabled&&(Y=Y.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),z.style=e.style(),C.stateChange(z),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,f,g,h=[],i=0,l=!0;if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(j,k){f=a.interactiveBisect(j.values,c.pointXValue,b.x());var m=j.values[f],n=b.y()(m,f);if(null!=n&&e.highlightPoint(k,f,!0),"undefined"!=typeof m){"undefined"==typeof d&&(d=m),"undefined"==typeof g&&(g=b.xScale()(b.x()(m,f)));var o="expand"==e.style()?m.display.y:b.y()(m,f);h.push({key:j.key,value:o,color:p(j,j.seriesIndex),point:m}),x&&"expand"!=e.style()&&null!=o&&(i+=o,l=!1)}}),h.reverse(),h.length>2){var m=b.yScale().invert(c.mouseY),n=null;h.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.point.display.y0),d=Math.abs(a.point.display.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(h[n].highlight=!0)}x&&"expand"!=e.style()&&h.length>=2&&!l&&h.push({key:y,value:i,total:!0});var o=b.x()(d,f),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(I||(I=q),q=d3.format(".1%")):I&&(q=I,I=null),j.tooltip.valueFormatter(q).data({value:o,series:h})(),j.renderGuideLine(g)}),j.dispatch.on("elementMouseout",function(a){e.clearHighlights()}),l.dispatch.on("onBrush",function(a){O(a)}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),z.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),K=a.style),b.update()})}),J.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l=a.models.focus(a.models.stackedArea()),m={top:30,right:25,bottom:50,left:60},n=null,o=null,p=a.utils.defaultColor(),q=!0,r=!0,s=!0,t=!0,u=!1,v=!1,w=!1,x=!0,y="TOTAL",z=a.utils.state(),A=null,B=null,C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=["Stacked","Stream","Expanded"],F={},G=250;z.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(u?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return null==a?"N/A":g.tickFormat()(a,b)});var H=null,I=null;i.updateState(!1);var J=a.utils.renderWatch(C),K=e.style(),L=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},M=function(a){return function(b){void 0!==b.style&&(K=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},N=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){k.hidden(!0)}),b.dispatch=C,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.x2Axis=l.xAxis,b.yAxis=g,b.y2Axis=l.yAxis,b.interactiveLayer=j,b.tooltip=k,b.focus=l,b.dispatch=C,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return r},set:function(a){r=a}},showXAxis:{get:function(){return s},set:function(a){s=a}},showYAxis:{get:function(){return t},set:function(a){t=a}},defaultState:{get:function(){return A},set:function(a){A=a}},noData:{get:function(){return B},set:function(a){B=a}},showControls:{get:function(){return q},set:function(a){q=a}},controlLabels:{get:function(){return F},set:function(a){F=a}},controlOptions:{get:function(){return E},set:function(a){E=a}},showTotalInTooltip:{get:function(){return x},set:function(a){x=a}},totalLabel:{get:function(){return y},set:function(a){y=a}},focusEnable:{get:function(){return v},set:function(a){v=a}},focusHeight:{get:function(){return l.height()},set:function(a){l.height(a)}},brushExtent:{get:function(){return l.brushExtent()},set:function(a){l.brushExtent(a)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},focusMargin:{get:function(){return l.margin},set:function(a){l.margin.top=void 0!==a.top?a.top:l.margin.top,l.margin.right=void 0!==a.right?a.right:l.margin.right,l.margin.bottom=void 0!==a.bottom?a.bottom:l.margin.bottom,l.margin.left=void 0!==a.left?a.left:l.margin.left}},duration:{get:function(){return G},set:function(a){G=a,J.reset(G),e.duration(G),f.duration(G),g.duration(G)}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b),h.color(p),e.color(p),l.color(p)}},x:{get:function(){return e.x()},set:function(a){e.x(a),l.x(a)}},y:{get:function(){return e.y()},set:function(a){e.y(a),l.y(a)}},rightAlignYAxis:{get:function(){return u},set:function(a){u=a,g.orient(u?"right":"left")}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.stackedAreaWithFocusChart=function(){return a.models.stackedAreaChart().margin({bottom:30}).focusEnable(!0)},a.models.sunburst=function(){"use strict";function b(a){var b=c(a);return b>90?180:0}function c(a){var b=Math.max(0,Math.min(2*Math.PI,F(a.x))),c=Math.max(0,Math.min(2*Math.PI,F(a.x+a.dx))),d=(b+c)/2*(180/Math.PI)-90;return d}function d(a){var b=Math.max(0,Math.min(2*Math.PI,F(a.x))),c=Math.max(0,Math.min(2*Math.PI,F(a.x+a.dx)));return(c-b)/(2*Math.PI)}function e(a){var b=Math.max(0,Math.min(2*Math.PI,F(a.x))),c=Math.max(0,Math.min(2*Math.PI,F(a.x+a.dx))),d=c-b;return d>z}function f(a,b){var c=d3.interpolate(F.domain(),[l.x,l.x+l.dx]),d=d3.interpolate(G.domain(),[l.y,1]),e=d3.interpolate(G.range(),[l.y?20:0,o]);return 0===b?function(){return J(a)}:function(b){return F.domain(c(b)),G.domain(d(b)).range(e(b)),J(a)}}function g(a){var b=d3.interpolate({x:a.x0,dx:a.dx0,y:a.y0,dy:a.dy0},a);return function(c){var d=b(c);return a.x0=d.x,a.dx0=d.dx,a.y0=d.y,a.dy0=d.dy,J(d)}}function h(a){var b=B(a);I[b]||(I[b]={});var c=I[b];c.dx=a.dx,c.x=a.x,c.dy=a.dy,c.y=a.y}function i(a){a.forEach(function(a){var b=B(a),c=I[b];c?(a.dx0=c.dx,a.x0=c.x,a.dy0=c.dy,a.y0=c.y):(a.dx0=a.dx,a.x0=a.x,a.dy0=a.dy,a.y0=a.y),h(a)})}function j(a){var d=v.selectAll("text"),g=v.selectAll("path");d.transition().attr("opacity",0),l=a,g.transition().duration(D).attrTween("d",f).each("end",function(d){if(d.x>=a.x&&d.x<a.x+a.dx&&d.depth>=a.depth){var f=d3.select(this.parentNode),g=f.select("text");g.transition().duration(D).text(function(a){return y(a)}).attr("opacity",function(a){return e(a)?1:0}).attr("transform",function(){var e=this.getBBox().width;if(0===d.depth)return"translate("+e/2*-1+",0)";if(d.depth===a.depth)return"translate("+(G(d.y)+5)+",0)";var f=c(d),g=b(d);return 0===g?"rotate("+f+")translate("+(G(d.y)+5)+",0)":"rotate("+f+")translate("+(G(d.y)+e+5)+",0)rotate("+g+")"})}})}function k(f){return K.reset(),f.each(function(f){v=d3.select(this),m=a.utils.availableWidth(q,v,p),n=a.utils.availableHeight(r,v,p),o=Math.min(m,n)/2,G.range([0,o]);var h=v.select("g.nvd3.nv-wrap.nv-sunburst");h[0][0]?h.attr("transform","translate("+(m/2+p.left+p.right)+","+(n/2+p.top+p.bottom)+")"):h=v.append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+u).attr("transform","translate("+(m/2+p.left+p.right)+","+(n/2+p.top+p.bottom)+")"),v.on("click",function(a,b){E.chartClick({data:a,index:b,pos:d3.event,id:u})}),H.value(t[s]||t.count);var k=H.nodes(f[0]).reverse();i(k);var l=h.selectAll(".arc-container").data(k,B),z=l.enter().append("g").attr("class","arc-container");z.append("path").attr("d",J).style("fill",function(a){return a.color?a.color:w(C?(a.children?a:a.parent).name:a.name)}).style("stroke","#FFF").on("click",j).on("mouseover",function(a,b){d3.select(this).classed("hover",!0).style("opacity",.8),E.elementMouseover({data:a,color:d3.select(this).style("fill"),percent:d(a)})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1).style("opacity",1),E.elementMouseout({data:a})}).on("mousemove",function(a,b){E.elementMousemove({data:a})}),l.each(function(a){d3.select(this).select("path").transition().duration(D).attrTween("d",g)}),x&&(l.selectAll("text").remove(),l.append("text").text(function(a){return y(a)}).transition().duration(D).attr("opacity",function(a){return e(a)?1:0}).attr("transform",function(a){var d=this.getBBox().width;if(0===a.depth)return"rotate(0)translate("+d/2*-1+",0)";var e=c(a),f=b(a);return 0===f?"rotate("+e+")translate("+(G(a.y)+5)+",0)":"rotate("+e+")translate("+(G(a.y)+d+5)+",0)rotate("+f+")"})),j(k[k.length-1]),l.exit().transition().duration(D).attr("opacity",0).each("end",function(a){var b=B(a);I[b]=void 0}).remove()}),K.renderEnd("sunburst immediate"),k}var l,m,n,o,p={top:0,right:0,bottom:0,left:0},q=600,r=600,s="count",t={count:function(a){return 1},value:function(a){return a.value||a.size},size:function(a){return a.value||a.size}},u=Math.floor(1e4*Math.random()),v=null,w=a.utils.defaultColor(),x=!1,y=function(a){return"count"===s?a.name+" #"+a.value:a.name+" "+(a.value||a.size)},z=.02,A=function(a,b){return a.name>b.name},B=function(a,b){return a.name},C=!0,D=500,E=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),F=d3.scale.linear().range([0,2*Math.PI]),G=d3.scale.sqrt(),H=d3.layout.partition().sort(A),I={},J=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,F(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,F(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,G(a.y))}).outerRadius(function(a){return Math.max(0,G(a.y+a.dy))}),K=a.utils.renderWatch(E);return k.dispatch=E,k.options=a.utils.optionsFunc.bind(k),k._options=Object.create({},{width:{get:function(){return q},set:function(a){q=a}},height:{get:function(){return r},set:function(a){r=a}},mode:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return u},set:function(a){u=a}},duration:{get:function(){return D},set:function(a){D=a}},groupColorByParent:{get:function(){return C},set:function(a){C=!!a}},showLabels:{get:function(){return x},set:function(a){x=!!a}},labelFormat:{get:function(){return y},set:function(a){y=a}},labelThreshold:{get:function(){return z},set:function(a){z=a}},sort:{get:function(){return A},set:function(a){A=a}},key:{get:function(){return B},set:function(a){B=a}},margin:{get:function(){return p},set:function(a){p.top=void 0!=a.top?a.top:p.top,p.right=void 0!=a.right?a.right:p.right,p.bottom=void 0!=a.bottom?a.bottom:p.bottom,p.left=void 0!=a.left?a.left:p.left}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}}}),a.utils.initOptions(k),k},a.models.sunburstChart=function(){"use strict";function b(d){return n.reset(),n.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);return b.update=function(){0===l?h.call(b):h.transition().duration(l).call(b)},b.container=h,d&&d.length?(h.selectAll(".nv-noData").remove(),c.width(i).height(j).margin(e),void h.call(c)):(a.utils.noData(b,h),b)}),n.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=!1,j=(Math.round(1e5*Math.random()),null),k=null,l=250,m=d3.dispatch("stateChange","changeState","renderEnd"),n=a.utils.renderWatch(m);return d.duration(0).headerEnabled(!1).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.value||a.data.size,color:a.color,percent:a.percent},i||(delete a.percent,delete a.series.percent),d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(a){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(a){d()}),b.dispatch=m,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return k},set:function(a){k=a}},defaultState:{get:function(){return j},set:function(a){j=a}},showTooltipPercent:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return l},set:function(a){l=a,n.reset(l),c.duration(l)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left,c.margin(e)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.4-dev"}(); \ No newline at end of file
diff --git a/eigen/bench/perf_monitoring/runall.sh b/eigen/bench/perf_monitoring/runall.sh
deleted file mode 100644
index de10854..0000000
--- a/eigen/bench/perf_monitoring/runall.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/bash
-
-# ./runall.sh "Title"
-
-# Examples of environment variables to be set:
-# PREFIX="haswell-fma-"
-# CXX_FLAGS="-mfma"
-# CXX=clang++
-
-# Options:
-# -up : enforce the recomputation of existing data, and keep best results as a merging strategy
-# -s : recompute selected changesets only and keep bests
-
-./run.sh gemm gemm_settings.txt $*
-./run.sh lazy_gemm lazy_gemm_settings.txt $*
-./run.sh gemv gemv_settings.txt $*
-./run.sh gemvt gemv_settings.txt $*
-./run.sh trmv_up gemv_square_settings.txt $*
-./run.sh trmv_lo gemv_square_settings.txt $*
-./run.sh trmv_upt gemv_square_settings.txt $*
-./run.sh trmv_lot gemv_square_settings.txt $*
-./run.sh llt gemm_square_settings.txt $*
-
-
-# generate html file
-
-function print_td {
- echo '<td><a href="'$PREFIX'-'$1"$2"'.html"><img src="'$PREFIX'-'$1"$2"'.png" title="'$3'"></a></td>' >> $htmlfile
-}
-
-function print_tr {
- echo '<tr><th colspan="3">'"$2"'</th></tr>' >> $htmlfile
- echo '<tr>' >> $htmlfile
- print_td s $1 float
- print_td d $1 double
- print_td c $1 complex
- echo '</tr>' >> $htmlfile
-}
-
-if [ -n "$PREFIX" ]; then
-
-
-cp resources/s1.js $PREFIX/
-cp resources/s2.js $PREFIX/
-
-htmlfile="$PREFIX/index.html"
-cat resources/header.html > $htmlfile
-
-echo '<h1>'$1'</h1>' >> $htmlfile
-echo '<table>' >> $htmlfile
-print_tr gemm 'C += A &middot; B &nbsp; (gemm)'
-print_tr lazy_gemm 'C += A &middot; B &nbsp; (gemm lazy)'
-print_tr gemv 'y += A &middot; x &nbsp; (gemv)'
-print_tr gemvt 'y += A<sup>T</sup> &middot; x &nbsp; (gemv)'
-print_tr trmv_up 'y += U &middot; x &nbsp; (trmv)'
-print_tr trmv_upt 'y += U<sup>T</sup> &middot; x &nbsp; (trmv)'
-print_tr trmv_lo 'y += L &middot; x &nbsp; (trmv)'
-print_tr trmv_lot 'y += L<sup>T</sup> &middot; x &nbsp; (trmv)'
-print_tr trmv_lot 'L &middot; L<sup>T<sup> = A &nbsp; (Cholesky,potrf)'
-
-cat resources/footer.html >> $htmlfile
-
-fi
diff --git a/eigen/bench/perf_monitoring/trmv_lo.cpp b/eigen/bench/perf_monitoring/trmv_lo.cpp
deleted file mode 100644
index 3fabb6e..0000000
--- a/eigen/bench/perf_monitoring/trmv_lo.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "gemv_common.h"
-
-EIGEN_DONT_INLINE
-void trmv(const Mat &A, const Vec &B, Vec &C)
-{
- C.noalias() += A.triangularView<Lower>() * B;
-}
-
-int main(int argc, char **argv)
-{
- return main_gemv(argc, argv, trmv);
-}
diff --git a/eigen/bench/perf_monitoring/trmv_lot.cpp b/eigen/bench/perf_monitoring/trmv_lot.cpp
deleted file mode 100644
index 32e085a..0000000
--- a/eigen/bench/perf_monitoring/trmv_lot.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "gemv_common.h"
-
-EIGEN_DONT_INLINE
-void trmv(const Mat &A, Vec &B, const Vec &C)
-{
- B.noalias() += A.transpose().triangularView<Lower>() * C;
-}
-
-int main(int argc, char **argv)
-{
- return main_gemv(argc, argv, trmv);
-}
diff --git a/eigen/bench/perf_monitoring/trmv_up.cpp b/eigen/bench/perf_monitoring/trmv_up.cpp
deleted file mode 100644
index c58e471..0000000
--- a/eigen/bench/perf_monitoring/trmv_up.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "gemv_common.h"
-
-EIGEN_DONT_INLINE
-void trmv(const Mat &A, const Vec &B, Vec &C)
-{
- C.noalias() += A.triangularView<Upper>() * B;
-}
-
-int main(int argc, char **argv)
-{
- return main_gemv(argc, argv, trmv);
-}
diff --git a/eigen/bench/perf_monitoring/trmv_upt.cpp b/eigen/bench/perf_monitoring/trmv_upt.cpp
deleted file mode 100644
index 511e008..0000000
--- a/eigen/bench/perf_monitoring/trmv_upt.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "gemv_common.h"
-
-EIGEN_DONT_INLINE
-void trmv(const Mat &A, Vec &B, const Vec &C)
-{
- B.noalias() += A.transpose().triangularView<Upper>() * C;
-}
-
-int main(int argc, char **argv)
-{
- return main_gemv(argc, argv, trmv);
-}
diff --git a/eigen/bench/spbench/CMakeLists.txt b/eigen/bench/spbench/CMakeLists.txt
index 8d53f4a..9327356 100644
--- a/eigen/bench/spbench/CMakeLists.txt
+++ b/eigen/bench/spbench/CMakeLists.txt
@@ -38,25 +38,32 @@ if(SUPERLU_FOUND AND BLAS_FOUND)
endif()
-find_package(Pastix)
-find_package(Scotch)
-find_package(Metis)
-if(PASTIX_FOUND AND BLAS_FOUND)
+find_package(PASTIX QUIET COMPONENTS METIS SCOTCH)
+# check that the PASTIX found is a version without MPI
+find_path(PASTIX_pastix_nompi.h_INCLUDE_DIRS
+ NAMES pastix_nompi.h
+ HINTS ${PASTIX_INCLUDE_DIRS}
+)
+if (NOT PASTIX_pastix_nompi.h_INCLUDE_DIRS)
+ message(STATUS "A version of Pastix has been found but pastix_nompi.h does not exist in the include directory."
+ " Because Eigen tests require a version without MPI, we disable the Pastix backend.")
+endif()
+if(PASTIX_FOUND AND PASTIX_pastix_nompi.h_INCLUDE_DIRS AND BLAS_FOUND)
add_definitions("-DEIGEN_PASTIX_SUPPORT")
- include_directories(${PASTIX_INCLUDES})
+ include_directories(${PASTIX_INCLUDE_DIRS_DEP})
if(SCOTCH_FOUND)
- include_directories(${SCOTCH_INCLUDES})
+ include_directories(${SCOTCH_INCLUDE_DIRS})
set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${SCOTCH_LIBRARIES})
elseif(METIS_FOUND)
- include_directories(${METIS_INCLUDES})
+ include_directories(${METIS_INCLUDE_DIRS})
set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${METIS_LIBRARIES})
endif(SCOTCH_FOUND)
- set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES} ${ORDERING_LIBRARIES} ${BLAS_LIBRARIES})
- set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES} ${BLAS_LIBRARIES})
+ set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES_DEP} ${ORDERING_LIBRARIES})
+ set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES_DEP})
endif(PASTIX_FOUND AND BLAS_FOUND)
if(METIS_FOUND)
- include_directories(${METIS_INCLUDES})
+ include_directories(${METIS_INCLUDE_DIRS})
set (SPARSE_LIBS ${SPARSE_LIBS} ${METIS_LIBRARIES})
add_definitions("-DEIGEN_METIS_SUPPORT")
endif(METIS_FOUND)
diff --git a/eigen/bench/tensors/tensor_benchmarks_sycl.cc b/eigen/bench/tensors/tensor_benchmarks_sycl.cc
index 6df1908..7eca4d9 100644
--- a/eigen/bench/tensors/tensor_benchmarks_sycl.cc
+++ b/eigen/bench/tensors/tensor_benchmarks_sycl.cc
@@ -5,12 +5,29 @@
#include "tensor_benchmarks.h"
+using Eigen::array;
+using Eigen::SyclDevice;
+using Eigen::Tensor;
+using Eigen::TensorMap;
+// Simple functions
+template <typename device_selector>
+cl::sycl::queue sycl_queue() {
+ return cl::sycl::queue(device_selector(), [=](cl::sycl::exception_list l) {
+ for (const auto& e : l) {
+ try {
+ std::rethrow_exception(e);
+ } catch (cl::sycl::exception e) {
+ std::cout << e.what() << std::endl;
+ }
+ }
+ });
+}
+
#define BM_FuncGPU(FUNC) \
static void BM_##FUNC(int iters, int N) { \
StopBenchmarkTiming(); \
- cl::sycl::gpu_selector selector; \
- Eigen::QueueInterface queue(selector); \
- Eigen::SyclDevice device(&queue); \
+ cl::sycl::queue q = sycl_queue<cl::sycl::gpu_selector>(); \
+ Eigen::SyclDevice device(q); \
BenchmarkSuite<Eigen::SyclDevice, float> suite(device, N); \
suite.FUNC(iters); \
} \
diff --git a/eigen/blas/CMakeLists.txt b/eigen/blas/CMakeLists.txt
index 9887d58..d0efb41 100644
--- a/eigen/blas/CMakeLists.txt
+++ b/eigen/blas/CMakeLists.txt
@@ -45,12 +45,10 @@ install(TARGETS eigen_blas eigen_blas_static
if(EIGEN_Fortran_COMPILER_WORKS)
-if(BUILD_TESTING)
- if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
- add_subdirectory(testing) # can't do EXCLUDE_FROM_ALL here, breaks CTest
- else()
- add_subdirectory(testing EXCLUDE_FROM_ALL)
- endif()
+if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
+ add_subdirectory(testing) # can't do EXCLUDE_FROM_ALL here, breaks CTest
+else()
+ add_subdirectory(testing EXCLUDE_FROM_ALL)
endif()
endif()
diff --git a/eigen/cmake/FindBLAS.cmake b/eigen/cmake/FindBLAS.cmake
index 68c4e07..9f74b07 100644
--- a/eigen/cmake/FindBLAS.cmake
+++ b/eigen/cmake/FindBLAS.cmake
@@ -1,385 +1,1363 @@
-# Find BLAS library
+###
#
-# This module finds an installed library that implements the BLAS
+# @copyright (c) 2009-2014 The University of Tennessee and The University
+# of Tennessee Research Foundation.
+# All rights reserved.
+# @copyright (c) 2012-2016 Inria. All rights reserved.
+# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
+#
+###
+#
+# - Find BLAS library
+# This module finds an installed fortran library that implements the BLAS
# linear-algebra interface (see http://www.netlib.org/blas/).
-# The list of libraries searched for is mainly taken
+# The list of libraries searched for is taken
# from the autoconf macro file, acx_blas.m4 (distributed at
# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
#
# This module sets the following variables:
# BLAS_FOUND - set to true if a library implementing the BLAS interface
# is found
-# BLAS_INCLUDE_DIR - Directories containing the BLAS header files
-# BLAS_DEFINITIONS - Compilation options to use BLAS
-# BLAS_LINKER_FLAGS - Linker flags to use BLAS (excluding -l
+# BLAS_LINKER_FLAGS - uncached list of required linker flags (excluding -l
# and -L).
-# BLAS_LIBRARIES_DIR - Directories containing the BLAS libraries.
-# May be null if BLAS_LIBRARIES contains libraries name using full path.
-# BLAS_LIBRARIES - List of libraries to link against BLAS interface.
-# May be null if the compiler supports auto-link (e.g. VC++).
-# BLAS_USE_FILE - The name of the cmake module to include to compile
-# applications or libraries using BLAS.
+# BLAS_COMPILER_FLAGS - uncached list of required compiler flags (including -I for mkl headers).
+# BLAS_LIBRARIES - uncached list of libraries (using full path name) to
+# link against to use BLAS
+# BLAS95_LIBRARIES - uncached list of libraries (using full path name)
+# to link against to use BLAS95 interface
+# BLAS95_FOUND - set to true if a library implementing the BLAS f95 interface
+# is found
+# BLA_STATIC if set on this determines what kind of linkage we do (static)
+# BLA_VENDOR if set checks only the specified vendor, if not set checks
+# all the possibilities
+# BLAS_VENDOR_FOUND stores the BLAS vendor found
+# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK
+# The user can give specific paths where to find the libraries adding cmake
+# options at configure (ex: cmake path/to/project -DBLAS_DIR=path/to/blas):
+# BLAS_DIR - Where to find the base directory of blas
+# BLAS_INCDIR - Where to find the header files
+# BLAS_LIBDIR - Where to find the library files
+# The module can also look for the following environment variables if paths
+# are not given as cmake variable: BLAS_DIR, BLAS_INCDIR, BLAS_LIBDIR
+# For MKL case and if no paths are given as hints, we will try to use the MKLROOT
+# environment variable
+# BLAS_VERBOSE Print some additional information during BLAS libraries detection
+##########
+### List of vendors (BLA_VENDOR) valid in this module
+########## List of vendors (BLA_VENDOR) valid in this module
+## Open (for OpenBlas), Eigen (for EigenBlas), Goto, ATLAS PhiPACK,
+##  CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT
+## Intel10_32 (intel mkl v10 32 bit), Intel10_64lp (intel mkl v10 64 bit,lp thread model, lp64 model),
+## Intel10_64lp_seq (intel mkl v10 64 bit,sequential code, lp64 model),
+## Intel( older versions of mkl 32 and 64 bit),
+##  ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic
+# C/CXX should be enabled to use Intel mkl
+###
+# We handle different modes to find the dependency
+#
+# - Detection if already installed on the system
+# - BLAS libraries can be detected from different ways
+# Here is the order of precedence:
+# 1) we look in cmake variable BLAS_LIBDIR or BLAS_DIR (we guess the libdirs) if defined
+# 2) we look in environment variable BLAS_LIBDIR or BLAS_DIR (we guess the libdirs) if defined
+# 3) we look in common environnment variables depending on the system (INCLUDE, C_INCLUDE_PATH, CPATH - LIB, DYLD_LIBRARY_PATH, LD_LIBRARY_PATH)
+# 4) we look in common system paths depending on the system, see for example paths contained in the following cmake variables:
+# - CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES, CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
+# - CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES, CMAKE_C_IMPLICIT_LINK_DIRECTORIES
+#
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
#
-# This module was modified by CGAL team:
-# - find libraries for a C++ compiler, instead of Fortran
-# - added BLAS_INCLUDE_DIR, BLAS_DEFINITIONS and BLAS_LIBRARIES_DIR
-# - removed BLAS95_LIBRARIES
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+## Some macros to print status when search for headers and libs
+# This macro informs why the _lib_to_find file has not been found
+macro(Print_Find_Library_Blas_Status _libname _lib_to_find)
+
+ # save _libname upper/lower case
+ string(TOUPPER ${_libname} LIBNAME)
+ string(TOLOWER ${_libname} libname)
+
+ # print status
+ #message(" ")
+ if(${LIBNAME}_LIBDIR)
+ message("${Yellow}${LIBNAME}_LIBDIR is defined but ${_lib_to_find}"
+ "has not been found in ${ARGN}${ColourReset}")
+ else()
+ if(${LIBNAME}_DIR)
+ message("${Yellow}${LIBNAME}_DIR is defined but ${_lib_to_find}"
+ "has not been found in ${ARGN}${ColourReset}")
+ else()
+ message("${Yellow}${_lib_to_find} not found."
+ "Nor ${LIBNAME}_DIR neither ${LIBNAME}_LIBDIR"
+ "are defined so that we look for ${_lib_to_find} in"
+ "system paths (Linux: LD_LIBRARY_PATH, Windows: LIB,"
+ "Mac: DYLD_LIBRARY_PATH,"
+ "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES,"
+ "CMAKE_C_IMPLICIT_LINK_DIRECTORIES)${ColourReset}")
+ if(_lib_env)
+ message("${Yellow}${_lib_to_find} has not been found in"
+ "${_lib_env}${ColourReset}")
+ endif()
+ endif()
+ endif()
+ message("${BoldYellow}Please indicate where to find ${_lib_to_find}. You have three options:\n"
+ "- Option 1: Provide the Installation directory of BLAS library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n"
+ "- Option 2: Provide the directory where to find the library with cmake option: -D${LIBNAME}_LIBDIR=your/path/to/${libname}/lib/\n"
+ "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n"
+ "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}")
+
+endmacro()
+
+# This macro informs why the _lib_to_find file has not been found
+macro(Print_Find_Library_Blas_CheckFunc_Status _name)
+
+ # save _libname upper/lower case
+ string(TOUPPER ${_name} FUNCNAME)
+ string(TOLOWER ${_name} funcname)
+
+ # print status
+ #message(" ")
+ message("${Red}Libs have been found but check of symbol ${_name} failed "
+ "with following libraries ${ARGN}${ColourReset}")
+ message("${BoldRed}Please open your error file CMakeFiles/CMakeError.log"
+ "to figure out why it fails${ColourReset}")
+ #message(" ")
+
+endmacro()
+
+if (NOT BLAS_FOUND)
+ set(BLAS_DIR "" CACHE PATH "Installation directory of BLAS library")
+ if (NOT BLAS_FIND_QUIETLY)
+ message(STATUS "A cache variable, namely BLAS_DIR, has been set to specify the install directory of BLAS")
+ endif()
+endif()
+
+option(BLAS_VERBOSE "Print some additional information during BLAS libraries detection" OFF)
+mark_as_advanced(BLAS_VERBOSE)
include(CheckFunctionExists)
+include(CheckFortranFunctionExists)
+set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
-# This macro checks for the existence of the combination of fortran libraries
-# given by _list. If the combination is found, this macro checks (using the
-# check_function_exists macro) whether can link against that library
-# combination using the name of a routine given by _name using the linker
-# flags given by _flags. If the combination of libraries is found and passes
-# the link test, LIBRARIES is set to the list of complete library paths that
-# have been found and DEFINITIONS to the required definitions.
-# Otherwise, LIBRARIES is set to FALSE.
-# N.B. _prefix is the prefix applied to the names of all cached variables that
-# are generated internally and marked advanced by this macro.
-macro(check_fortran_libraries DEFINITIONS LIBRARIES _prefix _name _flags _list _path)
- #message("DEBUG: check_fortran_libraries(${_list} in ${_path})")
-
- # Check for the existence of the libraries given by _list
- set(_libraries_found TRUE)
- set(_libraries_work FALSE)
- set(${DEFINITIONS} "")
- set(${LIBRARIES} "")
+# Check the language being used
+get_property( _LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES )
+if( _LANGUAGES_ MATCHES Fortran )
+ set( _CHECK_FORTRAN TRUE )
+elseif( (_LANGUAGES_ MATCHES C) OR (_LANGUAGES_ MATCHES CXX) )
+ set( _CHECK_FORTRAN FALSE )
+else()
+ if(BLAS_FIND_REQUIRED)
+ message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
+ else()
+ message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)")
+ return()
+ endif()
+endif()
+
+macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread)
+ # This macro checks for the existence of the combination of fortran libraries
+ # given by _list. If the combination is found, this macro checks (using the
+ # Check_Fortran_Function_Exists macro) whether can link against that library
+ # combination using the name of a routine given by _name using the linker
+ # flags given by _flags. If the combination of libraries is found and passes
+ # the link test, LIBRARIES is set to the list of complete library paths that
+ # have been found. Otherwise, LIBRARIES is set to FALSE.
+
+ # N.B. _prefix is the prefix applied to the names of all cached variables that
+ # are generated internally and marked advanced by this macro.
+
+ set(_libdir ${ARGN})
+
+ set(_libraries_work TRUE)
+ set(${LIBRARIES})
set(_combined_name)
+ set(ENV_MKLROOT "$ENV{MKLROOT}")
+ set(ENV_BLAS_DIR "$ENV{BLAS_DIR}")
+ set(ENV_BLAS_LIBDIR "$ENV{BLAS_LIBDIR}")
+ if (NOT _libdir)
+ if (BLAS_LIBDIR)
+ list(APPEND _libdir "${BLAS_LIBDIR}")
+ elseif (BLAS_DIR)
+ list(APPEND _libdir "${BLAS_DIR}")
+ list(APPEND _libdir "${BLAS_DIR}/lib")
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ list(APPEND _libdir "${BLAS_DIR}/lib64")
+ list(APPEND _libdir "${BLAS_DIR}/lib/intel64")
+ else()
+ list(APPEND _libdir "${BLAS_DIR}/lib32")
+ list(APPEND _libdir "${BLAS_DIR}/lib/ia32")
+ endif()
+ elseif(ENV_BLAS_LIBDIR)
+ list(APPEND _libdir "${ENV_BLAS_LIBDIR}")
+ elseif(ENV_BLAS_DIR)
+ list(APPEND _libdir "${ENV_BLAS_DIR}")
+ list(APPEND _libdir "${ENV_BLAS_DIR}/lib")
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ list(APPEND _libdir "${ENV_BLAS_DIR}/lib64")
+ list(APPEND _libdir "${ENV_BLAS_DIR}/lib/intel64")
+ else()
+ list(APPEND _libdir "${ENV_BLAS_DIR}/lib32")
+ list(APPEND _libdir "${ENV_BLAS_DIR}/lib/ia32")
+ endif()
+ else()
+ if (ENV_MKLROOT)
+ list(APPEND _libdir "${ENV_MKLROOT}/lib")
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ list(APPEND _libdir "${ENV_MKLROOT}/lib64")
+ list(APPEND _libdir "${ENV_MKLROOT}/lib/intel64")
+ else()
+ list(APPEND _libdir "${ENV_MKLROOT}/lib32")
+ list(APPEND _libdir "${ENV_MKLROOT}/lib/ia32")
+ endif()
+ endif()
+ if (WIN32)
+ string(REPLACE ":" ";" _libdir2 "$ENV{LIB}")
+ elseif (APPLE)
+ string(REPLACE ":" ";" _libdir2 "$ENV{DYLD_LIBRARY_PATH}")
+ else ()
+ string(REPLACE ":" ";" _libdir2 "$ENV{LD_LIBRARY_PATH}")
+ endif ()
+ list(APPEND _libdir "${_libdir2}")
+ list(APPEND _libdir "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
+ list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+ endif()
+ endif ()
+
+ if (BLAS_VERBOSE)
+ message("${Cyan}Try to find BLAS libraries: ${_list}")
+ endif ()
+
foreach(_library ${_list})
set(_combined_name ${_combined_name}_${_library})
- if(_libraries_found)
- # search first in ${_path}
- find_library(${_prefix}_${_library}_LIBRARY
- NAMES ${_library}
- PATHS ${_path} NO_DEFAULT_PATH
- )
- # if not found, search in environment variables and system
- if ( WIN32 )
- find_library(${_prefix}_${_library}_LIBRARY
- NAMES ${_library}
- PATHS ENV LIB
- )
- elseif ( APPLE )
- find_library(${_prefix}_${_library}_LIBRARY
- NAMES ${_library}
- PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH
- )
+ if(_libraries_work)
+ if (BLA_STATIC)
+ if (WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif ()
+ if (APPLE)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ else ()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif ()
else ()
- find_library(${_prefix}_${_library}_LIBRARY
- NAMES ${_library}
- PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH
- )
- endif()
+ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # for ubuntu's libblas3gf and liblapack3gf packages
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
+ endif ()
+ endif ()
+ find_library(${_prefix}_${_library}_LIBRARY
+ NAMES ${_library}
+ HINTS ${_libdir}
+ NO_DEFAULT_PATH
+ )
mark_as_advanced(${_prefix}_${_library}_LIBRARY)
+ # Print status if not found
+ # -------------------------
+ if (NOT ${_prefix}_${_library}_LIBRARY AND NOT BLAS_FIND_QUIETLY AND BLAS_VERBOSE)
+ Print_Find_Library_Blas_Status(blas ${_library} ${_libdir})
+ endif ()
set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
- set(_libraries_found ${${_prefix}_${_library}_LIBRARY})
- endif(_libraries_found)
+ set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+ endif(_libraries_work)
endforeach(_library ${_list})
- if(_libraries_found)
- set(_libraries_found ${${LIBRARIES}})
- endif()
-
- # Test this combination of libraries with the Fortran/f2c interface.
- # We test the Fortran interface first as it is well standardized.
- if(_libraries_found AND NOT _libraries_work)
- set(${DEFINITIONS} "-D${_prefix}_USE_F2C")
- set(${LIBRARIES} ${_libraries_found})
- # Some C++ linkers require the f2c library to link with Fortran libraries.
- # I do not know which ones, thus I just add the f2c library if it is available.
- find_package( F2C QUIET )
- if ( F2C_FOUND )
- set(${DEFINITIONS} ${${DEFINITIONS}} ${F2C_DEFINITIONS})
- set(${LIBRARIES} ${${LIBRARIES}} ${F2C_LIBRARIES})
+
+ if(_libraries_work)
+ # Test this combination of libraries.
+ if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND BLA_STATIC)
+ list(INSERT ${LIBRARIES} 0 "-Wl,--start-group")
+ list(APPEND ${LIBRARIES} "-Wl,--end-group")
+ endif()
+ set(CMAKE_REQUIRED_LIBRARIES "${_flags};${${LIBRARIES}};${_thread}")
+ set(CMAKE_REQUIRED_FLAGS "${BLAS_COMPILER_FLAGS}")
+ if (BLAS_VERBOSE)
+ message("${Cyan}BLAS libs found for BLA_VENDOR ${BLA_VENDOR}."
+ "Try to compile symbol ${_name} with following libraries:"
+ "${CMAKE_REQUIRED_LIBRARIES}")
+ endif ()
+ if(NOT BLAS_FOUND)
+ unset(${_prefix}${_combined_name}_WORKS CACHE)
+ endif()
+ if (_CHECK_FORTRAN)
+ if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
+ string(REPLACE "mkl_intel_lp64" "mkl_gf_lp64" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+ string(REPLACE "mkl_intel_ilp64" "mkl_gf_ilp64" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+ endif()
+ check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
+ else()
+ check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
endif()
- set(CMAKE_REQUIRED_DEFINITIONS ${${DEFINITIONS}})
- set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}})
- #message("DEBUG: CMAKE_REQUIRED_DEFINITIONS = ${CMAKE_REQUIRED_DEFINITIONS}")
- #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
- # Check if function exists with f2c calling convention (ie a trailing underscore)
- check_function_exists(${_name}_ ${_prefix}_${_name}_${_combined_name}_f2c_WORKS)
- set(CMAKE_REQUIRED_DEFINITIONS} "")
- set(CMAKE_REQUIRED_LIBRARIES "")
- mark_as_advanced(${_prefix}_${_name}_${_combined_name}_f2c_WORKS)
- set(_libraries_work ${${_prefix}_${_name}_${_combined_name}_f2c_WORKS})
- endif(_libraries_found AND NOT _libraries_work)
-
- # If not found, test this combination of libraries with a C interface.
- # A few implementations (ie ACML) provide a C interface. Unfortunately, there is no standard.
- if(_libraries_found AND NOT _libraries_work)
- set(${DEFINITIONS} "")
- set(${LIBRARIES} ${_libraries_found})
- set(CMAKE_REQUIRED_DEFINITIONS "")
- set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}})
- #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
- check_function_exists(${_name} ${_prefix}_${_name}${_combined_name}_WORKS)
- set(CMAKE_REQUIRED_LIBRARIES "")
- mark_as_advanced(${_prefix}_${_name}${_combined_name}_WORKS)
- set(_libraries_work ${${_prefix}_${_name}${_combined_name}_WORKS})
- endif(_libraries_found AND NOT _libraries_work)
-
- # on failure
- if(NOT _libraries_work)
- set(${DEFINITIONS} "")
- set(${LIBRARIES} FALSE)
- endif()
- #message("DEBUG: ${DEFINITIONS} = ${${DEFINITIONS}}")
- #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
-endmacro(check_fortran_libraries)
+ mark_as_advanced(${_prefix}${_combined_name}_WORKS)
+ set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
+ # Print status if not found
+ # -------------------------
+ if (NOT _libraries_work AND NOT BLAS_FIND_QUIETLY AND BLAS_VERBOSE)
+ Print_Find_Library_Blas_CheckFunc_Status(${_name} ${CMAKE_REQUIRED_LIBRARIES})
+ endif ()
+ set(CMAKE_REQUIRED_LIBRARIES)
+ endif()
+ if(_libraries_work)
+ set(${LIBRARIES} ${${LIBRARIES}} ${_thread})
+ else(_libraries_work)
+ set(${LIBRARIES} FALSE)
+ endif(_libraries_work)
-#
-# main
-#
+endmacro(Check_Fortran_Libraries)
-# Is it already configured?
-if (BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES)
- set(BLAS_FOUND TRUE)
+set(BLAS_LINKER_FLAGS)
+set(BLAS_LIBRARIES)
+set(BLAS95_LIBRARIES)
+if ($ENV{BLA_VENDOR} MATCHES ".+")
+ set(BLA_VENDOR $ENV{BLA_VENDOR})
+else ()
+ if(NOT BLA_VENDOR)
+ set(BLA_VENDOR "All")
+ endif()
+endif ()
-else()
+#BLAS in intel mkl 10 library? (em64t 64bit)
+if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES OR BLA_VENDOR MATCHES "Intel*")
+ # Looking for include
+ # -------------------
+
+ # Add system include paths to search include
+ # ------------------------------------------
+ unset(_inc_env)
+ set(ENV_MKLROOT "$ENV{MKLROOT}")
+ set(ENV_BLAS_DIR "$ENV{BLAS_DIR}")
+ set(ENV_BLAS_INCDIR "$ENV{BLAS_INCDIR}")
+ if(ENV_BLAS_INCDIR)
+ list(APPEND _inc_env "${ENV_BLAS_INCDIR}")
+ elseif(ENV_BLAS_DIR)
+ list(APPEND _inc_env "${ENV_BLAS_DIR}")
+ list(APPEND _inc_env "${ENV_BLAS_DIR}/include")
+ else()
+ if (ENV_MKLROOT)
+ list(APPEND _inc_env "${ENV_MKLROOT}/include")
+ endif()
+ # system variables
+ if(WIN32)
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
+ list(APPEND _inc_env "${_path_env}")
+ else()
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ endif()
+ endif()
+ list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
+ list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
+ list(REMOVE_DUPLICATES _inc_env)
- # reset variables
- set( BLAS_INCLUDE_DIR "" )
- set( BLAS_DEFINITIONS "" )
- set( BLAS_LINKER_FLAGS "" )
- set( BLAS_LIBRARIES "" )
- set( BLAS_LIBRARIES_DIR "" )
+ # set paths where to look for
+ set(PATH_TO_LOOK_FOR "${_inc_env}")
- #
- # If Unix, search for BLAS function in possible libraries
- #
+ # Try to find the fftw header in the given paths
+ # -------------------------------------------------
+ # call cmake macro to find the header path
+ if(BLAS_INCDIR)
+ set(BLAS_mkl.h_DIRS "BLAS_mkl.h_DIRS-NOTFOUND")
+ find_path(BLAS_mkl.h_DIRS
+ NAMES mkl.h
+ HINTS ${BLAS_INCDIR})
+ else()
+ if(BLAS_DIR)
+ set(BLAS_mkl.h_DIRS "BLAS_mkl.h_DIRS-NOTFOUND")
+ find_path(BLAS_mkl.h_DIRS
+ NAMES mkl.h
+ HINTS ${BLAS_DIR}
+ PATH_SUFFIXES "include")
+ else()
+ set(BLAS_mkl.h_DIRS "BLAS_mkl.h_DIRS-NOTFOUND")
+ find_path(BLAS_mkl.h_DIRS
+ NAMES mkl.h
+ HINTS ${PATH_TO_LOOK_FOR})
+ endif()
+ endif()
+ mark_as_advanced(BLAS_mkl.h_DIRS)
- # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ # If found, add path to cmake variable
+ # ------------------------------------
+ if (BLAS_mkl.h_DIRS)
+ set(BLAS_INCLUDE_DIRS "${BLAS_mkl.h_DIRS}")
+ else ()
+ set(BLAS_INCLUDE_DIRS "BLAS_INCLUDE_DIRS-NOTFOUND")
+ if(NOT BLAS_FIND_QUIETLY)
+ message(STATUS "Looking for BLAS -- mkl.h not found")
+ endif()
+ endif()
+
+ if (WIN32)
+ string(REPLACE ":" ";" _libdir "$ENV{LIB}")
+ elseif (APPLE)
+ string(REPLACE ":" ";" _libdir "$ENV{DYLD_LIBRARY_PATH}")
+ else ()
+ string(REPLACE ":" ";" _libdir "$ENV{LD_LIBRARY_PATH}")
+ endif ()
+ list(APPEND _libdir "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
+ list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+ # libiomp5
+ # --------
+ set(OMP_iomp5_LIBRARY "OMP_iomp5_LIBRARY-NOTFOUND")
+ find_library(OMP_iomp5_LIBRARY
+ NAMES iomp5
+ HINTS ${_libdir}
+ )
+ mark_as_advanced(OMP_iomp5_LIBRARY)
+ set(OMP_LIB "")
+ # libgomp
+ # -------
+ set(OMP_gomp_LIBRARY "OMP_gomp_LIBRARY-NOTFOUND")
+ find_library(OMP_gomp_LIBRARY
+ NAMES gomp
+ HINTS ${_libdir}
+ )
+ mark_as_advanced(OMP_gomp_LIBRARY)
+ # choose one or another depending on the compilo
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ if (OMP_gomp_LIBRARY)
+ set(OMP_LIB "${OMP_gomp_LIBRARY}")
+ endif()
+ else(CMAKE_C_COMPILER_ID STREQUAL "Intel")
+ if (OMP_iomp5_LIBRARY)
+ set(OMP_LIB "${OMP_iomp5_LIBRARY}")
+ endif()
+ endif()
+
+ if (UNIX AND NOT WIN32)
+ # m
+ find_library(M_LIBRARY
+ NAMES m
+ HINTS ${_libdir})
+ mark_as_advanced(M_LIBRARY)
+ if(M_LIBRARY)
+ set(LM "-lm")
+ else()
+ set(LM "")
+ endif()
+ # Fortran
+ set(LGFORTRAN "")
+ if (CMAKE_C_COMPILER_ID MATCHES "GNU")
+ find_library(
+ FORTRAN_gfortran_LIBRARY
+ NAMES gfortran
+ HINTS ${_libdir}
+ )
+ mark_as_advanced(FORTRAN_gfortran_LIBRARY)
+ if (FORTRAN_gfortran_LIBRARY)
+ set(LGFORTRAN "${FORTRAN_gfortran_LIBRARY}")
+ endif()
+ elseif (CMAKE_C_COMPILER_ID MATCHES "Intel")
+ find_library(
+ FORTRAN_ifcore_LIBRARY
+ NAMES ifcore
+ HINTS ${_libdir}
+ )
+ mark_as_advanced(FORTRAN_ifcore_LIBRARY)
+ if (FORTRAN_ifcore_LIBRARY)
+ set(LGFORTRAN "{FORTRAN_ifcore_LIBRARY}")
+ endif()
+ endif()
+ set(BLAS_COMPILER_FLAGS "")
+ if (NOT BLA_VENDOR STREQUAL "Intel10_64lp_seq")
+ if (CMAKE_C_COMPILER_ID STREQUAL "Intel")
+ list(APPEND BLAS_COMPILER_FLAGS "-openmp")
+ endif()
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ list(APPEND BLAS_COMPILER_FLAGS "-fopenmp")
+ endif()
+ endif()
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ if (BLA_VENDOR STREQUAL "Intel10_32")
+ list(APPEND BLAS_COMPILER_FLAGS "-m32")
+ else()
+ list(APPEND BLAS_COMPILER_FLAGS "-m64")
+ endif()
+ if (NOT BLA_VENDOR STREQUAL "Intel10_64lp_seq")
+ list(APPEND OMP_LIB "-ldl")
+ endif()
+ if (ENV_MKLROOT)
+ list(APPEND BLAS_COMPILER_FLAGS "-I${ENV_MKLROOT}/include")
+ endif()
+ endif()
+
+ set(additional_flags "")
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ set(additional_flags "-Wl,--no-as-needed")
+ endif()
+ endif ()
+
+ if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+ if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
+ find_package(Threads)
+ else()
+ find_package(Threads REQUIRED)
+ endif()
+
+ set(BLAS_SEARCH_LIBS "")
+
+ if(BLA_F95)
+
+ set(BLAS_mkl_SEARCH_SYMBOL SGEMM)
+ set(_LIBRARIES BLAS95_LIBRARIES)
+ if (WIN32)
+ if (BLA_STATIC)
+ set(BLAS_mkl_DLL_SUFFIX "")
+ else()
+ set(BLAS_mkl_DLL_SUFFIX "_dll")
+ endif()
+
+ # Find the main file (32-bit or 64-bit)
+ set(BLAS_SEARCH_LIBS_WIN_MAIN "")
+ if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
+ "mkl_blas95${BLAS_mkl_DLL_SUFFIX} mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+ if (BLA_VENDOR STREQUAL "Intel10_64lp*" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
+ "mkl_blas95_lp64${BLAS_mkl_DLL_SUFFIX} mkl_intel_lp64${BLAS_mkl_DLL_SUFFIX}")
+ endif ()
+
+ # Add threading/sequential libs
+ set(BLAS_SEARCH_LIBS_WIN_THREAD "")
+ if (BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+ if (NOT BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All")
+ # old version
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+ # mkl >= 10.3
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+
+ # Cartesian product of the above
+ foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
+ foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
+ list(APPEND BLAS_SEARCH_LIBS
+ "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
+ endforeach()
+ endforeach()
+ else (WIN32)
+ if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_blas95 mkl_intel mkl_intel_thread mkl_core guide")
+ endif ()
+ if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
+ # old version
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_blas95 mkl_intel_lp64 mkl_intel_thread mkl_core guide")
+ # mkl >= 10.3
+ if (CMAKE_C_COMPILER_ID STREQUAL "Intel")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_blas95_lp64 mkl_intel_lp64 mkl_intel_thread mkl_core")
+ endif()
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_blas95_lp64 mkl_intel_lp64 mkl_gnu_thread mkl_core")
+ endif()
+ endif ()
+ if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_sequential mkl_core")
+ if (BLA_VENDOR STREQUAL "Intel10_64lp_seq")
+ set(OMP_LIB "")
+ endif()
+ endif ()
+ endif (WIN32)
+
+ else (BLA_F95)
+
+ set(BLAS_mkl_SEARCH_SYMBOL sgemm)
+ set(_LIBRARIES BLAS_LIBRARIES)
+ if (WIN32)
+ if (BLA_STATIC)
+ set(BLAS_mkl_DLL_SUFFIX "")
+ else()
+ set(BLAS_mkl_DLL_SUFFIX "_dll")
+ endif()
+
+ # Find the main file (32-bit or 64-bit)
+ set(BLAS_SEARCH_LIBS_WIN_MAIN "")
+ if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
+ "mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+ if (BLA_VENDOR STREQUAL "Intel10_64lp*" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
+ "mkl_intel_lp64${BLAS_mkl_DLL_SUFFIX}")
+ endif ()
+
+ # Add threading/sequential libs
+ set(BLAS_SEARCH_LIBS_WIN_THREAD "")
+ if (NOT BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All")
+ # old version
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+ # mkl >= 10.3
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+ if (BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+
+ # Cartesian product of the above
+ foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
+ foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
+ list(APPEND BLAS_SEARCH_LIBS
+ "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
+ endforeach()
+ endforeach()
+ else (WIN32)
+ if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel mkl_intel_thread mkl_core guide")
+ endif ()
+ if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
+ # old version
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_intel_thread mkl_core guide")
+ # mkl >= 10.3
+ if (CMAKE_C_COMPILER_ID STREQUAL "Intel")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_intel_thread mkl_core")
+ endif()
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_gnu_thread mkl_core")
+ endif()
+ endif ()
+ if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_sequential mkl_core")
+ if (BLA_VENDOR STREQUAL "Intel10_64lp_seq")
+ set(OMP_LIB "")
+ endif()
+ endif ()
+ #older vesions of intel mkl libs
+ if (BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_ia32")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_em64t")
+ endif ()
+ endif (WIN32)
+
+ endif (BLA_F95)
+
+ foreach (IT ${BLAS_SEARCH_LIBS})
+ string(REPLACE " " ";" SEARCH_LIBS ${IT})
+ if (${_LIBRARIES})
+ else ()
+ check_fortran_libraries(
+ ${_LIBRARIES}
+ BLAS
+ ${BLAS_mkl_SEARCH_SYMBOL}
+ "${additional_flags}"
+ "${SEARCH_LIBS}"
+ "${OMP_LIB};${CMAKE_THREAD_LIBS_INIT};${LM}"
+ )
+ if(_LIBRARIES)
+ set(BLAS_LINKER_FLAGS "${additional_flags}")
+ endif()
+ endif()
+ endforeach ()
+ if(NOT BLAS_FIND_QUIETLY)
+ if(${_LIBRARIES})
+ message(STATUS "Looking for MKL BLAS: found")
+ else()
+ message(STATUS "Looking for MKL BLAS: not found")
+ endif()
+ endif()
+ if (${_LIBRARIES} AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "Intel MKL")
+ endif()
+ endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+ endif(NOT BLAS_LIBRARIES OR BLA_VENDOR MATCHES "Intel*")
+endif (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+
+
+if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "cblas;f77blas;atlas"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "goto2"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for Goto BLAS: found")
+ else()
+ message(STATUS "Looking for Goto BLAS: not found")
+ endif()
endif()
+ endif()
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "Goto")
+ endif()
- # BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+
+
+# OpenBlas
+if (BLA_VENDOR STREQUAL "Open" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ # openblas (http://www.openblas.net/)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "sgemm;dgemm;blas"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "openblas"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for Open BLAS: found")
+ else()
+ message(STATUS "Looking for Open BLAS: not found")
+ endif()
endif()
+ endif()
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "Openblas")
+ endif()
- # BLAS in Alpha CXML library?
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+endif (BLA_VENDOR STREQUAL "Open" OR BLA_VENDOR STREQUAL "All")
+
+
+# EigenBlas
+if (BLA_VENDOR STREQUAL "Eigen" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ # eigenblas (http://eigen.tuxfamily.org/index.php?title=Main_Page)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "cxml"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "eigen_blas"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ message(STATUS "Looking for Eigen BLAS: found")
+ else()
+ message(STATUS "Looking for Eigen BLAS: not found")
+ endif()
endif()
+ endif()
- # BLAS in Alpha DXML library? (now called CXML, see above)
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if(NOT BLAS_LIBRARIES)
+ # eigenblas (http://eigen.tuxfamily.org/index.php?title=Main_Page)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "dxml"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "eigen_blas_static"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for Eigen BLAS: found")
+ else()
+ message(STATUS "Looking for Eigen BLAS: not found")
+ endif()
endif()
+ endif()
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "Eigen")
+ endif()
- # BLAS in Sun Performance library?
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+endif (BLA_VENDOR STREQUAL "Eigen" OR BLA_VENDOR STREQUAL "All")
+
+
+if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
- sgemm
- "-xlic_lib=sunperf"
- "sunperf;sunmath"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ dgemm
+ ""
+ "f77blas;atlas"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
if(BLAS_LIBRARIES)
- # Extra linker flag
- set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
+ message(STATUS "Looking for Atlas BLAS: found")
+ else()
+ message(STATUS "Looking for Atlas BLAS: not found")
endif()
endif()
+ endif()
- # BLAS in SCSL library? (SGI/Cray Scientific Library)
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "Atlas")
+ endif()
+
+endif (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
+
+
+# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
+if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "scsl"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "sgemm;dgemm;blas"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for PhiPACK BLAS: found")
+ else()
+ message(STATUS "Looking for PhiPACK BLAS: not found")
+ endif()
endif()
+ endif()
- # BLAS in SGIMATH library?
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "PhiPACK")
+ endif()
+
+endif (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
+
+
+# BLAS in Alpha CXML library?
+if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "complib.sgimath"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "cxml"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for CXML BLAS: found")
+ else()
+ message(STATUS "Looking for CXML BLAS: not found")
+ endif()
endif()
+ endif()
- # BLAS in IBM ESSL library? (requires generic BLAS lib, too)
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "CXML")
+ endif()
+
+endif (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
+
+
+# BLAS in Alpha DXML library? (now called CXML, see above)
+if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "essl;blas"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "dxml"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for DXML BLAS: found")
+ else()
+ message(STATUS "Looking for DXML BLAS: not found")
+ endif()
endif()
+ endif()
- #BLAS in intel mkl 10 library? (em64t 64bit)
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "DXML")
+ endif()
+
+endif (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
+
+
+# BLAS in Sun Performance library?
+if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
+ "-xlic_lib=sunperf"
+ "sunperf;sunmath"
""
- "mkl_intel_lp64;mkl_intel_thread;mkl_core;guide;pthread"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
)
+ if(BLAS_LIBRARIES)
+ set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
endif()
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for SunPerf BLAS: found")
+ else()
+ message(STATUS "Looking for SunPerf BLAS: not found")
+ endif()
+ endif()
+ endif()
- ### windows version of intel mkl 10?
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "SunPerf")
+ endif()
+
+endif ()
+
+
+# BLAS in SCSL library? (SGI/Cray Scientific Library)
+if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
- SGEMM
+ sgemm
+ ""
+ "scsl"
""
- "mkl_c_dll;mkl_intel_thread_dll;mkl_core_dll;libguide40"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for SCSL BLAS: found")
+ else()
+ message(STATUS "Looking for SCSL BLAS: not found")
+ endif()
endif()
+ endif()
- #older versions of intel mkl libs
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "SunPerf")
+ endif()
- # BLAS in intel mkl library? (shared)
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+endif ()
+
+
+# BLAS in SGIMATH library?
+if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "mkl;guide;pthread"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "complib.sgimath"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for SGIMATH BLAS: found")
+ else()
+ message(STATUS "Looking for SGIMATH BLAS: not found")
+ endif()
endif()
+ endif()
- #BLAS in intel mkl library? (static, 32bit)
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "SGIMATH")
+ endif()
+
+endif ()
+
+
+# BLAS in IBM ESSL library (requires generic BLAS lib, too)
+if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "mkl_ia32;guide;pthread"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "essl;xlfmath;xlf90_r;blas"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for IBM ESSL BLAS: found")
+ else()
+ message(STATUS "Looking for IBM ESSL BLAS: not found")
+ endif()
endif()
+ endif()
- #BLAS in intel mkl library? (static, em64t 64bit)
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "IBM ESSL")
+ endif()
+
+endif ()
+
+# BLAS in IBM ESSL_MT library (requires generic BLAS lib, too)
+if (BLA_VENDOR STREQUAL "IBMESSLMT" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "mkl_em64t;guide;pthread"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "esslsmp;xlsmp;xlfmath;xlf90_r;blas"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for IBM ESSL MT BLAS: found")
+ else()
+ message(STATUS "Looking for IBM ESSL MT BLAS: not found")
+ endif()
endif()
+ endif()
- #BLAS in acml library?
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "IBM ESSL MT")
+ endif()
+
+endif ()
+
+
+#BLAS in acml library?
+if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All")
+
+ if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
+ ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR
+ ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS)))
+
+ # try to find acml in "standard" paths
+ if( WIN32 )
+ file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" )
+ else()
+ file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" )
+ endif()
+ if( WIN32 )
+ file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" )
+ else()
+ file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" )
+ endif()
+ list(GET _ACML_ROOT 0 _ACML_ROOT)
+ list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
+
+ if( _ACML_ROOT )
+
+ get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH )
+ if( SIZEOF_INTEGER EQUAL 8 )
+ set( _ACML_PATH_SUFFIX "_int64" )
+ else()
+ set( _ACML_PATH_SUFFIX "" )
+ endif()
+ if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" )
+ set( _ACML_COMPILER32 "ifort32" )
+ set( _ACML_COMPILER64 "ifort64" )
+ elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" )
+ set( _ACML_COMPILER32 "sun32" )
+ set( _ACML_COMPILER64 "sun64" )
+ elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" )
+ set( _ACML_COMPILER32 "pgi32" )
+ if( WIN32 )
+ set( _ACML_COMPILER64 "win64" )
+ else()
+ set( _ACML_COMPILER64 "pgi64" )
+ endif()
+ elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" )
+ # 32 bit builds not supported on Open64 but for code simplicity
+ # We'll just use the same directory twice
+ set( _ACML_COMPILER32 "open64_64" )
+ set( _ACML_COMPILER64 "open64_64" )
+ elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" )
+ set( _ACML_COMPILER32 "nag32" )
+ set( _ACML_COMPILER64 "nag64" )
+ else()
+ set( _ACML_COMPILER32 "gfortran32" )
+ set( _ACML_COMPILER64 "gfortran64" )
+ endif()
+
+ if( BLA_VENDOR STREQUAL "ACML_MP" )
+ set(_ACML_MP_LIB_DIRS
+ "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib"
+ "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" )
+ else()
+ set(_ACML_LIB_DIRS
+ "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib"
+ "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" )
+ endif()
+
+ endif(_ACML_ROOT)
+
+ elseif(BLAS_${BLA_VENDOR}_LIB_DIRS)
+
+ set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS})
+
+ endif()
+
+ if( BLA_VENDOR STREQUAL "ACML_MP" )
+ foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
+ check_fortran_libraries (
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS}
+ )
+ if( BLAS_LIBRARIES )
+ break()
+ endif()
+ endforeach()
+ elseif( BLA_VENDOR STREQUAL "ACML_GPU" )
+ foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
+ check_fortran_libraries (
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS}
+ )
+ if( BLAS_LIBRARIES )
+ break()
+ endif()
+ endforeach()
+ else()
+ foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} )
+ check_fortran_libraries (
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS}
+ )
+ if( BLAS_LIBRARIES )
+ break()
+ endif()
+ endforeach()
+ endif()
+
+ # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "acml"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "acml;acml_mv"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for ACML BLAS: found")
+ else()
+ message(STATUS "Looking for ACML BLAS: not found")
+ endif()
endif()
+ endif()
- # Apple BLAS library?
- if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "Accelerate"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "acml_mp;acml_mv"
+ ""
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for ACML BLAS: found")
+ else()
+ message(STATUS "Looking for ACML BLAS: not found")
+ endif()
endif()
+ endif()
- if ( NOT BLAS_LIBRARIES )
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "vecLib"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
+ "acml;acml_mv;CALBLAS"
+ ""
)
- endif ( NOT BLAS_LIBRARIES )
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for ACML BLAS: found")
+ else()
+ message(STATUS "Looking for ACML BLAS: not found")
+ endif()
+ endif()
+ endif()
- # Generic BLAS library?
- # This configuration *must* be the last try as this library is notably slow.
- if ( NOT BLAS_LIBRARIES )
- check_fortran_libraries(
- BLAS_DEFINITIONS
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "ACML")
+ endif()
+
+endif (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All") # ACML
+
+
+# Apple BLAS library?
+if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
BLAS_LIBRARIES
BLAS
- sgemm
+ dgemm
+ ""
+ "Accelerate"
""
- "blas"
- "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
)
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for Apple BLAS: found")
+ else()
+ message(STATUS "Looking for Apple BLAS: not found")
+ endif()
endif()
+ endif()
+
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "Apple Accelerate")
+ endif()
+
+endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
- if(BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES)
+
+if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+
+ if ( NOT BLAS_LIBRARIES )
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ dgemm
+ ""
+ "vecLib"
+ ""
+ )
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for NAS BLAS: found")
+ else()
+ message(STATUS "Looking for NAS BLAS: not found")
+ endif()
+ endif()
+ endif ()
+
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "NAS")
+ endif()
+
+endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+
+
+# Generic BLAS library?
+if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+
+ set(BLAS_SEARCH_LIBS "blas;blas_LINUX;blas_MAC;blas_WINDOWS;refblas")
+ foreach (SEARCH_LIB ${BLAS_SEARCH_LIBS})
+ if (BLAS_LIBRARIES)
+ else ()
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "${SEARCH_LIB}"
+ "${LGFORTRAN}"
+ )
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_LIBRARIES)
+ message(STATUS "Looking for Generic BLAS: found")
+ else()
+ message(STATUS "Looking for Generic BLAS: not found")
+ endif()
+ endif()
+ endif()
+ endforeach ()
+
+ if (BLAS_LIBRARIES AND NOT BLAS_VENDOR_FOUND)
+ set (BLAS_VENDOR_FOUND "Netlib or other Generic libblas")
+ endif()
+
+endif (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+
+
+if(BLA_F95)
+
+ if(BLAS95_LIBRARIES)
+ set(BLAS95_FOUND TRUE)
+ else()
+ set(BLAS95_FOUND FALSE)
+ endif()
+
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS95_FOUND)
+ message(STATUS "A library with BLAS95 API found.")
+ message(STATUS "BLAS_LIBRARIES ${BLAS_LIBRARIES}")
+ else(BLAS95_FOUND)
+ message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but blas 95 libraries could not be found or check of symbols failed."
+ "\nPlease indicate where to find blas libraries. You have three options:\n"
+ "- Option 1: Provide the installation directory of BLAS library with cmake option: -DBLAS_DIR=your/path/to/blas\n"
+ "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n"
+ "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n"
+ "\nTo follow libraries detection more precisely you can activate a verbose mode with -DBLAS_VERBOSE=ON at cmake configure."
+ "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name."
+ "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit),"
+ "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model),"
+ "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic")
+ if(BLAS_FIND_REQUIRED)
+ message(FATAL_ERROR
+ "A required library with BLAS95 API not found. Please specify library location.")
+ else()
+ message(STATUS
+ "A library with BLAS95 API not found. Please specify library location.")
+ endif()
+ endif(BLAS95_FOUND)
+ endif(NOT BLAS_FIND_QUIETLY)
+
+ set(BLAS_FOUND TRUE)
+ set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}")
+
+else(BLA_F95)
+
+ if(BLAS_LIBRARIES)
set(BLAS_FOUND TRUE)
else()
set(BLAS_FOUND FALSE)
@@ -388,32 +1366,41 @@ else()
if(NOT BLAS_FIND_QUIETLY)
if(BLAS_FOUND)
message(STATUS "A library with BLAS API found.")
+ message(STATUS "BLAS_LIBRARIES ${BLAS_LIBRARIES}")
else(BLAS_FOUND)
+ message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but blas libraries could not be found or check of symbols failed."
+ "\nPlease indicate where to find blas libraries. You have three options:\n"
+ "- Option 1: Provide the installation directory of BLAS library with cmake option: -DBLAS_DIR=your/path/to/blas\n"
+ "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n"
+ "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n"
+ "\nTo follow libraries detection more precisely you can activate a verbose mode with -DBLAS_VERBOSE=ON at cmake configure."
+ "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name."
+ "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit),"
+ "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model),"
+ "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic")
if(BLAS_FIND_REQUIRED)
- message(FATAL_ERROR "A required library with BLAS API not found. Please specify library location.")
+ message(FATAL_ERROR
+ "A required library with BLAS API not found. Please specify library location.")
else()
- message(STATUS "A library with BLAS API not found. Please specify library location.")
+ message(STATUS
+ "A library with BLAS API not found. Please specify library location.")
endif()
endif(BLAS_FOUND)
endif(NOT BLAS_FIND_QUIETLY)
- # Add variables to cache
- set( BLAS_INCLUDE_DIR "${BLAS_INCLUDE_DIR}"
- CACHE PATH "Directories containing the BLAS header files" FORCE )
- set( BLAS_DEFINITIONS "${BLAS_DEFINITIONS}"
- CACHE STRING "Compilation options to use BLAS" FORCE )
- set( BLAS_LINKER_FLAGS "${BLAS_LINKER_FLAGS}"
- CACHE STRING "Linker flags to use BLAS" FORCE )
- set( BLAS_LIBRARIES "${BLAS_LIBRARIES}"
- CACHE FILEPATH "BLAS libraries name" FORCE )
- set( BLAS_LIBRARIES_DIR "${BLAS_LIBRARIES_DIR}"
- CACHE PATH "Directories containing the BLAS libraries" FORCE )
-
- #message("DEBUG: BLAS_INCLUDE_DIR = ${BLAS_INCLUDE_DIR}")
- #message("DEBUG: BLAS_DEFINITIONS = ${BLAS_DEFINITIONS}")
- #message("DEBUG: BLAS_LINKER_FLAGS = ${BLAS_LINKER_FLAGS}")
- #message("DEBUG: BLAS_LIBRARIES = ${BLAS_LIBRARIES}")
- #message("DEBUG: BLAS_LIBRARIES_DIR = ${BLAS_LIBRARIES_DIR}")
- #message("DEBUG: BLAS_FOUND = ${BLAS_FOUND}")
-
-endif(BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES)
+endif(BLA_F95)
+
+set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+
+if (BLAS_FOUND)
+ list(GET BLAS_LIBRARIES 0 first_lib)
+ get_filename_component(first_lib_path "${first_lib}" PATH)
+ if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)")
+ string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}")
+ set(BLAS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of BLAS library" FORCE)
+ else()
+ set(BLAS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of BLAS library" FORCE)
+ endif()
+endif()
+mark_as_advanced(BLAS_DIR)
+mark_as_advanced(BLAS_DIR_FOUND)
diff --git a/eigen/cmake/FindBLASEXT.cmake b/eigen/cmake/FindBLASEXT.cmake
new file mode 100644
index 0000000..0fe7fb8
--- /dev/null
+++ b/eigen/cmake/FindBLASEXT.cmake
@@ -0,0 +1,380 @@
+###
+#
+# @copyright (c) 2009-2014 The University of Tennessee and The University
+# of Tennessee Research Foundation.
+# All rights reserved.
+# @copyright (c) 2012-2016 Inria. All rights reserved.
+# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
+#
+###
+#
+# - Find BLAS EXTENDED for MORSE projects: find include dirs and libraries
+#
+# This module allows to find BLAS libraries by calling the official FindBLAS module
+# and handles the creation of different library lists whether the user wishes to link
+# with a sequential BLAS or a multihreaded (BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES).
+# BLAS is detected with a FindBLAS call then if the BLAS vendor is Intel10_64lp, ACML
+# or IBMESSLMT then the module attempts to find the corresponding multithreaded libraries.
+#
+# The following variables have been added to manage links with sequential or multithreaded
+# versions:
+# BLAS_INCLUDE_DIRS - BLAS include directories
+# BLAS_LIBRARY_DIRS - Link directories for BLAS libraries
+# BLAS_SEQ_LIBRARIES - BLAS component libraries to be linked (sequential)
+# BLAS_PAR_LIBRARIES - BLAS component libraries to be linked (multithreaded)
+
+#=============================================================================
+# Copyright 2012-2013 Inria
+# Copyright 2012-2013 Emmanuel Agullo
+# Copyright 2012-2013 Mathieu Faverge
+# Copyright 2012 Cedric Castagnede
+# Copyright 2013-2016 Florent Pruvost
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file MORSE-Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of Morse, substitute the full
+# License text for the above reference.)
+
+# macro to factorize this call
+macro(find_package_blas)
+ if(BLASEXT_FIND_REQUIRED)
+ if(BLASEXT_FIND_QUIETLY)
+ find_package(BLAS REQUIRED QUIET)
+ else()
+ find_package(BLAS REQUIRED)
+ endif()
+ else()
+ if(BLASEXT_FIND_QUIETLY)
+ find_package(BLAS QUIET)
+ else()
+ find_package(BLAS)
+ endif()
+ endif()
+endmacro()
+
+# add a cache variable to let the user specify the BLAS vendor
+set(BLA_VENDOR "" CACHE STRING "list of possible BLAS vendor:
+ Open, Eigen, Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT,
+ Intel10_32 (intel mkl v10 32 bit),
+ Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model),
+ Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model),
+ Intel( older versions of mkl 32 and 64 bit),
+ ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic")
+
+if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "In FindBLASEXT")
+ message(STATUS "If you want to force the use of one specific library, "
+ "\n please specify the BLAS vendor by setting -DBLA_VENDOR=blas_vendor_name"
+ "\n at cmake configure.")
+ message(STATUS "List of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, "
+ "\n DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT, Intel10_32 (intel mkl v10 32 bit),"
+ "\n Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model),"
+ "\n Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model),"
+ "\n Intel( older versions of mkl 32 and 64 bit),"
+ "\n ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic")
+endif()
+
+if (NOT BLAS_FOUND)
+ # First try to detect two cases:
+ # 1: only SEQ libs are handled
+ # 2: both SEQ and PAR libs are handled
+ find_package_blas()
+endif ()
+
+# detect the cases where SEQ and PAR libs are handled
+if(BLA_VENDOR STREQUAL "All" AND
+ (BLAS_mkl_core_LIBRARY OR BLAS_mkl_core_dll_LIBRARY)
+ )
+ set(BLA_VENDOR "Intel")
+ if(BLAS_mkl_intel_LIBRARY)
+ set(BLA_VENDOR "Intel10_32")
+ endif()
+ if(BLAS_mkl_intel_lp64_LIBRARY)
+ set(BLA_VENDOR "Intel10_64lp")
+ endif()
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we"
+ "\n have also potentially detected some multithreaded BLAS libraries from the MKL."
+ "\n We try to find both libraries lists (Sequential/Multithreaded).")
+ endif()
+ set(BLAS_FOUND "")
+elseif(BLA_VENDOR STREQUAL "All" AND BLAS_acml_LIBRARY)
+ set(BLA_VENDOR "ACML")
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we"
+ "\n have also potentially detected some multithreaded BLAS libraries from the ACML."
+ "\n We try to find both libraries lists (Sequential/Multithreaded).")
+ endif()
+ set(BLAS_FOUND "")
+elseif(BLA_VENDOR STREQUAL "All" AND BLAS_essl_LIBRARY)
+ set(BLA_VENDOR "IBMESSL")
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we"
+ "\n have also potentially detected some multithreaded BLAS libraries from the ESSL."
+ "\n We try to find both libraries lists (Sequential/Multithreaded).")
+ endif()
+ set(BLAS_FOUND "")
+endif()
+
+# Intel case
+if(BLA_VENDOR MATCHES "Intel*")
+
+ ###
+ # look for include path if the BLAS vendor is Intel
+ ###
+
+ # gather system include paths
+ unset(_inc_env)
+ if(WIN32)
+ string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
+ else()
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ endif()
+ list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
+ list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
+ set(ENV_MKLROOT "$ENV{MKLROOT}")
+ if (ENV_MKLROOT)
+ list(APPEND _inc_env "${ENV_MKLROOT}/include")
+ endif()
+ list(REMOVE_DUPLICATES _inc_env)
+
+ # find mkl.h inside known include paths
+ set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
+ if(BLAS_INCDIR)
+ set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
+ find_path(BLAS_mkl.h_INCLUDE_DIRS
+ NAMES mkl.h
+ HINTS ${BLAS_INCDIR})
+ else()
+ if(BLAS_DIR)
+ set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
+ find_path(BLAS_mkl.h_INCLUDE_DIRS
+ NAMES mkl.h
+ HINTS ${BLAS_DIR}
+ PATH_SUFFIXES include)
+ else()
+ set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
+ find_path(BLAS_mkl.h_INCLUDE_DIRS
+ NAMES mkl.h
+ HINTS ${_inc_env})
+ endif()
+ endif()
+ mark_as_advanced(BLAS_mkl.h_INCLUDE_DIRS)
+ ## Print status if not found
+ ## -------------------------
+ #if (NOT BLAS_mkl.h_INCLUDE_DIRS AND MORSE_VERBOSE)
+ # Print_Find_Header_Status(blas mkl.h)
+ #endif ()
+ set(BLAS_INCLUDE_DIRS "")
+ if(BLAS_mkl.h_INCLUDE_DIRS)
+ list(APPEND BLAS_INCLUDE_DIRS "${BLAS_mkl.h_INCLUDE_DIRS}" )
+ endif()
+
+ ###
+ # look for libs
+ ###
+ # if Intel 10 64 bit -> look for sequential and multithreaded versions
+ if(BLA_VENDOR MATCHES "Intel10_64lp*")
+
+ ## look for the sequential version
+ set(BLA_VENDOR "Intel10_64lp_seq")
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "Look for the sequential version Intel10_64lp_seq")
+ endif()
+ find_package_blas()
+ if(BLAS_FOUND)
+ set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
+ else()
+ set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
+ endif()
+
+ ## look for the multithreaded version
+ set(BLA_VENDOR "Intel10_64lp")
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "Look for the multithreaded version Intel10_64lp")
+ endif()
+ find_package_blas()
+ if(BLAS_FOUND)
+ set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}")
+ else()
+ set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
+ endif()
+
+ else()
+
+ if(BLAS_FOUND)
+ set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
+ else()
+ set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
+ endif()
+
+ endif()
+
+ # ACML case
+elseif(BLA_VENDOR MATCHES "ACML*")
+
+ ## look for the sequential version
+ set(BLA_VENDOR "ACML")
+ find_package_blas()
+ if(BLAS_FOUND)
+ set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
+ else()
+ set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
+ endif()
+
+ ## look for the multithreaded version
+ set(BLA_VENDOR "ACML_MP")
+ find_package_blas()
+ if(BLAS_FOUND)
+ set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}")
+ else()
+ set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
+ endif()
+
+ # IBMESSL case
+elseif(BLA_VENDOR MATCHES "IBMESSL*")
+
+ ## look for the sequential version
+ set(BLA_VENDOR "IBMESSL")
+ find_package_blas()
+ if(BLAS_FOUND)
+ set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
+ else()
+ set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
+ endif()
+
+ ## look for the multithreaded version
+ set(BLA_VENDOR "IBMESSLMT")
+ find_package_blas()
+ if(BLAS_FOUND)
+ set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}")
+ else()
+ set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
+ endif()
+
+else()
+
+ if(BLAS_FOUND)
+ # define the SEQ libs as the BLAS_LIBRARIES
+ set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
+ else()
+ set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
+ endif()
+ set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
+
+endif()
+
+
+if(BLAS_SEQ_LIBRARIES)
+ set(BLAS_LIBRARIES "${BLAS_SEQ_LIBRARIES}")
+endif()
+
+# extract libs paths
+# remark: because it is not given by find_package(BLAS)
+set(BLAS_LIBRARY_DIRS "")
+string(REPLACE " " ";" BLAS_LIBRARIES "${BLAS_LIBRARIES}")
+foreach(blas_lib ${BLAS_LIBRARIES})
+ if (EXISTS "${blas_lib}")
+ get_filename_component(a_blas_lib_dir "${blas_lib}" PATH)
+ list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" )
+ else()
+ string(REPLACE "-L" "" blas_lib "${blas_lib}")
+ if (EXISTS "${blas_lib}")
+ list(APPEND BLAS_LIBRARY_DIRS "${blas_lib}" )
+ else()
+ get_filename_component(a_blas_lib_dir "${blas_lib}" PATH)
+ if (EXISTS "${a_blas_lib_dir}")
+ list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" )
+ endif()
+ endif()
+ endif()
+endforeach()
+if (BLAS_LIBRARY_DIRS)
+ list(REMOVE_DUPLICATES BLAS_LIBRARY_DIRS)
+endif ()
+
+# check that BLAS has been found
+# ---------------------------------
+include(FindPackageHandleStandardArgs)
+if(BLA_VENDOR MATCHES "Intel*")
+ if(BLA_VENDOR MATCHES "Intel10_64lp*")
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "BLAS found is Intel MKL:"
+ "\n we manage two lists of libs, one sequential and one parallel if found"
+ "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)")
+ message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
+ endif()
+ find_package_handle_standard_args(BLAS DEFAULT_MSG
+ BLAS_SEQ_LIBRARIES
+ BLAS_LIBRARY_DIRS
+ BLAS_INCLUDE_DIRS)
+ if(BLAS_PAR_LIBRARIES)
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES")
+ endif()
+ find_package_handle_standard_args(BLAS DEFAULT_MSG
+ BLAS_PAR_LIBRARIES)
+ endif()
+ else()
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
+ endif()
+ find_package_handle_standard_args(BLAS DEFAULT_MSG
+ BLAS_SEQ_LIBRARIES
+ BLAS_LIBRARY_DIRS
+ BLAS_INCLUDE_DIRS)
+ endif()
+elseif(BLA_VENDOR MATCHES "ACML*")
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "BLAS found is ACML:"
+ "\n we manage two lists of libs, one sequential and one parallel if found"
+ "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)")
+ message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
+ endif()
+ find_package_handle_standard_args(BLAS DEFAULT_MSG
+ BLAS_SEQ_LIBRARIES
+ BLAS_LIBRARY_DIRS)
+ if(BLAS_PAR_LIBRARIES)
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES")
+ endif()
+ find_package_handle_standard_args(BLAS DEFAULT_MSG
+ BLAS_PAR_LIBRARIES)
+ endif()
+elseif(BLA_VENDOR MATCHES "IBMESSL*")
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "BLAS found is ESSL:"
+ "\n we manage two lists of libs, one sequential and one parallel if found"
+ "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)")
+ message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
+ endif()
+ find_package_handle_standard_args(BLAS DEFAULT_MSG
+ BLAS_SEQ_LIBRARIES
+ BLAS_LIBRARY_DIRS)
+ if(BLAS_PAR_LIBRARIES)
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES")
+ endif()
+ find_package_handle_standard_args(BLAS DEFAULT_MSG
+ BLAS_PAR_LIBRARIES)
+ endif()
+else()
+ if(NOT BLASEXT_FIND_QUIETLY)
+ message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
+ endif()
+ find_package_handle_standard_args(BLAS DEFAULT_MSG
+ BLAS_SEQ_LIBRARIES
+ BLAS_LIBRARY_DIRS)
+endif()
diff --git a/eigen/cmake/FindComputeCpp.cmake b/eigen/cmake/FindComputeCpp.cmake
index 27e5c9b..07ebed6 100644
--- a/eigen/cmake/FindComputeCpp.cmake
+++ b/eigen/cmake/FindComputeCpp.cmake
@@ -138,7 +138,7 @@ else()
message(STATUS "compute++ flags - ${COMPUTECPP_DEVICE_COMPILER_FLAGS}")
endif()
-set(COMPUTECPP_DEVICE_COMPILER_FLAGS ${COMPUTECPP_DEVICE_COMPILER_FLAGS} -sycl-compress-name -Wall -no-serial-memop -DEIGEN_NO_ASSERTION_CHECKING=1)
+set(COMPUTECPP_DEVICE_COMPILER_FLAGS ${COMPUTECPP_DEVICE_COMPILER_FLAGS} -sycl-compress-name -no-serial-memop -DEIGEN_NO_ASSERTION_CHECKING=1)
# Check if the platform is supported
execute_process(COMMAND ${COMPUTECPP_INFO_TOOL} "--dump-is-supported"
diff --git a/eigen/cmake/FindHWLOC.cmake b/eigen/cmake/FindHWLOC.cmake
new file mode 100644
index 0000000..a831b5c
--- /dev/null
+++ b/eigen/cmake/FindHWLOC.cmake
@@ -0,0 +1,331 @@
+###
+#
+# @copyright (c) 2009-2014 The University of Tennessee and The University
+# of Tennessee Research Foundation.
+# All rights reserved.
+# @copyright (c) 2012-2014 Inria. All rights reserved.
+# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
+#
+###
+#
+# - Find HWLOC include dirs and libraries
+# Use this module by invoking find_package with the form:
+# find_package(HWLOC
+# [REQUIRED]) # Fail with error if hwloc is not found
+#
+# This module finds headers and hwloc library.
+# Results are reported in variables:
+# HWLOC_FOUND - True if headers and requested libraries were found
+# HWLOC_INCLUDE_DIRS - hwloc include directories
+# HWLOC_LIBRARY_DIRS - Link directories for hwloc libraries
+# HWLOC_LIBRARIES - hwloc component libraries to be linked
+#
+# The user can give specific paths where to find the libraries adding cmake
+# options at configure (ex: cmake path/to/project -DHWLOC_DIR=path/to/hwloc):
+# HWLOC_DIR - Where to find the base directory of hwloc
+# HWLOC_INCDIR - Where to find the header files
+# HWLOC_LIBDIR - Where to find the library files
+# The module can also look for the following environment variables if paths
+# are not given as cmake variable: HWLOC_DIR, HWLOC_INCDIR, HWLOC_LIBDIR
+
+#=============================================================================
+# Copyright 2012-2013 Inria
+# Copyright 2012-2013 Emmanuel Agullo
+# Copyright 2012-2013 Mathieu Faverge
+# Copyright 2012 Cedric Castagnede
+# Copyright 2013 Florent Pruvost
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file MORSE-Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of Morse, substitute the full
+# License text for the above reference.)
+
+include(CheckStructHasMember)
+include(CheckCSourceCompiles)
+
+if (NOT HWLOC_FOUND)
+ set(HWLOC_DIR "" CACHE PATH "Installation directory of HWLOC library")
+ if (NOT HWLOC_FIND_QUIETLY)
+ message(STATUS "A cache variable, namely HWLOC_DIR, has been set to specify the install directory of HWLOC")
+ endif()
+endif()
+
+set(ENV_HWLOC_DIR "$ENV{HWLOC_DIR}")
+set(ENV_HWLOC_INCDIR "$ENV{HWLOC_INCDIR}")
+set(ENV_HWLOC_LIBDIR "$ENV{HWLOC_LIBDIR}")
+set(HWLOC_GIVEN_BY_USER "FALSE")
+if ( HWLOC_DIR OR ( HWLOC_INCDIR AND HWLOC_LIBDIR) OR ENV_HWLOC_DIR OR (ENV_HWLOC_INCDIR AND ENV_HWLOC_LIBDIR) )
+ set(HWLOC_GIVEN_BY_USER "TRUE")
+endif()
+
+# Optionally use pkg-config to detect include/library dirs (if pkg-config is available)
+# -------------------------------------------------------------------------------------
+include(FindPkgConfig)
+find_package(PkgConfig QUIET)
+if( PKG_CONFIG_EXECUTABLE AND NOT HWLOC_GIVEN_BY_USER )
+
+ pkg_search_module(HWLOC hwloc)
+ if (NOT HWLOC_FIND_QUIETLY)
+ if (HWLOC_FOUND AND HWLOC_LIBRARIES)
+ message(STATUS "Looking for HWLOC - found using PkgConfig")
+ #if(NOT HWLOC_INCLUDE_DIRS)
+ # message("${Magenta}HWLOC_INCLUDE_DIRS is empty using PkgConfig."
+ # "Perhaps the path to hwloc headers is already present in your"
+ # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}")
+ #endif()
+ else()
+ message(STATUS "${Magenta}Looking for HWLOC - not found using PkgConfig."
+ "\n Perhaps you should add the directory containing hwloc.pc to"
+ "\n the PKG_CONFIG_PATH environment variable.${ColourReset}")
+ endif()
+ endif()
+
+endif( PKG_CONFIG_EXECUTABLE AND NOT HWLOC_GIVEN_BY_USER )
+
+if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT HWLOC_FOUND) OR (HWLOC_GIVEN_BY_USER) )
+
+ if (NOT HWLOC_FIND_QUIETLY)
+ message(STATUS "Looking for HWLOC - PkgConfig not used")
+ endif()
+
+ # Looking for include
+ # -------------------
+
+ # Add system include paths to search include
+ # ------------------------------------------
+ unset(_inc_env)
+ if(ENV_HWLOC_INCDIR)
+ list(APPEND _inc_env "${ENV_HWLOC_INCDIR}")
+ elseif(ENV_HWLOC_DIR)
+ list(APPEND _inc_env "${ENV_HWLOC_DIR}")
+ list(APPEND _inc_env "${ENV_HWLOC_DIR}/include")
+ list(APPEND _inc_env "${ENV_HWLOC_DIR}/include/hwloc")
+ else()
+ if(WIN32)
+ string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
+ else()
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ endif()
+ endif()
+ list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
+ list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
+ list(REMOVE_DUPLICATES _inc_env)
+
+ # set paths where to look for
+ set(PATH_TO_LOOK_FOR "${_inc_env}")
+
+ # Try to find the hwloc header in the given paths
+ # -------------------------------------------------
+ # call cmake macro to find the header path
+ if(HWLOC_INCDIR)
+ set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND")
+ find_path(HWLOC_hwloc.h_DIRS
+ NAMES hwloc.h
+ HINTS ${HWLOC_INCDIR})
+ else()
+ if(HWLOC_DIR)
+ set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND")
+ find_path(HWLOC_hwloc.h_DIRS
+ NAMES hwloc.h
+ HINTS ${HWLOC_DIR}
+ PATH_SUFFIXES "include" "include/hwloc")
+ else()
+ set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND")
+ find_path(HWLOC_hwloc.h_DIRS
+ NAMES hwloc.h
+ HINTS ${PATH_TO_LOOK_FOR}
+ PATH_SUFFIXES "hwloc")
+ endif()
+ endif()
+ mark_as_advanced(HWLOC_hwloc.h_DIRS)
+
+ # Add path to cmake variable
+ # ------------------------------------
+ if (HWLOC_hwloc.h_DIRS)
+ set(HWLOC_INCLUDE_DIRS "${HWLOC_hwloc.h_DIRS}")
+ else ()
+ set(HWLOC_INCLUDE_DIRS "HWLOC_INCLUDE_DIRS-NOTFOUND")
+ if(NOT HWLOC_FIND_QUIETLY)
+ message(STATUS "Looking for hwloc -- hwloc.h not found")
+ endif()
+ endif ()
+
+ if (HWLOC_INCLUDE_DIRS)
+ list(REMOVE_DUPLICATES HWLOC_INCLUDE_DIRS)
+ endif ()
+
+
+ # Looking for lib
+ # ---------------
+
+ # Add system library paths to search lib
+ # --------------------------------------
+ unset(_lib_env)
+ if(ENV_HWLOC_LIBDIR)
+ list(APPEND _lib_env "${ENV_HWLOC_LIBDIR}")
+ elseif(ENV_HWLOC_DIR)
+ list(APPEND _lib_env "${ENV_HWLOC_DIR}")
+ list(APPEND _lib_env "${ENV_HWLOC_DIR}/lib")
+ else()
+ if(WIN32)
+ string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
+ else()
+ if(APPLE)
+ string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
+ else()
+ string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
+ endif()
+ list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
+ list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+ endif()
+ endif()
+ list(REMOVE_DUPLICATES _lib_env)
+
+ # set paths where to look for
+ set(PATH_TO_LOOK_FOR "${_lib_env}")
+
+ # Try to find the hwloc lib in the given paths
+ # ----------------------------------------------
+
+ # call cmake macro to find the lib path
+ if(HWLOC_LIBDIR)
+ set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND")
+ find_library(HWLOC_hwloc_LIBRARY
+ NAMES hwloc
+ HINTS ${HWLOC_LIBDIR})
+ else()
+ if(HWLOC_DIR)
+ set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND")
+ find_library(HWLOC_hwloc_LIBRARY
+ NAMES hwloc
+ HINTS ${HWLOC_DIR}
+ PATH_SUFFIXES lib lib32 lib64)
+ else()
+ set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND")
+ find_library(HWLOC_hwloc_LIBRARY
+ NAMES hwloc
+ HINTS ${PATH_TO_LOOK_FOR})
+ endif()
+ endif()
+ mark_as_advanced(HWLOC_hwloc_LIBRARY)
+
+ # If found, add path to cmake variable
+ # ------------------------------------
+ if (HWLOC_hwloc_LIBRARY)
+ get_filename_component(hwloc_lib_path ${HWLOC_hwloc_LIBRARY} PATH)
+ # set cmake variables (respects naming convention)
+ set(HWLOC_LIBRARIES "${HWLOC_hwloc_LIBRARY}")
+ set(HWLOC_LIBRARY_DIRS "${hwloc_lib_path}")
+ else ()
+ set(HWLOC_LIBRARIES "HWLOC_LIBRARIES-NOTFOUND")
+ set(HWLOC_LIBRARY_DIRS "HWLOC_LIBRARY_DIRS-NOTFOUND")
+ if(NOT HWLOC_FIND_QUIETLY)
+ message(STATUS "Looking for hwloc -- lib hwloc not found")
+ endif()
+ endif ()
+
+ if (HWLOC_LIBRARY_DIRS)
+ list(REMOVE_DUPLICATES HWLOC_LIBRARY_DIRS)
+ endif ()
+
+ # check a function to validate the find
+ if(HWLOC_LIBRARIES)
+
+ set(REQUIRED_INCDIRS)
+ set(REQUIRED_LIBDIRS)
+ set(REQUIRED_LIBS)
+
+ # HWLOC
+ if (HWLOC_INCLUDE_DIRS)
+ set(REQUIRED_INCDIRS "${HWLOC_INCLUDE_DIRS}")
+ endif()
+ if (HWLOC_LIBRARY_DIRS)
+ set(REQUIRED_LIBDIRS "${HWLOC_LIBRARY_DIRS}")
+ endif()
+ set(REQUIRED_LIBS "${HWLOC_LIBRARIES}")
+
+ # set required libraries for link
+ set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
+ set(CMAKE_REQUIRED_LIBRARIES)
+ foreach(lib_dir ${REQUIRED_LIBDIRS})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
+ endforeach()
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
+ string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+
+ # test link
+ unset(HWLOC_WORKS CACHE)
+ include(CheckFunctionExists)
+ check_function_exists(hwloc_topology_init HWLOC_WORKS)
+ mark_as_advanced(HWLOC_WORKS)
+
+ if(NOT HWLOC_WORKS)
+ if(NOT HWLOC_FIND_QUIETLY)
+ message(STATUS "Looking for hwloc : test of hwloc_topology_init with hwloc library fails")
+ message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
+ message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
+ message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
+ endif()
+ endif()
+ set(CMAKE_REQUIRED_INCLUDES)
+ set(CMAKE_REQUIRED_FLAGS)
+ set(CMAKE_REQUIRED_LIBRARIES)
+ endif(HWLOC_LIBRARIES)
+
+endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT HWLOC_FOUND) OR (HWLOC_GIVEN_BY_USER) )
+
+if (HWLOC_LIBRARIES)
+ if (HWLOC_LIBRARY_DIRS)
+ list(GET HWLOC_LIBRARY_DIRS 0 first_lib_path)
+ else()
+ list(GET HWLOC_LIBRARIES 0 first_lib)
+ get_filename_component(first_lib_path "${first_lib}" PATH)
+ endif()
+ if (${first_lib_path} MATCHES "/lib(32|64)?$")
+ string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
+ set(HWLOC_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of HWLOC library" FORCE)
+ else()
+ set(HWLOC_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of HWLOC library" FORCE)
+ endif()
+endif()
+mark_as_advanced(HWLOC_DIR)
+mark_as_advanced(HWLOC_DIR_FOUND)
+
+# check that HWLOC has been found
+# -------------------------------
+include(FindPackageHandleStandardArgs)
+if (PKG_CONFIG_EXECUTABLE AND HWLOC_FOUND)
+ find_package_handle_standard_args(HWLOC DEFAULT_MSG
+ HWLOC_LIBRARIES)
+else()
+ find_package_handle_standard_args(HWLOC DEFAULT_MSG
+ HWLOC_LIBRARIES
+ HWLOC_WORKS)
+endif()
+
+if (HWLOC_FOUND)
+ set(HWLOC_SAVE_CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
+ list(APPEND CMAKE_REQUIRED_INCLUDES ${HWLOC_INCLUDE_DIRS})
+
+ # test headers to guess the version
+ check_struct_has_member( "struct hwloc_obj" parent hwloc.h HAVE_HWLOC_PARENT_MEMBER )
+ check_struct_has_member( "struct hwloc_cache_attr_s" size hwloc.h HAVE_HWLOC_CACHE_ATTR )
+ check_c_source_compiles( "#include <hwloc.h>
+ int main(void) { hwloc_obj_t o; o->type = HWLOC_OBJ_PU; return 0;}" HAVE_HWLOC_OBJ_PU)
+ include(CheckLibraryExists)
+ check_library_exists(${HWLOC_LIBRARIES} hwloc_bitmap_free "" HAVE_HWLOC_BITMAP)
+
+ set(CMAKE_REQUIRED_INCLUDES ${HWLOC_SAVE_CMAKE_REQUIRED_INCLUDES})
+endif()
diff --git a/eigen/cmake/FindMetis.cmake b/eigen/cmake/FindMetis.cmake
index 6a0ce79..da2f1f1 100644
--- a/eigen/cmake/FindMetis.cmake
+++ b/eigen/cmake/FindMetis.cmake
@@ -1,59 +1,264 @@
-# Pastix requires METIS or METIS (partitioning and reordering tools)
-
-if (METIS_INCLUDES AND METIS_LIBRARIES)
- set(METIS_FIND_QUIETLY TRUE)
-endif (METIS_INCLUDES AND METIS_LIBRARIES)
-
-find_path(METIS_INCLUDES
- NAMES
- metis.h
- PATHS
- $ENV{METISDIR}
- ${INCLUDE_INSTALL_DIR}
- PATH_SUFFIXES
- .
- metis
- include
-)
-
-macro(_metis_check_version)
- file(READ "${METIS_INCLUDES}/metis.h" _metis_version_header)
-
- string(REGEX MATCH "define[ \t]+METIS_VER_MAJOR[ \t]+([0-9]+)" _metis_major_version_match "${_metis_version_header}")
- set(METIS_MAJOR_VERSION "${CMAKE_MATCH_1}")
- string(REGEX MATCH "define[ \t]+METIS_VER_MINOR[ \t]+([0-9]+)" _metis_minor_version_match "${_metis_version_header}")
- set(METIS_MINOR_VERSION "${CMAKE_MATCH_1}")
- string(REGEX MATCH "define[ \t]+METIS_VER_SUBMINOR[ \t]+([0-9]+)" _metis_subminor_version_match "${_metis_version_header}")
- set(METIS_SUBMINOR_VERSION "${CMAKE_MATCH_1}")
- if(NOT METIS_MAJOR_VERSION)
- message(STATUS "Could not determine Metis version. Assuming version 4.0.0")
- set(METIS_VERSION 4.0.0)
+###
+#
+# @copyright (c) 2009-2014 The University of Tennessee and The University
+# of Tennessee Research Foundation.
+# All rights reserved.
+# @copyright (c) 2012-2014 Inria. All rights reserved.
+# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
+#
+###
+#
+# - Find METIS include dirs and libraries
+# Use this module by invoking find_package with the form:
+# find_package(METIS
+# [REQUIRED] # Fail with error if metis is not found
+# )
+#
+# This module finds headers and metis library.
+# Results are reported in variables:
+# METIS_FOUND - True if headers and requested libraries were found
+# METIS_INCLUDE_DIRS - metis include directories
+# METIS_LIBRARY_DIRS - Link directories for metis libraries
+# METIS_LIBRARIES - metis component libraries to be linked
+#
+# The user can give specific paths where to find the libraries adding cmake
+# options at configure (ex: cmake path/to/project -DMETIS_DIR=path/to/metis):
+# METIS_DIR - Where to find the base directory of metis
+# METIS_INCDIR - Where to find the header files
+# METIS_LIBDIR - Where to find the library files
+# The module can also look for the following environment variables if paths
+# are not given as cmake variable: METIS_DIR, METIS_INCDIR, METIS_LIBDIR
+
+#=============================================================================
+# Copyright 2012-2013 Inria
+# Copyright 2012-2013 Emmanuel Agullo
+# Copyright 2012-2013 Mathieu Faverge
+# Copyright 2012 Cedric Castagnede
+# Copyright 2013 Florent Pruvost
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file MORSE-Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of Morse, substitute the full
+# License text for the above reference.)
+
+if (NOT METIS_FOUND)
+ set(METIS_DIR "" CACHE PATH "Installation directory of METIS library")
+ if (NOT METIS_FIND_QUIETLY)
+ message(STATUS "A cache variable, namely METIS_DIR, has been set to specify the install directory of METIS")
+ endif()
+endif()
+
+# Looking for include
+# -------------------
+
+# Add system include paths to search include
+# ------------------------------------------
+unset(_inc_env)
+set(ENV_METIS_DIR "$ENV{METIS_DIR}")
+set(ENV_METIS_INCDIR "$ENV{METIS_INCDIR}")
+if(ENV_METIS_INCDIR)
+ list(APPEND _inc_env "${ENV_METIS_INCDIR}")
+elseif(ENV_METIS_DIR)
+ list(APPEND _inc_env "${ENV_METIS_DIR}")
+ list(APPEND _inc_env "${ENV_METIS_DIR}/include")
+ list(APPEND _inc_env "${ENV_METIS_DIR}/include/metis")
+else()
+ if(WIN32)
+ string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
else()
- set(METIS_VERSION ${METIS_MAJOR_VERSION}.${METIS_MINOR_VERSION}.${METIS_SUBMINOR_VERSION})
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
endif()
- if(${METIS_VERSION} VERSION_LESS ${Metis_FIND_VERSION})
- set(METIS_VERSION_OK FALSE)
+endif()
+list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
+list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
+list(REMOVE_DUPLICATES _inc_env)
+
+
+# Try to find the metis header in the given paths
+# -------------------------------------------------
+# call cmake macro to find the header path
+if(METIS_INCDIR)
+ set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND")
+ find_path(METIS_metis.h_DIRS
+ NAMES metis.h
+ HINTS ${METIS_INCDIR})
+else()
+ if(METIS_DIR)
+ set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND")
+ find_path(METIS_metis.h_DIRS
+ NAMES metis.h
+ HINTS ${METIS_DIR}
+ PATH_SUFFIXES "include" "include/metis")
else()
- set(METIS_VERSION_OK TRUE)
+ set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND")
+ find_path(METIS_metis.h_DIRS
+ NAMES metis.h
+ HINTS ${_inc_env})
endif()
+endif()
+mark_as_advanced(METIS_metis.h_DIRS)
- if(NOT METIS_VERSION_OK)
- message(STATUS "Metis version ${METIS_VERSION} found in ${METIS_INCLUDES}, "
- "but at least version ${Metis_FIND_VERSION} is required")
- endif(NOT METIS_VERSION_OK)
-endmacro(_metis_check_version)
- if(METIS_INCLUDES AND Metis_FIND_VERSION)
- _metis_check_version()
+# If found, add path to cmake variable
+# ------------------------------------
+if (METIS_metis.h_DIRS)
+ set(METIS_INCLUDE_DIRS "${METIS_metis.h_DIRS}")
+else ()
+ set(METIS_INCLUDE_DIRS "METIS_INCLUDE_DIRS-NOTFOUND")
+ if(NOT METIS_FIND_QUIETLY)
+ message(STATUS "Looking for metis -- metis.h not found")
+ endif()
+endif()
+
+
+# Looking for lib
+# ---------------
+
+# Add system library paths to search lib
+# --------------------------------------
+unset(_lib_env)
+set(ENV_METIS_LIBDIR "$ENV{METIS_LIBDIR}")
+if(ENV_METIS_LIBDIR)
+ list(APPEND _lib_env "${ENV_METIS_LIBDIR}")
+elseif(ENV_METIS_DIR)
+ list(APPEND _lib_env "${ENV_METIS_DIR}")
+ list(APPEND _lib_env "${ENV_METIS_DIR}/lib")
+else()
+ if(WIN32)
+ string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
else()
- set(METIS_VERSION_OK TRUE)
+ if(APPLE)
+ string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
+ else()
+ string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
+ endif()
+ list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
+ list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
endif()
+endif()
+list(REMOVE_DUPLICATES _lib_env)
+
+# Try to find the metis lib in the given paths
+# ----------------------------------------------
+# call cmake macro to find the lib path
+if(METIS_LIBDIR)
+ set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND")
+ find_library(METIS_metis_LIBRARY
+ NAMES metis
+ HINTS ${METIS_LIBDIR})
+else()
+ if(METIS_DIR)
+ set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND")
+ find_library(METIS_metis_LIBRARY
+ NAMES metis
+ HINTS ${METIS_DIR}
+ PATH_SUFFIXES lib lib32 lib64)
+ else()
+ set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND")
+ find_library(METIS_metis_LIBRARY
+ NAMES metis
+ HINTS ${_lib_env})
+ endif()
+endif()
+mark_as_advanced(METIS_metis_LIBRARY)
-find_library(METIS_LIBRARIES metis PATHS $ENV{METISDIR} ${LIB_INSTALL_DIR} PATH_SUFFIXES lib)
+# If found, add path to cmake variable
+# ------------------------------------
+if (METIS_metis_LIBRARY)
+ get_filename_component(metis_lib_path "${METIS_metis_LIBRARY}" PATH)
+ # set cmake variables
+ set(METIS_LIBRARIES "${METIS_metis_LIBRARY}")
+ set(METIS_LIBRARY_DIRS "${metis_lib_path}")
+else ()
+ set(METIS_LIBRARIES "METIS_LIBRARIES-NOTFOUND")
+ set(METIS_LIBRARY_DIRS "METIS_LIBRARY_DIRS-NOTFOUND")
+ if(NOT METIS_FIND_QUIETLY)
+ message(STATUS "Looking for metis -- lib metis not found")
+ endif()
+endif ()
+# check a function to validate the find
+if(METIS_LIBRARIES)
+
+ set(REQUIRED_INCDIRS)
+ set(REQUIRED_LIBDIRS)
+ set(REQUIRED_LIBS)
+
+ # METIS
+ if (METIS_INCLUDE_DIRS)
+ set(REQUIRED_INCDIRS "${METIS_INCLUDE_DIRS}")
+ endif()
+ if (METIS_LIBRARY_DIRS)
+ set(REQUIRED_LIBDIRS "${METIS_LIBRARY_DIRS}")
+ endif()
+ set(REQUIRED_LIBS "${METIS_LIBRARIES}")
+ # m
+ find_library(M_LIBRARY NAMES m)
+ mark_as_advanced(M_LIBRARY)
+ if(M_LIBRARY)
+ list(APPEND REQUIRED_LIBS "-lm")
+ endif()
+
+ # set required libraries for link
+ set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
+ set(CMAKE_REQUIRED_LIBRARIES)
+ foreach(lib_dir ${REQUIRED_LIBDIRS})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
+ endforeach()
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
+ string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+
+ # test link
+ unset(METIS_WORKS CACHE)
+ include(CheckFunctionExists)
+ check_function_exists(METIS_NodeND METIS_WORKS)
+ mark_as_advanced(METIS_WORKS)
+
+ if(NOT METIS_WORKS)
+ if(NOT METIS_FIND_QUIETLY)
+ message(STATUS "Looking for METIS : test of METIS_NodeND with METIS library fails")
+ message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
+ message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
+ message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
+ endif()
+ endif()
+ set(CMAKE_REQUIRED_INCLUDES)
+ set(CMAKE_REQUIRED_FLAGS)
+ set(CMAKE_REQUIRED_LIBRARIES)
+endif(METIS_LIBRARIES)
+
+if (METIS_LIBRARIES)
+ list(GET METIS_LIBRARIES 0 first_lib)
+ get_filename_component(first_lib_path "${first_lib}" PATH)
+ if (${first_lib_path} MATCHES "/lib(32|64)?$")
+ string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
+ set(METIS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of METIS library" FORCE)
+ else()
+ set(METIS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of METIS library" FORCE)
+ endif()
+endif()
+mark_as_advanced(METIS_DIR)
+mark_as_advanced(METIS_DIR_FOUND)
+
+# check that METIS has been found
+# ---------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(METIS DEFAULT_MSG
- METIS_INCLUDES METIS_LIBRARIES METIS_VERSION_OK)
-
-mark_as_advanced(METIS_INCLUDES METIS_LIBRARIES)
+ METIS_LIBRARIES
+ METIS_WORKS)
+#
+# TODO: Add possibility to check for specific functions in the library
+#
diff --git a/eigen/cmake/FindPTSCOTCH.cmake b/eigen/cmake/FindPTSCOTCH.cmake
new file mode 100644
index 0000000..1396d05
--- /dev/null
+++ b/eigen/cmake/FindPTSCOTCH.cmake
@@ -0,0 +1,423 @@
+###
+#
+# @copyright (c) 2009-2014 The University of Tennessee and The University
+# of Tennessee Research Foundation.
+# All rights reserved.
+# @copyright (c) 2012-2016 Inria. All rights reserved.
+# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
+#
+###
+#
+# - Find PTSCOTCH include dirs and libraries
+# Use this module by invoking find_package with the form:
+# find_package(PTSCOTCH
+# [REQUIRED] # Fail with error if ptscotch is not found
+# [COMPONENTS <comp1> <comp2> ...] # dependencies
+# )
+#
+# PTSCOTCH depends on the following libraries:
+# - Threads
+# - MPI
+#
+# COMPONENTS can be some of the following:
+# - ESMUMPS: to activate detection of PT-Scotch with the esmumps interface
+#
+# This module finds headers and ptscotch library.
+# Results are reported in variables:
+# PTSCOTCH_FOUND - True if headers and requested libraries were found
+# PTSCOTCH_LINKER_FLAGS - list of required linker flags (excluding -l and -L)
+# PTSCOTCH_INCLUDE_DIRS - ptscotch include directories
+# PTSCOTCH_LIBRARY_DIRS - Link directories for ptscotch libraries
+# PTSCOTCH_LIBRARIES - ptscotch component libraries to be linked
+# PTSCOTCH_INCLUDE_DIRS_DEP - ptscotch + dependencies include directories
+# PTSCOTCH_LIBRARY_DIRS_DEP - ptscotch + dependencies link directories
+# PTSCOTCH_LIBRARIES_DEP - ptscotch libraries + dependencies
+# PTSCOTCH_INTSIZE - Number of octets occupied by a SCOTCH_Num
+#
+# The user can give specific paths where to find the libraries adding cmake
+# options at configure (ex: cmake path/to/project -DPTSCOTCH=path/to/ptscotch):
+# PTSCOTCH_DIR - Where to find the base directory of ptscotch
+# PTSCOTCH_INCDIR - Where to find the header files
+# PTSCOTCH_LIBDIR - Where to find the library files
+# The module can also look for the following environment variables if paths
+# are not given as cmake variable: PTSCOTCH_DIR, PTSCOTCH_INCDIR, PTSCOTCH_LIBDIR
+
+#=============================================================================
+# Copyright 2012-2013 Inria
+# Copyright 2012-2013 Emmanuel Agullo
+# Copyright 2012-2013 Mathieu Faverge
+# Copyright 2012 Cedric Castagnede
+# Copyright 2013-2016 Florent Pruvost
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file MORSE-Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of Morse, substitute the full
+# License text for the above reference.)
+
+if (NOT PTSCOTCH_FOUND)
+ set(PTSCOTCH_DIR "" CACHE PATH "Installation directory of PTSCOTCH library")
+ if (NOT PTSCOTCH_FIND_QUIETLY)
+ message(STATUS "A cache variable, namely PTSCOTCH_DIR, has been set to specify the install directory of PTSCOTCH")
+ endif()
+endif()
+
+# Set the version to find
+set(PTSCOTCH_LOOK_FOR_ESMUMPS OFF)
+
+if( PTSCOTCH_FIND_COMPONENTS )
+ foreach( component ${PTSCOTCH_FIND_COMPONENTS} )
+ if (${component} STREQUAL "ESMUMPS")
+ # means we look for esmumps library
+ set(PTSCOTCH_LOOK_FOR_ESMUMPS ON)
+ endif()
+ endforeach()
+endif()
+
+# PTSCOTCH depends on Threads, try to find it
+if (NOT THREADS_FOUND)
+ if (PTSCOTCH_FIND_REQUIRED)
+ find_package(Threads REQUIRED)
+ else()
+ find_package(Threads)
+ endif()
+endif()
+
+# PTSCOTCH depends on MPI, try to find it
+if (NOT MPI_FOUND)
+ if (PTSCOTCH_FIND_REQUIRED)
+ find_package(MPI REQUIRED)
+ else()
+ find_package(MPI)
+ endif()
+endif()
+
+# Looking for include
+# -------------------
+
+# Add system include paths to search include
+# ------------------------------------------
+unset(_inc_env)
+set(ENV_PTSCOTCH_DIR "$ENV{PTSCOTCH_DIR}")
+set(ENV_PTSCOTCH_INCDIR "$ENV{PTSCOTCH_INCDIR}")
+if(ENV_PTSCOTCH_INCDIR)
+ list(APPEND _inc_env "${ENV_PTSCOTCH_INCDIR}")
+elseif(ENV_PTSCOTCH_DIR)
+ list(APPEND _inc_env "${ENV_PTSCOTCH_DIR}")
+ list(APPEND _inc_env "${ENV_PTSCOTCH_DIR}/include")
+ list(APPEND _inc_env "${ENV_PTSCOTCH_DIR}/include/ptscotch")
+else()
+ if(WIN32)
+ string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
+ else()
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ endif()
+endif()
+list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
+list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
+list(REMOVE_DUPLICATES _inc_env)
+
+
+# Try to find the ptscotch header in the given paths
+# -------------------------------------------------
+
+set(PTSCOTCH_hdrs_to_find "ptscotch.h;scotch.h")
+
+# call cmake macro to find the header path
+if(PTSCOTCH_INCDIR)
+ foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find})
+ set(PTSCOTCH_${ptscotch_hdr}_DIRS "PTSCOTCH_${ptscotch_hdr}_DIRS-NOTFOUND")
+ find_path(PTSCOTCH_${ptscotch_hdr}_DIRS
+ NAMES ${ptscotch_hdr}
+ HINTS ${PTSCOTCH_INCDIR})
+ mark_as_advanced(PTSCOTCH_${ptscotch_hdr}_DIRS)
+ endforeach()
+else()
+ if(PTSCOTCH_DIR)
+ foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find})
+ set(PTSCOTCH_${ptscotch_hdr}_DIRS "PTSCOTCH_${ptscotch_hdr}_DIRS-NOTFOUND")
+ find_path(PTSCOTCH_${ptscotch_hdr}_DIRS
+ NAMES ${ptscotch_hdr}
+ HINTS ${PTSCOTCH_DIR}
+ PATH_SUFFIXES "include" "include/scotch")
+ mark_as_advanced(PTSCOTCH_${ptscotch_hdr}_DIRS)
+ endforeach()
+ else()
+ foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find})
+ set(PTSCOTCH_${ptscotch_hdr}_DIRS "PTSCOTCH_${ptscotch_hdr}_DIRS-NOTFOUND")
+ find_path(PTSCOTCH_${ptscotch_hdr}_DIRS
+ NAMES ${ptscotch_hdr}
+ HINTS ${_inc_env}
+ PATH_SUFFIXES "scotch")
+ mark_as_advanced(PTSCOTCH_${ptscotch_hdr}_DIRS)
+ endforeach()
+ endif()
+endif()
+
+# If found, add path to cmake variable
+# ------------------------------------
+foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find})
+ if (PTSCOTCH_${ptscotch_hdr}_DIRS)
+ list(APPEND PTSCOTCH_INCLUDE_DIRS "${PTSCOTCH_${ptscotch_hdr}_DIRS}")
+ else ()
+ set(PTSCOTCH_INCLUDE_DIRS "PTSCOTCH_INCLUDE_DIRS-NOTFOUND")
+ if (NOT PTSCOTCH_FIND_QUIETLY)
+ message(STATUS "Looking for ptscotch -- ${ptscotch_hdr} not found")
+ endif()
+ endif()
+endforeach()
+list(REMOVE_DUPLICATES PTSCOTCH_INCLUDE_DIRS)
+
+# Looking for lib
+# ---------------
+
+# Add system library paths to search lib
+# --------------------------------------
+unset(_lib_env)
+set(ENV_PTSCOTCH_LIBDIR "$ENV{PTSCOTCH_LIBDIR}")
+if(ENV_PTSCOTCH_LIBDIR)
+ list(APPEND _lib_env "${ENV_PTSCOTCH_LIBDIR}")
+elseif(ENV_PTSCOTCH_DIR)
+ list(APPEND _lib_env "${ENV_PTSCOTCH_DIR}")
+ list(APPEND _lib_env "${ENV_PTSCOTCH_DIR}/lib")
+else()
+ if(WIN32)
+ string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
+ else()
+ if(APPLE)
+ string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
+ else()
+ string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
+ endif()
+ list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
+ list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+ endif()
+endif()
+list(REMOVE_DUPLICATES _lib_env)
+
+# Try to find the ptscotch lib in the given paths
+# ----------------------------------------------
+
+set(PTSCOTCH_libs_to_find "ptscotch;ptscotcherr")
+if (PTSCOTCH_LOOK_FOR_ESMUMPS)
+ list(INSERT PTSCOTCH_libs_to_find 0 "ptesmumps")
+ list(APPEND PTSCOTCH_libs_to_find "esmumps" )
+endif()
+list(APPEND PTSCOTCH_libs_to_find "scotch;scotcherr")
+
+# call cmake macro to find the lib path
+if(PTSCOTCH_LIBDIR)
+ foreach(ptscotch_lib ${PTSCOTCH_libs_to_find})
+ set(PTSCOTCH_${ptscotch_lib}_LIBRARY "PTSCOTCH_${ptscotch_lib}_LIBRARY-NOTFOUND")
+ find_library(PTSCOTCH_${ptscotch_lib}_LIBRARY
+ NAMES ${ptscotch_lib}
+ HINTS ${PTSCOTCH_LIBDIR})
+ endforeach()
+else()
+ if(PTSCOTCH_DIR)
+ foreach(ptscotch_lib ${PTSCOTCH_libs_to_find})
+ set(PTSCOTCH_${ptscotch_lib}_LIBRARY "PTSCOTCH_${ptscotch_lib}_LIBRARY-NOTFOUND")
+ find_library(PTSCOTCH_${ptscotch_lib}_LIBRARY
+ NAMES ${ptscotch_lib}
+ HINTS ${PTSCOTCH_DIR}
+ PATH_SUFFIXES lib lib32 lib64)
+ endforeach()
+ else()
+ foreach(ptscotch_lib ${PTSCOTCH_libs_to_find})
+ set(PTSCOTCH_${ptscotch_lib}_LIBRARY "PTSCOTCH_${ptscotch_lib}_LIBRARY-NOTFOUND")
+ find_library(PTSCOTCH_${ptscotch_lib}_LIBRARY
+ NAMES ${ptscotch_lib}
+ HINTS ${_lib_env})
+ endforeach()
+ endif()
+endif()
+
+set(PTSCOTCH_LIBRARIES "")
+set(PTSCOTCH_LIBRARY_DIRS "")
+# If found, add path to cmake variable
+# ------------------------------------
+foreach(ptscotch_lib ${PTSCOTCH_libs_to_find})
+
+ if (PTSCOTCH_${ptscotch_lib}_LIBRARY)
+ get_filename_component(${ptscotch_lib}_lib_path "${PTSCOTCH_${ptscotch_lib}_LIBRARY}" PATH)
+ # set cmake variables
+ list(APPEND PTSCOTCH_LIBRARIES "${PTSCOTCH_${ptscotch_lib}_LIBRARY}")
+ list(APPEND PTSCOTCH_LIBRARY_DIRS "${${ptscotch_lib}_lib_path}")
+ else ()
+ list(APPEND PTSCOTCH_LIBRARIES "${PTSCOTCH_${ptscotch_lib}_LIBRARY}")
+ if (NOT PTSCOTCH_FIND_QUIETLY)
+ message(STATUS "Looking for ptscotch -- lib ${ptscotch_lib} not found")
+ endif()
+ endif ()
+
+ mark_as_advanced(PTSCOTCH_${ptscotch_lib}_LIBRARY)
+
+endforeach()
+list(REMOVE_DUPLICATES PTSCOTCH_LIBRARY_DIRS)
+
+# check a function to validate the find
+if(PTSCOTCH_LIBRARIES)
+
+ set(REQUIRED_LDFLAGS)
+ set(REQUIRED_INCDIRS)
+ set(REQUIRED_LIBDIRS)
+ set(REQUIRED_LIBS)
+
+ # PTSCOTCH
+ if (PTSCOTCH_INCLUDE_DIRS)
+ set(REQUIRED_INCDIRS "${PTSCOTCH_INCLUDE_DIRS}")
+ endif()
+ if (PTSCOTCH_LIBRARY_DIRS)
+ set(REQUIRED_LIBDIRS "${PTSCOTCH_LIBRARY_DIRS}")
+ endif()
+ set(REQUIRED_LIBS "${PTSCOTCH_LIBRARIES}")
+ # MPI
+ if (MPI_FOUND)
+ if (MPI_C_INCLUDE_PATH)
+ list(APPEND CMAKE_REQUIRED_INCLUDES "${MPI_C_INCLUDE_PATH}")
+ endif()
+ if (MPI_C_LINK_FLAGS)
+ if (${MPI_C_LINK_FLAGS} MATCHES " -")
+ string(REGEX REPLACE " -" "-" MPI_C_LINK_FLAGS ${MPI_C_LINK_FLAGS})
+ endif()
+ list(APPEND REQUIRED_LDFLAGS "${MPI_C_LINK_FLAGS}")
+ endif()
+ list(APPEND REQUIRED_LIBS "${MPI_C_LIBRARIES}")
+ endif()
+ # THREADS
+ if(CMAKE_THREAD_LIBS_INIT)
+ list(APPEND REQUIRED_LIBS "${CMAKE_THREAD_LIBS_INIT}")
+ endif()
+ set(Z_LIBRARY "Z_LIBRARY-NOTFOUND")
+ find_library(Z_LIBRARY NAMES z)
+ mark_as_advanced(Z_LIBRARY)
+ if(Z_LIBRARY)
+ list(APPEND REQUIRED_LIBS "-lz")
+ endif()
+ set(M_LIBRARY "M_LIBRARY-NOTFOUND")
+ find_library(M_LIBRARY NAMES m)
+ mark_as_advanced(M_LIBRARY)
+ if(M_LIBRARY)
+ list(APPEND REQUIRED_LIBS "-lm")
+ endif()
+ set(RT_LIBRARY "RT_LIBRARY-NOTFOUND")
+ find_library(RT_LIBRARY NAMES rt)
+ mark_as_advanced(RT_LIBRARY)
+ if(RT_LIBRARY)
+ list(APPEND REQUIRED_LIBS "-lrt")
+ endif()
+
+ # set required libraries for link
+ set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
+ set(CMAKE_REQUIRED_LIBRARIES)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}")
+ foreach(lib_dir ${REQUIRED_LIBDIRS})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
+ endforeach()
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
+ list(APPEND CMAKE_REQUIRED_FLAGS "${REQUIRED_FLAGS}")
+ string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+
+ # test link
+ unset(PTSCOTCH_WORKS CACHE)
+ include(CheckFunctionExists)
+ check_function_exists(SCOTCH_dgraphInit PTSCOTCH_WORKS)
+ mark_as_advanced(PTSCOTCH_WORKS)
+
+ if(PTSCOTCH_WORKS)
+ # save link with dependencies
+ set(PTSCOTCH_LIBRARIES_DEP "${REQUIRED_LIBS}")
+ set(PTSCOTCH_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}")
+ set(PTSCOTCH_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}")
+ set(PTSCOTCH_LINKER_FLAGS "${REQUIRED_LDFLAGS}")
+ list(REMOVE_DUPLICATES PTSCOTCH_LIBRARY_DIRS_DEP)
+ list(REMOVE_DUPLICATES PTSCOTCH_INCLUDE_DIRS_DEP)
+ list(REMOVE_DUPLICATES PTSCOTCH_LINKER_FLAGS)
+ else()
+ if(NOT PTSCOTCH_FIND_QUIETLY)
+ message(STATUS "Looking for PTSCOTCH : test of SCOTCH_dgraphInit with PTSCOTCH library fails")
+ message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
+ message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
+ message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
+ endif()
+ endif()
+ set(CMAKE_REQUIRED_INCLUDES)
+ set(CMAKE_REQUIRED_FLAGS)
+ set(CMAKE_REQUIRED_LIBRARIES)
+endif(PTSCOTCH_LIBRARIES)
+
+if (PTSCOTCH_LIBRARIES)
+ list(GET PTSCOTCH_LIBRARIES 0 first_lib)
+ get_filename_component(first_lib_path "${first_lib}" PATH)
+ if (${first_lib_path} MATCHES "/lib(32|64)?$")
+ string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
+ set(PTSCOTCH_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of PTSCOTCH library" FORCE)
+ else()
+ set(PTSCOTCH_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of PTSCOTCH library" FORCE)
+ endif()
+endif()
+mark_as_advanced(PTSCOTCH_DIR)
+mark_as_advanced(PTSCOTCH_DIR_FOUND)
+
+# Check the size of SCOTCH_Num
+# ---------------------------------
+set(CMAKE_REQUIRED_INCLUDES ${PTSCOTCH_INCLUDE_DIRS})
+
+include(CheckCSourceRuns)
+#stdio.h and stdint.h should be included by scotch.h directly
+set(PTSCOTCH_C_TEST_SCOTCH_Num_4 "
+#include <stdio.h>
+#include <stdint.h>
+#include <ptscotch.h>
+int main(int argc, char **argv) {
+ if (sizeof(SCOTCH_Num) == 4)
+ return 0;
+ else
+ return 1;
+}
+")
+
+set(PTSCOTCH_C_TEST_SCOTCH_Num_8 "
+#include <stdio.h>
+#include <stdint.h>
+#include <ptscotch.h>
+int main(int argc, char **argv) {
+ if (sizeof(SCOTCH_Num) == 8)
+ return 0;
+ else
+ return 1;
+}
+")
+check_c_source_runs("${PTSCOTCH_C_TEST_SCOTCH_Num_4}" PTSCOTCH_Num_4)
+if(NOT PTSCOTCH_Num_4)
+ check_c_source_runs("${PTSCOTCH_C_TEST_SCOTCH_Num_8}" PTSCOTCH_Num_8)
+ if(NOT PTSCOTCH_Num_8)
+ set(PTSCOTCH_INTSIZE -1)
+ else()
+ set(PTSCOTCH_INTSIZE 8)
+ endif()
+else()
+ set(PTSCOTCH_INTSIZE 4)
+endif()
+set(CMAKE_REQUIRED_INCLUDES "")
+
+# check that PTSCOTCH has been found
+# ---------------------------------
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(PTSCOTCH DEFAULT_MSG
+ PTSCOTCH_LIBRARIES
+ PTSCOTCH_WORKS)
+#
+# TODO: Add possibility to check for specific functions in the library
+#
diff --git a/eigen/cmake/FindPastix.cmake b/eigen/cmake/FindPastix.cmake
index e2e6c81..470477f 100644
--- a/eigen/cmake/FindPastix.cmake
+++ b/eigen/cmake/FindPastix.cmake
@@ -1,25 +1,704 @@
-# Pastix lib requires linking to a blas library.
-# It is up to the user of this module to find a BLAS and link to it.
-# Pastix requires SCOTCH or METIS (partitioning and reordering tools) as well
+###
+#
+# @copyright (c) 2009-2014 The University of Tennessee and The University
+# of Tennessee Research Foundation.
+# All rights reserved.
+# @copyright (c) 2012-2014 Inria. All rights reserved.
+# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
+#
+###
+#
+# - Find PASTIX include dirs and libraries
+# Use this module by invoking find_package with the form:
+# find_package(PASTIX
+# [REQUIRED] # Fail with error if pastix is not found
+# [COMPONENTS <comp1> <comp2> ...] # dependencies
+# )
+#
+# PASTIX depends on the following libraries:
+# - Threads, m, rt
+# - MPI
+# - HWLOC
+# - BLAS
+#
+# COMPONENTS are optional libraries PASTIX could be linked with,
+# Use it to drive detection of a specific compilation chain
+# COMPONENTS can be some of the following:
+# - MPI: to activate detection of the parallel MPI version (default)
+# it looks for Threads, HWLOC, BLAS, MPI and ScaLAPACK libraries
+# - SEQ: to activate detection of the sequential version (exclude MPI version)
+# - STARPU: to activate detection of StarPU version
+# it looks for MPI version of StarPU (default behaviour)
+# if SEQ and STARPU are given, it looks for a StarPU without MPI
+# - STARPU_CUDA: to activate detection of StarPU with CUDA
+# - STARPU_FXT: to activate detection of StarPU with FxT
+# - SCOTCH: to activate detection of PASTIX linked with SCOTCH
+# - PTSCOTCH: to activate detection of PASTIX linked with SCOTCH
+# - METIS: to activate detection of PASTIX linked with SCOTCH
+#
+# This module finds headers and pastix library.
+# Results are reported in variables:
+# PASTIX_FOUND - True if headers and requested libraries were found
+# PASTIX_LINKER_FLAGS - list of required linker flags (excluding -l and -L)
+# PASTIX_INCLUDE_DIRS - pastix include directories
+# PASTIX_LIBRARY_DIRS - Link directories for pastix libraries
+# PASTIX_LIBRARIES - pastix libraries
+# PASTIX_INCLUDE_DIRS_DEP - pastix + dependencies include directories
+# PASTIX_LIBRARY_DIRS_DEP - pastix + dependencies link directories
+# PASTIX_LIBRARIES_DEP - pastix libraries + dependencies
+#
+# The user can give specific paths where to find the libraries adding cmake
+# options at configure (ex: cmake path/to/project -DPASTIX_DIR=path/to/pastix):
+# PASTIX_DIR - Where to find the base directory of pastix
+# PASTIX_INCDIR - Where to find the header files
+# PASTIX_LIBDIR - Where to find the library files
+# The module can also look for the following environment variables if paths
+# are not given as cmake variable: PASTIX_DIR, PASTIX_INCDIR, PASTIX_LIBDIR
-if (PASTIX_INCLUDES AND PASTIX_LIBRARIES)
- set(PASTIX_FIND_QUIETLY TRUE)
-endif (PASTIX_INCLUDES AND PASTIX_LIBRARIES)
+#=============================================================================
+# Copyright 2012-2013 Inria
+# Copyright 2012-2013 Emmanuel Agullo
+# Copyright 2012-2013 Mathieu Faverge
+# Copyright 2012 Cedric Castagnede
+# Copyright 2013 Florent Pruvost
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file MORSE-Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of Morse, substitute the full
+# License text for the above reference.)
-find_path(PASTIX_INCLUDES
- NAMES
- pastix_nompi.h
- PATHS
- $ENV{PASTIXDIR}
- ${INCLUDE_INSTALL_DIR}
-)
-find_library(PASTIX_LIBRARIES pastix PATHS $ENV{PASTIXDIR} ${LIB_INSTALL_DIR})
+if (NOT PASTIX_FOUND)
+ set(PASTIX_DIR "" CACHE PATH "Installation directory of PASTIX library")
+ if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "A cache variable, namely PASTIX_DIR, has been set to specify the install directory of PASTIX")
+ endif()
+endif()
+# Set the version to find
+set(PASTIX_LOOK_FOR_MPI ON)
+set(PASTIX_LOOK_FOR_SEQ OFF)
+set(PASTIX_LOOK_FOR_STARPU OFF)
+set(PASTIX_LOOK_FOR_STARPU_CUDA OFF)
+set(PASTIX_LOOK_FOR_STARPU_FXT OFF)
+set(PASTIX_LOOK_FOR_SCOTCH ON)
+set(PASTIX_LOOK_FOR_PTSCOTCH OFF)
+set(PASTIX_LOOK_FOR_METIS OFF)
+if( PASTIX_FIND_COMPONENTS )
+ foreach( component ${PASTIX_FIND_COMPONENTS} )
+ if (${component} STREQUAL "SEQ")
+ # means we look for the sequential version of PaStiX (without MPI)
+ set(PASTIX_LOOK_FOR_SEQ ON)
+ set(PASTIX_LOOK_FOR_MPI OFF)
+ endif()
+ if (${component} STREQUAL "MPI")
+ # means we look for the MPI version of PaStiX (default)
+ set(PASTIX_LOOK_FOR_SEQ OFF)
+ set(PASTIX_LOOK_FOR_MPI ON)
+ endif()
+ if (${component} STREQUAL "STARPU")
+ # means we look for PaStiX with StarPU
+ set(PASTIX_LOOK_FOR_STARPU ON)
+ endif()
+ if (${component} STREQUAL "STARPU_CUDA")
+ # means we look for PaStiX with StarPU + CUDA
+ set(PASTIX_LOOK_FOR_STARPU ON)
+ set(PASTIX_LOOK_FOR_STARPU_CUDA ON)
+ endif()
+ if (${component} STREQUAL "STARPU_FXT")
+ # means we look for PaStiX with StarPU + FxT
+ set(PASTIX_LOOK_FOR_STARPU_FXT ON)
+ endif()
+ if (${component} STREQUAL "SCOTCH")
+ set(PASTIX_LOOK_FOR_SCOTCH ON)
+ endif()
+ if (${component} STREQUAL "SCOTCH")
+ set(PASTIX_LOOK_FOR_PTSCOTCH ON)
+ endif()
+ if (${component} STREQUAL "METIS")
+ set(PASTIX_LOOK_FOR_METIS ON)
+ endif()
+ endforeach()
+endif()
+# Dependencies detection
+# ----------------------
+
+
+# Required dependencies
+# ---------------------
+
+if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect pthread")
+endif()
+if (PASTIX_FIND_REQUIRED)
+ find_package(Threads REQUIRED QUIET)
+else()
+ find_package(Threads QUIET)
+endif()
+set(PASTIX_EXTRA_LIBRARIES "")
+if( THREADS_FOUND )
+ list(APPEND PASTIX_EXTRA_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+endif ()
+
+# Add math library to the list of extra
+# it normally exists on all common systems provided with a C compiler
+if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect libm")
+endif()
+set(PASTIX_M_LIBRARIES "")
+if(UNIX OR WIN32)
+ find_library(
+ PASTIX_M_m_LIBRARY
+ NAMES m
+ )
+ mark_as_advanced(PASTIX_M_m_LIBRARY)
+ if (PASTIX_M_m_LIBRARY)
+ list(APPEND PASTIX_M_LIBRARIES "${PASTIX_M_m_LIBRARY}")
+ list(APPEND PASTIX_EXTRA_LIBRARIES "${PASTIX_M_m_LIBRARY}")
+ else()
+ if (PASTIX_FIND_REQUIRED)
+ message(FATAL_ERROR "Could NOT find libm on your system."
+ "Are you sure to a have a C compiler installed?")
+ endif()
+ endif()
+endif()
+
+# Try to find librt (libposix4 - POSIX.1b Realtime Extensions library)
+# on Unix systems except Apple ones because it does not exist on it
+if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect librt")
+endif()
+set(PASTIX_RT_LIBRARIES "")
+if(UNIX AND NOT APPLE)
+ find_library(
+ PASTIX_RT_rt_LIBRARY
+ NAMES rt
+ )
+ mark_as_advanced(PASTIX_RT_rt_LIBRARY)
+ if (PASTIX_RT_rt_LIBRARY)
+ list(APPEND PASTIX_RT_LIBRARIES "${PASTIX_RT_rt_LIBRARY}")
+ list(APPEND PASTIX_EXTRA_LIBRARIES "${PASTIX_RT_rt_LIBRARY}")
+ else()
+ if (PASTIX_FIND_REQUIRED)
+ message(FATAL_ERROR "Could NOT find librt on your system")
+ endif()
+ endif()
+endif()
+
+# PASTIX depends on HWLOC
+#------------------------
+if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect HWLOC")
+endif()
+if (PASTIX_FIND_REQUIRED)
+ find_package(HWLOC REQUIRED QUIET)
+else()
+ find_package(HWLOC QUIET)
+endif()
+
+# PASTIX depends on BLAS
+#-----------------------
+if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect BLAS")
+endif()
+if (PASTIX_FIND_REQUIRED)
+ find_package(BLASEXT REQUIRED QUIET)
+else()
+ find_package(BLASEXT QUIET)
+endif()
+
+# Optional dependencies
+# ---------------------
+
+# PASTIX may depend on MPI
+#-------------------------
+if (NOT MPI_FOUND AND PASTIX_LOOK_FOR_MPI)
+ if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect MPI")
+ endif()
+ # allows to use an external mpi compilation by setting compilers with
+ # -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90
+ # at cmake configure
+ if(NOT MPI_C_COMPILER)
+ set(MPI_C_COMPILER mpicc)
+ endif()
+ if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_MPI)
+ find_package(MPI REQUIRED QUIET)
+ else()
+ find_package(MPI QUIET)
+ endif()
+ if (MPI_FOUND)
+ mark_as_advanced(MPI_LIBRARY)
+ mark_as_advanced(MPI_EXTRA_LIBRARY)
+ endif()
+endif (NOT MPI_FOUND AND PASTIX_LOOK_FOR_MPI)
+
+# PASTIX may depend on STARPU
+#----------------------------
+if( NOT STARPU_FOUND AND PASTIX_LOOK_FOR_STARPU)
+
+ if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect StarPU")
+ endif()
+
+ set(PASTIX_STARPU_VERSION "1.1" CACHE STRING "oldest STARPU version desired")
+
+ # create list of components in order to make a single call to find_package(starpu...)
+ # we explicitly need a StarPU version built with hwloc
+ set(STARPU_COMPONENT_LIST "HWLOC")
+
+ # StarPU may depend on MPI
+ # allows to use an external mpi compilation by setting compilers with
+ # -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90
+ # at cmake configure
+ if (PASTIX_LOOK_FOR_MPI)
+ if(NOT MPI_C_COMPILER)
+ set(MPI_C_COMPILER mpicc)
+ endif()
+ list(APPEND STARPU_COMPONENT_LIST "MPI")
+ endif()
+ if (PASTIX_LOOK_FOR_STARPU_CUDA)
+ list(APPEND STARPU_COMPONENT_LIST "CUDA")
+ endif()
+ if (PASTIX_LOOK_FOR_STARPU_FXT)
+ list(APPEND STARPU_COMPONENT_LIST "FXT")
+ endif()
+ # set the list of optional dependencies we may discover
+ if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_STARPU)
+ find_package(STARPU ${PASTIX_STARPU_VERSION} REQUIRED
+ COMPONENTS ${STARPU_COMPONENT_LIST})
+ else()
+ find_package(STARPU ${PASTIX_STARPU_VERSION}
+ COMPONENTS ${STARPU_COMPONENT_LIST})
+ endif()
+
+endif( NOT STARPU_FOUND AND PASTIX_LOOK_FOR_STARPU)
+
+# PASTIX may depends on SCOTCH
+#-----------------------------
+if (NOT SCOTCH_FOUND AND PASTIX_LOOK_FOR_SCOTCH)
+ if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect SCOTCH")
+ endif()
+ if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_SCOTCH)
+ find_package(SCOTCH REQUIRED QUIET)
+ else()
+ find_package(SCOTCH QUIET)
+ endif()
+endif()
+
+# PASTIX may depends on PTSCOTCH
+#-------------------------------
+if (NOT PTSCOTCH_FOUND AND PASTIX_LOOK_FOR_PTSCOTCH)
+ if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect PTSCOTCH")
+ endif()
+ if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_PTSCOTCH)
+ find_package(PTSCOTCH REQUIRED QUIET)
+ else()
+ find_package(PTSCOTCH QUIET)
+ endif()
+endif()
+
+# PASTIX may depends on METIS
+#----------------------------
+if (NOT METIS_FOUND AND PASTIX_LOOK_FOR_METIS)
+ if (NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX - Try to detect METIS")
+ endif()
+ if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_METIS)
+ find_package(METIS REQUIRED QUIET)
+ else()
+ find_package(METIS QUIET)
+ endif()
+endif()
+
+# Error if pastix required and no partitioning lib found
+if (PASTIX_FIND_REQUIRED AND NOT SCOTCH_FOUND AND NOT PTSCOTCH_FOUND AND NOT METIS_FOUND)
+ message(FATAL_ERROR "Could NOT find any partitioning library on your system"
+ " (install scotch, ptscotch or metis)")
+endif()
+
+
+# Looking for PaStiX
+# ------------------
+
+# Looking for include
+# -------------------
+
+# Add system include paths to search include
+# ------------------------------------------
+unset(_inc_env)
+set(ENV_PASTIX_DIR "$ENV{PASTIX_DIR}")
+set(ENV_PASTIX_INCDIR "$ENV{PASTIX_INCDIR}")
+if(ENV_PASTIX_INCDIR)
+ list(APPEND _inc_env "${ENV_PASTIX_INCDIR}")
+elseif(ENV_PASTIX_DIR)
+ list(APPEND _inc_env "${ENV_PASTIX_DIR}")
+ list(APPEND _inc_env "${ENV_PASTIX_DIR}/include")
+ list(APPEND _inc_env "${ENV_PASTIX_DIR}/include/pastix")
+else()
+ if(WIN32)
+ string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
+ else()
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ endif()
+endif()
+list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
+list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
+list(REMOVE_DUPLICATES _inc_env)
+
+
+# Try to find the pastix header in the given paths
+# ---------------------------------------------------
+# call cmake macro to find the header path
+if(PASTIX_INCDIR)
+ set(PASTIX_pastix.h_DIRS "PASTIX_pastix.h_DIRS-NOTFOUND")
+ find_path(PASTIX_pastix.h_DIRS
+ NAMES pastix.h
+ HINTS ${PASTIX_INCDIR})
+else()
+ if(PASTIX_DIR)
+ set(PASTIX_pastix.h_DIRS "PASTIX_pastix.h_DIRS-NOTFOUND")
+ find_path(PASTIX_pastix.h_DIRS
+ NAMES pastix.h
+ HINTS ${PASTIX_DIR}
+ PATH_SUFFIXES "include" "include/pastix")
+ else()
+ set(PASTIX_pastix.h_DIRS "PASTIX_pastix.h_DIRS-NOTFOUND")
+ find_path(PASTIX_pastix.h_DIRS
+ NAMES pastix.h
+ HINTS ${_inc_env}
+ PATH_SUFFIXES "pastix")
+ endif()
+endif()
+mark_as_advanced(PASTIX_pastix.h_DIRS)
+
+# If found, add path to cmake variable
+# ------------------------------------
+if (PASTIX_pastix.h_DIRS)
+ set(PASTIX_INCLUDE_DIRS "${PASTIX_pastix.h_DIRS}")
+else ()
+ set(PASTIX_INCLUDE_DIRS "PASTIX_INCLUDE_DIRS-NOTFOUND")
+ if(NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for pastix -- pastix.h not found")
+ endif()
+endif()
+
+
+# Looking for lib
+# ---------------
+
+# Add system library paths to search lib
+# --------------------------------------
+unset(_lib_env)
+set(ENV_PASTIX_LIBDIR "$ENV{PASTIX_LIBDIR}")
+if(ENV_PASTIX_LIBDIR)
+ list(APPEND _lib_env "${ENV_PASTIX_LIBDIR}")
+elseif(ENV_PASTIX_DIR)
+ list(APPEND _lib_env "${ENV_PASTIX_DIR}")
+ list(APPEND _lib_env "${ENV_PASTIX_DIR}/lib")
+else()
+ if(WIN32)
+ string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
+ else()
+ if(APPLE)
+ string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
+ else()
+ string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
+ endif()
+ list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
+ list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+ endif()
+endif()
+list(REMOVE_DUPLICATES _lib_env)
+
+# Try to find the pastix lib in the given paths
+# ------------------------------------------------
+
+# create list of libs to find
+set(PASTIX_libs_to_find "pastix_murge;pastix")
+
+# call cmake macro to find the lib path
+if(PASTIX_LIBDIR)
+ foreach(pastix_lib ${PASTIX_libs_to_find})
+ set(PASTIX_${pastix_lib}_LIBRARY "PASTIX_${pastix_lib}_LIBRARY-NOTFOUND")
+ find_library(PASTIX_${pastix_lib}_LIBRARY
+ NAMES ${pastix_lib}
+ HINTS ${PASTIX_LIBDIR})
+ endforeach()
+else()
+ if(PASTIX_DIR)
+ foreach(pastix_lib ${PASTIX_libs_to_find})
+ set(PASTIX_${pastix_lib}_LIBRARY "PASTIX_${pastix_lib}_LIBRARY-NOTFOUND")
+ find_library(PASTIX_${pastix_lib}_LIBRARY
+ NAMES ${pastix_lib}
+ HINTS ${PASTIX_DIR}
+ PATH_SUFFIXES lib lib32 lib64)
+ endforeach()
+ else()
+ foreach(pastix_lib ${PASTIX_libs_to_find})
+ set(PASTIX_${pastix_lib}_LIBRARY "PASTIX_${pastix_lib}_LIBRARY-NOTFOUND")
+ find_library(PASTIX_${pastix_lib}_LIBRARY
+ NAMES ${pastix_lib}
+ HINTS ${_lib_env})
+ endforeach()
+ endif()
+endif()
+
+# If found, add path to cmake variable
+# ------------------------------------
+foreach(pastix_lib ${PASTIX_libs_to_find})
+
+ get_filename_component(${pastix_lib}_lib_path ${PASTIX_${pastix_lib}_LIBRARY} PATH)
+ # set cmake variables (respects naming convention)
+ if (PASTIX_LIBRARIES)
+ list(APPEND PASTIX_LIBRARIES "${PASTIX_${pastix_lib}_LIBRARY}")
+ else()
+ set(PASTIX_LIBRARIES "${PASTIX_${pastix_lib}_LIBRARY}")
+ endif()
+ if (PASTIX_LIBRARY_DIRS)
+ list(APPEND PASTIX_LIBRARY_DIRS "${${pastix_lib}_lib_path}")
+ else()
+ set(PASTIX_LIBRARY_DIRS "${${pastix_lib}_lib_path}")
+ endif()
+ mark_as_advanced(PASTIX_${pastix_lib}_LIBRARY)
+
+endforeach(pastix_lib ${PASTIX_libs_to_find})
+
+# check a function to validate the find
+if(PASTIX_LIBRARIES)
+
+ set(REQUIRED_LDFLAGS)
+ set(REQUIRED_INCDIRS)
+ set(REQUIRED_LIBDIRS)
+ set(REQUIRED_LIBS)
+
+ # PASTIX
+ if (PASTIX_INCLUDE_DIRS)
+ set(REQUIRED_INCDIRS "${PASTIX_INCLUDE_DIRS}")
+ endif()
+ foreach(libdir ${PASTIX_LIBRARY_DIRS})
+ if (libdir)
+ list(APPEND REQUIRED_LIBDIRS "${libdir}")
+ endif()
+ endforeach()
+ set(REQUIRED_LIBS "${PASTIX_LIBRARIES}")
+ # STARPU
+ if (PASTIX_LOOK_FOR_STARPU AND STARPU_FOUND)
+ if (STARPU_INCLUDE_DIRS_DEP)
+ list(APPEND REQUIRED_INCDIRS "${STARPU_INCLUDE_DIRS_DEP}")
+ elseif (STARPU_INCLUDE_DIRS)
+ list(APPEND REQUIRED_INCDIRS "${STARPU_INCLUDE_DIRS}")
+ endif()
+ if(STARPU_LIBRARY_DIRS_DEP)
+ list(APPEND REQUIRED_LIBDIRS "${STARPU_LIBRARY_DIRS_DEP}")
+ elseif(STARPU_LIBRARY_DIRS)
+ list(APPEND REQUIRED_LIBDIRS "${STARPU_LIBRARY_DIRS}")
+ endif()
+ if (STARPU_LIBRARIES_DEP)
+ list(APPEND REQUIRED_LIBS "${STARPU_LIBRARIES_DEP}")
+ elseif (STARPU_LIBRARIES)
+ foreach(lib ${STARPU_LIBRARIES})
+ if (EXISTS ${lib} OR ${lib} MATCHES "^-")
+ list(APPEND REQUIRED_LIBS "${lib}")
+ else()
+ list(APPEND REQUIRED_LIBS "-l${lib}")
+ endif()
+ endforeach()
+ endif()
+ endif()
+ # CUDA
+ if (PASTIX_LOOK_FOR_STARPU_CUDA AND CUDA_FOUND)
+ if (CUDA_INCLUDE_DIRS)
+ list(APPEND REQUIRED_INCDIRS "${CUDA_INCLUDE_DIRS}")
+ endif()
+ foreach(libdir ${CUDA_LIBRARY_DIRS})
+ if (libdir)
+ list(APPEND REQUIRED_LIBDIRS "${libdir}")
+ endif()
+ endforeach()
+ list(APPEND REQUIRED_LIBS "${CUDA_CUBLAS_LIBRARIES};${CUDA_LIBRARIES}")
+ endif()
+ # MPI
+ if (PASTIX_LOOK_FOR_MPI AND MPI_FOUND)
+ if (MPI_C_INCLUDE_PATH)
+ list(APPEND REQUIRED_INCDIRS "${MPI_C_INCLUDE_PATH}")
+ endif()
+ if (MPI_C_LINK_FLAGS)
+ if (${MPI_C_LINK_FLAGS} MATCHES " -")
+ string(REGEX REPLACE " -" "-" MPI_C_LINK_FLAGS ${MPI_C_LINK_FLAGS})
+ endif()
+ list(APPEND REQUIRED_LDFLAGS "${MPI_C_LINK_FLAGS}")
+ endif()
+ list(APPEND REQUIRED_LIBS "${MPI_C_LIBRARIES}")
+ endif()
+ # HWLOC
+ if (HWLOC_FOUND)
+ if (HWLOC_INCLUDE_DIRS)
+ list(APPEND REQUIRED_INCDIRS "${HWLOC_INCLUDE_DIRS}")
+ endif()
+ foreach(libdir ${HWLOC_LIBRARY_DIRS})
+ if (libdir)
+ list(APPEND REQUIRED_LIBDIRS "${libdir}")
+ endif()
+ endforeach()
+ foreach(lib ${HWLOC_LIBRARIES})
+ if (EXISTS ${lib} OR ${lib} MATCHES "^-")
+ list(APPEND REQUIRED_LIBS "${lib}")
+ else()
+ list(APPEND REQUIRED_LIBS "-l${lib}")
+ endif()
+ endforeach()
+ endif()
+ # BLAS
+ if (BLAS_FOUND)
+ if (BLAS_INCLUDE_DIRS)
+ list(APPEND REQUIRED_INCDIRS "${BLAS_INCLUDE_DIRS}")
+ endif()
+ foreach(libdir ${BLAS_LIBRARY_DIRS})
+ if (libdir)
+ list(APPEND REQUIRED_LIBDIRS "${libdir}")
+ endif()
+ endforeach()
+ list(APPEND REQUIRED_LIBS "${BLAS_LIBRARIES}")
+ if (BLAS_LINKER_FLAGS)
+ list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}")
+ endif()
+ endif()
+ # SCOTCH
+ if (PASTIX_LOOK_FOR_SCOTCH AND SCOTCH_FOUND)
+ if (SCOTCH_INCLUDE_DIRS)
+ list(APPEND REQUIRED_INCDIRS "${SCOTCH_INCLUDE_DIRS}")
+ endif()
+ foreach(libdir ${SCOTCH_LIBRARY_DIRS})
+ if (libdir)
+ list(APPEND REQUIRED_LIBDIRS "${libdir}")
+ endif()
+ endforeach()
+ list(APPEND REQUIRED_LIBS "${SCOTCH_LIBRARIES}")
+ endif()
+ # PTSCOTCH
+ if (PASTIX_LOOK_FOR_PTSCOTCH AND PTSCOTCH_FOUND)
+ if (PTSCOTCH_INCLUDE_DIRS)
+ list(APPEND REQUIRED_INCDIRS "${PTSCOTCH_INCLUDE_DIRS}")
+ endif()
+ foreach(libdir ${PTSCOTCH_LIBRARY_DIRS})
+ if (libdir)
+ list(APPEND REQUIRED_LIBDIRS "${libdir}")
+ endif()
+ endforeach()
+ list(APPEND REQUIRED_LIBS "${PTSCOTCH_LIBRARIES}")
+ endif()
+ # METIS
+ if (PASTIX_LOOK_FOR_METIS AND METIS_FOUND)
+ if (METIS_INCLUDE_DIRS)
+ list(APPEND REQUIRED_INCDIRS "${METIS_INCLUDE_DIRS}")
+ endif()
+ foreach(libdir ${METIS_LIBRARY_DIRS})
+ if (libdir)
+ list(APPEND REQUIRED_LIBDIRS "${libdir}")
+ endif()
+ endforeach()
+ list(APPEND REQUIRED_LIBS "${METIS_LIBRARIES}")
+ endif()
+ # Fortran
+ if (CMAKE_C_COMPILER_ID MATCHES "GNU")
+ find_library(
+ FORTRAN_gfortran_LIBRARY
+ NAMES gfortran
+ HINTS ${_lib_env}
+ )
+ mark_as_advanced(FORTRAN_gfortran_LIBRARY)
+ if (FORTRAN_gfortran_LIBRARY)
+ list(APPEND REQUIRED_LIBS "${FORTRAN_gfortran_LIBRARY}")
+ endif()
+ elseif (CMAKE_C_COMPILER_ID MATCHES "Intel")
+ find_library(
+ FORTRAN_ifcore_LIBRARY
+ NAMES ifcore
+ HINTS ${_lib_env}
+ )
+ mark_as_advanced(FORTRAN_ifcore_LIBRARY)
+ if (FORTRAN_ifcore_LIBRARY)
+ list(APPEND REQUIRED_LIBS "${FORTRAN_ifcore_LIBRARY}")
+ endif()
+ endif()
+ # EXTRA LIBS such that pthread, m, rt
+ list(APPEND REQUIRED_LIBS ${PASTIX_EXTRA_LIBRARIES})
+
+ # set required libraries for link
+ set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
+ set(CMAKE_REQUIRED_LIBRARIES)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}")
+ foreach(lib_dir ${REQUIRED_LIBDIRS})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
+ endforeach()
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
+ list(APPEND CMAKE_REQUIRED_FLAGS "${REQUIRED_FLAGS}")
+ string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+
+ # test link
+ unset(PASTIX_WORKS CACHE)
+ include(CheckFunctionExists)
+ check_function_exists(pastix PASTIX_WORKS)
+ mark_as_advanced(PASTIX_WORKS)
+
+ if(PASTIX_WORKS)
+ # save link with dependencies
+ set(PASTIX_LIBRARIES_DEP "${REQUIRED_LIBS}")
+ set(PASTIX_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}")
+ set(PASTIX_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}")
+ set(PASTIX_LINKER_FLAGS "${REQUIRED_LDFLAGS}")
+ list(REMOVE_DUPLICATES PASTIX_LIBRARY_DIRS_DEP)
+ list(REMOVE_DUPLICATES PASTIX_INCLUDE_DIRS_DEP)
+ list(REMOVE_DUPLICATES PASTIX_LINKER_FLAGS)
+ else()
+ if(NOT PASTIX_FIND_QUIETLY)
+ message(STATUS "Looking for PASTIX : test of pastix() fails")
+ message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
+ message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
+ message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
+ message(STATUS "Maybe PASTIX is linked with specific libraries. "
+ "Have you tried with COMPONENTS (MPI/SEQ, STARPU, STARPU_CUDA, SCOTCH, PTSCOTCH, METIS)? "
+ "See the explanation in FindPASTIX.cmake.")
+ endif()
+ endif()
+ set(CMAKE_REQUIRED_INCLUDES)
+ set(CMAKE_REQUIRED_FLAGS)
+ set(CMAKE_REQUIRED_LIBRARIES)
+endif(PASTIX_LIBRARIES)
+
+if (PASTIX_LIBRARIES)
+ list(GET PASTIX_LIBRARIES 0 first_lib)
+ get_filename_component(first_lib_path "${first_lib}" PATH)
+ if (${first_lib_path} MATCHES "/lib(32|64)?$")
+ string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
+ set(PASTIX_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of PASTIX library" FORCE)
+ else()
+ set(PASTIX_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of PASTIX library" FORCE)
+ endif()
+endif()
+mark_as_advanced(PASTIX_DIR)
+mark_as_advanced(PASTIX_DIR_FOUND)
+
+# check that PASTIX has been found
+# ---------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PASTIX DEFAULT_MSG
- PASTIX_INCLUDES PASTIX_LIBRARIES)
-
-mark_as_advanced(PASTIX_INCLUDES PASTIX_LIBRARIES)
+ PASTIX_LIBRARIES
+ PASTIX_WORKS)
diff --git a/eigen/cmake/FindScotch.cmake b/eigen/cmake/FindScotch.cmake
index 530340b..89d295a 100644
--- a/eigen/cmake/FindScotch.cmake
+++ b/eigen/cmake/FindScotch.cmake
@@ -1,24 +1,369 @@
-# Pastix requires SCOTCH or METIS (partitioning and reordering tools)
+###
+#
+# @copyright (c) 2009-2014 The University of Tennessee and The University
+# of Tennessee Research Foundation.
+# All rights reserved.
+# @copyright (c) 2012-2014 Inria. All rights reserved.
+# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
+#
+###
+#
+# - Find SCOTCH include dirs and libraries
+# Use this module by invoking find_package with the form:
+# find_package(SCOTCH
+# [REQUIRED] # Fail with error if scotch is not found
+# [COMPONENTS <comp1> <comp2> ...] # dependencies
+# )
+#
+# COMPONENTS can be some of the following:
+# - ESMUMPS: to activate detection of Scotch with the esmumps interface
+#
+# This module finds headers and scotch library.
+# Results are reported in variables:
+# SCOTCH_FOUND - True if headers and requested libraries were found
+# SCOTCH_INCLUDE_DIRS - scotch include directories
+# SCOTCH_LIBRARY_DIRS - Link directories for scotch libraries
+# SCOTCH_LIBRARIES - scotch component libraries to be linked
+# SCOTCH_INTSIZE - Number of octets occupied by a SCOTCH_Num
+#
+# The user can give specific paths where to find the libraries adding cmake
+# options at configure (ex: cmake path/to/project -DSCOTCH=path/to/scotch):
+# SCOTCH_DIR - Where to find the base directory of scotch
+# SCOTCH_INCDIR - Where to find the header files
+# SCOTCH_LIBDIR - Where to find the library files
+# The module can also look for the following environment variables if paths
+# are not given as cmake variable: SCOTCH_DIR, SCOTCH_INCDIR, SCOTCH_LIBDIR
-if (SCOTCH_INCLUDES AND SCOTCH_LIBRARIES)
- set(SCOTCH_FIND_QUIETLY TRUE)
-endif (SCOTCH_INCLUDES AND SCOTCH_LIBRARIES)
+#=============================================================================
+# Copyright 2012-2013 Inria
+# Copyright 2012-2013 Emmanuel Agullo
+# Copyright 2012-2013 Mathieu Faverge
+# Copyright 2012 Cedric Castagnede
+# Copyright 2013 Florent Pruvost
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file MORSE-Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of Morse, substitute the full
+# License text for the above reference.)
-find_path(SCOTCH_INCLUDES
- NAMES
- scotch.h
- PATHS
- $ENV{SCOTCHDIR}
- ${INCLUDE_INSTALL_DIR}
- PATH_SUFFIXES
- scotch
-)
+if (NOT SCOTCH_FOUND)
+ set(SCOTCH_DIR "" CACHE PATH "Installation directory of SCOTCH library")
+ if (NOT SCOTCH_FIND_QUIETLY)
+ message(STATUS "A cache variable, namely SCOTCH_DIR, has been set to specify the install directory of SCOTCH")
+ endif()
+endif()
+# Set the version to find
+set(SCOTCH_LOOK_FOR_ESMUMPS OFF)
-find_library(SCOTCH_LIBRARIES scotch PATHS $ENV{SCOTCHDIR} ${LIB_INSTALL_DIR})
+if( SCOTCH_FIND_COMPONENTS )
+ foreach( component ${SCOTCH_FIND_COMPONENTS} )
+ if (${component} STREQUAL "ESMUMPS")
+ # means we look for esmumps library
+ set(SCOTCH_LOOK_FOR_ESMUMPS ON)
+ endif()
+ endforeach()
+endif()
+# SCOTCH may depend on Threads, try to find it
+if (NOT THREADS_FOUND)
+ if (SCOTCH_FIND_REQUIRED)
+ find_package(Threads REQUIRED)
+ else()
+ find_package(Threads)
+ endif()
+endif()
+
+# Looking for include
+# -------------------
+
+# Add system include paths to search include
+# ------------------------------------------
+unset(_inc_env)
+set(ENV_SCOTCH_DIR "$ENV{SCOTCH_DIR}")
+set(ENV_SCOTCH_INCDIR "$ENV{SCOTCH_INCDIR}")
+if(ENV_SCOTCH_INCDIR)
+ list(APPEND _inc_env "${ENV_SCOTCH_INCDIR}")
+elseif(ENV_SCOTCH_DIR)
+ list(APPEND _inc_env "${ENV_SCOTCH_DIR}")
+ list(APPEND _inc_env "${ENV_SCOTCH_DIR}/include")
+ list(APPEND _inc_env "${ENV_SCOTCH_DIR}/include/scotch")
+else()
+ if(WIN32)
+ string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
+ else()
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
+ list(APPEND _inc_env "${_path_env}")
+ string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
+ list(APPEND _inc_env "${_path_env}")
+ endif()
+endif()
+list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
+list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
+list(REMOVE_DUPLICATES _inc_env)
+
+
+# Try to find the scotch header in the given paths
+# -------------------------------------------------
+# call cmake macro to find the header path
+if(SCOTCH_INCDIR)
+ set(SCOTCH_scotch.h_DIRS "SCOTCH_scotch.h_DIRS-NOTFOUND")
+ find_path(SCOTCH_scotch.h_DIRS
+ NAMES scotch.h
+ HINTS ${SCOTCH_INCDIR})
+else()
+ if(SCOTCH_DIR)
+ set(SCOTCH_scotch.h_DIRS "SCOTCH_scotch.h_DIRS-NOTFOUND")
+ find_path(SCOTCH_scotch.h_DIRS
+ NAMES scotch.h
+ HINTS ${SCOTCH_DIR}
+ PATH_SUFFIXES "include" "include/scotch")
+ else()
+ set(SCOTCH_scotch.h_DIRS "SCOTCH_scotch.h_DIRS-NOTFOUND")
+ find_path(SCOTCH_scotch.h_DIRS
+ NAMES scotch.h
+ HINTS ${_inc_env}
+ PATH_SUFFIXES "scotch")
+ endif()
+endif()
+mark_as_advanced(SCOTCH_scotch.h_DIRS)
+
+# If found, add path to cmake variable
+# ------------------------------------
+if (SCOTCH_scotch.h_DIRS)
+ set(SCOTCH_INCLUDE_DIRS "${SCOTCH_scotch.h_DIRS}")
+else ()
+ set(SCOTCH_INCLUDE_DIRS "SCOTCH_INCLUDE_DIRS-NOTFOUND")
+ if (NOT SCOTCH_FIND_QUIETLY)
+ message(STATUS "Looking for scotch -- scotch.h not found")
+ endif()
+endif()
+list(REMOVE_DUPLICATES SCOTCH_INCLUDE_DIRS)
+
+# Looking for lib
+# ---------------
+
+# Add system library paths to search lib
+# --------------------------------------
+unset(_lib_env)
+set(ENV_SCOTCH_LIBDIR "$ENV{SCOTCH_LIBDIR}")
+if(ENV_SCOTCH_LIBDIR)
+ list(APPEND _lib_env "${ENV_SCOTCH_LIBDIR}")
+elseif(ENV_SCOTCH_DIR)
+ list(APPEND _lib_env "${ENV_SCOTCH_DIR}")
+ list(APPEND _lib_env "${ENV_SCOTCH_DIR}/lib")
+else()
+ if(WIN32)
+ string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
+ else()
+ if(APPLE)
+ string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
+ else()
+ string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
+ endif()
+ list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
+ list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+ endif()
+endif()
+list(REMOVE_DUPLICATES _lib_env)
+
+# Try to find the scotch lib in the given paths
+# ----------------------------------------------
+
+set(SCOTCH_libs_to_find "scotch;scotcherrexit")
+if (SCOTCH_LOOK_FOR_ESMUMPS)
+ list(INSERT SCOTCH_libs_to_find 0 "esmumps")
+endif()
+
+# call cmake macro to find the lib path
+if(SCOTCH_LIBDIR)
+ foreach(scotch_lib ${SCOTCH_libs_to_find})
+ set(SCOTCH_${scotch_lib}_LIBRARY "SCOTCH_${scotch_lib}_LIBRARY-NOTFOUND")
+ find_library(SCOTCH_${scotch_lib}_LIBRARY
+ NAMES ${scotch_lib}
+ HINTS ${SCOTCH_LIBDIR})
+ endforeach()
+else()
+ if(SCOTCH_DIR)
+ foreach(scotch_lib ${SCOTCH_libs_to_find})
+ set(SCOTCH_${scotch_lib}_LIBRARY "SCOTCH_${scotch_lib}_LIBRARY-NOTFOUND")
+ find_library(SCOTCH_${scotch_lib}_LIBRARY
+ NAMES ${scotch_lib}
+ HINTS ${SCOTCH_DIR}
+ PATH_SUFFIXES lib lib32 lib64)
+ endforeach()
+ else()
+ foreach(scotch_lib ${SCOTCH_libs_to_find})
+ set(SCOTCH_${scotch_lib}_LIBRARY "SCOTCH_${scotch_lib}_LIBRARY-NOTFOUND")
+ find_library(SCOTCH_${scotch_lib}_LIBRARY
+ NAMES ${scotch_lib}
+ HINTS ${_lib_env})
+ endforeach()
+ endif()
+endif()
+
+set(SCOTCH_LIBRARIES "")
+set(SCOTCH_LIBRARY_DIRS "")
+# If found, add path to cmake variable
+# ------------------------------------
+foreach(scotch_lib ${SCOTCH_libs_to_find})
+
+ if (SCOTCH_${scotch_lib}_LIBRARY)
+ get_filename_component(${scotch_lib}_lib_path "${SCOTCH_${scotch_lib}_LIBRARY}" PATH)
+ # set cmake variables
+ list(APPEND SCOTCH_LIBRARIES "${SCOTCH_${scotch_lib}_LIBRARY}")
+ list(APPEND SCOTCH_LIBRARY_DIRS "${${scotch_lib}_lib_path}")
+ else ()
+ list(APPEND SCOTCH_LIBRARIES "${SCOTCH_${scotch_lib}_LIBRARY}")
+ if (NOT SCOTCH_FIND_QUIETLY)
+ message(STATUS "Looking for scotch -- lib ${scotch_lib} not found")
+ endif()
+ endif ()
+
+ mark_as_advanced(SCOTCH_${scotch_lib}_LIBRARY)
+
+endforeach()
+list(REMOVE_DUPLICATES SCOTCH_LIBRARY_DIRS)
+
+# check a function to validate the find
+if(SCOTCH_LIBRARIES)
+
+ set(REQUIRED_INCDIRS)
+ set(REQUIRED_LIBDIRS)
+ set(REQUIRED_LIBS)
+
+ # SCOTCH
+ if (SCOTCH_INCLUDE_DIRS)
+ set(REQUIRED_INCDIRS "${SCOTCH_INCLUDE_DIRS}")
+ endif()
+ if (SCOTCH_LIBRARY_DIRS)
+ set(REQUIRED_LIBDIRS "${SCOTCH_LIBRARY_DIRS}")
+ endif()
+ set(REQUIRED_LIBS "${SCOTCH_LIBRARIES}")
+ # THREADS
+ if(CMAKE_THREAD_LIBS_INIT)
+ list(APPEND REQUIRED_LIBS "${CMAKE_THREAD_LIBS_INIT}")
+ endif()
+ set(Z_LIBRARY "Z_LIBRARY-NOTFOUND")
+ find_library(Z_LIBRARY NAMES z)
+ mark_as_advanced(Z_LIBRARY)
+ if(Z_LIBRARY)
+ list(APPEND REQUIRED_LIBS "-lz")
+ endif()
+ set(M_LIBRARY "M_LIBRARY-NOTFOUND")
+ find_library(M_LIBRARY NAMES m)
+ mark_as_advanced(M_LIBRARY)
+ if(M_LIBRARY)
+ list(APPEND REQUIRED_LIBS "-lm")
+ endif()
+ set(RT_LIBRARY "RT_LIBRARY-NOTFOUND")
+ find_library(RT_LIBRARY NAMES rt)
+ mark_as_advanced(RT_LIBRARY)
+ if(RT_LIBRARY)
+ list(APPEND REQUIRED_LIBS "-lrt")
+ endif()
+
+ # set required libraries for link
+ set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
+ set(CMAKE_REQUIRED_LIBRARIES)
+ foreach(lib_dir ${REQUIRED_LIBDIRS})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
+ endforeach()
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
+ string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+
+ # test link
+ unset(SCOTCH_WORKS CACHE)
+ include(CheckFunctionExists)
+ check_function_exists(SCOTCH_graphInit SCOTCH_WORKS)
+ mark_as_advanced(SCOTCH_WORKS)
+
+ if(SCOTCH_WORKS)
+ # save link with dependencies
+ set(SCOTCH_LIBRARIES "${REQUIRED_LIBS}")
+ else()
+ if(NOT SCOTCH_FIND_QUIETLY)
+ message(STATUS "Looking for SCOTCH : test of SCOTCH_graphInit with SCOTCH library fails")
+ message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
+ message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
+ message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
+ endif()
+ endif()
+ set(CMAKE_REQUIRED_INCLUDES)
+ set(CMAKE_REQUIRED_FLAGS)
+ set(CMAKE_REQUIRED_LIBRARIES)
+endif(SCOTCH_LIBRARIES)
+
+if (SCOTCH_LIBRARIES)
+ list(GET SCOTCH_LIBRARIES 0 first_lib)
+ get_filename_component(first_lib_path "${first_lib}" PATH)
+ if (${first_lib_path} MATCHES "/lib(32|64)?$")
+ string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
+ set(SCOTCH_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of SCOTCH library" FORCE)
+ else()
+ set(SCOTCH_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of SCOTCH library" FORCE)
+ endif()
+endif()
+mark_as_advanced(SCOTCH_DIR)
+mark_as_advanced(SCOTCH_DIR_FOUND)
+
+# Check the size of SCOTCH_Num
+# ---------------------------------
+set(CMAKE_REQUIRED_INCLUDES ${SCOTCH_INCLUDE_DIRS})
+
+include(CheckCSourceRuns)
+#stdio.h and stdint.h should be included by scotch.h directly
+set(SCOTCH_C_TEST_SCOTCH_Num_4 "
+#include <stdio.h>
+#include <stdint.h>
+#include <scotch.h>
+int main(int argc, char **argv) {
+ if (sizeof(SCOTCH_Num) == 4)
+ return 0;
+ else
+ return 1;
+}
+")
+
+set(SCOTCH_C_TEST_SCOTCH_Num_8 "
+#include <stdio.h>
+#include <stdint.h>
+#include <scotch.h>
+int main(int argc, char **argv) {
+ if (sizeof(SCOTCH_Num) == 8)
+ return 0;
+ else
+ return 1;
+}
+")
+check_c_source_runs("${SCOTCH_C_TEST_SCOTCH_Num_4}" SCOTCH_Num_4)
+if(NOT SCOTCH_Num_4)
+ check_c_source_runs("${SCOTCH_C_TEST_SCOTCH_Num_8}" SCOTCH_Num_8)
+ if(NOT SCOTCH_Num_8)
+ set(SCOTCH_INTSIZE -1)
+ else()
+ set(SCOTCH_INTSIZE 8)
+ endif()
+else()
+ set(SCOTCH_INTSIZE 4)
+endif()
+set(CMAKE_REQUIRED_INCLUDES "")
+
+# check that SCOTCH has been found
+# ---------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SCOTCH DEFAULT_MSG
- SCOTCH_INCLUDES SCOTCH_LIBRARIES)
-
-mark_as_advanced(SCOTCH_INCLUDES SCOTCH_LIBRARIES)
+ SCOTCH_LIBRARIES
+ SCOTCH_WORKS)
+#
+# TODO: Add possibility to check for specific functions in the library
+#
diff --git a/eigen/cmake/FindXsmm.cmake b/eigen/cmake/FindXsmm.cmake
deleted file mode 100644
index 809d6f4..0000000
--- a/eigen/cmake/FindXsmm.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-# libxsmm support.
-# libxsmm provides matrix multiplication kernels optimized for
-# the latest Intel architectures.
-# Download the library from https://github.com/hfp/libxsmm
-# Compile with make BLAS=0
-
-if (LIBXSMM)
- set(XSMM_FIND_QUIETLY TRUE)
- set(XSMM_INCLUDES ${LIBXSMM}/include)
- set(XSMM_LIBRARIES ${LIBXSMM}/lib)
-endif (LIBXSMM)
-
-find_path(LIBXSMM
- NAMES
- libxsmm.h
- PATHS
- $ENV{XSMMDIR}/include
- ${INCLUDE_INSTALL_DIR}
-)
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(XSMM DEFAULT_MSG
- LIBXSMM)
-
-mark_as_advanced(LIBXSMM)
diff --git a/eigen/debug/gdb/printers.py b/eigen/debug/gdb/printers.py
index 24961d1..0d67a5f 100644
--- a/eigen/debug/gdb/printers.py
+++ b/eigen/debug/gdb/printers.py
@@ -10,7 +10,8 @@
# Pretty printers for Eigen::Matrix
# This is still pretty basic as the python extension to gdb is still pretty basic.
-# It cannot handle complex eigen types and it doesn't support many of the other eigen types
+# It cannot handle complex eigen types and it doesn't support any of the other eigen types
+# Such as quaternion or some other type.
# This code supports fixed size as well as dynamic size matrices
# To use it:
@@ -28,45 +29,7 @@
import gdb
import re
import itertools
-from bisect import bisect_left
-# Basic row/column iteration code for use with Sparse and Dense matrices
-class _MatrixEntryIterator(object):
-
- def __init__ (self, rows, cols, rowMajor):
- self.rows = rows
- self.cols = cols
- self.currentRow = 0
- self.currentCol = 0
- self.rowMajor = rowMajor
-
- def __iter__ (self):
- return self
-
- def next(self):
- return self.__next__() # Python 2.x compatibility
-
- def __next__(self):
- row = self.currentRow
- col = self.currentCol
- if self.rowMajor == 0:
- if self.currentCol >= self.cols:
- raise StopIteration
-
- self.currentRow = self.currentRow + 1
- if self.currentRow >= self.rows:
- self.currentRow = 0
- self.currentCol = self.currentCol + 1
- else:
- if self.currentRow >= self.rows:
- raise StopIteration
-
- self.currentCol = self.currentCol + 1
- if self.currentCol >= self.cols:
- self.currentCol = 0
- self.currentRow = self.currentRow + 1
-
- return (row, col)
class EigenMatrixPrinter:
"Print Eigen Matrix or Array of some kind"
@@ -114,15 +77,42 @@ class EigenMatrixPrinter:
self.data = self.data['array']
self.data = self.data.cast(self.innerType.pointer())
- class _iterator(_MatrixEntryIterator):
+ class _iterator:
def __init__ (self, rows, cols, dataPtr, rowMajor):
- super(EigenMatrixPrinter._iterator, self).__init__(rows, cols, rowMajor)
-
+ self.rows = rows
+ self.cols = cols
self.dataPtr = dataPtr
+ self.currentRow = 0
+ self.currentCol = 0
+ self.rowMajor = rowMajor
+
+ def __iter__ (self):
+ return self
+
+ def next(self):
+ return self.__next__() # Python 2.x compatibility
def __next__(self):
- row, col = super(EigenMatrixPrinter._iterator, self).__next__()
+ row = self.currentRow
+ col = self.currentCol
+ if self.rowMajor == 0:
+ if self.currentCol >= self.cols:
+ raise StopIteration
+
+ self.currentRow = self.currentRow + 1
+ if self.currentRow >= self.rows:
+ self.currentRow = 0
+ self.currentCol = self.currentCol + 1
+ else:
+ if self.currentRow >= self.rows:
+ raise StopIteration
+
+ self.currentCol = self.currentCol + 1
+ if self.currentCol >= self.cols:
+ self.currentCol = 0
+ self.currentRow = self.currentRow + 1
+
item = self.dataPtr.dereference()
self.dataPtr = self.dataPtr + 1
@@ -139,95 +129,6 @@ class EigenMatrixPrinter:
def to_string(self):
return "Eigen::%s<%s,%d,%d,%s> (data ptr: %s)" % (self.variety, self.innerType, self.rows, self.cols, "RowMajor" if self.rowMajor else "ColMajor", self.data)
-class EigenSparseMatrixPrinter:
- "Print an Eigen SparseMatrix"
-
- def __init__(self, val):
- "Extract all the necessary information"
-
- type = val.type
- if type.code == gdb.TYPE_CODE_REF:
- type = type.target()
- self.type = type.unqualified().strip_typedefs()
- tag = self.type.tag
- regex = re.compile('\<.*\>')
- m = regex.findall(tag)[0][1:-1]
- template_params = m.split(',')
- template_params = [x.replace(" ", "") for x in template_params]
-
- self.options = 0
- if len(template_params) > 1:
- self.options = template_params[1];
-
- self.rowMajor = (int(self.options) & 0x1)
-
- self.innerType = self.type.template_argument(0)
-
- self.val = val
-
- self.data = self.val['m_data']
- self.data = self.data.cast(self.innerType.pointer())
-
- class _iterator(_MatrixEntryIterator):
- def __init__ (self, rows, cols, val, rowMajor):
- super(EigenSparseMatrixPrinter._iterator, self).__init__(rows, cols, rowMajor)
-
- self.val = val
-
- def __next__(self):
-
- row, col = super(EigenSparseMatrixPrinter._iterator, self).__next__()
-
- # repeat calculations from SparseMatrix.h:
- outer = row if self.rowMajor else col
- inner = col if self.rowMajor else row
- start = self.val['m_outerIndex'][outer]
- end = ((start + self.val['m_innerNonZeros'][outer]) if self.val['m_innerNonZeros'] else
- self.val['m_outerIndex'][outer+1])
-
- # and from CompressedStorage.h:
- data = self.val['m_data']
- if start >= end:
- item = 0
- elif (end > start) and (inner == data['m_indices'][end-1]):
- item = data['m_values'][end-1]
- else:
- # create Python index list from the target range within m_indices
- indices = [data['m_indices'][x] for x in range(int(start), int(end)-1)]
- # find the index with binary search
- idx = int(start) + bisect_left(indices, inner)
- if ((idx < end) and (data['m_indices'][idx] == inner)):
- item = data['m_values'][idx]
- else:
- item = 0
-
- return ('[%d,%d]' % (row, col), item)
-
- def children(self):
- if self.data:
- return self._iterator(self.rows(), self.cols(), self.val, self.rowMajor)
-
- return iter([]) # empty matrix, for now
-
-
- def rows(self):
- return self.val['m_outerSize'] if self.rowMajor else self.val['m_innerSize']
-
- def cols(self):
- return self.val['m_innerSize'] if self.rowMajor else self.val['m_outerSize']
-
- def to_string(self):
-
- if self.data:
- status = ("not compressed" if self.val['m_innerNonZeros'] else "compressed")
- else:
- status = "empty"
- dimensions = "%d x %d" % (self.rows(), self.cols())
- layout = "row" if self.rowMajor else "column"
-
- return "Eigen::SparseMatrix<%s>, %s, %s major, %s" % (
- self.innerType, dimensions, layout, status )
-
class EigenQuaternionPrinter:
"Print an Eigen Quaternion"
@@ -255,7 +156,7 @@ class EigenQuaternionPrinter:
return self
def next(self):
- return self.__next__() # Python 2.x compatibility
+ return self.__next__() # Python 2.x compatibility
def __next__(self):
element = self.currentElement
@@ -279,7 +180,6 @@ class EigenQuaternionPrinter:
def build_eigen_dictionary ():
pretty_printers_dict[re.compile('^Eigen::Quaternion<.*>$')] = lambda val: EigenQuaternionPrinter(val)
pretty_printers_dict[re.compile('^Eigen::Matrix<.*>$')] = lambda val: EigenMatrixPrinter("Matrix", val)
- pretty_printers_dict[re.compile('^Eigen::SparseMatrix<.*>$')] = lambda val: EigenSparseMatrixPrinter(val)
pretty_printers_dict[re.compile('^Eigen::Array<.*>$')] = lambda val: EigenMatrixPrinter("Array", val)
def register_eigen_printers(obj):
diff --git a/eigen/doc/AsciiQuickReference.txt b/eigen/doc/AsciiQuickReference.txt
index 8409f88..0ca54ce 100644
--- a/eigen/doc/AsciiQuickReference.txt
+++ b/eigen/doc/AsciiQuickReference.txt
@@ -140,7 +140,7 @@ R.array().abs() // abs(P)
R.cwiseAbs2() // abs(P.^2)
R.array().abs2() // abs(P.^2)
(R.array() < s).select(P,Q ); // (R < s ? P : Q)
-R = (Q.array()==0).select(P,A) // R(Q==0) = P(Q==0)
+R = (Q.array()==0).select(P,R) // R(Q==0) = P(Q==0)
R = P.unaryExpr(ptr_fun(func)) // R = arrayfun(func, P) // with: scalar func(const scalar &x);
diff --git a/eigen/doc/Doxyfile.in b/eigen/doc/Doxyfile.in
index 2109978..48bb0a8 100644
--- a/eigen/doc/Doxyfile.in
+++ b/eigen/doc/Doxyfile.in
@@ -229,8 +229,7 @@ ALIASES = "only_for_vectors=This is only for vectors (either row-
"blank= " \
"cpp11=<span class='cpp11'>[c++11]</span>" \
"cpp14=<span class='cpp14'>[c++14]</span>" \
- "cpp17=<span class='cpp17'>[c++17]</span>" \
- "newin{1}=<span class='newin3x'>New in %Eigen \1.</span>"
+ "cpp17=<span class='cpp17'>[c++17]</span>"
ALIASES += "eigenAutoToc= "
@@ -410,7 +409,7 @@ EXTRACT_PACKAGE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
-EXTRACT_STATIC = YES
+EXTRACT_STATIC = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
diff --git a/eigen/doc/FixedSizeVectorizable.dox b/eigen/doc/FixedSizeVectorizable.dox
index 0012465..49e38af 100644
--- a/eigen/doc/FixedSizeVectorizable.dox
+++ b/eigen/doc/FixedSizeVectorizable.dox
@@ -1,6 +1,6 @@
namespace Eigen {
-/** \eigenManualPage TopicFixedSizeVectorizable Fixed-size vectorizable %Eigen objects
+/** \eigenManualPage TopicFixedSizeVectorizable Fixed-size vectorizable Eigen objects
The goal of this page is to explain what we mean by "fixed-size vectorizable".
@@ -23,15 +23,15 @@ Examples include:
\section FixedSizeVectorizable_explanation Explanation
-First, "fixed-size" should be clear: an %Eigen object has fixed size if its number of rows and its number of columns are fixed at compile-time. So for example \ref Matrix3f has fixed size, but \ref MatrixXf doesn't (the opposite of fixed-size is dynamic-size).
+First, "fixed-size" should be clear: an Eigen object has fixed size if its number of rows and its number of columns are fixed at compile-time. So for example Matrix3f has fixed size, but MatrixXf doesn't (the opposite of fixed-size is dynamic-size).
-The array of coefficients of a fixed-size %Eigen object is a plain "static array", it is not dynamically allocated. For example, the data behind a \ref Matrix4f is just a "float array[16]".
+The array of coefficients of a fixed-size Eigen object is a plain "static array", it is not dynamically allocated. For example, the data behind a Matrix4f is just a "float array[16]".
Fixed-size objects are typically very small, which means that we want to handle them with zero runtime overhead -- both in terms of memory usage and of speed.
-Now, vectorization works with 128-bit packets (e.g., SSE, AltiVec, NEON), 256-bit packets (e.g., AVX), or 512-bit packets (e.g., AVX512). Moreover, for performance reasons, these packets are most efficiently read and written if they have the same alignment as the packet size, that is 16 bytes, 32 bytes, and 64 bytes respectively.
+Now, vectorization (both SSE and AltiVec) works with 128-bit packets. Moreover, for performance reasons, these packets need to be have 128-bit alignment.
-So it turns out that the best way that fixed-size %Eigen objects can be vectorized, is if their size is a multiple of 16 bytes (or more). %Eigen will then request 16-byte alignment (or more) for these objects, and henceforth rely on these objects being aligned to achieve maximal efficiency.
+So it turns out that the only way that fixed-size Eigen objects can be vectorized, is if their size is a multiple of 128 bits, or 16 bytes. Eigen will then request 16-byte alignment for these objects, and henceforth rely on these objects being aligned so no runtime check for alignment is performed.
*/
diff --git a/eigen/doc/PassingByValue.dox b/eigen/doc/PassingByValue.dox
index 9254fe6..bf4d0ef 100644
--- a/eigen/doc/PassingByValue.dox
+++ b/eigen/doc/PassingByValue.dox
@@ -4,21 +4,21 @@ namespace Eigen {
Passing objects by value is almost always a very bad idea in C++, as this means useless copies, and one should pass them by reference instead.
-With %Eigen, this is even more important: passing \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen objects" by value is not only inefficient, it can be illegal or make your program crash! And the reason is that these %Eigen objects have alignment modifiers that aren't respected when they are passed by value.
+With Eigen, this is even more important: passing \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen objects" by value is not only inefficient, it can be illegal or make your program crash! And the reason is that these Eigen objects have alignment modifiers that aren't respected when they are passed by value.
-For example, a function like this, where \c v is passed by value:
+So for example, a function like this, where v is passed by value:
\code
void my_function(Eigen::Vector2d v);
\endcode
-needs to be rewritten as follows, passing \c v by const reference:
+needs to be rewritten as follows, passing v by reference:
\code
void my_function(const Eigen::Vector2d& v);
\endcode
-Likewise if you have a class having an %Eigen object as member:
+Likewise if you have a class having a Eigen object as member:
\code
struct Foo
diff --git a/eigen/doc/TopicCMakeGuide.dox b/eigen/doc/TopicCMakeGuide.dox
index cf767d0..896cfa8 100644
--- a/eigen/doc/TopicCMakeGuide.dox
+++ b/eigen/doc/TopicCMakeGuide.dox
@@ -32,13 +32,9 @@ which requires at least version 3.3 of %Eigen. Here, `path-to-example-directory`
is the path to the directory that contains both `CMakeLists.txt` and
`example.cpp`.
-Do not forget to set the <a href="https://cmake.org/cmake/help/v3.7/variable/CMAKE_PREFIX_PATH.html">\c CMAKE_PREFIX_PATH </a> variable if Eigen is not installed in a default location or if you want to pick a specific version. For instance:
-\code{.sh}
-$ cmake path-to-example-directory -DCMAKE_PREFIX_PATH=$HOME/mypackages
-\endcode
-An alternative is to set the \c Eigen3_DIR cmake's variable to the respective path containing the \c Eigen3*.cmake files. For instance:
-\code{.sh}
-$ cmake path-to-example-directory -DEigen3_DIR=$HOME/mypackages/share/eigen3/cmake/
+If you have multiple installed version of %Eigen, you can pick your favorite one by setting the \c Eigen3_DIR cmake's variable to the respective path containing the \c Eigen3*.cmake files. For instance:
+\code
+cmake path-to-example-directory -DEigen3_DIR=$HOME/mypackages/share/eigen3/cmake/
\endcode
If the `REQUIRED` option is omitted when locating %Eigen using
diff --git a/eigen/doc/UnalignedArrayAssert.dox b/eigen/doc/UnalignedArrayAssert.dox
index 0f70229..95d95a2 100644
--- a/eigen/doc/UnalignedArrayAssert.dox
+++ b/eigen/doc/UnalignedArrayAssert.dox
@@ -115,15 +115,6 @@ If you want to know why defining EIGEN_DONT_VECTORIZE does not by itself disable
It doesn't disable the assertion, because otherwise code that runs fine without vectorization would suddenly crash when enabling vectorization.
It doesn't disable 16-byte alignment, because that would mean that vectorized and non-vectorized code are not mutually ABI-compatible. This ABI compatibility is very important, even for people who develop only an in-house application, as for instance one may want to have in the same application a vectorized path and a non-vectorized path.
-\section checkmycode How can I check my code is safe regarding alignment issues?
-
-Unfortunately, there is no possibility in C++ to detect any of the aformentioned shortcoming at compile time (though static analysers are becoming more and more powerful and could detect some of them).
-Even at runtime, all we can do is to catch invalid unaligned allocation and trigger the explicit assertion mentioned at the begining of this page.
-Therefore, if your program runs fine on a given system with some given compilation flags, then this does not guarantee that your code is safe. For instance, on most 64 bits systems buffer are aligned on 16 bytes boundary and so, if you do not enable AVX instruction set, then your code will run fine. On the other hand, the same code may assert if moving to a more exotic platform, or enabling AVX instructions that required 32 bytes alignment by default.
-
-The situation is not hopeless though. Assuming your code is well covered by unit test, then you can check its alignment safety by linking it to a custom malloc library returning 8 bytes aligned buffers only. This way all alignment shortcomings should pop-up. To this end, you must also compile your program with \link TopicPreprocessorDirectivesPerformance EIGEN_MALLOC_ALREADY_ALIGNED=0 \endlink.
-
-
*/
}
diff --git a/eigen/doc/eigendoxy.css b/eigen/doc/eigendoxy.css
index 6ce2b83..6274e6c 100644
--- a/eigen/doc/eigendoxy.css
+++ b/eigen/doc/eigendoxy.css
@@ -181,11 +181,6 @@ span.cpp11,span.cpp14,span.cpp17 {
font-weight: bold;
}
-.newin3x {
- color: #a37c1a;
- font-weight: bold;
-}
-
/**** old Eigen's styles ****/
diff --git a/eigen/scripts/eigen_monitor_perf.sh b/eigen/scripts/eigen_monitor_perf.sh
deleted file mode 100644
index 39f8e7e..0000000
--- a/eigen/scripts/eigen_monitor_perf.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# This is a script example to automatically update and upload performance unit tests.
-# The following five variables must be adjusted to match your settings.
-
-USER='ggael'
-UPLOAD_DIR=perf_monitoring/ggaelmacbook26
-EIGEN_SOURCE_PATH=$HOME/Eigen/eigen
-export PREFIX="haswell-fma"
-export CXX_FLAGS="-mfma -w"
-
-####
-
-BENCH_PATH=$EIGEN_SOURCE_PATH/bench/perf_monitoring/$PREFIX
-PREVPATH=`pwd`
-cd $EIGEN_SOURCE_PATH/bench/perf_monitoring && ./runall.sh "Haswell 2.6GHz, FMA, Apple's clang" $*
-cd $PREVPATH
-
-ALLFILES="$BENCH_PATH/*.png $BENCH_PATH/*.html $BENCH_PATH/index.html $BENCH_PATH/s1.js $BENCH_PATH/s2.js"
-
-# (the '/' at the end of path is very important, see rsync documentation)
-rsync -az --no-p --delete $ALLFILES $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/$UPLOAD_DIR/ || { echo "upload failed"; exit 1; }
-
-# fix the perm
-ssh $USER@ssh.tuxfamily.org "chmod -R g+w /home/eigen/eigen.tuxfamily.org-web/htdocs/perf_monitoring" || { echo "perm failed"; exit 1; }
diff --git a/eigen/test/CMakeLists.txt b/eigen/test/CMakeLists.txt
index d337594..0747aa6 100644
--- a/eigen/test/CMakeLists.txt
+++ b/eigen/test/CMakeLists.txt
@@ -27,7 +27,7 @@ endif()
if(NOT EIGEN_Fortran_COMPILER_WORKS)
# search for a default Lapack library to complete Eigen's one
- find_package(LAPACK)
+ find_package(LAPACK QUIET)
endif()
# configure blas/lapack (use Eigen's ones)
@@ -80,23 +80,30 @@ else()
endif()
-find_package(Pastix)
-find_package(Scotch)
-find_package(Metis 5.0 REQUIRED)
-if(PASTIX_FOUND)
+find_package(PASTIX QUIET COMPONENTS METIS SCOTCH)
+# check that the PASTIX found is a version without MPI
+find_path(PASTIX_pastix_nompi.h_INCLUDE_DIRS
+ NAMES pastix_nompi.h
+ HINTS ${PASTIX_INCLUDE_DIRS}
+)
+if (NOT PASTIX_pastix_nompi.h_INCLUDE_DIRS)
+ message(STATUS "A version of Pastix has been found but pastix_nompi.h does not exist in the include directory."
+ " Because Eigen tests require a version without MPI, we disable the Pastix backend.")
+endif()
+if(PASTIX_FOUND AND PASTIX_pastix_nompi.h_INCLUDE_DIRS)
add_definitions("-DEIGEN_PASTIX_SUPPORT")
- include_directories(${PASTIX_INCLUDES})
+ include_directories(${PASTIX_INCLUDE_DIRS_DEP})
if(SCOTCH_FOUND)
- include_directories(${SCOTCH_INCLUDES})
+ include_directories(${SCOTCH_INCLUDE_DIRS})
set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${SCOTCH_LIBRARIES})
elseif(METIS_FOUND)
- include_directories(${METIS_INCLUDES})
+ include_directories(${METIS_INCLUDE_DIRS})
set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${METIS_LIBRARIES})
else(SCOTCH_FOUND)
ei_add_property(EIGEN_MISSING_BACKENDS "PaStiX, ")
endif(SCOTCH_FOUND)
- set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES} ${ORDERING_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
- set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
+ set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES_DEP} ${ORDERING_LIBRARIES})
+ set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES_DEP})
ei_add_property(EIGEN_TESTED_BACKENDS "PaStiX, ")
else()
ei_add_property(EIGEN_MISSING_BACKENDS "PaStiX, ")
@@ -104,7 +111,7 @@ endif()
if(METIS_FOUND)
add_definitions("-DEIGEN_METIS_SUPPORT")
- include_directories(${METIS_INCLUDES})
+ include_directories(${METIS_INCLUDE_DIRS})
ei_add_property(EIGEN_TESTED_BACKENDS "METIS, ")
else()
ei_add_property(EIGEN_MISSING_BACKENDS "METIS, ")
@@ -141,6 +148,7 @@ add_custom_target(BuildOfficial)
ei_add_test(rand)
ei_add_test(meta)
+ei_add_test(numext)
ei_add_test(sizeof)
ei_add_test(dynalloc)
ei_add_test(nomalloc)
@@ -162,8 +170,6 @@ ei_add_test(redux)
ei_add_test(visitor)
ei_add_test(block)
ei_add_test(corners)
-ei_add_test(symbolic_index)
-ei_add_test(indexed_view)
ei_add_test(swap)
ei_add_test(resize)
ei_add_test(conservative_resize)
diff --git a/eigen/test/array.cpp b/eigen/test/array.cpp
index f7f3ba7..15c3266 100644
--- a/eigen/test/array.cpp
+++ b/eigen/test/array.cpp
@@ -18,7 +18,7 @@ template<typename ArrayType> void array(const ArrayType& m)
typedef Array<Scalar, 1, ArrayType::ColsAtCompileTime> RowVectorType;
Index rows = m.rows();
- Index cols = m.cols();
+ Index cols = m.cols();
ArrayType m1 = ArrayType::Random(rows, cols),
m2 = ArrayType::Random(rows, cols),
@@ -44,25 +44,25 @@ template<typename ArrayType> void array(const ArrayType& m)
VERIFY_IS_APPROX(m3, m1 + s2);
m3 = m1;
m3 -= s1;
- VERIFY_IS_APPROX(m3, m1 - s1);
-
+ VERIFY_IS_APPROX(m3, m1 - s1);
+
// scalar operators via Maps
m3 = m1;
ArrayType::Map(m1.data(), m1.rows(), m1.cols()) -= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
VERIFY_IS_APPROX(m1, m3 - m2);
-
+
m3 = m1;
ArrayType::Map(m1.data(), m1.rows(), m1.cols()) += ArrayType::Map(m2.data(), m2.rows(), m2.cols());
VERIFY_IS_APPROX(m1, m3 + m2);
-
+
m3 = m1;
ArrayType::Map(m1.data(), m1.rows(), m1.cols()) *= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
VERIFY_IS_APPROX(m1, m3 * m2);
-
+
m3 = m1;
m2 = ArrayType::Random(rows,cols);
m2 = (m2==0).select(1,m2);
- ArrayType::Map(m1.data(), m1.rows(), m1.cols()) /= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
+ ArrayType::Map(m1.data(), m1.rows(), m1.cols()) /= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
VERIFY_IS_APPROX(m1, m3 / m2);
// reductions
@@ -84,7 +84,7 @@ template<typename ArrayType> void array(const ArrayType& m)
VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);
m3 = m1;
VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);
-
+
// Conversion from scalar
VERIFY_IS_APPROX((m3 = s1), ArrayType::Constant(rows,cols,s1));
VERIFY_IS_APPROX((m3 = 1), ArrayType::Constant(rows,cols,1));
@@ -102,7 +102,7 @@ template<typename ArrayType> void array(const ArrayType& m)
f1.setRandom();
FixedArrayType f4(f1.data());
VERIFY_IS_APPROX(f4, f1);
-
+
// pow
VERIFY_IS_APPROX(m1.pow(2), m1.square());
VERIFY_IS_APPROX(pow(m1,2), m1.square());
@@ -144,7 +144,7 @@ template<typename ArrayType> void comparisons(const ArrayType& m)
m2 = ArrayType::Random(rows, cols),
m3(rows, cols),
m4 = m1;
-
+
m4 = (m4.abs()==Scalar(0)).select(1,m4);
VERIFY(((m1 + Scalar(1)) > m1).all());
@@ -295,9 +295,6 @@ template<typename ArrayType> void array_real(const ArrayType& m)
VERIFY_IS_APPROX(m1.exp(), exp(m1));
VERIFY_IS_APPROX(m1.exp() / m2.exp(),(m1-m2).exp());
- VERIFY_IS_APPROX(m1.expm1(), expm1(m1));
- VERIFY_IS_APPROX((m3 + smallNumber).exp() - 1, expm1(abs(m3) + smallNumber));
-
VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt());
VERIFY_IS_APPROX(pow(m3,RealScalar(0.5)), m3.sqrt());
@@ -332,7 +329,7 @@ template<typename ArrayType> void array_complex(const ArrayType& m)
ArrayType m1 = ArrayType::Random(rows, cols),
m2(rows, cols),
m4 = m1;
-
+
m4.real() = (m4.real().abs()==RealScalar(0)).select(RealScalar(1),m4.real());
m4.imag() = (m4.imag().abs()==RealScalar(0)).select(RealScalar(1),m4.imag());
diff --git a/eigen/test/array_for_matrix.cpp b/eigen/test/array_for_matrix.cpp
index c150194..b872139 100644
--- a/eigen/test/array_for_matrix.cpp
+++ b/eigen/test/array_for_matrix.cpp
@@ -235,12 +235,31 @@ template<typename MatrixTraits> void resize(const MatrixTraits& t)
VERIFY(a1.size()==cols);
}
+template<int>
void regression_bug_654()
{
ArrayXf a = RowVectorXf(3);
VectorXf v = Array<float,1,Dynamic>(3);
}
+// Check propagation of LvalueBit through Array/Matrix-Wrapper
+template<int>
+void regrrssion_bug_1410()
+{
+ const Matrix4i M;
+ const Array4i A;
+ ArrayWrapper<const Matrix4i> MA = M.array();
+ MA.row(0);
+ MatrixWrapper<const Array4i> AM = A.matrix();
+ AM.row(0);
+
+ VERIFY((internal::traits<ArrayWrapper<const Matrix4i> >::Flags&LvalueBit)==0);
+ VERIFY((internal::traits<MatrixWrapper<const Array4i> >::Flags&LvalueBit)==0);
+
+ VERIFY((internal::traits<ArrayWrapper<Matrix4i> >::Flags&LvalueBit)==LvalueBit);
+ VERIFY((internal::traits<MatrixWrapper<Array4i> >::Flags&LvalueBit)==LvalueBit);
+}
+
void test_array_for_matrix()
{
for(int i = 0; i < g_repeat; i++) {
@@ -280,5 +299,6 @@ void test_array_for_matrix()
CALL_SUBTEST_5( resize(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
CALL_SUBTEST_6( resize(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
}
- CALL_SUBTEST_6( regression_bug_654() );
+ CALL_SUBTEST_6( regression_bug_654<0>() );
+ CALL_SUBTEST_6( regrrssion_bug_1410<0>() );
}
diff --git a/eigen/test/basicstuff.cpp b/eigen/test/basicstuff.cpp
index c346ce6..99d91f9 100644
--- a/eigen/test/basicstuff.cpp
+++ b/eigen/test/basicstuff.cpp
@@ -49,22 +49,6 @@ template<typename MatrixType> void basicStuff(const MatrixType& m)
v1[r] = x;
VERIFY_IS_APPROX(x, v1[r]);
- // test fetching with various index types.
- Index r1 = internal::random<Index>(0, numext::mini(Index(127),rows-1));
- x = v1(static_cast<char>(r1));
- x = v1(static_cast<signed char>(r1));
- x = v1(static_cast<unsigned char>(r1));
- x = v1(static_cast<signed short>(r1));
- x = v1(static_cast<unsigned short>(r1));
- x = v1(static_cast<signed int>(r1));
- x = v1(static_cast<unsigned int>(r1));
- x = v1(static_cast<signed long>(r1));
- x = v1(static_cast<unsigned long>(r1));
-#if EIGEN_HAS_CXX11
- x = v1(static_cast<long long int>(r1));
- x = v1(static_cast<unsigned long long int>(r1));
-#endif
-
VERIFY_IS_APPROX( v1, v1);
VERIFY_IS_NOT_APPROX( v1, 2*v1);
VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1);
diff --git a/eigen/test/block.cpp b/eigen/test/block.cpp
index d610598..39565af 100644
--- a/eigen/test/block.cpp
+++ b/eigen/test/block.cpp
@@ -29,13 +29,6 @@ block_real_only(const MatrixType &, Index, Index, Index, Index, const Scalar&) {
return Scalar(0);
}
-// Check at compile-time that T1==T2, and at runtime-time that a==b
-template<typename T1,typename T2>
-typename internal::enable_if<internal::is_same<T1,T2>::value,bool>::type
-is_same_block(const T1& a, const T2& b)
-{
- return a.isApprox(b);
-}
template<typename MatrixType> void block(const MatrixType& m)
{
@@ -94,9 +87,10 @@ template<typename MatrixType> void block(const MatrixType& m)
m1.block(r1,c1,r2-r1+1,c2-c1+1) = s1 * m2.block(0, 0, r2-r1+1,c2-c1+1);
m1.block(r1,c1,r2-r1+1,c2-c1+1)(r2-r1,c2-c1) = m2.block(0, 0, r2-r1+1,c2-c1+1)(0,0);
- const Index BlockRows = 2;
- const Index BlockCols = 5;
-
+ enum {
+ BlockRows = 2,
+ BlockCols = 5
+ };
if (rows>=5 && cols>=8)
{
// test fixed block() as lvalue
@@ -112,11 +106,6 @@ template<typename MatrixType> void block(const MatrixType& m)
m1.template block<BlockRows,Dynamic>(1,1,BlockRows,BlockCols)(0,3) = m1.template block<2,5>(1,1)(1,2);
Matrix<Scalar,Dynamic,Dynamic> b2 = m1.template block<Dynamic,BlockCols>(3,3,2,5);
VERIFY_IS_EQUAL(b2, m1.block(3,3,BlockRows,BlockCols));
-
- VERIFY(is_same_block(m1.block(3,3,BlockRows,BlockCols), m1.block(3,3,fix<Dynamic>(BlockRows),fix<Dynamic>(BlockCols))));
- VERIFY(is_same_block(m1.template block<BlockRows,Dynamic>(1,1,BlockRows,BlockCols), m1.block(1,1,fix<BlockRows>,BlockCols)));
- VERIFY(is_same_block(m1.template block<BlockRows,BlockCols>(1,1,BlockRows,BlockCols), m1.block(1,1,fix<BlockRows>(),fix<BlockCols>)));
- VERIFY(is_same_block(m1.template block<BlockRows,BlockCols>(1,1,BlockRows,BlockCols), m1.block(1,1,fix<BlockRows>,fix<BlockCols>(BlockCols))));
}
if (rows>2)
diff --git a/eigen/test/cholmod_support.cpp b/eigen/test/cholmod_support.cpp
index 9312073..a7eda28 100644
--- a/eigen/test/cholmod_support.cpp
+++ b/eigen/test/cholmod_support.cpp
@@ -12,21 +12,21 @@
#include <Eigen/CholmodSupport>
-template<typename SparseType> void test_cholmod_ST()
+template<typename T> void test_cholmod_T()
{
- CholmodDecomposition<SparseType, Lower> g_chol_colmajor_lower; g_chol_colmajor_lower.setMode(CholmodSupernodalLLt);
- CholmodDecomposition<SparseType, Upper> g_chol_colmajor_upper; g_chol_colmajor_upper.setMode(CholmodSupernodalLLt);
- CholmodDecomposition<SparseType, Lower> g_llt_colmajor_lower; g_llt_colmajor_lower.setMode(CholmodSimplicialLLt);
- CholmodDecomposition<SparseType, Upper> g_llt_colmajor_upper; g_llt_colmajor_upper.setMode(CholmodSimplicialLLt);
- CholmodDecomposition<SparseType, Lower> g_ldlt_colmajor_lower; g_ldlt_colmajor_lower.setMode(CholmodLDLt);
- CholmodDecomposition<SparseType, Upper> g_ldlt_colmajor_upper; g_ldlt_colmajor_upper.setMode(CholmodLDLt);
+ CholmodDecomposition<SparseMatrix<T>, Lower> g_chol_colmajor_lower; g_chol_colmajor_lower.setMode(CholmodSupernodalLLt);
+ CholmodDecomposition<SparseMatrix<T>, Upper> g_chol_colmajor_upper; g_chol_colmajor_upper.setMode(CholmodSupernodalLLt);
+ CholmodDecomposition<SparseMatrix<T>, Lower> g_llt_colmajor_lower; g_llt_colmajor_lower.setMode(CholmodSimplicialLLt);
+ CholmodDecomposition<SparseMatrix<T>, Upper> g_llt_colmajor_upper; g_llt_colmajor_upper.setMode(CholmodSimplicialLLt);
+ CholmodDecomposition<SparseMatrix<T>, Lower> g_ldlt_colmajor_lower; g_ldlt_colmajor_lower.setMode(CholmodLDLt);
+ CholmodDecomposition<SparseMatrix<T>, Upper> g_ldlt_colmajor_upper; g_ldlt_colmajor_upper.setMode(CholmodLDLt);
- CholmodSupernodalLLT<SparseType, Lower> chol_colmajor_lower;
- CholmodSupernodalLLT<SparseType, Upper> chol_colmajor_upper;
- CholmodSimplicialLLT<SparseType, Lower> llt_colmajor_lower;
- CholmodSimplicialLLT<SparseType, Upper> llt_colmajor_upper;
- CholmodSimplicialLDLT<SparseType, Lower> ldlt_colmajor_lower;
- CholmodSimplicialLDLT<SparseType, Upper> ldlt_colmajor_upper;
+ CholmodSupernodalLLT<SparseMatrix<T>, Lower> chol_colmajor_lower;
+ CholmodSupernodalLLT<SparseMatrix<T>, Upper> chol_colmajor_upper;
+ CholmodSimplicialLLT<SparseMatrix<T>, Lower> llt_colmajor_lower;
+ CholmodSimplicialLLT<SparseMatrix<T>, Upper> llt_colmajor_upper;
+ CholmodSimplicialLDLT<SparseMatrix<T>, Lower> ldlt_colmajor_lower;
+ CholmodSimplicialLDLT<SparseMatrix<T>, Upper> ldlt_colmajor_upper;
check_sparse_spd_solving(g_chol_colmajor_lower);
check_sparse_spd_solving(g_chol_colmajor_upper);
@@ -50,20 +50,8 @@ template<typename SparseType> void test_cholmod_ST()
check_sparse_spd_determinant(ldlt_colmajor_upper);
}
-template<typename T, int flags, typename IdxType> void test_cholmod_T()
-{
- test_cholmod_ST<SparseMatrix<T, flags, IdxType> >();
-}
-
void test_cholmod_support()
{
- CALL_SUBTEST_11( (test_cholmod_T<double , ColMajor, int >()) );
- CALL_SUBTEST_12( (test_cholmod_T<double , ColMajor, long>()) );
- CALL_SUBTEST_13( (test_cholmod_T<double , RowMajor, int >()) );
- CALL_SUBTEST_14( (test_cholmod_T<double , RowMajor, long>()) );
- CALL_SUBTEST_21( (test_cholmod_T<std::complex<double>, ColMajor, int >()) );
- CALL_SUBTEST_22( (test_cholmod_T<std::complex<double>, ColMajor, long>()) );
- // TODO complex row-major matrices do not work at the moment:
- // CALL_SUBTEST_23( (test_cholmod_T<std::complex<double>, RowMajor, int >()) );
- // CALL_SUBTEST_24( (test_cholmod_T<std::complex<double>, RowMajor, long>()) );
+ CALL_SUBTEST_1(test_cholmod_T<double>());
+ CALL_SUBTEST_2(test_cholmod_T<std::complex<double> >());
}
diff --git a/eigen/test/geo_alignedbox.cpp b/eigen/test/geo_alignedbox.cpp
index 223ff5e..d2339a6 100644
--- a/eigen/test/geo_alignedbox.cpp
+++ b/eigen/test/geo_alignedbox.cpp
@@ -15,17 +15,8 @@
#include<iostream>
using namespace std;
-// NOTE the following workaround was needed on some 32 bits builds to kill extra precision of x87 registers.
-// It seems that it os not needed anymore, but let's keep it here, just in case...
-
template<typename T> EIGEN_DONT_INLINE
-void kill_extra_precision(T& /* x */) {
- // This one worked but triggered a warning:
- /* eigen_assert((void*)(&x) != (void*)0); */
- // An alternative could be:
- /* volatile T tmp = x; */
- /* x = tmp; */
-}
+void kill_extra_precision(T& x) { eigen_assert((void*)(&x) != (void*)0); }
template<typename BoxType> void alignedbox(const BoxType& _box)
diff --git a/eigen/test/geo_parametrizedline.cpp b/eigen/test/geo_parametrizedline.cpp
index 29c1b10..9bf5f3c 100644
--- a/eigen/test/geo_parametrizedline.cpp
+++ b/eigen/test/geo_parametrizedline.cpp
@@ -25,8 +25,6 @@ template<typename LineType> void parametrizedline(const LineType& _line)
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef Matrix<Scalar, LineType::AmbientDimAtCompileTime, 1> VectorType;
typedef Hyperplane<Scalar,LineType::AmbientDimAtCompileTime> HyperplaneType;
- typedef Matrix<Scalar, HyperplaneType::AmbientDimAtCompileTime,
- HyperplaneType::AmbientDimAtCompileTime> MatrixType;
VectorType p0 = VectorType::Random(dim);
VectorType p1 = VectorType::Random(dim);
@@ -61,31 +59,6 @@ template<typename LineType> void parametrizedline(const LineType& _line)
VERIFY_IS_MUCH_SMALLER_THAN(hp.signedDistance(pi), RealScalar(1));
VERIFY_IS_MUCH_SMALLER_THAN(l0.distance(pi), RealScalar(1));
VERIFY_IS_APPROX(l0.intersectionPoint(hp), pi);
-
- // transform
- if (!NumTraits<Scalar>::IsComplex)
- {
- MatrixType rot = MatrixType::Random(dim,dim).householderQr().householderQ();
- DiagonalMatrix<Scalar,LineType::AmbientDimAtCompileTime> scaling(VectorType::Random());
- Translation<Scalar,LineType::AmbientDimAtCompileTime> translation(VectorType::Random());
-
- while(scaling.diagonal().cwiseAbs().minCoeff()<RealScalar(1e-4)) scaling.diagonal() = VectorType::Random();
-
- LineType l1 = l0;
- VectorType p3 = l0.pointAt(Scalar(1));
- VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot).distance(rot * p3), Scalar(1) );
- l1 = l0;
- VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot,Isometry).distance(rot * p3), Scalar(1) );
- l1 = l0;
- VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot*scaling).distance((rot*scaling) * p3), Scalar(1) );
- l1 = l0;
- VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot*scaling*translation)
- .distance((rot*scaling*translation) * p3), Scalar(1) );
- l1 = l0;
- VERIFY_IS_MUCH_SMALLER_THAN( l1.transform(rot*translation,Isometry)
- .distance((rot*translation) * p3), Scalar(1) );
- }
-
}
template<typename Scalar> void parametrizedline_alignment()
diff --git a/eigen/test/half_float.cpp b/eigen/test/half_float.cpp
index 6f31968..3d2410a 100644
--- a/eigen/test/half_float.cpp
+++ b/eigen/test/half_float.cpp
@@ -96,12 +96,24 @@ void test_conversion()
void test_numtraits()
{
- std::cout << "epsilon = " << NumTraits<half>::epsilon() << std::endl;
- std::cout << "highest = " << NumTraits<half>::highest() << std::endl;
- std::cout << "lowest = " << NumTraits<half>::lowest() << std::endl;
- std::cout << "inifinty = " << NumTraits<half>::infinity() << std::endl;
- std::cout << "nan = " << NumTraits<half>::quiet_NaN() << std::endl;
-
+ std::cout << "epsilon = " << NumTraits<half>::epsilon() << " (0x" << std::hex << NumTraits<half>::epsilon().x << ")" << std::endl;
+ std::cout << "highest = " << NumTraits<half>::highest() << " (0x" << std::hex << NumTraits<half>::highest().x << ")" << std::endl;
+ std::cout << "lowest = " << NumTraits<half>::lowest() << " (0x" << std::hex << NumTraits<half>::lowest().x << ")" << std::endl;
+ std::cout << "min = " << (std::numeric_limits<half>::min)() << " (0x" << std::hex << half((std::numeric_limits<half>::min)()).x << ")" << std::endl;
+ std::cout << "denorm min = " << (std::numeric_limits<half>::denorm_min)() << " (0x" << std::hex << half((std::numeric_limits<half>::denorm_min)()).x << ")" << std::endl;
+ std::cout << "infinity = " << NumTraits<half>::infinity() << " (0x" << std::hex << NumTraits<half>::infinity().x << ")" << std::endl;
+ std::cout << "quiet nan = " << NumTraits<half>::quiet_NaN() << " (0x" << std::hex << NumTraits<half>::quiet_NaN().x << ")" << std::endl;
+ std::cout << "signaling nan = " << std::numeric_limits<half>::signaling_NaN() << " (0x" << std::hex << std::numeric_limits<half>::signaling_NaN().x << ")" << std::endl;
+
+ VERIFY(NumTraits<half>::IsSigned);
+
+ VERIFY_IS_EQUAL( std::numeric_limits<half>::infinity().x, half(std::numeric_limits<float>::infinity()).x );
+ VERIFY_IS_EQUAL( std::numeric_limits<half>::quiet_NaN().x, half(std::numeric_limits<float>::quiet_NaN()).x );
+ VERIFY_IS_EQUAL( std::numeric_limits<half>::signaling_NaN().x, half(std::numeric_limits<float>::signaling_NaN()).x );
+ VERIFY( (std::numeric_limits<half>::min)() > half(0.f) );
+ VERIFY( (std::numeric_limits<half>::denorm_min)() > half(0.f) );
+ VERIFY( (std::numeric_limits<half>::min)()/half(2) > half(0.f) );
+ VERIFY_IS_EQUAL( (std::numeric_limits<half>::denorm_min)()/half(2), half(0.f) );
}
void test_arithmetic()
@@ -185,11 +197,6 @@ void test_basic_functions()
VERIFY_IS_APPROX(float(numext::exp(half(EIGEN_PI))), 20.f + float(EIGEN_PI));
VERIFY_IS_APPROX(float(exp(half(EIGEN_PI))), 20.f + float(EIGEN_PI));
- VERIFY_IS_EQUAL(float(numext::expm1(half(0.0f))), 0.0f);
- VERIFY_IS_EQUAL(float(expm1(half(0.0f))), 0.0f);
- VERIFY_IS_APPROX(float(numext::expm1(half(2.0f))), 6.3890561f);
- VERIFY_IS_APPROX(float(expm1(half(2.0f))), 6.3890561f);
-
VERIFY_IS_EQUAL(float(numext::log(half(1.0f))), 0.0f);
VERIFY_IS_EQUAL(float(log(half(1.0f))), 0.0f);
VERIFY_IS_APPROX(float(numext::log(half(10.0f))), 2.30273f);
diff --git a/eigen/test/indexed_view.cpp b/eigen/test/indexed_view.cpp
deleted file mode 100644
index 7245cf3..0000000
--- a/eigen/test/indexed_view.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2017 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/.
-
-#ifdef EIGEN_TEST_PART_2
-// Make sure we also check c++11 max implementation
-#define EIGEN_MAX_CPP_VER 11
-#endif
-
-#ifdef EIGEN_TEST_PART_3
-// Make sure we also check c++98 max implementation
-#define EIGEN_MAX_CPP_VER 03
-#endif
-
-#include <valarray>
-#include <vector>
-#include "main.h"
-
-#if EIGEN_HAS_CXX11
-#include <array>
-#endif
-
-typedef std::pair<Index,Index> IndexPair;
-
-int encode(Index i, Index j) {
- return int(i*100 + j);
-}
-
-IndexPair decode(Index ij) {
- return IndexPair(ij / 100, ij % 100);
-}
-
-template<typename T>
-bool match(const T& xpr, std::string ref, std::string str_xpr = "") {
- EIGEN_UNUSED_VARIABLE(str_xpr);
- std::stringstream str;
- str << xpr;
- if(!(str.str() == ref))
- std::cout << str_xpr << "\n" << xpr << "\n\n";
- return str.str() == ref;
-}
-
-#define MATCH(X,R) match(X, R, #X)
-
-template<typename T1,typename T2>
-typename internal::enable_if<internal::is_same<T1,T2>::value,bool>::type
-is_same_eq(const T1& a, const T2& b)
-{
- return (a == b).all();
-}
-
-template<typename T1,typename T2>
-bool is_same_seq(const T1& a, const T2& b)
-{
- bool ok = a.first()==b.first() && a.size() == b.size() && Index(a.incrObject())==Index(b.incrObject());;
- if(!ok)
- {
- std::cerr << "seqN(" << a.first() << ", " << a.size() << ", " << Index(a.incrObject()) << ") != ";
- std::cerr << "seqN(" << b.first() << ", " << b.size() << ", " << Index(b.incrObject()) << ")\n";
- }
- return ok;
-}
-
-template<typename T1,typename T2>
-typename internal::enable_if<internal::is_same<T1,T2>::value,bool>::type
-is_same_seq_type(const T1& a, const T2& b)
-{
- return is_same_seq(a,b);
-}
-
-
-
-#define VERIFY_EQ_INT(A,B) VERIFY_IS_APPROX(int(A),int(B))
-
-void check_indexed_view()
-{
- using Eigen::placeholders::all;
- using Eigen::placeholders::last;
- using Eigen::placeholders::end;
-
- Index n = 10;
-
- ArrayXd a = ArrayXd::LinSpaced(n,0,n-1);
- Array<double,1,Dynamic> b = a.transpose();
-
- ArrayXXi A = ArrayXXi::NullaryExpr(n,n, std::ptr_fun(encode));
-
- for(Index i=0; i<n; ++i)
- for(Index j=0; j<n; ++j)
- VERIFY( decode(A(i,j)) == IndexPair(i,j) );
-
- Array4i eii(4); eii << 3, 1, 6, 5;
- std::valarray<int> vali(4); Map<ArrayXi>(&vali[0],4) = eii;
- std::vector<int> veci(4); Map<ArrayXi>(veci.data(),4) = eii;
-
- VERIFY( MATCH( A(3, seq(9,3,-1)),
- "309 308 307 306 305 304 303")
- );
-
- VERIFY( MATCH( A(seqN(2,5), seq(9,3,-1)),
- "209 208 207 206 205 204 203\n"
- "309 308 307 306 305 304 303\n"
- "409 408 407 406 405 404 403\n"
- "509 508 507 506 505 504 503\n"
- "609 608 607 606 605 604 603")
- );
-
- VERIFY( MATCH( A(seqN(2,5), 5),
- "205\n"
- "305\n"
- "405\n"
- "505\n"
- "605")
- );
-
- VERIFY( MATCH( A(seqN(last,5,-1), seq(2,last)),
- "902 903 904 905 906 907 908 909\n"
- "802 803 804 805 806 807 808 809\n"
- "702 703 704 705 706 707 708 709\n"
- "602 603 604 605 606 607 608 609\n"
- "502 503 504 505 506 507 508 509")
- );
-
- VERIFY( MATCH( A(eii, veci),
- "303 301 306 305\n"
- "103 101 106 105\n"
- "603 601 606 605\n"
- "503 501 506 505")
- );
-
- VERIFY( MATCH( A(eii, all),
- "300 301 302 303 304 305 306 307 308 309\n"
- "100 101 102 103 104 105 106 107 108 109\n"
- "600 601 602 603 604 605 606 607 608 609\n"
- "500 501 502 503 504 505 506 507 508 509")
- );
-
- // takes the row numer 3, and repeat it 5 times
- VERIFY( MATCH( A(seqN(3,5,0), all),
- "300 301 302 303 304 305 306 307 308 309\n"
- "300 301 302 303 304 305 306 307 308 309\n"
- "300 301 302 303 304 305 306 307 308 309\n"
- "300 301 302 303 304 305 306 307 308 309\n"
- "300 301 302 303 304 305 306 307 308 309")
- );
-
- VERIFY( MATCH( a(seqN(3,3),0), "3\n4\n5" ) );
- VERIFY( MATCH( a(seq(3,5)), "3\n4\n5" ) );
- VERIFY( MATCH( a(seqN(3,3,1)), "3\n4\n5" ) );
- VERIFY( MATCH( a(seqN(5,3,-1)), "5\n4\n3" ) );
-
- VERIFY( MATCH( b(0,seqN(3,3)), "3 4 5" ) );
- VERIFY( MATCH( b(seq(3,5)), "3 4 5" ) );
- VERIFY( MATCH( b(seqN(3,3,1)), "3 4 5" ) );
- VERIFY( MATCH( b(seqN(5,3,-1)), "5 4 3" ) );
-
- VERIFY( MATCH( b(all), "0 1 2 3 4 5 6 7 8 9" ) );
- VERIFY( MATCH( b(eii), "3 1 6 5" ) );
-
- Array44i B;
- B.setRandom();
- VERIFY( (A(seqN(2,5), 5)).ColsAtCompileTime == 1);
- VERIFY( (A(seqN(2,5), 5)).RowsAtCompileTime == Dynamic);
- VERIFY_EQ_INT( (A(seqN(2,5), 5)).InnerStrideAtCompileTime , A.InnerStrideAtCompileTime);
- VERIFY_EQ_INT( (A(seqN(2,5), 5)).OuterStrideAtCompileTime , A.col(5).OuterStrideAtCompileTime);
-
- VERIFY_EQ_INT( (A(5,seqN(2,5))).InnerStrideAtCompileTime , A.row(5).InnerStrideAtCompileTime);
- VERIFY_EQ_INT( (A(5,seqN(2,5))).OuterStrideAtCompileTime , A.row(5).OuterStrideAtCompileTime);
- VERIFY_EQ_INT( (B(1,seqN(1,2))).InnerStrideAtCompileTime , B.row(1).InnerStrideAtCompileTime);
- VERIFY_EQ_INT( (B(1,seqN(1,2))).OuterStrideAtCompileTime , B.row(1).OuterStrideAtCompileTime);
-
- VERIFY_EQ_INT( (A(seqN(2,5), seq(1,3))).InnerStrideAtCompileTime , A.InnerStrideAtCompileTime);
- VERIFY_EQ_INT( (A(seqN(2,5), seq(1,3))).OuterStrideAtCompileTime , A.OuterStrideAtCompileTime);
- VERIFY_EQ_INT( (B(seqN(1,2), seq(1,3))).InnerStrideAtCompileTime , B.InnerStrideAtCompileTime);
- VERIFY_EQ_INT( (B(seqN(1,2), seq(1,3))).OuterStrideAtCompileTime , B.OuterStrideAtCompileTime);
- VERIFY_EQ_INT( (A(seqN(2,5,2), seq(1,3,2))).InnerStrideAtCompileTime , Dynamic);
- VERIFY_EQ_INT( (A(seqN(2,5,2), seq(1,3,2))).OuterStrideAtCompileTime , Dynamic);
- VERIFY_EQ_INT( (A(seqN(2,5,fix<2>), seq(1,3,fix<3>))).InnerStrideAtCompileTime , 2);
- VERIFY_EQ_INT( (A(seqN(2,5,fix<2>), seq(1,3,fix<3>))).OuterStrideAtCompileTime , Dynamic);
- VERIFY_EQ_INT( (B(seqN(1,2,fix<2>), seq(1,3,fix<3>))).InnerStrideAtCompileTime , 2);
- VERIFY_EQ_INT( (B(seqN(1,2,fix<2>), seq(1,3,fix<3>))).OuterStrideAtCompileTime , 3*4);
-
- VERIFY_EQ_INT( (A(seqN(2,fix<5>), seqN(1,fix<3>))).RowsAtCompileTime, 5);
- VERIFY_EQ_INT( (A(seqN(2,fix<5>), seqN(1,fix<3>))).ColsAtCompileTime, 3);
- VERIFY_EQ_INT( (A(seqN(2,fix<5>(5)), seqN(1,fix<3>(3)))).RowsAtCompileTime, 5);
- VERIFY_EQ_INT( (A(seqN(2,fix<5>(5)), seqN(1,fix<3>(3)))).ColsAtCompileTime, 3);
- VERIFY_EQ_INT( (A(seqN(2,fix<Dynamic>(5)), seqN(1,fix<Dynamic>(3)))).RowsAtCompileTime, Dynamic);
- VERIFY_EQ_INT( (A(seqN(2,fix<Dynamic>(5)), seqN(1,fix<Dynamic>(3)))).ColsAtCompileTime, Dynamic);
- VERIFY_EQ_INT( (A(seqN(2,fix<Dynamic>(5)), seqN(1,fix<Dynamic>(3)))).rows(), 5);
- VERIFY_EQ_INT( (A(seqN(2,fix<Dynamic>(5)), seqN(1,fix<Dynamic>(3)))).cols(), 3);
-
- VERIFY( is_same_seq_type( seqN(2,5,fix<-1>), seqN(2,5,fix<-1>(-1)) ) );
- VERIFY( is_same_seq_type( seqN(2,5), seqN(2,5,fix<1>(1)) ) );
- VERIFY( is_same_seq_type( seqN(2,5,3), seqN(2,5,fix<DynamicIndex>(3)) ) );
- VERIFY( is_same_seq_type( seq(2,7,fix<3>), seqN(2,2,fix<3>) ) );
- VERIFY( is_same_seq_type( seqN(2,fix<Dynamic>(5),3), seqN(2,5,fix<DynamicIndex>(3)) ) );
- VERIFY( is_same_seq_type( seqN(2,fix<5>(5),fix<-2>), seqN(2,fix<5>,fix<-2>()) ) );
-
- VERIFY( is_same_seq_type( seq(2,fix<5>), seqN(2,4) ) );
-#if EIGEN_HAS_CXX11
- VERIFY( is_same_seq_type( seq(fix<2>,fix<5>), seqN(fix<2>,fix<4>) ) );
- VERIFY( is_same_seq( seqN(2,std::integral_constant<int,5>(),std::integral_constant<int,-2>()), seqN(2,fix<5>,fix<-2>()) ) );
- VERIFY( is_same_seq( seq(std::integral_constant<int,1>(),std::integral_constant<int,5>(),std::integral_constant<int,2>()),
- seq(fix<1>,fix<5>,fix<2>()) ) );
- VERIFY( is_same_seq_type( seqN(2,std::integral_constant<int,5>(),std::integral_constant<int,-2>()), seqN(2,fix<5>,fix<-2>()) ) );
- VERIFY( is_same_seq_type( seq(std::integral_constant<int,1>(),std::integral_constant<int,5>(),std::integral_constant<int,2>()),
- seq(fix<1>,fix<5>,fix<2>()) ) );
-
- VERIFY( is_same_seq_type( seqN(2,std::integral_constant<int,5>()), seqN(2,fix<5>) ) );
- VERIFY( is_same_seq_type( seq(std::integral_constant<int,1>(),std::integral_constant<int,5>()), seq(fix<1>,fix<5>) ) );
-#else
- // sorry, no compile-time size recovery in c++98/03
- VERIFY( is_same_seq( seq(fix<2>,fix<5>), seqN(fix<2>,fix<4>) ) );
-#endif
-
- VERIFY( (A(seqN(2,fix<5>), 5)).RowsAtCompileTime == 5);
- VERIFY( (A(4, all)).ColsAtCompileTime == Dynamic);
- VERIFY( (A(4, all)).RowsAtCompileTime == 1);
- VERIFY( (B(1, all)).ColsAtCompileTime == 4);
- VERIFY( (B(1, all)).RowsAtCompileTime == 1);
- VERIFY( (B(all,1)).ColsAtCompileTime == 1);
- VERIFY( (B(all,1)).RowsAtCompileTime == 4);
-
- VERIFY(int( (A(all, eii)).ColsAtCompileTime) == int(eii.SizeAtCompileTime));
- VERIFY_EQ_INT( (A(eii, eii)).Flags&DirectAccessBit, (unsigned int)(0));
- VERIFY_EQ_INT( (A(eii, eii)).InnerStrideAtCompileTime, 0);
- VERIFY_EQ_INT( (A(eii, eii)).OuterStrideAtCompileTime, 0);
-
- VERIFY_IS_APPROX( A(seq(n-1,2,-2), seqN(n-1-6,3,-1)), A(seq(last,2,fix<-2>), seqN(last-6,3,fix<-1>)) );
-
- VERIFY_IS_APPROX( A(seq(n-1,2,-2), seqN(n-1-6,4)), A(seq(last,2,-2), seqN(last-6,4)) );
- VERIFY_IS_APPROX( A(seq(n-1-6,n-1-2), seqN(n-1-6,4)), A(seq(last-6,last-2), seqN(6+last-6-6,4)) );
- VERIFY_IS_APPROX( A(seq((n-1)/2,(n)/2+3), seqN(2,4)), A(seq(last/2,(last+1)/2+3), seqN(last+2-last,4)) );
- VERIFY_IS_APPROX( A(seq(n-2,2,-2), seqN(n-8,4)), A(seq(end-2,2,-2), seqN(end-8,4)) );
-
- // Check all combinations of seq:
- VERIFY_IS_APPROX( A(seq(1,n-1-2,2), seq(1,n-1-2,2)), A(seq(1,last-2,2), seq(1,last-2,fix<2>)) );
- VERIFY_IS_APPROX( A(seq(n-1-5,n-1-2,2), seq(n-1-5,n-1-2,2)), A(seq(last-5,last-2,2), seq(last-5,last-2,fix<2>)) );
- VERIFY_IS_APPROX( A(seq(n-1-5,7,2), seq(n-1-5,7,2)), A(seq(last-5,7,2), seq(last-5,7,fix<2>)) );
- VERIFY_IS_APPROX( A(seq(1,n-1-2), seq(n-1-5,7)), A(seq(1,last-2), seq(last-5,7)) );
- VERIFY_IS_APPROX( A(seq(n-1-5,n-1-2), seq(n-1-5,n-1-2)), A(seq(last-5,last-2), seq(last-5,last-2)) );
-
- VERIFY_IS_APPROX( A.col(A.cols()-1), A(all,last) );
- VERIFY_IS_APPROX( A(A.rows()-2, A.cols()/2), A(last-1, end/2) );
- VERIFY_IS_APPROX( a(a.size()-2), a(last-1) );
- VERIFY_IS_APPROX( a(a.size()/2), a((last+1)/2) );
-
- // Check fall-back to Block
- {
- VERIFY( is_same_eq(A.col(0), A(all,0)) );
- VERIFY( is_same_eq(A.row(0), A(0,all)) );
- VERIFY( is_same_eq(A.block(0,0,2,2), A(seqN(0,2),seq(0,1))) );
- VERIFY( is_same_eq(A.middleRows(2,4), A(seqN(2,4),all)) );
- VERIFY( is_same_eq(A.middleCols(2,4), A(all,seqN(2,4))) );
-
- VERIFY( is_same_eq(A.col(A.cols()-1), A(all,last)) );
-
- const ArrayXXi& cA(A);
- VERIFY( is_same_eq(cA.col(0), cA(all,0)) );
- VERIFY( is_same_eq(cA.row(0), cA(0,all)) );
- VERIFY( is_same_eq(cA.block(0,0,2,2), cA(seqN(0,2),seq(0,1))) );
- VERIFY( is_same_eq(cA.middleRows(2,4), cA(seqN(2,4),all)) );
- VERIFY( is_same_eq(cA.middleCols(2,4), cA(all,seqN(2,4))) );
-
- VERIFY( is_same_eq(a.head(4), a(seq(0,3))) );
- VERIFY( is_same_eq(a.tail(4), a(seqN(last-3,4))) );
- VERIFY( is_same_eq(a.tail(4), a(seq(end-4,last))) );
- VERIFY( is_same_eq(a.segment<4>(3), a(seqN(3,fix<4>))) );
- }
-
- ArrayXXi A1=A, A2 = ArrayXXi::Random(4,4);
- ArrayXi range25(4); range25 << 3,2,4,5;
- A1(seqN(3,4),seq(2,5)) = A2;
- VERIFY_IS_APPROX( A1.block(3,2,4,4), A2 );
- A1 = A;
- A2.setOnes();
- A1(seq(6,3,-1),range25) = A2;
- VERIFY_IS_APPROX( A1.block(3,2,4,4), A2 );
-
- // check reverse
- {
- VERIFY( is_same_seq_type( seq(3,7).reverse(), seqN(7,5,fix<-1>) ) );
- VERIFY( is_same_seq_type( seq(7,3,fix<-2>).reverse(), seqN(3,3,fix<2>) ) );
- VERIFY_IS_APPROX( a(seqN(2,last/2).reverse()), a(seqN(2+(last/2-1)*1,last/2,fix<-1>)) );
- VERIFY_IS_APPROX( a(seqN(last/2,fix<4>).reverse()),a(seqN(last/2,fix<4>)).reverse() );
- VERIFY_IS_APPROX( A(seq(last-5,last-1,2).reverse(), seqN(last-3,3,fix<-2>).reverse()),
- A(seq(last-5,last-1,2), seqN(last-3,3,fix<-2>)).reverse() );
- }
-
-#if EIGEN_HAS_CXX11
- VERIFY( (A(all, std::array<int,4>{{1,3,2,4}})).ColsAtCompileTime == 4);
-
- VERIFY_IS_APPROX( (A(std::array<int,3>{{1,3,5}}, std::array<int,4>{{9,6,3,0}})), A(seqN(1,3,2), seqN(9,4,-3)) );
-
-#if EIGEN_HAS_STATIC_ARRAY_TEMPLATE
- VERIFY_IS_APPROX( A({3, 1, 6, 5}, all), A(std::array<int,4>{{3, 1, 6, 5}}, all) );
- VERIFY_IS_APPROX( A(all,{3, 1, 6, 5}), A(all,std::array<int,4>{{3, 1, 6, 5}}) );
- VERIFY_IS_APPROX( A({1,3,5},{3, 1, 6, 5}), A(std::array<int,3>{{1,3,5}},std::array<int,4>{{3, 1, 6, 5}}) );
-
- VERIFY_IS_EQUAL( A({1,3,5},{3, 1, 6, 5}).RowsAtCompileTime, 3 );
- VERIFY_IS_EQUAL( A({1,3,5},{3, 1, 6, 5}).ColsAtCompileTime, 4 );
-
- VERIFY_IS_APPROX( a({3, 1, 6, 5}), a(std::array<int,4>{{3, 1, 6, 5}}) );
- VERIFY_IS_EQUAL( a({1,3,5}).SizeAtCompileTime, 3 );
-
- VERIFY_IS_APPROX( b({3, 1, 6, 5}), b(std::array<int,4>{{3, 1, 6, 5}}) );
- VERIFY_IS_EQUAL( b({1,3,5}).SizeAtCompileTime, 3 );
-#endif
-
-#endif
-
- // check mat(i,j) with weird types for i and j
- {
- VERIFY_IS_APPROX( A(B.RowsAtCompileTime-1, 1), A(3,1) );
- VERIFY_IS_APPROX( A(B.RowsAtCompileTime, 1), A(4,1) );
- VERIFY_IS_APPROX( A(B.RowsAtCompileTime-1, B.ColsAtCompileTime-1), A(3,3) );
- VERIFY_IS_APPROX( A(B.RowsAtCompileTime, B.ColsAtCompileTime), A(4,4) );
- const Index I = 3, J = 4;
- VERIFY_IS_APPROX( A(I,J), A(3,4) );
- }
-
- // check extended block API
- {
- VERIFY( is_same_eq( A.block<3,4>(1,1), A.block(1,1,fix<3>,fix<4>)) );
- VERIFY( is_same_eq( A.block<3,4>(1,1,3,4), A.block(1,1,fix<3>(),fix<4>(4))) );
- VERIFY( is_same_eq( A.block<3,Dynamic>(1,1,3,4), A.block(1,1,fix<3>,4)) );
- VERIFY( is_same_eq( A.block<Dynamic,4>(1,1,3,4), A.block(1,1,fix<Dynamic>(3),fix<4>)) );
- VERIFY( is_same_eq( A.block(1,1,3,4), A.block(1,1,fix<Dynamic>(3),fix<Dynamic>(4))) );
-
- VERIFY( is_same_eq( A.topLeftCorner<3,4>(), A.topLeftCorner(fix<3>,fix<4>)) );
- VERIFY( is_same_eq( A.bottomLeftCorner<3,4>(), A.bottomLeftCorner(fix<3>,fix<4>)) );
- VERIFY( is_same_eq( A.bottomRightCorner<3,4>(), A.bottomRightCorner(fix<3>,fix<4>)) );
- VERIFY( is_same_eq( A.topRightCorner<3,4>(), A.topRightCorner(fix<3>,fix<4>)) );
-
- VERIFY( is_same_eq( A.leftCols<3>(), A.leftCols(fix<3>)) );
- VERIFY( is_same_eq( A.rightCols<3>(), A.rightCols(fix<3>)) );
- VERIFY( is_same_eq( A.middleCols<3>(1), A.middleCols(1,fix<3>)) );
-
- VERIFY( is_same_eq( A.topRows<3>(), A.topRows(fix<3>)) );
- VERIFY( is_same_eq( A.bottomRows<3>(), A.bottomRows(fix<3>)) );
- VERIFY( is_same_eq( A.middleRows<3>(1), A.middleRows(1,fix<3>)) );
-
- VERIFY( is_same_eq( a.segment<3>(1), a.segment(1,fix<3>)) );
- VERIFY( is_same_eq( a.head<3>(), a.head(fix<3>)) );
- VERIFY( is_same_eq( a.tail<3>(), a.tail(fix<3>)) );
-
- const ArrayXXi& cA(A);
- VERIFY( is_same_eq( cA.block<Dynamic,4>(1,1,3,4), cA.block(1,1,fix<Dynamic>(3),fix<4>)) );
-
- VERIFY( is_same_eq( cA.topLeftCorner<3,4>(), cA.topLeftCorner(fix<3>,fix<4>)) );
- VERIFY( is_same_eq( cA.bottomLeftCorner<3,4>(), cA.bottomLeftCorner(fix<3>,fix<4>)) );
- VERIFY( is_same_eq( cA.bottomRightCorner<3,4>(), cA.bottomRightCorner(fix<3>,fix<4>)) );
- VERIFY( is_same_eq( cA.topRightCorner<3,4>(), cA.topRightCorner(fix<3>,fix<4>)) );
-
- VERIFY( is_same_eq( cA.leftCols<3>(), cA.leftCols(fix<3>)) );
- VERIFY( is_same_eq( cA.rightCols<3>(), cA.rightCols(fix<3>)) );
- VERIFY( is_same_eq( cA.middleCols<3>(1), cA.middleCols(1,fix<3>)) );
-
- VERIFY( is_same_eq( cA.topRows<3>(), cA.topRows(fix<3>)) );
- VERIFY( is_same_eq( cA.bottomRows<3>(), cA.bottomRows(fix<3>)) );
- VERIFY( is_same_eq( cA.middleRows<3>(1), cA.middleRows(1,fix<3>)) );
- }
-
-}
-
-void test_indexed_view()
-{
-// for(int i = 0; i < g_repeat; i++) {
- CALL_SUBTEST_1( check_indexed_view() );
- CALL_SUBTEST_2( check_indexed_view() );
- CALL_SUBTEST_3( check_indexed_view() );
-// }
-}
diff --git a/eigen/test/lscg.cpp b/eigen/test/lscg.cpp
index daa62a9..d49ee00 100644
--- a/eigen/test/lscg.cpp
+++ b/eigen/test/lscg.cpp
@@ -14,12 +14,20 @@ template<typename T> void test_lscg_T()
{
LeastSquaresConjugateGradient<SparseMatrix<T> > lscg_colmajor_diag;
LeastSquaresConjugateGradient<SparseMatrix<T>, IdentityPreconditioner> lscg_colmajor_I;
+ LeastSquaresConjugateGradient<SparseMatrix<T,RowMajor> > lscg_rowmajor_diag;
+ LeastSquaresConjugateGradient<SparseMatrix<T,RowMajor>, IdentityPreconditioner> lscg_rowmajor_I;
CALL_SUBTEST( check_sparse_square_solving(lscg_colmajor_diag) );
CALL_SUBTEST( check_sparse_square_solving(lscg_colmajor_I) );
CALL_SUBTEST( check_sparse_leastsquare_solving(lscg_colmajor_diag) );
CALL_SUBTEST( check_sparse_leastsquare_solving(lscg_colmajor_I) );
+
+ CALL_SUBTEST( check_sparse_square_solving(lscg_rowmajor_diag) );
+ CALL_SUBTEST( check_sparse_square_solving(lscg_rowmajor_I) );
+
+ CALL_SUBTEST( check_sparse_leastsquare_solving(lscg_rowmajor_diag) );
+ CALL_SUBTEST( check_sparse_leastsquare_solving(lscg_rowmajor_I) );
}
void test_lscg()
diff --git a/eigen/test/main.h b/eigen/test/main.h
index 25d2dcf..bd53251 100644
--- a/eigen/test/main.h
+++ b/eigen/test/main.h
@@ -310,6 +310,17 @@ template<> inline float test_precision<std::complex<float> >() { return test_pre
template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }
template<> inline long double test_precision<std::complex<long double> >() { return test_precision<long double>(); }
+inline bool test_isApprox(const short& a, const short& b)
+{ return internal::isApprox(a, b, test_precision<short>()); }
+inline bool test_isApprox(const unsigned short& a, const unsigned short& b)
+{ return internal::isApprox(a, b, test_precision<unsigned long>()); }
+inline bool test_isApprox(const unsigned int& a, const unsigned int& b)
+{ return internal::isApprox(a, b, test_precision<unsigned int>()); }
+inline bool test_isApprox(const long& a, const long& b)
+{ return internal::isApprox(a, b, test_precision<long>()); }
+inline bool test_isApprox(const unsigned long& a, const unsigned long& b)
+{ return internal::isApprox(a, b, test_precision<unsigned long>()); }
+
inline bool test_isApprox(const int& a, const int& b)
{ return internal::isApprox(a, b, test_precision<int>()); }
inline bool test_isMuchSmallerThan(const int& a, const int& b)
diff --git a/eigen/test/mixingtypes.cpp b/eigen/test/mixingtypes.cpp
index b796082..ad9c2c6 100644
--- a/eigen/test/mixingtypes.cpp
+++ b/eigen/test/mixingtypes.cpp
@@ -69,7 +69,7 @@ template<int SizeAtCompileType> void mixingtypes(int size = SizeAtCompileType)
double epsd = std::sqrt(std::numeric_limits<double>::min EIGEN_EMPTY ());
while(std::abs(sf )<epsf) sf = internal::random<float>();
- while(std::abs(sd )<epsd) sd = internal::random<double>();
+ while(std::abs(sd )<epsd) sf = internal::random<double>();
while(std::abs(scf)<epsf) scf = internal::random<CF>();
while(std::abs(scd)<epsd) scd = internal::random<CD>();
diff --git a/eigen/test/numext.cpp b/eigen/test/numext.cpp
new file mode 100644
index 0000000..3de33e2
--- /dev/null
+++ b/eigen/test/numext.cpp
@@ -0,0 +1,53 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2017 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/.
+
+#include "main.h"
+
+template<typename T>
+void check_abs() {
+ typedef typename NumTraits<T>::Real Real;
+
+ if(NumTraits<T>::IsSigned)
+ VERIFY_IS_EQUAL(numext::abs(-T(1)), T(1));
+ VERIFY_IS_EQUAL(numext::abs(T(0)), T(0));
+ VERIFY_IS_EQUAL(numext::abs(T(1)), T(1));
+
+ for(int k=0; k<g_repeat*100; ++k)
+ {
+ T x = internal::random<T>();
+ if(!internal::is_same<T,bool>::value)
+ x = x/Real(2);
+ if(NumTraits<T>::IsSigned)
+ {
+ VERIFY_IS_EQUAL(numext::abs(x), numext::abs(-x));
+ VERIFY( numext::abs(-x) >= Real(0));
+ }
+ VERIFY( numext::abs(x) >= Real(0));
+ VERIFY_IS_APPROX( numext::abs2(x), numext::abs2(numext::abs(x)) );
+ }
+}
+
+void test_numext() {
+ CALL_SUBTEST( check_abs<bool>() );
+ CALL_SUBTEST( check_abs<signed char>() );
+ CALL_SUBTEST( check_abs<unsigned char>() );
+ CALL_SUBTEST( check_abs<short>() );
+ CALL_SUBTEST( check_abs<unsigned short>() );
+ CALL_SUBTEST( check_abs<int>() );
+ CALL_SUBTEST( check_abs<unsigned int>() );
+ CALL_SUBTEST( check_abs<long>() );
+ CALL_SUBTEST( check_abs<unsigned long>() );
+ CALL_SUBTEST( check_abs<half>() );
+ CALL_SUBTEST( check_abs<float>() );
+ CALL_SUBTEST( check_abs<double>() );
+ CALL_SUBTEST( check_abs<long double>() );
+
+ CALL_SUBTEST( check_abs<std::complex<float> >() );
+ CALL_SUBTEST( check_abs<std::complex<double> >() );
+}
diff --git a/eigen/test/packetmath.cpp b/eigen/test/packetmath.cpp
index 08b3603..7821a17 100644
--- a/eigen/test/packetmath.cpp
+++ b/eigen/test/packetmath.cpp
@@ -438,7 +438,6 @@ template<typename Scalar> void packetmath_real()
CHECK_CWISE1_IF(PacketTraits::HasSqrt, std::sqrt, internal::psqrt);
CHECK_CWISE1_IF(PacketTraits::HasLog, std::log, internal::plog);
#if EIGEN_HAS_C99_MATH && (__cplusplus > 199711L)
- CHECK_CWISE1_IF(PacketTraits::HasExpm1, std::expm1, internal::pexpm1);
CHECK_CWISE1_IF(PacketTraits::HasLog1p, std::log1p, internal::plog1p);
CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasLGamma, std::lgamma, internal::plgamma);
CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasErf, std::erf, internal::perf);
diff --git a/eigen/test/product_mmtr.cpp b/eigen/test/product_mmtr.cpp
index f6e4bb1..d3e24b0 100644
--- a/eigen/test/product_mmtr.cpp
+++ b/eigen/test/product_mmtr.cpp
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2010-2017 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
@@ -10,12 +10,19 @@
#include "main.h"
#define CHECK_MMTR(DEST, TRI, OP) { \
+ ref3 = DEST; \
ref2 = ref1 = DEST; \
DEST.template triangularView<TRI>() OP; \
ref1 OP; \
ref2.template triangularView<TRI>() \
= ref1.template triangularView<TRI>(); \
VERIFY_IS_APPROX(DEST,ref2); \
+ \
+ DEST = ref3; \
+ ref3 = ref2; \
+ ref3.diagonal() = DEST.diagonal(); \
+ DEST.template triangularView<TRI|ZeroDiag>() OP; \
+ VERIFY_IS_APPROX(DEST,ref3); \
}
template<typename Scalar> void mmtr(int size)
@@ -27,7 +34,7 @@ template<typename Scalar> void mmtr(int size)
MatrixColMaj matc = MatrixColMaj::Zero(size, size);
MatrixRowMaj matr = MatrixRowMaj::Zero(size, size);
- MatrixColMaj ref1(size, size), ref2(size, size);
+ MatrixColMaj ref1(size, size), ref2(size, size), ref3(size,size);
MatrixColMaj soc(size,othersize); soc.setRandom();
MatrixColMaj osc(othersize,size); osc.setRandom();
diff --git a/eigen/test/product_notemporary.cpp b/eigen/test/product_notemporary.cpp
index 8bf71b4..30592b7 100644
--- a/eigen/test/product_notemporary.cpp
+++ b/eigen/test/product_notemporary.cpp
@@ -51,6 +51,7 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m)
VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * (m1 * m2.transpose()), 0);
VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()), 1);
+ VERIFY_EVALUATION_COUNT( m3 = m3 - (m1 * m2.adjoint()), 1);
VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()).transpose(), 1);
VERIFY_EVALUATION_COUNT( m3.noalias() = m3 + m1 * m2.transpose(), 0);
diff --git a/eigen/test/sparse_product.cpp b/eigen/test/sparse_product.cpp
index c1edd26..1975867 100644
--- a/eigen/test/sparse_product.cpp
+++ b/eigen/test/sparse_product.cpp
@@ -297,6 +297,10 @@ template<typename SparseMatrixType> void sparse_product()
VERIFY_IS_APPROX(x=mLo.template selfadjointView<Lower>()*b, refX=refS*b);
VERIFY_IS_APPROX(x=mS.template selfadjointView<Upper|Lower>()*b, refX=refS*b);
+ VERIFY_IS_APPROX(x=b * mUp.template selfadjointView<Upper>(), refX=b*refS);
+ VERIFY_IS_APPROX(x=b * mLo.template selfadjointView<Lower>(), refX=b*refS);
+ VERIFY_IS_APPROX(x=b * mS.template selfadjointView<Upper|Lower>(), refX=b*refS);
+
VERIFY_IS_APPROX(x.noalias()+=mUp.template selfadjointView<Upper>()*b, refX+=refS*b);
VERIFY_IS_APPROX(x.noalias()-=mLo.template selfadjointView<Lower>()*b, refX-=refS*b);
VERIFY_IS_APPROX(x.noalias()+=mS.template selfadjointView<Upper|Lower>()*b, refX+=refS*b);
diff --git a/eigen/test/symbolic_index.cpp b/eigen/test/symbolic_index.cpp
deleted file mode 100644
index 1db8514..0000000
--- a/eigen/test/symbolic_index.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2017 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/.
-
-#ifdef EIGEN_TEST_PART_2
-#define EIGEN_MAX_CPP_VER 03
-#endif
-
-#include "main.h"
-
-template<typename T>
-bool match(const T& xpr, std::string ref, std::string str_xpr = "") {
- EIGEN_UNUSED_VARIABLE(str_xpr);
- std::stringstream str;
- str << xpr;
- if(!(str.str() == ref))
- std::cout << str_xpr << "\n" << xpr << "\n\n";
- return str.str() == ref;
-}
-
-#define MATCH(X,R) match(X, R, #X)
-
-template<typename T1,typename T2>
-typename internal::enable_if<internal::is_same<T1,T2>::value,bool>::type
-is_same_fixed(const T1& a, const T2& b)
-{
- return (Index(a) == Index(b));
-}
-
-template<typename T1,typename T2>
-bool is_same_seq(const T1& a, const T2& b)
-{
- bool ok = a.first()==b.first() && a.size() == b.size() && Index(a.incrObject())==Index(b.incrObject());;
- if(!ok)
- {
- std::cerr << "seqN(" << a.first() << ", " << a.size() << ", " << Index(a.incrObject()) << ") != ";
- std::cerr << "seqN(" << b.first() << ", " << b.size() << ", " << Index(b.incrObject()) << ")\n";
- }
- return ok;
-}
-
-template<typename T1,typename T2>
-typename internal::enable_if<internal::is_same<T1,T2>::value,bool>::type
-is_same_type(const T1&, const T2&)
-{
- return true;
-}
-
-template<typename T1,typename T2>
-bool is_same_symb(const T1& a, const T2& b, Index size)
-{
- using Eigen::placeholders::last;
- return a.eval(last=size-1) == b.eval(last=size-1);
-}
-
-
-#define VERIFY_EQ_INT(A,B) VERIFY_IS_APPROX(int(A),int(B))
-
-void check_symbolic_index()
-{
- using Eigen::placeholders::last;
- using Eigen::placeholders::end;
-
- Index size=100;
-
- // First, let's check FixedInt arithmetic:
- VERIFY( is_same_type( (fix<5>()-fix<3>())*fix<9>()/(-fix<3>()), fix<-(5-3)*9/3>() ) );
- VERIFY( is_same_type( (fix<5>()-fix<3>())*fix<9>()/fix<2>(), fix<(5-3)*9/2>() ) );
- VERIFY( is_same_type( fix<9>()/fix<2>(), fix<9/2>() ) );
- VERIFY( is_same_type( fix<9>()%fix<2>(), fix<9%2>() ) );
- VERIFY( is_same_type( fix<9>()&fix<2>(), fix<9&2>() ) );
- VERIFY( is_same_type( fix<9>()|fix<2>(), fix<9|2>() ) );
- VERIFY( is_same_type( fix<9>()/2, int(9/2) ) );
-
- VERIFY( is_same_symb( end-1, last, size) );
- VERIFY( is_same_symb( end-fix<1>, last, size) );
-
- VERIFY_IS_EQUAL( ( (last*5-2)/3 ).eval(last=size-1), ((size-1)*5-2)/3 );
- VERIFY_IS_EQUAL( ( (last*fix<5>-fix<2>)/fix<3> ).eval(last=size-1), ((size-1)*5-2)/3 );
- VERIFY_IS_EQUAL( ( -last*end ).eval(last=size-1), -(size-1)*size );
- VERIFY_IS_EQUAL( ( end-3*last ).eval(last=size-1), size- 3*(size-1) );
- VERIFY_IS_EQUAL( ( (end-3*last)/end ).eval(last=size-1), (size- 3*(size-1))/size );
-
-#if EIGEN_HAS_CXX14
- {
- struct x_tag {}; static const Symbolic::SymbolExpr<x_tag> x;
- struct y_tag {}; static const Symbolic::SymbolExpr<y_tag> y;
- struct z_tag {}; static const Symbolic::SymbolExpr<z_tag> z;
-
- VERIFY_IS_APPROX( int(((x+3)/y+z).eval(x=6,y=3,z=-13)), (6+3)/3+(-13) );
- }
-#endif
-}
-
-void test_symbolic_index()
-{
- CALL_SUBTEST_1( check_symbolic_index() );
- CALL_SUBTEST_2( check_symbolic_index() );
-}
diff --git a/eigen/unsupported/CMakeLists.txt b/eigen/unsupported/CMakeLists.txt
index 9a56661..4fef40a 100644
--- a/eigen/unsupported/CMakeLists.txt
+++ b/eigen/unsupported/CMakeLists.txt
@@ -1,9 +1,7 @@
add_subdirectory(Eigen)
add_subdirectory(doc EXCLUDE_FROM_ALL)
-if(BUILD_TESTING)
- if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
- add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
- else()
- add_subdirectory(test EXCLUDE_FROM_ALL)
- endif()
+if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
+ add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
+else()
+ add_subdirectory(test EXCLUDE_FROM_ALL)
endif()
diff --git a/eigen/unsupported/Eigen/CXX11/Tensor b/eigen/unsupported/Eigen/CXX11/Tensor
index 3991609..7ecb4c7 100644
--- a/eigen/unsupported/Eigen/CXX11/Tensor
+++ b/eigen/unsupported/Eigen/CXX11/Tensor
@@ -13,14 +13,13 @@
#include "../../../Eigen/Core"
-#if defined(EIGEN_USE_SYCL)
+#ifdef EIGEN_USE_SYCL
#undef min
#undef max
#undef isnan
#undef isinf
#undef isfinite
#include <SYCL/sycl.hpp>
-#include <iostream>
#include <map>
#include <memory>
#include <utility>
@@ -53,10 +52,8 @@ typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
-#include <windows.h>
#else
#include <stdint.h>
-#include <unistd.h>
#endif
#if __cplusplus > 199711 || EIGEN_COMP_MSVC >= 1900
@@ -71,10 +68,6 @@ typedef unsigned __int64 uint64_t;
#include <time.h>
#endif
-#if defined(EIGEN_USE_LIBXSMM)
-#include "libxsmm.h"
-#endif
-
#ifdef EIGEN_USE_THREADS
#include "ThreadPool"
#endif
diff --git a/eigen/unsupported/Eigen/CXX11/ThreadPool b/eigen/unsupported/Eigen/CXX11/ThreadPool
index c346141..09d637e 100644
--- a/eigen/unsupported/Eigen/CXX11/ThreadPool
+++ b/eigen/unsupported/Eigen/CXX11/ThreadPool
@@ -50,7 +50,6 @@
#include "src/ThreadPool/ThreadLocal.h"
#include "src/ThreadPool/ThreadYield.h"
-#include "src/ThreadPool/ThreadCancel.h"
#include "src/ThreadPool/EventCount.h"
#include "src/ThreadPool/RunQueue.h"
#include "src/ThreadPool/ThreadPoolInterface.h"
@@ -58,18 +57,6 @@
#include "src/ThreadPool/SimpleThreadPool.h"
#include "src/ThreadPool/NonBlockingThreadPool.h"
-
-// Use the more efficient NonBlockingThreadPool by default.
-namespace Eigen {
-#ifndef EIGEN_USE_SIMPLE_THREAD_POOL
-template <typename Env> using ThreadPoolTempl = NonBlockingThreadPoolTempl<Env>;
-typedef NonBlockingThreadPool ThreadPool;
-#else
-template <typename Env> using ThreadPoolTempl = SimpleThreadPoolTempl<Env>;
-typedef SimpleThreadPool ThreadPool;
-#endif
-} // namespace Eigen
-
#endif
#include <Eigen/src/Core/util/ReenableStupidWarnings.h>
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/README.md b/eigen/unsupported/Eigen/CXX11/src/Tensor/README.md
index 38cdb9c..98e8381 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/README.md
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/README.md
@@ -1737,9 +1737,11 @@ TODO
## Representation of scalar values
-Scalar values are often represented by tensors of size 1 and rank 0.For example
-Tensor<T, N>::maximum() currently returns a Tensor<T, 0>. Similarly, the inner
-product of 2 1d tensors (through contractions) returns a 0d tensor.
+Scalar values are often represented by tensors of size 1 and rank 1. It would be
+more logical and user friendly to use tensors of rank 0 instead. For example
+Tensor<T, N>::maximum() currently returns a Tensor<T, 1>. Similarly, the inner
+product of 2 1d tensors (through contractions) returns a 1d tensor. In the
+future these operations might be updated to return 0d tensors instead.
## Limitations
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h
index fbe3408..7a45a5c 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h
@@ -186,12 +186,6 @@ class TensorBase<Derived, ReadOnlyAccessors>
}
EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_expm1_op<Scalar>, const Derived>
- expm1() const {
- return unaryExpr(internal::scalar_expm1_op<Scalar>());
- }
-
- EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived>
log() const {
return unaryExpr(internal::scalar_log_op<Scalar>());
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h
index 23a7446..4cfe300 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h
@@ -54,7 +54,7 @@ struct is_input_scalar<Sizes<> > {
static const bool value = true;
};
#ifndef EIGEN_EMULATE_CXX11_META_H
-template <typename std::ptrdiff_t... Indices>
+template <typename std::size_t... Indices>
struct is_input_scalar<Sizes<Indices...> > {
static const bool value = (Sizes<Indices...>::total_size == 1);
};
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h
index c46a778..1ba7ef1 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h
@@ -50,7 +50,6 @@ template <DenseIndex DimId>
struct DimensionId
{
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DimensionId(DenseIndex dim) {
- EIGEN_UNUSED_VARIABLE(dim);
eigen_assert(dim == DimId);
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex actualDim() const {
@@ -151,7 +150,7 @@ struct TensorEvaluator<const TensorChippingOp<DimId, ArgType>, Device>
};
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
- : m_impl(op.expression(), device), m_dim(op.dim()), m_device(device), m_offset(op.offset())
+ : m_impl(op.expression(), device), m_dim(op.dim()), m_device(device)
{
EIGEN_STATIC_ASSERT((NumInputDims >= 1), YOU_MADE_A_PROGRAMMING_MISTAKE);
eigen_assert(NumInputDims > m_dim.actualDim());
@@ -207,7 +206,7 @@ struct TensorEvaluator<const TensorChippingOp<DimId, ArgType>, Device>
eigen_assert(index+PacketSize-1 < dimensions().TotalSize());
if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) && m_dim.actualDim() == 0) ||
- (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == NumInputDims-1)) {
+ (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == NumInputDims-1)) {
// m_stride is equal to 1, so let's avoid the integer division.
eigen_assert(m_stride == 1);
Index inputIndex = index * m_inputStride + m_inputOffset;
@@ -219,7 +218,7 @@ struct TensorEvaluator<const TensorChippingOp<DimId, ArgType>, Device>
PacketReturnType rslt = internal::pload<PacketReturnType>(values);
return rslt;
} else if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) && m_dim.actualDim() == NumInputDims - 1) ||
- (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == 0)) {
+ (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == 0)) {
// m_stride is aways greater than index, so let's avoid the integer division.
eigen_assert(m_stride > index);
return m_impl.template packet<LoadMode>(index + m_inputOffset);
@@ -275,29 +274,17 @@ struct TensorEvaluator<const TensorChippingOp<DimId, ArgType>, Device>
}
}
- /// used by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex dimId() const {
- return m_dim.actualDim();
- }
-
- /// used by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const DenseIndex& offset() const {
- return m_offset;
- }
- /// required by sycl in order to extract the accessor
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorEvaluator<ArgType, Device>& impl() const { return m_impl; }
-
protected:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index) const
{
Index inputIndex;
if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) && m_dim.actualDim() == 0) ||
- (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == NumInputDims-1)) {
+ (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == NumInputDims-1)) {
// m_stride is equal to 1, so let's avoid the integer division.
eigen_assert(m_stride == 1);
inputIndex = index * m_inputStride + m_inputOffset;
} else if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) && m_dim.actualDim() == NumInputDims-1) ||
- (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == 0)) {
+ (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == 0)) {
// m_stride is aways greater than index, so let's avoid the integer division.
eigen_assert(m_stride > index);
inputIndex = index + m_inputOffset;
@@ -317,9 +304,6 @@ struct TensorEvaluator<const TensorChippingOp<DimId, ArgType>, Device>
TensorEvaluator<ArgType, Device> m_impl;
const internal::DimensionId<DimId> m_dim;
const Device& m_device;
-// required by sycl
- const DenseIndex m_offset;
-
};
@@ -360,7 +344,7 @@ struct TensorEvaluator<TensorChippingOp<DimId, ArgType>, Device>
EIGEN_STATIC_ASSERT((PacketSize > 1), YOU_MADE_A_PROGRAMMING_MISTAKE)
if ((static_cast<int>(this->Layout) == static_cast<int>(ColMajor) && this->m_dim.actualDim() == 0) ||
- (static_cast<int>(this->Layout) == static_cast<int>(RowMajor) && this->m_dim.actualDim() == NumInputDims-1)) {
+ (static_cast<int>(this->Layout) == static_cast<int>(RowMajor) && this->m_dim.actualDim() == NumInputDims-1)) {
// m_stride is equal to 1, so let's avoid the integer division.
eigen_assert(this->m_stride == 1);
EIGEN_ALIGN_MAX typename internal::remove_const<CoeffReturnType>::type values[PacketSize];
@@ -371,7 +355,7 @@ struct TensorEvaluator<TensorChippingOp<DimId, ArgType>, Device>
inputIndex += this->m_inputStride;
}
} else if ((static_cast<int>(this->Layout) == static_cast<int>(ColMajor) && this->m_dim.actualDim() == NumInputDims-1) ||
- (static_cast<int>(this->Layout) == static_cast<int>(RowMajor) && this->m_dim.actualDim() == 0)) {
+ (static_cast<int>(this->Layout) == static_cast<int>(RowMajor) && this->m_dim.actualDim() == 0)) {
// m_stride is aways greater than index, so let's avoid the integer division.
eigen_assert(this->m_stride > index);
this->m_impl.template writePacket<StoreMode>(index + this->m_inputOffset, x);
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h
index 2c7ba96..59bf90d 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h
@@ -276,12 +276,6 @@ struct TensorEvaluator<const TensorConcatenationOp<Axis, LeftArgType, RightArgTy
}
EIGEN_DEVICE_FUNC Scalar* data() const { return NULL; }
- /// required by sycl in order to extract the accessor
- const TensorEvaluator<LeftArgType, Device>& left_impl() const { return m_leftImpl; }
- /// required by sycl in order to extract the accessor
- const TensorEvaluator<RightArgType, Device>& right_impl() const { return m_rightImpl; }
- /// required by sycl in order to extract the accessor
- const Axis& axis() const { return m_axis; }
protected:
Dimensions m_dimensions;
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h
index bf4a476..20b29e5 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h
@@ -20,70 +20,6 @@ namespace Eigen {
*
*/
namespace internal {
-#if defined(EIGEN_VECTORIZE_AVX) && defined(EIGEN_USE_LIBXSMM)
-template<typename Scalar, typename Index>
-void pack_simple(Scalar * dst, const Scalar * src, Index cols, Index rows, Index lddst, Index ldsrc) {
- size_t psize = packet_traits<Scalar>::size; // Packet size
- typedef typename packet_traits<Scalar>::type Packet; // Packet type
- size_t alignment = psize*sizeof(Scalar); // Needed alignment
- if (rows % psize == 0 && (lddst*sizeof(Scalar)) % alignment == 0 &&
- (ldsrc*sizeof(Scalar)) % alignment == 0 &&
- reinterpret_cast<uintptr_t>(src) % alignment == 0 &&
- reinterpret_cast<uintptr_t>(dst) % alignment == 0) {
- // Optimized version using packets
- size_t num_packets = rows / psize;
- for (Index col = 0; col < cols; ++col) {
- EIGEN_ASM_COMMENT("begin pack_simple inner copy");
- // Unrolled manually 4 times.
- for (size_t i=0; i < num_packets/4; ++i) {
- internal::pstore(dst, internal::pload<Packet>(src));
- dst += psize; src += psize;
- internal::pstore(dst, internal::pload<Packet>(src));
- dst += psize; src += psize;
- internal::pstore(dst, internal::pload<Packet>(src));
- dst += psize; src += psize;
- internal::pstore(dst, internal::pload<Packet>(src));
- dst += psize; src += psize;
- }
- for (size_t i=0; i < num_packets%4; ++i) {
- internal::pstore(dst, internal::pload<Packet>(src));
- dst += psize; src += psize;
- }
- dst += lddst - num_packets*psize;
- src += ldsrc - num_packets*psize;
- EIGEN_ASM_COMMENT("end pack_simple inner copy");
- }
- } else {
- // Naive memcpy calls
- for (Index col = 0; col < cols; ++col) {
- memcpy(dst + col*lddst, src + col*ldsrc, rows*sizeof(Scalar));
- }
- }
-}
-
-template<typename LhsScalar, typename RhsScalar, typename Scalar>
- struct libxsmm_wrapper {
- libxsmm_wrapper() {}
- libxsmm_wrapper(int, int, int, int, int, int, int, float, float, int) {}
- void operator()(const LhsScalar*, const RhsScalar*, Scalar*) {}
- void operator()(const LhsScalar*, const RhsScalar*, Scalar*, const LhsScalar*, const RhsScalar*, const Scalar*) {}
- };
-
- template<>
- struct libxsmm_wrapper<float, float, float>: public libxsmm_mmfunction<float> {
- libxsmm_wrapper(): libxsmm_mmfunction() {}
- libxsmm_wrapper(int flags, int m, int n, int k, int lda, int ldb, int ldc, float alpha, float beta, int prefetch) :
- libxsmm_mmfunction(flags, m, n, k, lda, ldb, ldc, alpha, beta, prefetch) {}
- };
-
- template<>
- struct libxsmm_wrapper<double, double, double>: public libxsmm_mmfunction<double> {
- libxsmm_wrapper(): libxsmm_mmfunction() {}
- libxsmm_wrapper(int flags, int m, int n, int k, int lda, int ldb, int ldc, float alpha, float beta, int prefetch) :
- libxsmm_mmfunction(flags, m, n, k, lda, ldb, ldc, alpha, beta, prefetch) {}
- };
-#endif
-
template<typename Dimensions, typename LhsXprType, typename RhsXprType>
struct traits<TensorContractionOp<Dimensions, LhsXprType, RhsXprType> >
@@ -222,7 +158,7 @@ struct TensorContractionEvaluatorBase
m_device(device),
m_result(NULL) {
EIGEN_STATIC_ASSERT((static_cast<int>(TensorEvaluator<LeftArgType, Device>::Layout) ==
- static_cast<int>(TensorEvaluator<RightArgType, Device>::Layout)),
+ static_cast<int>(TensorEvaluator<RightArgType, Device>::Layout)),
YOU_MADE_A_PROGRAMMING_MISTAKE);
@@ -381,8 +317,6 @@ struct TensorContractionEvaluatorBase
}
}
- EnableXSMMIfPossible(eval_op_indices);
-
// If the layout is RowMajor, we need to reverse the m_dimensions
if (static_cast<int>(Layout) == static_cast<int>(RowMajor)) {
for (int i = 0, j = NumDims - 1; i < j; i++, j--) {
@@ -393,7 +327,7 @@ struct TensorContractionEvaluatorBase
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar * data) {
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar* data) {
m_leftImpl.evalSubExprsIfNeeded(NULL);
m_rightImpl.evalSubExprsIfNeeded(NULL);
if (data) {
@@ -488,13 +422,6 @@ struct TensorContractionEvaluatorBase
template <bool lhs_inner_dim_contiguous, bool rhs_inner_dim_contiguous, bool rhs_inner_dim_reordered, int Alignment>
EIGEN_DEVICE_FUNC void evalGemm(Scalar* buffer) const {
- #if defined(EIGEN_VECTORIZE_AVX) && defined(EIGEN_USE_LIBXSMM)
- if (m_can_use_xsmm) {
- evalGemmXSMM(buffer);
- return;
- }
- #endif
-
// columns in left side, rows in right side
const Index k = this->m_k_size;
@@ -611,214 +538,7 @@ struct TensorContractionEvaluatorBase
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar* data() const { return m_result; }
-protected:
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void EnableXSMMIfPossible(const array<IndexPair<Index>, ContractDims>& eval_op_indices) {
- m_can_use_xsmm = false;
-
-#if defined(EIGEN_VECTORIZE_AVX) && defined(EIGEN_USE_LIBXSMM)
- typedef typename internal::remove_const<typename EvalLeftArgType::Scalar>::type LhsScalar;
- typedef typename internal::remove_const<typename EvalRightArgType::Scalar>::type RhsScalar;
- if (!std::is_same<Scalar, LhsScalar>::value ||
- !std::is_same<Scalar, RhsScalar>::value ||
- !(std::is_same<Scalar, float>::value ||
- std::is_same<Scalar, double>::value) ||
- m_leftImpl.data() == NULL ||
- m_rightImpl.data() == NULL) {
- return;
- }
-
- // Check if we can use faster matmul algorithms. For contraction to be
- // equivalent to matmul, we need both lhs and rhs contracting dims sequences
- // to be either a prefix or suffix of all dims. Also, the order of both
- // must be the same, so we don't have to do reordering.
- // For example:
- // * OK: lhs 4D, rhs 4D, contraction: [(0, 2), (1, 3)]
- // * BAD: lhs 3D, rhs 3D, contraction: [(1,1)]
- // * BAD: lhs 3D, rhs 3D, contraction: [(0, 0), (2, 2)]
- // * BAD: lhs 3D, rhs 3D, contraction: [(0, 2), (1, 1)]
- // Depending if contraction dims are prefix or suffix of all dims we need to
- // pre-transpose matrices in matmul algorithm:
- // lhs: prefix -> transpose, suffix -> no transpose
- // rhs: prefix -> no transpose, suffix -> transpose
- // For example, for lhs 2D, rhs 2D, contraction [(1, 0)] is regular,
- // non-transposed matmul.
- if (ContractDims == 0) {
- // This case is totally uninteresting, filter it out to avoid problems
- // with iterations in further tests.
- return;
- }
-
- // Check if RHS dims list is increasing. LHS already is, so if not, the
- // order is different and we cannot do matmul.
- for (int i = 1; i < ContractDims; i++) {
- if (eval_op_indices[i].second < eval_op_indices[i-1].second) {
- return;
- }
- }
-
- // Check if no holes.
- int diff;
- for (int i = 1; i < ContractDims; i++) {
- // LHS contract dims are sorted to form an increasing seq.
- diff = eval_op_indices[i].first - eval_op_indices[i-1].first;
- if (diff != 1) {
- return;
- }
- // Now we may already assume RHS contract dims seq is increasing too.
- diff = eval_op_indices[i].second - eval_op_indices[i-1].second;
- if (diff != 1) {
- return;
- }
- }
-
- // Check if suffix or prefix.
- if (eval_op_indices[0].first != 0 &&
- eval_op_indices[ContractDims-1].first != LDims-1) {
- return;
- }
- if (eval_op_indices[0].second != 0 &&
- eval_op_indices[ContractDims-1].second != RDims-1) {
- return;
- }
-
- m_can_use_xsmm = true;
-#else
- EIGEN_UNUSED_VARIABLE(eval_op_indices);
-#endif
- }
-
-#if defined(EIGEN_VECTORIZE_AVX) && defined(EIGEN_USE_LIBXSMM)
- EIGEN_DEVICE_FUNC void evalGemmXSMM(Scalar* buffer) const {
- // columns in left side, rows in right side
- const Index k = this->m_k_size;
-
- // rows in left side
- const Index m = this->m_i_size;
-
- // columns in right side
- const Index n = this->m_j_size;
-
- const bool transposeA = !m_lhs_inner_dim_contiguous;
- const bool transposeB = !m_rhs_inner_dim_contiguous;
-
- typedef typename internal::remove_const<typename EvalLeftArgType::Scalar>::type LhsScalar;
- typedef typename internal::remove_const<typename EvalRightArgType::Scalar>::type RhsScalar;
-
- internal::TensorXsmmContractionBlocking<LhsScalar, RhsScalar, Index> blocking(
- k, m, n, 1, transposeA, transposeB);
-
- // Outer blocks sizes
- const Index mc_outer = blocking.outer_m();
- const Index nc_outer = blocking.outer_n();
- const Index kc_outer = blocking.outer_k();
- // Inner blocks sizes
- const Index mc = blocking.mc();
- const Index nc = blocking.nc();
- const Index kc = blocking.kc();
- // Decisions whether we should copy parts of matrices
- const bool copyA = blocking.copyA();
- const bool copyB = blocking.copyB();
-
- const LhsScalar* leftData = m_leftImpl.data();
- const RhsScalar* rightData = m_rightImpl.data();
-
- const libxsmm_blasint stride_A = static_cast<libxsmm_blasint>(transposeA ? k : m);
- const libxsmm_blasint stride_B = static_cast<libxsmm_blasint>(transposeB ? n : k);
- const libxsmm_blasint stride_C = static_cast<libxsmm_blasint>(m);
-
- const libxsmm_blasint stride_blockA = static_cast<libxsmm_blasint>(mc);
- // Use bigger stride to avoid hitting same cache line too often.
- // This consistently gives +~0.5 Gflops.
- const libxsmm_blasint stride_panelB = static_cast<libxsmm_blasint>(
- kc % 32 == 0 ? kc + 16 : kc
- );
-
- // Kernel for the general case (not edges)
- internal::libxsmm_wrapper<LhsScalar, RhsScalar, Scalar> kernel;
-
- LhsScalar* blockA = NULL;
- RhsScalar* panelB = NULL;
-
- if (copyA) {
- blockA = static_cast<LhsScalar*>(this->m_device.allocate(mc * kc * sizeof(LhsScalar)));
- }
- if (copyB) {
- panelB = static_cast<RhsScalar*>(this->m_device.allocate(nc_outer * stride_panelB * sizeof(RhsScalar)));
- }
-
- const Index kernel_stride_A = copyA ? stride_blockA : stride_A;
- const Index kernel_stride_B = copyB ? stride_panelB : stride_B;
- kernel = internal::libxsmm_wrapper<LhsScalar, RhsScalar, Scalar>(0, mc, nc, kc, kernel_stride_A, kernel_stride_B, stride_C, 1, 1, blocking.prefetch());
-
- // Outer blocking
- for (Index ki_outer = 0; ki_outer < k; ki_outer += kc_outer) {
- for (Index mi_outer = 0; mi_outer < m; mi_outer += mc_outer) {
- for (Index ni_outer = 0; ni_outer < n; ni_outer += nc_outer) {
- using numext::mini;
-
- Index actual_nc_outer = mini(ni_outer+nc_outer, n) - ni_outer;
-
- // Inner blocking
- for (Index ki = ki_outer; ki < mini(ki_outer+kc_outer, k); ki += kc) {
- const Index actual_kc = mini(ki_outer+kc_outer, mini(ki+kc, k)) - ki;
- const float beta = ki == 0 ? 0 : 1;
-
- if (copyB) {
- if (transposeB) {
- libxsmm_otrans(panelB, rightData + ki*stride_B + ni_outer, sizeof(RhsScalar), actual_nc_outer, actual_kc, stride_B, stride_panelB);
- } else {
- internal::pack_simple<RhsScalar, Index>(panelB, rightData + ni_outer*stride_B + ki, actual_nc_outer, actual_kc, stride_panelB, stride_B);
- }
- }
-
- for (Index mi = mi_outer; mi < mini(mi_outer+mc_outer, m); mi += mc) {
- const Index actual_mc = mini(mi_outer+mc_outer, mini(mi+mc, m)) - mi;
-
- const LhsScalar* a = transposeA ? leftData + mi*stride_A + ki :
- leftData + ki*stride_A + mi;
-
- if (copyA) {
- if (transposeA) {
- libxsmm_otrans(blockA, a, sizeof(LhsScalar), actual_kc, actual_mc, stride_A, stride_blockA);
- } else {
- internal::pack_simple<LhsScalar, Index>(blockA, a, actual_kc, actual_mc, stride_blockA, stride_A);
- }
- }
- const LhsScalar* actual_a = copyA ? blockA : a;
-
- for (Index ni = ni_outer; ni < mini(ni_outer+nc_outer, n); ni += nc) {
- const Index actual_nc = mini(ni_outer+nc_outer, mini(ni+nc, n)) - ni;
-
- const RhsScalar* b = rightData + ni*stride_B + ki;
- Scalar* c = buffer + ni*stride_C + mi;
- const Scalar* cp = c + nc*stride_C;
-
- const RhsScalar* actual_b = copyB ? panelB + (ni-ni_outer)*stride_panelB : b;
- const RhsScalar* bp = copyB ? panelB + nc*stride_panelB : b + nc*stride_B;
-
- if (actual_mc == mc && actual_kc == kc && actual_nc == nc && beta == 1) {
- // Most used, cached kernel.
- kernel(actual_a, actual_b, c, actual_a, bp, cp);
- } else {
- // Edges - use libxsmm kernel cache.
- internal::libxsmm_wrapper<LhsScalar, RhsScalar, Scalar>(0, actual_mc, actual_nc, actual_kc, kernel_stride_A, kernel_stride_B, stride_C, 1, beta, blocking.prefetch())(actual_a, actual_b, c, actual_a, bp, cp);
- }
- }
- }
- }
- }
- }
- }
-
- if (copyA) {
- this->m_device.deallocate(blockA);
- }
- if (copyB) {
- this->m_device.deallocate(panelB);
- }
- }
-#endif
-
+ protected:
// Prevent assignment
TensorContractionEvaluatorBase& operator = (const TensorContractionEvaluatorBase&);
Dimensions m_dimensions;
@@ -844,7 +564,6 @@ protected:
TensorEvaluator<EvalRightArgType, Device> m_rightImpl;
const Device& m_device;
Scalar* m_result;
- bool m_can_use_xsmm;
};
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h
index d34f9ca..5cf7b4f 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h
@@ -50,140 +50,6 @@ class TensorContractionBlocking {
};
-
-#if defined(EIGEN_USE_LIBXSMM)
-template <typename LhsScalar, typename RhsScalar, typename Index>
-class TensorXsmmContractionBlocking {
- public:
- TensorXsmmContractionBlocking(Index k, Index m, Index n,
- size_t max_num_threads = 1, bool transposeA = false,
- bool transposeB = false):
- k_(k), m_(m), n_(n), transposeA_(transposeA),
- transposeB_(transposeB), num_threads_(max_num_threads) {
-#ifdef EIGEN_TEST_SPECIFIC_BLOCKING_SIZES
- if (EIGEN_TEST_SPECIFIC_BLOCKING_SIZES) {
- mc_ = EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_M;
- kc_ = EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_K;
- nc_ = EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_N;
- outer_m_ = EIGEN_TEST_SPECIFIC_OUTER_BLOCKING_SIZE_M;
- outer_k_ = EIGEN_TEST_SPECIFIC_OUTER_BLOCKING_SIZE_K;
- outer_n_ = EIGEN_TEST_SPECIFIC_OUTER_BLOCKING_SIZE_N;
- copyA_ = EIGEN_TEST_SPECIFIC_BLOCKING_COPY_A;
- copyB_ = EIGEN_TEST_SPECIFIC_BLOCKING_COPY_B;
- outer_m_ = outer_m_ != 0 ? outer_m_ : m;
- outer_k_ = outer_k_ != 0 ? outer_k_ : k;
- outer_n_ = outer_n_ != 0 ? outer_n_ : n;
- }
-#else
- // Defaults, possibly overriden per-platform.
- copyA_ = true;
- copyB_ = false;
-
- // If the matrix is small enough, don't do blocking, just call single xsmm
- // kernel.
- if (static_cast<double>(m)*k*n <= LIBXSMM_THRESHOLD) {
- mc_ = m; kc_ = k; nc_ = n;
- outer_m_ = m; outer_k_ = k; outer_n_ = n;
- copyA_ = false; copyB_ = false;
- } else {
- int arch = libxsmm_cpuid_x86();
-
- if (arch == LIBXSMM_X86_AVX512_CORE) {
- // skylake
- mc_ = 64; kc_ = 64; nc_ = 24;
- outer_m_ = 512; outer_k_ = 512; outer_n_ = 24*22;
- // Hack to use this kernel architecture as the other one has performance
- // issues (no hardware prefetching).
- // TODO(nishantpatil): This should be removed if the issues are fixed,
- // or this one becomes the default.
- setenv("LIBXSMM_AVX512_CLASSIC_GEMM", "1", 1);
- } else if (arch == LIBXSMM_X86_AVX2) {
- // haswell
- mc_ = 32; kc_ = 192; nc_ = 33;
- outer_m_ = 512; outer_k_ = 3*192; outer_n_ = 33*16;
- } else if (arch == LIBXSMM_X86_AVX) {
- // ivybridge
- mc_ = 32; kc_ = 192; nc_ = 48;
- outer_m_ = 512; outer_k_ = 3*192; outer_n_ = 48*11;
- } else {
- // generic kernel size, usually performing well
- mc_ = 32; kc_ = 128; nc_ = 32;
- outer_m_ = 512; outer_k_ = 512; outer_n_ = 512;
- }
-
- // Only copy if it makes the stride smaller.
- copyA_ = copyA_ && (m > mc_);
- copyB_ = copyB_ && (k > kc_);
- }
-
- // We need to copy anyway if transposing
- copyA_ = copyA_ || transposeA;
- copyB_ = copyB_ || transposeB;
-
- // See libxsmm_gemm_prefetch_type definition in libxsmm_typedefs.h
- prefetch_ = LIBXSMM_PREFETCH_AL2CL2BL2_VIA_C;
-
-#endif
-
- mc_ = mc_ > m ? m : mc_;
- nc_ = nc_ > n ? n : nc_;
- kc_ = kc_ > k ? k : kc_;
-
- size_t compute_parallelism = (m / mc_) * (n / nc_);
- size_t pack_parallelism = 0;
- if (copyA_) {
- pack_parallelism += (m / mc_) * (k / kc_);
- }
- if (copyB_) {
- pack_parallelism += (n / nc_) * (k / kc_);
- }
- size_t parallelism = numext::maxi(compute_parallelism, pack_parallelism);
-
- num_threads_ = numext::mini<size_t>(num_threads_,
- parallelism / MIN_JOBS_PER_THREAD);
- num_threads_ = numext::maxi<size_t>(num_threads_, 1);
-
- // For optimal performance outer block sizes should be multiplies of kernel
- // sizes, or bigger than matrix size (=no outer blocking).
- eigen_assert(outer_m_ % mc_ == 0 || outer_m_ >= m);
- eigen_assert(outer_k_ % kc_ == 0 || outer_k_ >= k);
- eigen_assert(outer_n_ % nc_ == 0 || outer_n_ >= n);
- }
-
- EIGEN_ALWAYS_INLINE Index kc() const { return kc_; }
- EIGEN_ALWAYS_INLINE Index mc() const { return mc_; }
- EIGEN_ALWAYS_INLINE Index nc() const { return nc_; }
- EIGEN_ALWAYS_INLINE Index outer_k() const { return outer_k_; }
- EIGEN_ALWAYS_INLINE Index outer_m() const { return outer_m_; }
- EIGEN_ALWAYS_INLINE Index outer_n() const { return outer_n_; }
- EIGEN_ALWAYS_INLINE bool copyA() const { return copyA_; }
- EIGEN_ALWAYS_INLINE bool copyB() const { return copyB_; }
- EIGEN_ALWAYS_INLINE bool transposeA() const { return transposeA_; }
- EIGEN_ALWAYS_INLINE bool transposeB() const { return transposeB_; }
- EIGEN_ALWAYS_INLINE int num_threads() const { return num_threads_; }
- EIGEN_ALWAYS_INLINE Index blocks_m() const { return divup(m_, mc_); }
- EIGEN_ALWAYS_INLINE Index blocks_k() const { return divup(k_, kc_); }
- EIGEN_ALWAYS_INLINE Index blocks_n() const { return divup(n_, nc_); }
- EIGEN_ALWAYS_INLINE libxsmm_gemm_prefetch_type prefetch() const {
- return prefetch_;
- }
-
- private:
- Index k_, m_, n_;
- Index kc_, mc_, nc_;
- Index outer_k_, outer_m_, outer_n_;
- bool copyA_, copyB_, transposeA_, transposeB_;
- size_t num_threads_;
-
- // Threshold for m*k*n to skip blocking and just call libxsmm
- const double LIBXSMM_THRESHOLD = 80*80*80;
- // For computing optimal number of threads - so that each thread gets at least
- // that many jobs.
- const double MIN_JOBS_PER_THREAD = 3;
- libxsmm_gemm_prefetch_type prefetch_;
-};
-#endif // EIGEN_USE_LIBXSMM
-
} // end namespace internal
} // end namespace Eigen
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionCuda.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionCuda.h
index c04b784..d65dbb4 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionCuda.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionCuda.h
@@ -529,6 +529,7 @@ EigenFloatContractionKernelInternal16x16(const LhsMapper lhs, const RhsMapper rh
float2 rhs_shmem2[][8], const Index m_size,
const Index n_size, const Index k_size,
const Index base_m, const Index base_n) {
+ typedef float Scalar;
// prefetch registers
float4 lhs_pf0, rhs_pf0;
@@ -539,27 +540,27 @@ EigenFloatContractionKernelInternal16x16(const LhsMapper lhs, const RhsMapper rh
}
-#define prefetch_lhs(reg, row, col) \
- if (!CHECK_LHS_BOUNDARY) { \
- if (col < k_size) { \
- reg =lhs.template loadPacket<Unaligned>(row, col); \
- } \
- } else { \
- if (col < k_size) { \
- if (row + 3 < m_size) { \
- reg =lhs.template loadPacket<Unaligned>(row, col); \
- } else if (row + 2 < m_size) { \
- reg.x =lhs(row + 0, col); \
- reg.y =lhs(row + 1, col); \
- reg.z =lhs(row + 2, col); \
- } else if (row + 1 < m_size) { \
- reg.x =lhs(row + 0, col); \
- reg.y =lhs(row + 1, col); \
- } else if (row < m_size) { \
- reg.x =lhs(row + 0, col); \
- } \
- } \
- } \
+#define prefetch_lhs(reg, row, col) \
+ if (!CHECK_LHS_BOUNDARY) { \
+ if (col < k_size) { \
+ reg =lhs.loadPacket<Unaligned>(row, col); \
+ } \
+ } else { \
+ if (col < k_size) { \
+ if (row + 3 < m_size) { \
+ reg =lhs.loadPacket<Unaligned>(row, col); \
+ } else if (row + 2 < m_size) { \
+ reg.x =lhs(row + 0, col); \
+ reg.y =lhs(row + 1, col); \
+ reg.z =lhs(row + 2, col); \
+ } else if (row + 1 < m_size) { \
+ reg.x =lhs(row + 0, col); \
+ reg.y =lhs(row + 1, col); \
+ } else if (row < m_size) { \
+ reg.x =lhs(row + 0, col); \
+ } \
+ } \
+ } \
Index lhs_vert = base_m+threadIdx.x*4;
@@ -577,7 +578,7 @@ EigenFloatContractionKernelInternal16x16(const LhsMapper lhs, const RhsMapper rh
if (!CHECK_RHS_BOUNDARY) {
if ((rhs_vert + 3) < k_size) {
// just CHECK_RHS_BOUNDARY
- rhs_pf0 = rhs.template loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
+ rhs_pf0 = rhs.loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
} else if (rhs_vert + 2 < k_size) {
// just CHECK_RHS_BOUNDARY
rhs_pf0.x = rhs(rhs_vert, rhs_horiz0);
@@ -592,7 +593,7 @@ EigenFloatContractionKernelInternal16x16(const LhsMapper lhs, const RhsMapper rh
} else {
if (rhs_horiz0 < n_size) {
if ((rhs_vert + 3) < k_size) {
- rhs_pf0 = rhs.template loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
+ rhs_pf0 = rhs.loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
} else if ((rhs_vert + 2) < k_size) {
rhs_pf0.x = rhs(rhs_vert, rhs_horiz0);
rhs_pf0.y = rhs(rhs_vert + 1, rhs_horiz0);
@@ -765,6 +766,7 @@ EigenFloatContractionKernelInternal(const LhsMapper lhs, const RhsMapper rhs,
float2 rhs_shmem2[][8], const Index m_size,
const Index n_size, const Index k_size,
const Index base_m, const Index base_n) {
+ typedef float Scalar;
// prefetch registers
float4 lhs_pf0, lhs_pf1, lhs_pf2, lhs_pf3;
@@ -788,37 +790,37 @@ EigenFloatContractionKernelInternal(const LhsMapper lhs, const RhsMapper rhs,
if (!CHECK_LHS_BOUNDARY) {
if ((threadIdx.y/4+k+24) < k_size) {
- lhs_pf0 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
- lhs_pf1 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
- lhs_pf2 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+16));
- lhs_pf3 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+24));
+ lhs_pf0 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
+ lhs_pf1 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
+ lhs_pf2 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+16));
+ lhs_pf3 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+24));
} else if ((threadIdx.y/4+k+16) < k_size) {
- lhs_pf0 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
- lhs_pf1 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
- lhs_pf2 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+16));
+ lhs_pf0 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
+ lhs_pf1 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
+ lhs_pf2 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+16));
} else if ((threadIdx.y/4+k+8) < k_size) {
- lhs_pf0 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
- lhs_pf1 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
+ lhs_pf0 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
+ lhs_pf1 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
} else if ((threadIdx.y/4+k) < k_size) {
- lhs_pf0 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
+ lhs_pf0 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
}
} else {
// just CHECK_LHS_BOUNDARY
if (lhs_vert + 3 < m_size) {
if ((threadIdx.y/4+k+24) < k_size) {
- lhs_pf0 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
- lhs_pf1 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
- lhs_pf2 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+16));
- lhs_pf3 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+24));
+ lhs_pf0 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
+ lhs_pf1 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
+ lhs_pf2 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+16));
+ lhs_pf3 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+24));
} else if ((threadIdx.y/4+k+16) < k_size) {
- lhs_pf0 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
- lhs_pf1 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
- lhs_pf2 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+16));
+ lhs_pf0 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
+ lhs_pf1 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
+ lhs_pf2 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+16));
} else if ((threadIdx.y/4+k+8) < k_size) {
- lhs_pf0 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
- lhs_pf1 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
+ lhs_pf0 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
+ lhs_pf1 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k+8));
} else if ((threadIdx.y/4+k) < k_size) {
- lhs_pf0 =lhs.template loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
+ lhs_pf0 =lhs.loadPacket<Unaligned>(lhs_vert, (threadIdx.y/4+k));
}
} else if (lhs_vert + 2 < m_size) {
if ((threadIdx.y/4+k+24) < k_size) {
@@ -907,8 +909,8 @@ EigenFloatContractionKernelInternal(const LhsMapper lhs, const RhsMapper rhs,
if (!CHECK_RHS_BOUNDARY) {
if ((rhs_vert + 3) < k_size) {
// just CHECK_RHS_BOUNDARY
- rhs_pf0 = rhs.template loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
- rhs_pf1 = rhs.template loadPacket<Unaligned>(rhs_vert, rhs_horiz1);
+ rhs_pf0 = rhs.loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
+ rhs_pf1 = rhs.loadPacket<Unaligned>(rhs_vert, rhs_horiz1);
} else if (rhs_vert + 2 < k_size) {
// just CHECK_RHS_BOUNDARY
rhs_pf0.x = rhs(rhs_vert, rhs_horiz0);
@@ -930,8 +932,8 @@ EigenFloatContractionKernelInternal(const LhsMapper lhs, const RhsMapper rhs,
if (rhs_horiz1 < n_size) {
if ((rhs_vert + 3) < k_size) {
// just CHECK_RHS_BOUNDARY
- rhs_pf0 = rhs.template loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
- rhs_pf1 = rhs.template loadPacket<Unaligned>(rhs_vert, rhs_horiz1);
+ rhs_pf0 = rhs.loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
+ rhs_pf1 = rhs.loadPacket<Unaligned>(rhs_vert, rhs_horiz1);
} else if (rhs_vert + 2 < k_size) {
// just CHECK_RHS_BOUNDARY
rhs_pf0.x = rhs(rhs_vert, rhs_horiz0);
@@ -952,7 +954,7 @@ EigenFloatContractionKernelInternal(const LhsMapper lhs, const RhsMapper rhs,
} else if (rhs_horiz0 < n_size) {
if ((rhs_vert + 3) < k_size) {
// just CHECK_RHS_BOUNDARY
- rhs_pf0 = rhs.template loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
+ rhs_pf0 = rhs.loadPacket<Unaligned>(rhs_vert, rhs_horiz0);
} else if ((rhs_vert + 2) < k_size) {
// just CHECK_RHS_BOUNDARY
rhs_pf0.x = rhs(rhs_vert, rhs_horiz0);
@@ -1135,6 +1137,9 @@ EigenFloatContractionKernel(const LhsMapper lhs, const RhsMapper rhs,
typedef float2 LHS_MEM[64][32];
typedef float2 RHS_MEM[128][8];
+ typedef float2 LHS_MEM16x16[32][16];
+ typedef float2 RHS_MEM16x16[64][8];
+
const Index m_block_idx = blockIdx.x;
const Index n_block_idx = blockIdx.y;
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h
index ab320a5..9b2cb3f 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h
@@ -22,14 +22,8 @@ enum {
/*
* Implementation of the Eigen blas_data_mapper class for tensors.
*/
-/// The make pointer class is used by sycl in order to build the mapper class on the device. For other platform the default make pointer is used which
-/// is scalar * for CoeffLoader.
-template <typename Tensor, bool HasRawAccess, template <class> class MakePointer_ = MakePointer> struct CoeffLoader;
-template<typename Scalar, typename Index, int side, typename Tensor, typename nocontract_t, typename contract_t,
- int packet_size, bool inner_dim_contiguous, bool inner_dim_reordered, int Alignment,
- template <class> class MakePointer_ = MakePointer> class BaseTensorContractionMapper;
-
-template <typename Tensor, bool HasRawAccess, template <class> class MakePointer_> struct CoeffLoader {
+
+template <typename Tensor, bool HasRawAccess> struct CoeffLoader {
enum {
DirectOffsets = false
};
@@ -53,7 +47,7 @@ template <typename Tensor, bool HasRawAccess, template <class> class MakePointer
const Tensor m_tensor;
};
-template <typename Tensor, template <class> class MakePointer_> struct CoeffLoader<Tensor, true, MakePointer_> {
+template <typename Tensor> struct CoeffLoader<Tensor, true> {
enum {
DirectOffsets = true
};
@@ -73,14 +67,13 @@ template <typename Tensor, template <class> class MakePointer_> struct CoeffLoad
}
private:
typedef typename Tensor::Scalar Scalar;
-
- typename MakePointer_<const Scalar>::Type m_data;
+ const Scalar* m_data;
};
template<typename Scalar, typename Index, int side,
typename Tensor,
typename nocontract_t, typename contract_t,
- int packet_size, bool inner_dim_contiguous, int Alignment, template <class> class MakePointer_ = MakePointer>
+ int packet_size, bool inner_dim_contiguous, int Alignment>
class SimpleTensorContractionMapper {
public:
EIGEN_DEVICE_FUNC
@@ -96,7 +89,7 @@ class SimpleTensorContractionMapper {
m_k_strides(k_strides) { }
enum {
- DirectOffsets = CoeffLoader<Tensor, Tensor::RawAccess, MakePointer_>::DirectOffsets
+ DirectOffsets = CoeffLoader<Tensor, Tensor::RawAccess>::DirectOffsets
};
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void offsetBuffer(typename Tensor::Index offset) {
@@ -213,22 +206,23 @@ class SimpleTensorContractionMapper {
}
protected:
- CoeffLoader<Tensor, Tensor::RawAccess, MakePointer_> m_tensor;
+ CoeffLoader<Tensor, Tensor::RawAccess> m_tensor;
const nocontract_t m_nocontract_strides;
const nocontract_t m_ij_strides;
const contract_t m_contract_strides;
const contract_t m_k_strides;
};
+
template<typename Scalar, typename Index, int side,
typename Tensor,
typename nocontract_t, typename contract_t,
int packet_size, bool inner_dim_contiguous,
- bool inner_dim_reordered, int Alignment, template <class> class MakePointer_>
-class BaseTensorContractionMapper : public SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, Alignment, MakePointer_>
+ bool inner_dim_reordered, int Alignment>
+class BaseTensorContractionMapper : public SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, Alignment>
{
public:
- typedef SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, Alignment, MakePointer_> ParentMapper;
+ typedef SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, Alignment> ParentMapper;
EIGEN_DEVICE_FUNC
BaseTensorContractionMapper(const Tensor& tensor,
@@ -241,9 +235,9 @@ class BaseTensorContractionMapper : public SimpleTensorContractionMapper<Scalar,
typedef typename Tensor::PacketReturnType Packet;
typedef typename unpacket_traits<Packet>::half HalfPacket;
- template <typename PacketT,int AlignmentType>
+ template <int AlignmentType>
EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE PacketT load(Index i, Index j) const {
+ EIGEN_STRONG_INLINE Packet loadPacket(Index i, Index j) const {
// whole method makes column major assumption
// don't need to add offsets for now (because operator handles that)
@@ -281,13 +275,7 @@ class BaseTensorContractionMapper : public SimpleTensorContractionMapper<Scalar,
}
data[packet_size - 1] = this->m_tensor.coeff(last);
- return pload<PacketT>(data);
- }
-
- template <int AlignmentType>
- EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE Packet loadPacket(Index i, Index j) const {
- return this->load<Packet,AlignmentType>(i,j);
+ return pload<Packet>(data);
}
template <int AlignmentType>
@@ -313,11 +301,11 @@ template<typename Scalar, typename Index, int side,
typename Tensor,
typename nocontract_t, typename contract_t,
bool inner_dim_contiguous,
- bool inner_dim_reordered, int Alignment, template <class> class MakePointer_>
-class BaseTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, inner_dim_reordered, Alignment, MakePointer_> : public SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, Alignment, MakePointer_>
+ bool inner_dim_reordered, int Alignment>
+class BaseTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, inner_dim_reordered, Alignment> : public SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, Alignment>
{
public:
- typedef SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, Alignment, MakePointer_> ParentMapper;
+ typedef SimpleTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, 1, inner_dim_contiguous, Alignment> ParentMapper;
EIGEN_DEVICE_FUNC
BaseTensorContractionMapper(const Tensor& tensor,
@@ -334,12 +322,6 @@ class BaseTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, con
data[0] = this->m_tensor.coeff(this->computeIndex(i, j));
return pload<typename Tensor::PacketReturnType>(data);
}
- template <typename PacketT,int> EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE PacketT load(Index i, Index j) const {
- EIGEN_ALIGN_MAX Scalar data[1];
- data[0] = this->m_tensor.coeff(this->computeIndex(i, j));
- return pload<PacketT>(data);
- }
template <int> EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Packet loadHalfPacket(Index i, Index j) const {
return loadPacket(i, j);
@@ -351,14 +333,14 @@ template<typename Scalar, typename Index, int side,
typename Tensor,
typename nocontract_t, typename contract_t,
int packet_size,
- bool inner_dim_contiguous, bool inner_dim_reordered, int Alignment, template <class> class MakePointer_=MakePointer>
+ bool inner_dim_contiguous, bool inner_dim_reordered, int Alignment>
class TensorContractionSubMapper {
public:
typedef typename Tensor::PacketReturnType Packet;
typedef typename unpacket_traits<Packet>::half HalfPacket;
- typedef BaseTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment, MakePointer_> ParentMapper;
- typedef TensorContractionSubMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment, MakePointer_> Self;
+ typedef BaseTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment> ParentMapper;
+ typedef TensorContractionSubMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment> Self;
typedef Self LinearMapper;
enum {
@@ -403,14 +385,6 @@ class TensorContractionSubMapper {
return m_base_mapper.template loadPacket<Alignment>(i + m_vert_offset, j + m_horiz_offset);
}
- template <typename PacketT, int AlignmentType>
- EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketT loadPacket(Index i, Index j) const {
- if (UseDirectOffsets) {
- return m_base_mapper.template load<PacketT,AlignmentType>(i, j);
- }
- return m_base_mapper.template loadPacket<PacketT,AlignmentType>(i + m_vert_offset, j + m_horiz_offset);
- }
-
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i) const {
if (UseDirectOffsets) {
return m_base_mapper.template loadHalfPacket<Alignment>(i, 0);
@@ -418,7 +392,7 @@ class TensorContractionSubMapper {
return m_base_mapper.template loadHalfPacket<Alignment>(i + m_vert_offset, m_horiz_offset);
}
- EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const Packet& p) const {
+ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, Packet p) const {
if (UseDirectOffsets) {
m_base_mapper.storePacket(i, 0, p);
}
@@ -458,14 +432,14 @@ template<typename Scalar_, typename Index, int side,
typename Tensor,
typename nocontract_t, typename contract_t,
int packet_size,
- bool inner_dim_contiguous, bool inner_dim_reordered, int Alignment, template <class> class MakePointer_=MakePointer>
+ bool inner_dim_contiguous, bool inner_dim_reordered, int Alignment>
class TensorContractionInputMapper
- : public BaseTensorContractionMapper<Scalar_, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment, MakePointer_> {
+ : public BaseTensorContractionMapper<Scalar_, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment> {
public:
typedef Scalar_ Scalar;
- typedef BaseTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment, MakePointer_> Base;
- typedef TensorContractionSubMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment, MakePointer_> SubMapper;
+ typedef BaseTensorContractionMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment> Base;
+ typedef TensorContractionSubMapper<Scalar, Index, side, Tensor, nocontract_t, contract_t, packet_size, inner_dim_contiguous, inner_dim_reordered, Alignment> SubMapper;
typedef SubMapper VectorMapper;
EIGEN_DEVICE_FUNC TensorContractionInputMapper(const Tensor& tensor,
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h
deleted file mode 100644
index e87de0c..0000000
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h
+++ /dev/null
@@ -1,400 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.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/.
-
-/*****************************************************************
- * TensorSyclConvertToDeviceExpression.h
- *
- * \brief:
- * TensorContractionsycl
- *
-*****************************************************************/
-
-#ifndef EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_SYCL_H
-#define EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_SYCL_H
-namespace Eigen {
-
-template <typename Index, typename LhsScalar, typename RhsScalar,bool lhs_inner_dim_contiguous, bool rhs_inner_dim_contiguous, bool rhs_inner_dim_reordered> struct LaunchSyclKernels;
-template<typename Indices, typename LeftArgType, typename RightArgType>
-struct TensorEvaluator<const TensorContractionOp<Indices, LeftArgType, RightArgType>, const Eigen::SyclDevice> :
- public TensorContractionEvaluatorBase<TensorEvaluator<const TensorContractionOp<Indices, LeftArgType, RightArgType>, const Eigen::SyclDevice> > {
-
- typedef const Eigen::SyclDevice Device;
-
- typedef TensorEvaluator<const TensorContractionOp<Indices, LeftArgType, RightArgType>, Device> Self;
- typedef TensorContractionEvaluatorBase<Self> Base;
- typedef TensorContractionOp<Indices, LeftArgType, RightArgType> XprType;
- typedef typename internal::remove_const<typename XprType::Scalar>::type Scalar;
- typedef typename XprType::Index Index;
- typedef typename XprType::CoeffReturnType CoeffReturnType;
- typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
-
- enum {
- Layout = TensorEvaluator<LeftArgType, Device>::Layout,
- };
-
- // Most of the code is assuming that both input tensors are ColMajor. If the
- // inputs are RowMajor, we will "cheat" by swapping the LHS and RHS:
- // If we want to compute A * B = C, where A is LHS and B is RHS, the code
- // will pretend B is LHS and A is RHS.
- typedef typename internal::conditional<
- static_cast<int>(Layout) == static_cast<int>(ColMajor), LeftArgType, RightArgType>::type EvalLeftArgType;
- typedef typename internal::conditional<
- static_cast<int>(Layout) == static_cast<int>(ColMajor), RightArgType, LeftArgType>::type EvalRightArgType;
-
- static const int LDims =
- internal::array_size<typename TensorEvaluator<EvalLeftArgType, Device>::Dimensions>::value;
- static const int RDims =
- internal::array_size<typename TensorEvaluator<EvalRightArgType, Device>::Dimensions>::value;
- static const int ContractDims = internal::array_size<Indices>::value;
-
- typedef array<Index, LDims> left_dim_mapper_t;
- typedef array<Index, RDims> right_dim_mapper_t;
-
- typedef array<Index, ContractDims> contract_t;
- typedef array<Index, LDims - ContractDims> left_nocontract_t;
- typedef array<Index, RDims - ContractDims> right_nocontract_t;
-
- static const int NumDims = LDims + RDims - 2 * ContractDims;
-
- typedef DSizes<Index, NumDims> Dimensions;
-
- // typedefs needed in evalTo
- typedef typename internal::remove_const<typename EvalLeftArgType::Scalar>::type LhsScalar;
- typedef typename internal::remove_const<typename EvalRightArgType::Scalar>::type RhsScalar;
-
- typedef TensorEvaluator<EvalLeftArgType, Device> LeftEvaluator;
- typedef TensorEvaluator<EvalRightArgType, Device> RightEvaluator;
-
- typedef typename LeftEvaluator::Dimensions LeftDimensions;
- typedef typename RightEvaluator::Dimensions RightDimensions;
-
- EIGEN_DEVICE_FUNC TensorEvaluator(const XprType& op, const Device& device) :
- Base(op, device) {}
-
- // We need to redefine this method to make nvcc happy
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar* data) {
- this->m_leftImpl.evalSubExprsIfNeeded(NULL);
- this->m_rightImpl.evalSubExprsIfNeeded(NULL);
- if (data) {
- evalTo(data);
- return false;
- } else {
- this->m_result = static_cast<Scalar*>(this->m_device.allocate(this->dimensions().TotalSize() * sizeof(Scalar)));
- evalTo(this->m_result);
- return true;
- }
- }
- const Eigen::SyclDevice& device() const {return this->m_device;}
- void evalTo(Scalar* buffer) const {
- // Here is the result
- if (this->m_lhs_inner_dim_contiguous) {
- if (this->m_rhs_inner_dim_contiguous) {
- if (this->m_rhs_inner_dim_reordered) {
- evalTyped<true, true, true, Unaligned>(buffer);
- }
- else {
- evalTyped<true, true, false, Unaligned>(buffer);
- }
- }
- else {
- if (this->m_rhs_inner_dim_reordered) {
- evalTyped<true, false, true, Unaligned>(buffer);
- }
- else {
- evalTyped<true, false, false, Unaligned>(buffer);
- }
- }
- }
- else {
- if (this->m_rhs_inner_dim_contiguous) {
- if (this->m_rhs_inner_dim_reordered) {
- evalTyped<false, true, true, Unaligned>(buffer);
- }
- else {
- evalTyped<false, true, false, Unaligned>(buffer);
- }
- }
- else {
- if (this->m_rhs_inner_dim_reordered) {
- evalTyped<false, false, true, Unaligned>(buffer);
- }
- else {
- evalTyped<false, false, false, Unaligned>(buffer);
- }
- }
- }
- }
-
- template <bool lhs_inner_dim_contiguous, bool rhs_inner_dim_contiguous, bool rhs_inner_dim_reordered, int Alignment>
- void evalTyped(Scalar* buffer) const {
- // columns in left side, rows in right side
- const Index k = this->m_k_size;
- EIGEN_UNUSED_VARIABLE(k)
- // rows in left side
- const Index m = this->m_i_size;
- // columns in right side
- const Index n = this->m_j_size;
-
- // zero out the result buffer (which must be of size at least m * n * sizeof(Scalar)
- this->m_device.memset(buffer, 0, m * n * sizeof(Scalar));
- LaunchSyclKernels<Index, LhsScalar, RhsScalar,lhs_inner_dim_contiguous, rhs_inner_dim_contiguous, rhs_inner_dim_reordered>::Run(*this, buffer, m, n, k,
- this->m_k_strides, this->m_left_contracting_strides, this->m_right_contracting_strides,
- this->m_i_strides, this->m_j_strides, this->m_left_nocontract_strides, this->m_right_nocontract_strides);
- }
- // required by sycl to construct the expr on the device. Returns original left_impl
- const TensorEvaluator<LeftArgType, Device>& left_impl() const {
- return choose(Cond<static_cast<int>(Layout) == static_cast<int>(ColMajor)>(), this->m_leftImpl, this->m_rightImpl);
- }
- // required by sycl to construct the expr on the device. Returns original right_impl
- const TensorEvaluator<RightArgType, Device>& right_impl() const {
- return choose(Cond<static_cast<int>(Layout) == static_cast<int>(ColMajor)>(), this->m_rightImpl, this->m_leftImpl);
- }
-};
-
-template <typename HostExpr, typename OutScalar, typename LhsScalar, typename RhsScalar, typename LHSFunctorExpr, typename RHSFunctorExpr, typename LhsLocalAcc, typename RhsLocalAcc, typename OutAccessor, typename Index, typename ContractT, typename LeftNocontractT,
-typename RightNocontractT, bool lhs_inner_dim_contiguous, bool rhs_inner_dim_contiguous, bool rhs_inner_dim_reordered,
-typename HostExpr::Index TileSizeDimM, typename HostExpr::Index TileSizeDimN,typename HostExpr::Index TileSizeDimK, typename HostExpr::Index WorkLoadPerThreadM,typename HostExpr::Index WorkLoadPerThreadN,
-typename HostExpr::Index LocalThreadSizeM, typename HostExpr::Index LocalThreadSizeN, typename HostExpr::Index LoadPerThreadLhs, typename HostExpr::Index LoadPerThreadRhs, typename LHSTupleType, typename RHSTupleType, typename Device> struct KernelConstructor{
- typedef typename Eigen::internal::traits<HostExpr>::_LhsNested LHSHostExpr;
- typedef typename Eigen::internal::traits<HostExpr>::_RhsNested RHSHostExpr;
- typedef typename Eigen::TensorSycl::internal::createPlaceHolderExpression<LHSHostExpr>::Type LHSPlaceHolderExpr;
- typedef typename Eigen::TensorSycl::internal::createPlaceHolderExpression<RHSHostExpr>::Type RHSPlaceHolderExpr;
- LHSFunctorExpr lhs_functors;
- RHSFunctorExpr rhs_functors;
- LhsLocalAcc localLhs;
- RhsLocalAcc localRhs;
- OutAccessor out_res;
- Index roundUpK, M, N, K;
- ContractT m_k_strides, m_left_contracting_strides, m_right_contracting_strides;
- LeftNocontractT m_i_strides, m_left_nocontract_strides;
- RightNocontractT m_j_strides, m_right_nocontract_strides;
- LHSTupleType left_tuple_of_accessors;
- RHSTupleType right_tuple_of_accessors;
- Device dev;
-
-
- KernelConstructor(LHSFunctorExpr lhs_functors_, RHSFunctorExpr rhs_functors_, LhsLocalAcc localLhs_, RhsLocalAcc localRhs_, OutAccessor out_res_,
- Index roundUpK_, Index M_, Index N_, Index K_, ContractT m_k_strides_, ContractT m_left_contracting_strides_,
- ContractT m_right_contracting_strides_, LeftNocontractT m_i_strides_, RightNocontractT m_j_strides_,
- LeftNocontractT m_left_nocontract_strides_, RightNocontractT m_right_nocontract_strides_, LHSTupleType left_tuple_of_accessors_, RHSTupleType right_tuple_of_accessors_, Device dev_)
- :lhs_functors(lhs_functors_), rhs_functors(rhs_functors_), localLhs(localLhs_), localRhs(localRhs_), out_res(out_res_), roundUpK(roundUpK_), M(M_), N(N_), K(K_),
- m_k_strides(m_k_strides_), m_left_contracting_strides(m_left_contracting_strides_),
- m_right_contracting_strides(m_right_contracting_strides_),
- m_i_strides(m_i_strides_), m_left_nocontract_strides(m_left_nocontract_strides_),
- m_j_strides(m_j_strides_), m_right_nocontract_strides(m_right_nocontract_strides_),
- left_tuple_of_accessors(left_tuple_of_accessors_), right_tuple_of_accessors(right_tuple_of_accessors_), dev(dev_){}
-
- void operator()(cl::sycl::nd_item<1> itemID) {
- typedef typename Eigen::TensorSycl::internal::ConvertToDeviceExpression<HostExpr>::Type DevExpr;
- typedef typename Eigen::TensorSycl::internal::ConvertToDeviceExpression<LHSHostExpr>::Type LHSDevExpr;
- typedef typename Eigen::TensorSycl::internal::ConvertToDeviceExpression<RHSHostExpr>::Type RHSDevExpr;
- auto lhs_dev_expr = Eigen::TensorSycl::internal::createDeviceExpression<LHSDevExpr, LHSPlaceHolderExpr>(lhs_functors, left_tuple_of_accessors);
- auto rhs_dev_expr = Eigen::TensorSycl::internal::createDeviceExpression<RHSDevExpr, RHSPlaceHolderExpr>(rhs_functors, right_tuple_of_accessors);
- typedef decltype(lhs_dev_expr.expr) LeftArgType;
- typedef decltype(rhs_dev_expr.expr) RightArgType;
- typedef typename internal::conditional<static_cast<int>(Eigen::internal::traits<DevExpr>::Layout) == static_cast<int>(ColMajor), LeftArgType, RightArgType>::type EvalLeftArgType;
- typedef typename internal::conditional<static_cast<int>(Eigen::internal::traits<DevExpr>::Layout) == static_cast<int>(ColMajor), RightArgType, LeftArgType>::type EvalRightArgType;
- typedef TensorEvaluator<EvalLeftArgType, Device> LeftEvaluator;
- typedef TensorEvaluator<EvalRightArgType, Device> RightEvaluator;
- typedef internal::TensorContractionInputMapper<LhsScalar, Index, internal::Lhs,
- LeftEvaluator, LeftNocontractT,
- ContractT, 1,
- lhs_inner_dim_contiguous,
- false, Unaligned, MakeGlobalPointer> LhsMapper;
-
- typedef internal::TensorContractionInputMapper<RhsScalar, Index, internal::Rhs,
- RightEvaluator, RightNocontractT,
- ContractT, 1,
- rhs_inner_dim_contiguous,
- rhs_inner_dim_reordered, Unaligned, MakeGlobalPointer> RhsMapper;
- // initialize data mappers must happen inside the kernel for device eval
- LhsMapper lhs(LeftEvaluator(choose(Cond<static_cast<int>(Eigen::internal::traits<DevExpr>::Layout) == static_cast<int>(ColMajor)>(),
- lhs_dev_expr.expr, rhs_dev_expr.expr), dev), m_left_nocontract_strides, m_i_strides, m_left_contracting_strides, m_k_strides);
- RhsMapper rhs(RightEvaluator(choose(Cond<static_cast<int>(Eigen::internal::traits<DevExpr>::Layout) == static_cast<int>(ColMajor)>(),
- rhs_dev_expr.expr, lhs_dev_expr.expr),dev), m_right_nocontract_strides, m_j_strides, m_right_contracting_strides, m_k_strides);
- auto out_ptr = ConvertToActualTypeSycl(OutScalar, out_res);
- // Matmul Kernel
- // Thread identifiers
- const Index mLocalThreadId = itemID.get_local(0); // Local ID row
- const Index nLocalThreadId = itemID.get_local(1); // Local ID col
- const Index mGroupId = itemID.get_group(0); // Work-group ID row
- const Index nGroupId = itemID.get_group(1); // Work-group ID localCol
- const Index linearLocalThreadId = nLocalThreadId*LocalThreadSizeM + mLocalThreadId; // linear local thread ID
- // Allocate register space
- float privateLhs;
- float privateRhs[WorkLoadPerThreadN];
- float privateRes[WorkLoadPerThreadM][WorkLoadPerThreadN];
- // Initialise the privateResumulation registers
- for (Index wLPTM=0; wLPTM<WorkLoadPerThreadM; wLPTM++) {
- for (Index wLPTN=0; wLPTN<WorkLoadPerThreadN; wLPTN++) {
- privateRes[wLPTM][wLPTN] = 0.0f;
- }
- }
-
- // Tile Lhs
- for (Index lPTL=0; lPTL<LoadPerThreadLhs; lPTL++) {
- Index localLhsLinearId = lPTL*LocalThreadSizeN*LocalThreadSizeM + linearLocalThreadId;
- Index localLhsRow = localLhsLinearId% TileSizeDimM;
- Index localLhsCol = localLhsLinearId/TileSizeDimM;
- // Load the value (wide vector load)
- Index GlobalLhsColId = TileSizeDimK*0 + localLhsCol;
- localLhs[0 + ((localLhsCol*TileSizeDimM + localLhsRow)*2)] =((GlobalLhsColId < K)&& (mGroupId*(TileSizeDimM)+ localLhsRow <M))? lhs(mGroupId*(TileSizeDimM) + localLhsRow, GlobalLhsColId):static_cast<OutScalar>(0);
- }
- // Tile Rhs
- for (Index lPTR=0; lPTR<LoadPerThreadRhs; lPTR++) {
- Index localRhsLinearId = lPTR*LocalThreadSizeN*LocalThreadSizeM + linearLocalThreadId;
- Index localRhsRow = localRhsLinearId% TileSizeDimN;
- Index localRhsCol = localRhsLinearId/TileSizeDimN;
- // Load the value (wide vector load)
- Index GlobalRhsRowId = TileSizeDimK*0 + localRhsCol;
- localRhs[0 + ((localRhsCol*TileSizeDimN + localRhsRow) *2)] = ((GlobalRhsRowId < K)&& ((nGroupId*(TileSizeDimN) + localRhsRow)< N))? rhs(GlobalRhsRowId, nGroupId*(TileSizeDimN) + localRhsRow): static_cast<OutScalar>(0);
-
- }
- // Loop over all tiles
- const Index numTiles = roundUpK/TileSizeDimK;
- Index firstHalf=0;
- do {
- // Synchronise
- itemID.barrier(cl::sycl::access::fence_space::local_space);
- // Load the next tile of Lhs and Rhs into local memory
- Index nextHalf = firstHalf + 1;
- if (nextHalf < numTiles) {
- // Tile A
- for (Index lPTL=0; lPTL<LoadPerThreadLhs; lPTL++) {
- Index localLhsLinearId = lPTL*LocalThreadSizeN*LocalThreadSizeM + linearLocalThreadId;
- Index localLhsRow = localLhsLinearId% TileSizeDimM;
- Index localLhsCol = localLhsLinearId/TileSizeDimM;
- // global K id
- Index GlobalLhsColId = TileSizeDimK*nextHalf + localLhsCol;
- // Store the loaded value into local memory
- localLhs[(nextHalf%2) + ((localLhsCol*TileSizeDimM + localLhsRow) *2)] = ((GlobalLhsColId < K)&& (mGroupId*(TileSizeDimM)+ localLhsRow <M))? lhs(mGroupId*(TileSizeDimM) + localLhsRow, GlobalLhsColId): static_cast<OutScalar>(0);
- }
- // Tile B
- for (Index lPTR=0; lPTR<LoadPerThreadRhs; lPTR++) {
- Index localRhsLinearId = lPTR*LocalThreadSizeN*LocalThreadSizeM + linearLocalThreadId;
- Index localRhsRow = localRhsLinearId% TileSizeDimN;
- Index localRhsCol = localRhsLinearId/TileSizeDimN;
- // Load the value (wide vector load)
- Index GlobalRhsRowId = TileSizeDimK*nextHalf + localRhsCol;
- // Store the loaded vector into local memory
- localRhs[(nextHalf%2) +((localRhsCol*TileSizeDimN + localRhsRow)*2)] = ((GlobalRhsRowId < K)&& ((nGroupId*(TileSizeDimN) + localRhsRow)< N))? rhs(GlobalRhsRowId, nGroupId*(TileSizeDimN) + localRhsRow):static_cast<OutScalar>(0);
- }
- }
- // Loop over the values of a single tile
- for (Index k=0; k<TileSizeDimK; k++) {
- // Cache the values of localRhs in registers
- for (Index wLPTN=0; wLPTN<WorkLoadPerThreadN; wLPTN++) {
- Index localRhsCol = nLocalThreadId + wLPTN*LocalThreadSizeN;
- privateRhs[wLPTN] = localRhs[(firstHalf%2) +((k*TileSizeDimN + localRhsCol)*2)];
- }
- // Perform the computation
- for (Index wLPTM=0; wLPTM<WorkLoadPerThreadM; wLPTM++) {
- Index localLhsRow = mLocalThreadId + wLPTM*LocalThreadSizeM;
- privateLhs = localLhs[(firstHalf%2)+ ((k*TileSizeDimM + localLhsRow)*2)];
- for (Index wLPTN=0; wLPTN<WorkLoadPerThreadN; wLPTN++) {
- privateRes[wLPTM][wLPTN] += privateLhs * privateRhs[wLPTN];
- }
- }
- }
- // Next tile
- firstHalf++;
- } while (firstHalf<numTiles);
-
- // Store the final results in C
- for (Index wLPTM=0; wLPTM<WorkLoadPerThreadM; wLPTM++) {
- Index globalRow = mGroupId*TileSizeDimM + mLocalThreadId + wLPTM*LocalThreadSizeM;
- if (globalRow< M){
- for (Index wLPTN=0; wLPTN<WorkLoadPerThreadN; wLPTN++) {
- Index globalCol = nGroupId*TileSizeDimN + nLocalThreadId + wLPTN*LocalThreadSizeN;
- if(globalCol<N)
- out_ptr[globalCol*M + globalRow] = privateRes[wLPTM][wLPTN];
- }
- }
- }
-
- }
-
-};
-template <typename Index, typename LhsScalar, typename RhsScalar, bool lhs_inner_dim_contiguous, bool rhs_inner_dim_contiguous, bool rhs_inner_dim_reordered> struct LaunchSyclKernels {
-
-static const Index TileSizeDimM = 32ul; // Tile size for dimension M
-static const Index TileSizeDimN = 32ul; // Tile size for dimension N
-static const Index TileSizeDimK = 16ul; // Tile size for dimension K
-static const Index WorkLoadPerThreadM = 4ul; // Work load per thread in dimension M
-static const Index WorkLoadPerThreadN = 4ul; // work load per thread in dimension N
-static const Index LocalThreadSizeM = (TileSizeDimM/WorkLoadPerThreadM); // Local thread size for the first dimension (M here)
-static const Index LocalThreadSizeN = (TileSizeDimN/WorkLoadPerThreadN); // Local thread size for the second dimension (N here)
-static const Index LoadPerThreadLhs = ((TileSizeDimK*WorkLoadPerThreadM*WorkLoadPerThreadN)/(TileSizeDimN)); // workload per thread for Lhs expression
-static const Index LoadPerThreadRhs = ((TileSizeDimK*WorkLoadPerThreadM*WorkLoadPerThreadN)/(TileSizeDimM)); // workload per thread for Rhs expression
-
-// RoundUp function to make sure that the global threadId is divisable by local threadId
-static Index RoundUp(Index x, Index y) {
- return ((((x) + (y) - 1) / (y))*(y));
-}
-
-template< typename Self, typename OutScalar, typename ContractT, typename LeftNocontractT, typename RightNocontractT>
- static void Run(const Self& self, OutScalar* buffer, Index M, Index N, Index K,
- ContractT m_k_strides, ContractT m_left_contracting_strides, ContractT m_right_contracting_strides,
- LeftNocontractT m_i_strides, RightNocontractT m_j_strides, LeftNocontractT m_left_nocontract_strides, RightNocontractT m_right_nocontract_strides){
-
- typedef typename Self::XprType HostExpr;
- typedef typename Eigen::internal::traits<HostExpr>::_LhsNested LHSHostExpr;
- typedef typename Eigen::internal::traits<HostExpr>::_RhsNested RHSHostExpr;
- typedef TensorEvaluator<LHSHostExpr, const Eigen::SyclDevice> OrigLHSExpr;
- typedef TensorEvaluator<RHSHostExpr, const Eigen::SyclDevice> OrigRHSExpr;
- typedef Eigen::TensorSycl::internal::FunctorExtractor<OrigLHSExpr> LHSFunctorExpr;
- typedef Eigen::TensorSycl::internal::FunctorExtractor<OrigRHSExpr> RHSFunctorExpr;
- // extract lhs functor list
- LHSFunctorExpr lhs_functors = Eigen::TensorSycl::internal::extractFunctors(self.left_impl());
- // extract rhs functor list
- RHSFunctorExpr rhs_functors = Eigen::TensorSycl::internal::extractFunctors(self.left_impl());
-
- Index roundUpK = RoundUp(K, TileSizeDimK);
- Index roundUpM = RoundUp(M, TileSizeDimM);
- Index roundUpN = RoundUp(N, TileSizeDimN);
-
- self.device().sycl_queue().submit([&](cl::sycl::handler &cgh) {
- /// work-around for gcc bug
- typedef decltype(Eigen::TensorSycl::internal::createTupleOfAccessors<OrigLHSExpr>(cgh, self.left_impl())) LHSTupleType;
- /// work-around for gcc bug
- typedef decltype(Eigen::TensorSycl::internal::createTupleOfAccessors<OrigRHSExpr>(cgh, self.right_impl())) RHSTupleType;
- // create lhs tuple of accessors
- LHSTupleType left_tuple_of_accessors = Eigen::TensorSycl::internal::createTupleOfAccessors<OrigLHSExpr>(cgh, self.left_impl());
- // create rhs tuple of accessors
- RHSTupleType right_tuple_of_accessors = Eigen::TensorSycl::internal::createTupleOfAccessors<OrigRHSExpr>(cgh, self.right_impl());
-
- // Local memory for elements of Lhs
- typedef cl::sycl::accessor<LhsScalar, 1, cl::sycl::access::mode::read_write, cl::sycl::access::target::local> LhsLocalAcc;
- LhsLocalAcc localLhs(cl::sycl::range<1>(2* TileSizeDimM * TileSizeDimK), cgh);
- // Local memory for elements of Rhs
- typedef cl::sycl::accessor<RhsScalar, 1, cl::sycl::access::mode::read_write, cl::sycl::access::target::local> RhsLocalAcc;
- RhsLocalAcc localRhs(cl::sycl::range<1>(2* TileSizeDimK * TileSizeDimN), cgh);
-
- typedef cl::sycl::accessor<uint8_t, 1, cl::sycl::access::mode::write, cl::sycl::access::target::global_buffer> OutAccessor;
- //OutScalar memory
- OutAccessor out_res= self.device(). template get_sycl_accessor<cl::sycl::access::mode::write>(cgh, buffer);
-
- // sycl parallel for
- cgh.parallel_for(cl::sycl::nd_range<2>(cl::sycl::range<2>(roundUpM/WorkLoadPerThreadM, roundUpN/WorkLoadPerThreadN),
- cl::sycl::range<2>(LocalThreadSizeM, LocalThreadSizeN)),
- KernelConstructor<HostExpr, OutScalar, LhsScalar, RhsScalar, LHSFunctorExpr, RHSFunctorExpr, LhsLocalAcc, RhsLocalAcc, OutAccessor, Index, ContractT, LeftNocontractT,
- RightNocontractT, lhs_inner_dim_contiguous, rhs_inner_dim_contiguous, rhs_inner_dim_reordered, TileSizeDimM, TileSizeDimN, TileSizeDimK,
- WorkLoadPerThreadM, WorkLoadPerThreadN, LocalThreadSizeM, LocalThreadSizeN, LoadPerThreadLhs, LoadPerThreadRhs, LHSTupleType, RHSTupleType, Eigen::DefaultDevice>(lhs_functors, rhs_functors,
- localLhs, localRhs, out_res, roundUpK, M, N, K, m_k_strides, m_left_contracting_strides, m_right_contracting_strides,m_i_strides, m_j_strides,
- m_left_nocontract_strides,m_right_nocontract_strides, left_tuple_of_accessors, right_tuple_of_accessors, Eigen::DefaultDevice()));
- });
- self.device().asynchronousExec();
- }
-};
-
-} // end namespace Eigen
-#endif // EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_SYCL_H
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h
index d30cc96..ee16cde 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h
@@ -116,28 +116,6 @@ struct TensorEvaluator<const TensorContractionOp<Indices, LeftArgType, RightArgT
template <bool lhs_inner_dim_contiguous, bool rhs_inner_dim_contiguous,
bool rhs_inner_dim_reordered, int Alignment>
void evalProduct(Scalar* buffer) const {
- const Index m = this->m_i_size;
- const Index n = this->m_j_size;
- const Index k = this->m_k_size;
- if (m == 0 || n == 0 || k == 0) return;
-
-#if defined(EIGEN_VECTORIZE_AVX) && defined(EIGEN_USE_LIBXSMM)
- if (this->m_can_use_xsmm) {
- bool transposeA = !this->m_lhs_inner_dim_contiguous;
- bool transposeB = !this->m_rhs_inner_dim_contiguous;
- internal::TensorXsmmContractionBlocking<LhsScalar, RhsScalar, Index>
- blocking(k, m, n, this->m_device.numThreads(), transposeA,
- transposeB);
-
- if (blocking.num_threads() == 1) {
- this->evalGemmXSMM(buffer);
- } else {
- ContextXsmm<Alignment>(this, buffer, m, n, k, blocking).run();
- }
- return;
- }
-#endif
-
typedef
typename internal::remove_const<typename EvalLeftArgType::Scalar>::type
LhsScalar;
@@ -169,7 +147,10 @@ struct TensorEvaluator<const TensorContractionOp<Indices, LeftArgType, RightArgT
Traits::mr, Traits::nr, false, false>
GebpKernel;
-
+ const Index m = this->m_i_size;
+ const Index n = this->m_j_size;
+ const Index k = this->m_k_size;
+ if (m == 0 || n == 0 || k == 0) return;
// Compute a set of algorithm parameters:
// - kernel block sizes (bm, bn, bk)
@@ -1063,187 +1044,6 @@ struct TensorEvaluator<const TensorContractionOp<Indices, LeftArgType, RightArgT
rhsCost.dropMemoryCost();
return cost + lhsCost + rhsCost;
}
-
-#if defined(EIGEN_VECTORIZE_AVX) && defined(EIGEN_USE_LIBXSMM)
- template<int Alignment>
- class ContextXsmm {
- public:
- ContextXsmm(const Self* self, Scalar* buffer, Index m, Index n, Index k,
- const internal::TensorXsmmContractionBlocking<LhsScalar,
- RhsScalar, Index>& blocking):
- device(self->m_device),
- m(m), k(k), n(n),
- stride_a(blocking.transposeA() ? k : m),
- stride_b(blocking.transposeB() ? n : k),
- stride_c(m),
- bm(blocking.mc()), bk(blocking.kc()), bn(blocking.nc()),
- blocks_m(blocking.blocks_m()), blocks_k(blocking.blocks_k()),
- blocks_n(blocking.blocks_n()),
- copyA(blocking.copyA()), copyB(blocking.copyB()),
- transposeA(blocking.transposeA()), transposeB(blocking.transposeB()),
- num_threads(blocking.num_threads()),
- buffer(buffer),
- leftData(self->m_leftImpl.data()), rightData(self->m_rightImpl.data()),
- workers_done(blocking.num_threads()),
-
- packingA_jobs(0), packingB_jobs(0), compute_jobs(0),
- packingA_done(blocking.blocks_m()), packingB_done(blocking.blocks_n()) {}
-
- void worker() {
- // Pack
-
- if (copyA) {
- while (true) {
- uint32_t mk = packingA_jobs++;
- Index mi = mk / blocks_k;
- Index ki = mk % blocks_k;
- if (mi >= blocks_m) break;
-
- LhsScalar * blockA = blocksA + (bk*bm) * (mi*blocks_k+ki);
- if (transposeA) {
- const LhsScalar * current_a = leftData + (bm*mi)*stride_a + (bk*ki);
- libxsmm_otrans(blockA, current_a, sizeof(LhsScalar), actual_bk(ki),
- actual_bm(mi), stride_a, bm);
- } else {
- const LhsScalar * current_a = leftData + (bk*ki)*stride_a + (bm*mi);
- internal::pack_simple<LhsScalar, Index>(blockA, current_a,
- actual_bk(ki), actual_bm(mi), bm, stride_a);
- }
- packingA_done.at(mi)++;
- }
- }
-
- if (copyB) {
- while (true) {
- uint32_t nk = packingB_jobs++;
- Index ni = nk / blocks_k;
- Index ki = nk % blocks_k;
- if (ni >= blocks_n) break;
-
- RhsScalar * blockB = blocksB + (bk*bn) * (ni*blocks_k+ki);
- if (transposeB) {
- const RhsScalar * current_b = rightData + (ki*bk)*stride_b +
- (ni*bn);
- libxsmm_otrans(blockB, current_b, sizeof(RhsScalar), actual_bn(ni),
- actual_bk(ki), stride_b, bk);
- } else {
- const RhsScalar * current_b = rightData + (ni*bn)*stride_b +
- (ki*bk);
- internal::pack_simple<RhsScalar, Index>(blockB, current_b,
- actual_bn(ni), actual_bk(ki), bk, stride_b);
- }
- packingB_done.at(ni)++;
- }
- }
-
- // Compute
-
- while (true) {
- uint32_t mn = compute_jobs++;
- Index mi = mn / blocks_n;
- Index ni = mn % blocks_n;
- if (mi >= blocks_m) break;
-
- // Wait for mi, ni packings to be done. This is more fine-grained than
- // waiting for all workers to finish packing.
- while ((copyA && (packingA_done.at(mi) < blocks_k)) ||
- (copyB && (packingB_done.at(ni) < blocks_k)))
- {}
-
- for (Index ki=0; ki < blocks_k; ++ki) {
- const LhsScalar * current_a = copyA ?
- blocksA + (bk*bm) * (mi*blocks_k+ki) :
- leftData + (bk*ki)*stride_a + (bm*mi);
- const RhsScalar * current_b = copyB ?
- blocksB + (bk*bn) * (ni*blocks_k+ki) :
- rightData + (ni*bn)*stride_b + (bk*ki);
-
- Index current_stride_a = copyA ? bm : stride_a;
- Index current_stride_b = copyB ? bk : stride_b;
-
- // Memory may not be zeroed, overwrite instead of adding in first
- // iteration.
- float beta = ki == 0 ? 0 : 1;
-
- Scalar * current_c = buffer + (mi*bm) + (ni*bn)*stride_c;
- internal::libxsmm_wrapper<LhsScalar, RhsScalar, Scalar>(
- 0, actual_bm(mi), actual_bn(ni), actual_bk(ki),
- current_stride_a, current_stride_b, stride_c, 1, beta, 0)
- (current_a, current_b, current_c);
- }
- }
-
- workers_done.Notify();
- }
-
- void run() {
- // Parallelization strategy.
- //
- // First pack A into blocks (sharding by m, k) and B (sharding by n,k),
- // then shard by m, n.
- //
- // Do not use advanced ThreadPool queuing, just run a single long-standing
- // function in each thread.
- if (copyA) {
- blocksA = static_cast<LhsScalar*>(device.allocate(
- (blocks_m*bm)*(blocks_k*bk)*sizeof(LhsScalar)));
- }
- if (copyB) {
- blocksB = static_cast<RhsScalar*>(device.allocate(
- (blocks_n*bn)*(blocks_k*bk)*sizeof(RhsScalar)));
- }
-
- for (Index i = 0; i < num_threads; ++i) {
- device.enqueueNoNotification([=]() { worker(); });
- }
-
- workers_done.Wait();
-
- if (copyA) {
- device.deallocate(blocksA);
- }
- if (copyB) {
- device.deallocate(blocksB);
- }
- }
-
- private:
- // real block size for block index in [0, ..., blocks - 1].
- Index actual_bm(Index mi) const {
- return mi != blocks_m - 1 ? bm : m + bm - bm * blocks_m;
- }
- Index actual_bk(Index ki) const {
- return ki != blocks_k - 1 ? bk : k + bk - bk * blocks_k;
- }
- Index actual_bn(Index ni) const {
- return ni != blocks_n - 1 ? bn : n + bn - bn * blocks_n;
- }
-
- const Device& device;
- Index m, k, n;
- Index stride_a, stride_b, stride_c;
- Index bm, bk, bn; // Block sizes.
- Index blocks_m, blocks_k, blocks_n; // Number of blocks in each dimension.
- bool copyA, copyB, transposeA, transposeB;
- Index num_threads;
- Scalar *buffer;
- const LhsScalar *leftData;
- const RhsScalar *rightData;
-
- LhsScalar *blocksA;
- RhsScalar *blocksB;
- // barrier for joining all threads after all done.
- Barrier workers_done;
- // "queues" of (mi,ki), (ki,ni), (mi,ni) jobs packed [0,p)x[0,q) -> [0, p*q)
- std::atomic<uint32_t> packingA_jobs;
- std::atomic<uint32_t> packingB_jobs;
- std::atomic<uint32_t> compute_jobs;
- // already packed blocks for each mi-panel in A and ni-panel in B.
- std::vector<std::atomic<uint8_t>> packingA_done;
- std::vector<std::atomic<uint8_t>> packingB_done;
- };
-#endif
-
};
} // end namespace Eigen
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h
index b29968b..860a694 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h
@@ -246,9 +246,6 @@ struct TensorEvaluator<const TensorConversionOp<TargetType, ArgType>, Device>
EIGEN_DEVICE_FUNC Scalar* data() const { return NULL; }
- /// required by sycl in order to extract the sycl accessor
- const TensorEvaluator<ArgType, Device>& impl() const { return m_impl; }
-
protected:
template <int LoadMode, bool ActuallyVectorize>
struct PacketConv {
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h
index 378f5cc..abdf742 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h
@@ -100,7 +100,7 @@ class IndexMapper {
}
} else {
for (int i = NumDims - 1; i >= 0; --i) {
- if (static_cast<size_t>(i + 1) < offset) {
+ if (i + 1 < offset) {
m_cudaInputStrides[i] =
m_cudaInputStrides[i + 1] * cudaInputDimensions[i + 1];
m_cudaOutputStrides[i] =
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h
deleted file mode 100644
index 4247c1c..0000000
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h
+++ /dev/null
@@ -1,476 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.com>
-// Copyright (C) 2016 Benoit Steiner <benoit.steiner.goog@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_CXX11_TENSOR_TENSOR_CONVOLUTION_SYCL_H
-#define EIGEN_CXX11_TENSOR_TENSOR_CONVOLUTION_SYCL_H
-
-namespace Eigen {
-
-/** \class TensorConvolution
- * \ingroup CXX11_Tensor_Module
- *
- * \brief Tensor convolution class.
- *
- *
- */
-template <typename CoeffReturnType, typename KernelType, typename HostExpr, typename FunctorExpr, typename Index,
-typename InputDims, typename Kernel_accessor, typename Buffer_accessor, typename Local_accessor, typename TupleType>
-struct EigenConvolutionKernel1D{
-typedef typename TensorSycl::internal::createPlaceHolderExpression<HostExpr>::Type PlaceHolderExpr;
-internal::IndexMapper<Index, InputDims, 1, Eigen::internal::traits<HostExpr>::Layout> indexMapper;
-Kernel_accessor kernel_filter;
-const size_t kernelSize, range_x, range_y;
-Buffer_accessor buffer_acc;
-Local_accessor local_acc;
-FunctorExpr functors;
-TupleType tuple_of_accessors;
-EigenConvolutionKernel1D(internal::IndexMapper<Index, InputDims, 1, Eigen::internal::traits<HostExpr>::Layout> indexMapper_,
- Kernel_accessor kernel_filter_, const size_t kernelSize_, const size_t range_x_, const size_t range_y_,
- Buffer_accessor buffer_acc_, Local_accessor local_acc_, FunctorExpr functors_, TupleType tuple_of_accessors_)
- :indexMapper(indexMapper_), kernel_filter(kernel_filter_), kernelSize(kernelSize_), range_x(range_x_), range_y(range_y_),
- buffer_acc(buffer_acc_), local_acc(local_acc_), functors(functors_), tuple_of_accessors(tuple_of_accessors_) {}
-
- void operator()(cl::sycl::nd_item<2> itemID) {
- typedef typename TensorSycl::internal::ConvertToDeviceExpression<HostExpr>::Type DevExpr;
- auto device_expr =TensorSycl::internal::createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
- auto device_evaluator = Eigen::TensorEvaluator<DevExpr, Eigen::DefaultDevice>(device_expr.expr, Eigen::DefaultDevice());
-
- auto buffer_ptr = ConvertToActualTypeSycl(CoeffReturnType, buffer_acc);
- auto kernel_ptr = ConvertToActualTypeSycl(KernelType, kernel_filter);
-
- const size_t num_x_input = (itemID.get_local_range()[0] +kernelSize -1); //the required row to be calculated for the for each plane in shered memory
- const size_t plane_kernel_offset = itemID.get_local(1) * num_x_input;
- const size_t first_input_start = itemID.get_group(0)*itemID.get_local_range()[0];
- const size_t plane_tensor_offset =indexMapper.mapCudaInputPlaneToTensorInputOffset(itemID.get_global(1));
- /// fill the shared memory
- for (size_t i = itemID.get_local(0); i < num_x_input ; i += itemID.get_local_range()[0]) {
- const size_t local_index = i + plane_kernel_offset ;
- const size_t tensor_index = plane_tensor_offset + indexMapper.mapCudaInputKernelToTensorInputOffset(i + first_input_start);
- if(((i + first_input_start) < (range_x +kernelSize-1)) && itemID.get_global(1)< range_y){
- local_acc[local_index] = device_evaluator.coeff(tensor_index);
- }
- else local_acc[local_index]=0.0f;
- }
-
- itemID.barrier(cl::sycl::access::fence_space::local_space);
-
- // calculate the convolution
- const size_t first_output_start =itemID.get_group(0)*(itemID.get_local_range()[0]); // output start x
- if(itemID.get_global(0)< range_x && itemID.get_global(1)< range_y){
- CoeffReturnType result = static_cast<CoeffReturnType>(0);
- const size_t index = plane_kernel_offset+ itemID.get_local(0);
- for (size_t k = 0; k < kernelSize; ++k) {
- result += (local_acc[k + index] * kernel_ptr[k]);
- }
- const size_t tensor_index = indexMapper.mapCudaOutputPlaneToTensorOutputOffset(itemID.get_global(1))
- +indexMapper.mapCudaOutputKernelToTensorOutputOffset(itemID.get_local(0) + first_output_start);
- buffer_ptr[tensor_index] = result;
- }
- }
-};
-
-
-template <typename CoeffReturnType, typename KernelType, typename HostExpr, typename FunctorExpr, typename Index,
-typename InputDims, typename Kernel_accessor, typename Buffer_accessor, typename Local_accessor, typename TupleType>
-struct EigenConvolutionKernel2D{
-typedef typename TensorSycl::internal::createPlaceHolderExpression<HostExpr>::Type PlaceHolderExpr;
-internal::IndexMapper<Index, InputDims, 2, Eigen::internal::traits<HostExpr>::Layout> indexMapper;
-Kernel_accessor kernel_filter;
-const size_t kernelSize_x, kernelSize_y, range_x, range_y , range_z;
-Buffer_accessor buffer_acc;
-Local_accessor local_acc;
-FunctorExpr functors;
-TupleType tuple_of_accessors;
-EigenConvolutionKernel2D(internal::IndexMapper<Index, InputDims, 2, Eigen::internal::traits<HostExpr>::Layout> indexMapper_,
- Kernel_accessor kernel_filter_, const size_t kernelSize_x_, const size_t kernelSize_y_ ,const size_t range_x_, const size_t range_y_, const size_t range_z_,
- Buffer_accessor buffer_acc_, Local_accessor local_acc_, FunctorExpr functors_, TupleType tuple_of_accessors_)
- :indexMapper(indexMapper_), kernel_filter(kernel_filter_), kernelSize_x(kernelSize_x_), kernelSize_y(kernelSize_y_), range_x(range_x_), range_y(range_y_), range_z(range_z_),
- buffer_acc(buffer_acc_), local_acc(local_acc_), functors(functors_), tuple_of_accessors(tuple_of_accessors_) {}
-
- void operator()(cl::sycl::nd_item<3> itemID) {
- typedef typename TensorSycl::internal::ConvertToDeviceExpression<HostExpr>::Type DevExpr;
- auto device_expr =TensorSycl::internal::createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
- auto device_evaluator = Eigen::TensorEvaluator<DevExpr, Eigen::DefaultDevice>(device_expr.expr, Eigen::DefaultDevice());
-
- auto buffer_ptr = ConvertToActualTypeSycl(CoeffReturnType, buffer_acc);
- auto kernel_ptr = ConvertToActualTypeSycl(KernelType, kernel_filter);
- const size_t num_x_input = (itemID.get_local_range()[0] +kernelSize_x -1); //the required row to be calculated for the for each plane in shered memory
- const size_t num_y_input = (itemID.get_local_range()[1] +kernelSize_y -1); //the required row to be calculated for the for each plane in shered memory
- const size_t plane_input_offset = indexMapper.mapCudaInputPlaneToTensorInputOffset(itemID.get_global(2));
- const size_t plane_kernel_offset = itemID.get_local(2) * num_y_input;
-
- /// fill the shared memory
- const size_t first_x_input_start = itemID.get_group(0)*itemID.get_local_range()[0];
- const size_t first_y_input_start = itemID.get_group(1)*itemID.get_local_range()[1];
- for (size_t j = itemID.get_local(1); j < num_y_input; j += itemID.get_local_range()[1]) {
- const size_t local_input_offset = num_x_input * (j + plane_kernel_offset);
- for (size_t i = itemID.get_local(0); i < num_x_input ; i += itemID.get_local_range()[0]) {
- const size_t local_index = i + local_input_offset;
- const size_t tensor_index = plane_input_offset + indexMapper.mapCudaInputKernelToTensorInputOffset(i + first_x_input_start, j+ first_y_input_start );
- if(((i + first_x_input_start) < (range_x +kernelSize_x-1)) &&((j + first_y_input_start) < (range_y +kernelSize_y-1)) && itemID.get_global(2)< range_z){
- local_acc[local_index] = device_evaluator.coeff(tensor_index);
- }
- else local_acc[local_index]=0.0f;
- }
- }
-
- itemID.barrier(cl::sycl::access::fence_space::local_space);
-
- // calculate the convolution
- const size_t fitst_x_output_start =itemID.get_group(0)*(itemID.get_local_range()[0]); // output start x
- const size_t fitst_y_output_start =itemID.get_group(1)*(itemID.get_local_range()[1]); // output start y
- if(itemID.get_global(0)< range_x && itemID.get_global(1)< range_y && itemID.get_global(2)< range_z){
- CoeffReturnType result = static_cast<CoeffReturnType>(0);
- for (size_t j = 0; j < kernelSize_y; j++) {
- size_t kernel_offset =kernelSize_x * j;
- const size_t index = (num_x_input*(plane_kernel_offset + j+ itemID.get_local(1))) + itemID.get_local(0);
- for (size_t i = 0; i < kernelSize_x; i++) {
- result += (local_acc[i + index] * kernel_ptr[i+kernel_offset]);
- }
- }
- const size_t tensor_index = indexMapper.mapCudaOutputPlaneToTensorOutputOffset(itemID.get_global(2))
- +indexMapper.mapCudaOutputKernelToTensorOutputOffset(itemID.get_local(0) + fitst_x_output_start, itemID.get_local(1) + fitst_y_output_start);
- buffer_ptr[tensor_index] = result;
- }
- }
-};
-
-
-
-template <typename CoeffReturnType, typename KernelType, typename HostExpr, typename FunctorExpr, typename Index,
-typename InputDims, typename Kernel_accessor, typename Buffer_accessor, typename Local_accessor, typename TupleType>
-struct EigenConvolutionKernel3D{
-typedef typename TensorSycl::internal::createPlaceHolderExpression<HostExpr>::Type PlaceHolderExpr;
-internal::IndexMapper<Index, InputDims, 3, Eigen::internal::traits<HostExpr>::Layout> indexMapper;
-Kernel_accessor kernel_filter;
-const size_t kernelSize_x, kernelSize_y, kernelSize_z, range_x, range_y , range_z, numP;
-Buffer_accessor buffer_acc;
-Local_accessor local_acc;
-FunctorExpr functors;
-TupleType tuple_of_accessors;
-EigenConvolutionKernel3D(internal::IndexMapper<Index, InputDims, 3, Eigen::internal::traits<HostExpr>::Layout> indexMapper_,
- Kernel_accessor kernel_filter_, const size_t kernelSize_x_, const size_t kernelSize_y_ , const size_t kernelSize_z_ ,
- const size_t range_x_, const size_t range_y_, const size_t range_z_, const size_t numP_,
- Buffer_accessor buffer_acc_, Local_accessor local_acc_, FunctorExpr functors_, TupleType tuple_of_accessors_)
- :indexMapper(indexMapper_), kernel_filter(kernel_filter_), kernelSize_x(kernelSize_x_), kernelSize_y(kernelSize_y_),
- kernelSize_z(kernelSize_z_), range_x(range_x_), range_y(range_y_), range_z(range_z_), numP(numP_),
- buffer_acc(buffer_acc_), local_acc(local_acc_), functors(functors_), tuple_of_accessors(tuple_of_accessors_) {}
-
- void operator()(cl::sycl::nd_item<3> itemID) {
- typedef typename TensorSycl::internal::ConvertToDeviceExpression<HostExpr>::Type DevExpr;
- auto device_expr =TensorSycl::internal::createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
- auto device_evaluator = Eigen::TensorEvaluator<DevExpr, Eigen::DefaultDevice>(device_expr.expr, Eigen::DefaultDevice());
-
- auto buffer_ptr = ConvertToActualTypeSycl(CoeffReturnType, buffer_acc);
- auto kernel_ptr = ConvertToActualTypeSycl(KernelType, kernel_filter);
- const size_t num_x_input = (itemID.get_local_range()[0] +kernelSize_x -1); //the required row to be calculated for the for each plane in shered memory
- const size_t num_y_input = (itemID.get_local_range()[1] +kernelSize_y -1); //the required row to be calculated for the for each plane in shered memory
- const size_t num_z_input = (itemID.get_local_range()[2] +kernelSize_z -1); //the required row to be calculated for the for each plane in shered memory
- const size_t first_x_input_start = itemID.get_group(0)*itemID.get_local_range()[0];
- const size_t first_y_input_start = itemID.get_group(1)*itemID.get_local_range()[1];
- const size_t first_z_input_start = itemID.get_group(2)*itemID.get_local_range()[2];
- for(size_t p=0; p<numP; p++){
- /// fill the shared memory
- const size_t plane_input_offset = indexMapper.mapCudaInputPlaneToTensorInputOffset(p);
- for (size_t k = itemID.get_local(2); k < num_z_input; k += itemID.get_local_range()[2]) {
- for (size_t j = itemID.get_local(1); j < num_y_input; j += itemID.get_local_range()[1]) {
- for (size_t i = itemID.get_local(0); i < num_x_input ; i += itemID.get_local_range()[0]) {
- const size_t local_index = i + (num_x_input * (j + (num_y_input * k)));
- const size_t tensor_index = plane_input_offset + indexMapper.mapCudaInputKernelToTensorInputOffset(i + first_x_input_start, j+ first_y_input_start , k+ first_z_input_start );
- if(((i + first_x_input_start) < (range_x +kernelSize_x-1)) && ((j + first_y_input_start) < (range_y +kernelSize_y-1)) && ((k + first_z_input_start) < (range_z +kernelSize_z-1)) ){
- local_acc[local_index] = device_evaluator.coeff(tensor_index);
- }
- else local_acc[local_index]=0.0f;
- }
- }
- }
- itemID.barrier(cl::sycl::access::fence_space::local_space);
-
- // calculate the convolution
- const size_t fitst_x_output_start =itemID.get_group(0)*(itemID.get_local_range()[0]); // x
- const size_t fitst_y_output_start =itemID.get_group(1)*(itemID.get_local_range()[1]); // y
- const size_t fitst_z_output_start =itemID.get_group(2)*(itemID.get_local_range()[2]); // z
-
- if(itemID.get_global(0)< range_x && itemID.get_global(1)< range_y && itemID.get_global(2)< range_z){
- CoeffReturnType result = static_cast<CoeffReturnType>(0);
- for (size_t k = 0; k < kernelSize_z; k++) {
- for (size_t j = 0; j < kernelSize_y; j++) {
- for (size_t i = 0; i < kernelSize_x; i++) {
- const size_t kernel_index =i + kernelSize_x * (j + kernelSize_y * k);
- const size_t local_index = ((i+ itemID.get_local(0))+ num_x_input*((j+ itemID.get_local(1)) + num_y_input * (k+ itemID.get_local(2))));
- result += (local_acc[local_index] * kernel_ptr[kernel_index]);
- }
- }
- }
- const size_t tensor_index = indexMapper.mapCudaOutputPlaneToTensorOutputOffset(p)
- +indexMapper.mapCudaOutputKernelToTensorOutputOffset(itemID.get_local(0) + fitst_x_output_start, itemID.get_local(1) + fitst_y_output_start, itemID.get_local(2) + fitst_z_output_start );
- buffer_ptr[tensor_index] = result;
- }
-
- itemID.barrier(cl::sycl::access::fence_space::local_space);
- }
- }
-};
-
-
-template<typename Indices, typename InputArgType, typename KernelArgType>
-struct TensorEvaluator<const TensorConvolutionOp<Indices, InputArgType, KernelArgType>, const Eigen::SyclDevice>
-{
- typedef TensorConvolutionOp<Indices, InputArgType, KernelArgType> XprType;
-
- static const int NumDims = internal::array_size<typename TensorEvaluator<InputArgType, const Eigen::SyclDevice>::Dimensions>::value;
- static const int NumKernelDims = internal::array_size<Indices>::value;
- typedef typename XprType::Index Index;
- typedef DSizes<Index, NumDims> Dimensions;
- typedef typename TensorEvaluator<KernelArgType, const Eigen::SyclDevice>::Dimensions KernelDimensions;
- typedef const Eigen::SyclDevice Device;
-
- enum {
- IsAligned = TensorEvaluator<InputArgType, const Eigen::SyclDevice>::IsAligned & TensorEvaluator<KernelArgType, const Eigen::SyclDevice>::IsAligned,
- PacketAccess = false,
- Layout = TensorEvaluator<InputArgType, const Eigen::SyclDevice>::Layout,
- CoordAccess = false, // to be implemented
- RawAccess = false
- };
-
- EIGEN_DEVICE_FUNC TensorEvaluator(const XprType& op, const Eigen::SyclDevice& device)
- : m_inputImpl(op.inputExpression(), device), m_kernelArg(op.kernelExpression()), m_kernelImpl(op.kernelExpression(), device), m_indices(op.indices()), m_buf(NULL), m_kernel(NULL), m_local_kernel(false), m_device(device)
- {
- EIGEN_STATIC_ASSERT((static_cast<int>(TensorEvaluator<InputArgType, const Eigen::SyclDevice>::Layout) == static_cast<int>(TensorEvaluator<KernelArgType, const Eigen::SyclDevice>::Layout)), YOU_MADE_A_PROGRAMMING_MISTAKE);
-
- const typename TensorEvaluator<InputArgType, const Eigen::SyclDevice>::Dimensions& input_dims = m_inputImpl.dimensions();
- const typename TensorEvaluator<KernelArgType, const Eigen::SyclDevice>::Dimensions& kernel_dims = m_kernelImpl.dimensions();
-
- m_dimensions = m_inputImpl.dimensions();
- for (int i = 0; i < NumKernelDims; ++i) {
- const Index index = op.indices()[i];
- const Index input_dim = input_dims[index];
- const Index kernel_dim = kernel_dims[i];
- const Index result_dim = input_dim - kernel_dim + 1;
- m_dimensions[index] = result_dim;
- }
- }
-
- typedef typename XprType::CoeffReturnType CoeffReturnType;
- typedef typename PacketType<CoeffReturnType, const Eigen::SyclDevice>::type PacketReturnType;
- typedef typename InputArgType::Scalar Scalar;
- static const int PacketSize = internal::unpacket_traits<PacketReturnType>::size;
-
- EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_dimensions; }
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar* data) {
- preloadKernel();
- m_inputImpl.evalSubExprsIfNeeded(NULL);
- if (data) {
- executeEval(data);
- return false;
- } else {
- m_buf = (Scalar*)m_device.allocate(dimensions().TotalSize() * sizeof(Scalar));
- executeEval(m_buf);
- return true;
- }
- }
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
- m_inputImpl.cleanup();
- if (m_buf) {
- m_device.deallocate(m_buf);
- m_buf = NULL;
- }
- if (m_local_kernel) {
- m_device.deallocate((void*)m_kernel);
- m_local_kernel = false;
- }
- m_kernel = NULL;
- }
- /// used by sycl in order to build the sycl buffer
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Device& device() const{return m_device;}
- /// used by sycl in order to build the sycl buffer
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType* data() const { return m_buf; }
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void preloadKernel() {
- // Don't make a local copy of the kernel unless we have to (i.e. it's an
- // expression that needs to be evaluated)
- const Scalar* in_place = m_kernelImpl.data();
- if (in_place) {
- m_kernel = in_place;
- m_local_kernel = false;
- } else {
- size_t kernel_sz = m_kernelImpl.dimensions().TotalSize() * sizeof(Scalar);
- Scalar* local = (Scalar*)m_device.allocate(kernel_sz);
- typedef TensorEvalToOp<const KernelArgType> EvalTo;
- EvalTo evalToTmp(local, m_kernelArg);
- const bool PacketAccess = internal::IsVectorizable<const Eigen::SyclDevice, KernelArgType>::value;
- internal::TensorExecutor<const EvalTo, const Eigen::SyclDevice, PacketAccess>::run(evalToTmp, m_device);
- m_kernel = local;
- m_local_kernel = true;
- }
- }
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void executeEval(Scalar* data) const {
- typedef TensorEvaluator<InputArgType, const Eigen::SyclDevice> InputEvaluator;
- typedef typename InputEvaluator::Dimensions InputDims;
-
- typedef Eigen::TensorSycl::internal::FunctorExtractor<InputEvaluator> InputFunctorExpr;
- // extract input functor list
- InputFunctorExpr input_functors = Eigen::TensorSycl::internal::extractFunctors(m_inputImpl);
-
-
- m_device.sycl_queue().submit([&](cl::sycl::handler &cgh) {
-
- typedef cl::sycl::accessor<CoeffReturnType, 1, cl::sycl::access::mode::read_write, cl::sycl::access::target::local> InputLocalAcc;
- /// work-around for gcc 4.8 auto bug
- typedef decltype(Eigen::TensorSycl::internal::createTupleOfAccessors<InputEvaluator>(cgh, m_inputImpl)) InputTupleType;
- // create input tuple of accessors
- InputTupleType tuple_of_accessors = Eigen::TensorSycl::internal::createTupleOfAccessors<InputEvaluator>(cgh, m_inputImpl);
-
- typedef cl::sycl::accessor<uint8_t, 1, cl::sycl::access::mode::discard_write, cl::sycl::access::target::global_buffer> OutputAccessorType;
- OutputAccessorType out_res= m_device. template get_sycl_accessor<cl::sycl::access::mode::discard_write>(cgh, data);
- typedef cl::sycl::accessor<uint8_t, 1, cl::sycl::access::mode::read, cl::sycl::access::target::global_buffer> KernelAccessorType;
- KernelAccessorType kernel_acc= m_device. template get_sycl_accessor<cl::sycl::access::mode::read>(cgh, m_kernel);
-
- switch (NumKernelDims) {
- case 1: {
- const size_t numX = dimensions()[m_indices[0]];
- const size_t numP = dimensions().TotalSize() / numX;
- const size_t kernel_size = m_kernelImpl.dimensions().TotalSize();
- size_t range_x, GRange_x, tileSize_x, range_y, GRange_y, tileSize_y;
- m_device.parallel_for_setup(numX, numP, tileSize_x,tileSize_y,range_x,range_y, GRange_x, GRange_y );
- const size_t shared_mem =(tileSize_x +kernel_size -1)*(tileSize_y);
- assert(static_cast<unsigned long>(shared_mem) <= m_device.sharedMemPerBlock());
- auto global_range=cl::sycl::range<2>(GRange_x, GRange_y); // global range
- auto local_range=cl::sycl::range<2>(tileSize_x, tileSize_y); // local range
- InputLocalAcc local_acc(cl::sycl::range<1>(shared_mem), cgh);
- const array<Index, 1> indices{{m_indices[0]}};
- const array<Index, 1> kernel_dims{{m_kernelImpl.dimensions()[0]}};
- internal::IndexMapper<Index, InputDims, 1, Layout> indexMapper(m_inputImpl.dimensions(), kernel_dims, indices);
- cgh.parallel_for(cl::sycl::nd_range<2>(global_range, local_range),
- EigenConvolutionKernel1D<CoeffReturnType, Scalar, InputArgType, InputFunctorExpr, Index,
- InputDims, KernelAccessorType, OutputAccessorType, InputLocalAcc, InputTupleType>(
- indexMapper,kernel_acc, kernel_size, numX, numP, out_res, local_acc, input_functors, tuple_of_accessors));
- break;
- }
-
- case 2: {
- const size_t idxX =static_cast<int>(Layout) == static_cast<int>(ColMajor) ? 0 : 1;
- const size_t idxY =static_cast<int>(Layout) == static_cast<int>(ColMajor) ? 1 : 0;
- const size_t kernel_size_x = m_kernelImpl.dimensions()[idxX];
- const size_t kernel_size_y = m_kernelImpl.dimensions()[idxY];
- const size_t numX = dimensions()[m_indices[idxX]];
- const size_t numY = dimensions()[m_indices[idxY]];
- const size_t numP = dimensions().TotalSize() / (numX*numY);
- size_t range_x, GRange_x, tileSize_x, range_y, GRange_y, tileSize_y, range_z, GRange_z, tileSize_z;
- m_device.parallel_for_setup(numX, numY, numP, tileSize_x, tileSize_y, tileSize_z, range_x, range_y, range_z, GRange_x, GRange_y, GRange_z );
- const size_t shared_mem =(tileSize_x +kernel_size_x -1)*(tileSize_y +kernel_size_y -1) * tileSize_z;
- assert(static_cast<unsigned long>(shared_mem) <= m_device.sharedMemPerBlock());
- auto global_range=cl::sycl::range<3>(GRange_x, GRange_y, GRange_z); // global range
- auto local_range=cl::sycl::range<3>(tileSize_x, tileSize_y, tileSize_z); // local range
- InputLocalAcc local_acc(cl::sycl::range<1>(shared_mem), cgh);
- const array<Index, 2> indices {{m_indices[idxX], m_indices[idxY]}};
- const array<Index, 2> kernel_dims{{m_kernelImpl.dimensions()[idxX], m_kernelImpl.dimensions()[idxY]}};
- internal::IndexMapper<Index, InputDims, 2, Layout> indexMapper(m_inputImpl.dimensions(), kernel_dims, indices);
- cgh.parallel_for(cl::sycl::nd_range<3>(global_range, local_range),
- EigenConvolutionKernel2D<CoeffReturnType, Scalar, InputArgType, InputFunctorExpr, Index,
- InputDims, KernelAccessorType, OutputAccessorType, InputLocalAcc, InputTupleType>(
- indexMapper,kernel_acc, kernel_size_x, kernel_size_y, numX, numY, numP, out_res, local_acc, input_functors, tuple_of_accessors));
- break;
- }
-
- case 3: {
- const size_t idxX =static_cast<int>(Layout) == static_cast<int>(ColMajor) ? 0 : 2;
- const size_t idxY =static_cast<int>(Layout) == static_cast<int>(ColMajor) ? 1 : 1;
- const size_t idxZ =static_cast<int>(Layout) == static_cast<int>(ColMajor) ? 2 : 0;
- const size_t kernel_size_x = m_kernelImpl.dimensions()[idxX];
- const size_t kernel_size_y = m_kernelImpl.dimensions()[idxY];
- const size_t kernel_size_z = m_kernelImpl.dimensions()[idxZ];
- const size_t numX = dimensions()[m_indices[idxX]];
- const size_t numY = dimensions()[m_indices[idxY]];
- const size_t numZ = dimensions()[m_indices[idxZ]];
- const size_t numP = dimensions().TotalSize() / (numX*numY*numZ);
- const array<Index, 3> indices{{m_indices[idxX], m_indices[idxY], m_indices[idxZ]}};
- const array<Index, 3> kernel_dims{{m_kernelImpl.dimensions()[idxX],m_kernelImpl.dimensions()[idxY], m_kernelImpl.dimensions()[idxZ]}};
- internal::IndexMapper<Index, InputDims, 3, Layout> indexMapper(m_inputImpl.dimensions(), kernel_dims, indices);
- size_t range_x, GRange_x, tileSize_x, range_y, GRange_y, tileSize_y, range_z, GRange_z, tileSize_z;
- m_device.parallel_for_setup(numX, numY, numZ, tileSize_x, tileSize_y, tileSize_z, range_x, range_y, range_z, GRange_x, GRange_y, GRange_z );
- const size_t shared_mem =(tileSize_x +kernel_size_x -1)*(tileSize_y +kernel_size_y -1) * (tileSize_z +kernel_size_y -1);
- assert(static_cast<unsigned long>(shared_mem) <= m_device.sharedMemPerBlock());
- auto global_range=cl::sycl::range<3>(GRange_x, GRange_y, GRange_z); // global range
- auto local_range=cl::sycl::range<3>(tileSize_x, tileSize_y, tileSize_z); // local range
- InputLocalAcc local_acc(cl::sycl::range<1>(shared_mem), cgh);
- cgh.parallel_for(cl::sycl::nd_range<3>(global_range, local_range),
- EigenConvolutionKernel3D<CoeffReturnType, Scalar, InputArgType, InputFunctorExpr, Index,
- InputDims, KernelAccessorType, OutputAccessorType, InputLocalAcc, InputTupleType>(
- indexMapper,kernel_acc, kernel_size_x, kernel_size_y, kernel_size_z, numX, numY,
- numZ, numP, out_res, local_acc, input_functors, tuple_of_accessors));
- break;
- }
-
- default: {
- EIGEN_STATIC_ASSERT((NumKernelDims >= 1 && NumKernelDims <= 3), THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE);
- }
- }
- });
- }
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
- {
- eigen_assert(m_buf);
- eigen_assert(index < m_dimensions.TotalSize());
- return m_buf[index];
- }
-
- template<int LoadMode>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(const Index index) const
- {
- eigen_assert(m_buf);
- eigen_assert(index < m_dimensions.TotalSize());
- return internal::ploadt<PacketReturnType, LoadMode>(m_buf+index);
- }
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost
- costPerCoeff(bool vectorized) const {
- // TODO(rmlarsen): FIXME: For now, this is just a copy of the CPU cost
- // model.
- const double kernel_size = m_kernelImpl.dimensions().TotalSize();
- // We ignore the use of fused multiply-add.
- const double convolve_compute_cost =
- TensorOpCost::AddCost<Scalar>() + TensorOpCost::MulCost<Scalar>();
- const double firstIndex_compute_cost =
- NumDims *
- (2 * TensorOpCost::AddCost<Index>() + 2 * TensorOpCost::MulCost<Index>() +
- TensorOpCost::DivCost<Index>());
- return TensorOpCost(0, 0, firstIndex_compute_cost, vectorized, PacketSize) +
- kernel_size * (m_inputImpl.costPerCoeff(vectorized) +
- m_kernelImpl.costPerCoeff(vectorized) +
- TensorOpCost(0, 0, convolve_compute_cost, vectorized,
- PacketSize));
- }
-
- private:
- // No assignment (copies are needed by the kernels)
- TensorEvaluator& operator = (const TensorEvaluator&);
- TensorEvaluator<InputArgType, const Eigen::SyclDevice> m_inputImpl;
- KernelArgType m_kernelArg;
- TensorEvaluator<KernelArgType, const Eigen::SyclDevice> m_kernelImpl;
- Indices m_indices;
- Dimensions m_dimensions;
- Scalar* m_buf;
- const Scalar* m_kernel;
- bool m_local_kernel;
- const Eigen::SyclDevice& m_device;
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_CXX11_TENSOR_TENSOR_CONVOLUTION_H
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceCuda.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceCuda.h
index be8d693..4f5767b 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceCuda.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceCuda.h
@@ -88,7 +88,7 @@ static void initializeDeviceProp() {
#if __cplusplus >= 201103L
std::atomic_thread_fence(std::memory_order_acquire);
#endif
- EIGEN_SLEEP(1000);
+ sleep(1);
}
}
}
@@ -217,10 +217,7 @@ struct GpuDevice {
EIGEN_UNUSED_VARIABLE(err)
assert(err == cudaSuccess);
#else
- EIGEN_UNUSED_VARIABLE(dst);
- EIGEN_UNUSED_VARIABLE(src);
- EIGEN_UNUSED_VARIABLE(n);
- eigen_assert(false && "The default device should be used instead to generate kernel code");
+ eigen_assert(false && "The default device should be used instead to generate kernel code");
#endif
}
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h
index ccaaa6c..9d14139 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h
@@ -45,7 +45,7 @@ struct DefaultDevice {
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t firstLevelCacheSize() const {
-#if !defined(__CUDA_ARCH__) && !defined(__SYCL_DEVICE_ONLY__)
+#ifndef __CUDA_ARCH__
// Running on the host CPU
return l1CacheSize();
#else
@@ -55,7 +55,7 @@ struct DefaultDevice {
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t lastLevelCacheSize() const {
-#if !defined(__CUDA_ARCH__) && !defined(__SYCL_DEVICE_ONLY__)
+#ifndef __CUDA_ARCH__
// Running single threaded on the host CPU
return l3CacheSize();
#else
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h
index e209799..7c03989 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h
@@ -16,400 +16,107 @@
#define EIGEN_CXX11_TENSOR_TENSOR_DEVICE_SYCL_H
namespace Eigen {
-
- #define ConvertToActualTypeSycl(Scalar, buf_acc) reinterpret_cast<typename cl::sycl::global_ptr<Scalar>::pointer_t>((&(*buf_acc.get_pointer())))
-
- template <typename Scalar, typename read_accessor, typename write_accessor> class MemCopyFunctor {
- public:
- MemCopyFunctor(read_accessor src_acc, write_accessor dst_acc, size_t rng, size_t i, size_t offset) : m_src_acc(src_acc), m_dst_acc(dst_acc), m_rng(rng), m_i(i), m_offset(offset) {}
-
- void operator()(cl::sycl::nd_item<1> itemID) {
- auto src_ptr = ConvertToActualTypeSycl(Scalar, m_src_acc);
- auto dst_ptr = ConvertToActualTypeSycl(Scalar, m_dst_acc);
- auto globalid = itemID.get_global_linear_id();
- if (globalid < m_rng) {
- dst_ptr[globalid + m_i] = src_ptr[globalid + m_offset];
- }
- }
-
- private:
- read_accessor m_src_acc;
- write_accessor m_dst_acc;
- size_t m_rng;
- size_t m_i;
- size_t m_offset;
- };
-
- struct memsetkernelFunctor{
- typedef cl::sycl::accessor<uint8_t, 1, cl::sycl::access::mode::discard_write, cl::sycl::access::target::global_buffer> AccType;
- AccType m_acc;
- const size_t m_rng, m_c;
- memsetkernelFunctor(AccType acc, const size_t rng, const size_t c):m_acc(acc), m_rng(rng), m_c(c){}
- void operator()(cl::sycl::nd_item<1> itemID) {
- auto globalid=itemID.get_global_linear_id();
- if (globalid< m_rng) m_acc[globalid] = m_c;
- }
-
- };
-
-EIGEN_STRONG_INLINE auto get_sycl_supported_devices()->decltype(cl::sycl::device::get_devices()){
- auto devices = cl::sycl::device::get_devices();
- std::vector<cl::sycl::device>::iterator it =devices.begin();
- while(it!=devices.end()) {
- /// get_devices returns all the available opencl devices. Either use device_selector or exclude devices that computecpp does not support (AMD OpenCL for CPU )
- auto s= (*it).template get_info<cl::sycl::info::device::vendor>();
- std::transform(s.begin(), s.end(), s.begin(), ::tolower);
- if((*it).is_cpu() && s.find("amd")!=std::string::npos && s.find("apu") == std::string::npos){ // remove amd cpu as it is not supported by computecpp allow APUs
- it=devices.erase(it);
- }
- else{
- ++it;
- }
- }
- return devices;
-}
-
-struct QueueInterface {
- /// class members:
- bool exception_caught_ = false;
-
- mutable std::mutex mutex_;
-
+struct SyclDevice {
+ /// class members
+ /// sycl queue
+ mutable cl::sycl::queue m_queue;
/// std::map is the container used to make sure that we create only one buffer
/// per pointer. The lifespan of the buffer now depends on the lifespan of SyclDevice.
/// If a non-read-only pointer is needed to be accessed on the host we should manually deallocate it.
- mutable std::map<const uint8_t *, cl::sycl::buffer<uint8_t, 1>> buffer_map;
- /// sycl queue
- mutable cl::sycl::queue m_queue;
- /// creating device by using cl::sycl::selector or cl::sycl::device both are the same and can be captured through dev_Selector typename
- /// SyclStreamDevice is not owned. it is the caller's responsibility to destroy it.
- template<typename dev_Selector> explicit QueueInterface(const dev_Selector& s):
+ mutable std::map<const void *, std::shared_ptr<void>> buffer_map;
+ /// creating device by using selector
+ template<typename dev_Selector> SyclDevice(dev_Selector s)
+ :
#ifdef EIGEN_EXCEPTIONS
- m_queue(cl::sycl::queue(s, [&](cl::sycl::exception_list l) {
+ m_queue(cl::sycl::queue(s, [=](cl::sycl::exception_list l) {
for (const auto& e : l) {
try {
- if (e) {
- exception_caught_ = true;
- std::rethrow_exception(e);
- }
+ std::rethrow_exception(e);
} catch (cl::sycl::exception e) {
- std::cerr << e.what() << std::endl;
- }
+ std::cout << e.what() << std::endl;
+ }
}
}))
#else
-m_queue(cl::sycl::queue(s, [&](cl::sycl::exception_list l) {
- for (const auto& e : l) {
- if (e) {
- exception_caught_ = true;
- std::cerr << "Error detected Inside Sycl Device."<< std::endl;
-
- }
- }
-}))
+ m_queue(cl::sycl::queue(s))
#endif
{}
+ // destructor
+ ~SyclDevice() { deallocate_all(); }
- /// Allocating device pointer. This pointer is actually an 8 bytes host pointer used as key to access the sycl device buffer.
- /// The reason is that we cannot use device buffer as a pointer as a m_data in Eigen leafNode expressions. So we create a key
- /// pointer to be used in Eigen expression construction. When we convert the Eigen construction into the sycl construction we
- /// use this pointer as a key in our buffer_map and we make sure that we dedicate only one buffer only for this pointer.
- /// The device pointer would be deleted by calling deallocate function.
- EIGEN_STRONG_INLINE void* allocate(size_t num_bytes) const {
- auto buf = cl::sycl::buffer<uint8_t,1>(cl::sycl::range<1>(num_bytes));
- auto ptr =buf.get_access<cl::sycl::access::mode::discard_write, cl::sycl::access::target::host_buffer>().get_pointer();
- buf.set_final_data(nullptr);
- std::lock_guard<std::mutex> lock(mutex_);
- buffer_map.insert(std::pair<const uint8_t *, cl::sycl::buffer<uint8_t, 1>>(static_cast<const uint8_t*>(ptr),buf));
- return static_cast<void*>(ptr);
- }
-
- /// This is used to deallocate the device pointer. p is used as a key inside
- /// the map to find the device buffer and delete it.
- EIGEN_STRONG_INLINE void deallocate(void *p) const {
- std::lock_guard<std::mutex> lock(mutex_);
- auto it = buffer_map.find(static_cast<const uint8_t*>(p));
+ template <typename T> void deallocate(T *p) const {
+ auto it = buffer_map.find(p);
if (it != buffer_map.end()) {
buffer_map.erase(it);
+ internal::aligned_free(p);
}
}
-
- EIGEN_STRONG_INLINE void deallocate_all() const {
- std::lock_guard<std::mutex> lock(mutex_);
- buffer_map.clear();
- }
-
- EIGEN_STRONG_INLINE std::map<const uint8_t *, cl::sycl::buffer<uint8_t,1>>::iterator find_buffer(const void* ptr) const {
- std::lock_guard<std::mutex> lock(mutex_);
- auto it1 = buffer_map.find(static_cast<const uint8_t*>(ptr));
- if (it1 != buffer_map.end()){
- return it1;
- }
- else{
- for(std::map<const uint8_t *, cl::sycl::buffer<uint8_t,1>>::iterator it=buffer_map.begin(); it!=buffer_map.end(); ++it){
- auto size = it->second.get_size();
- if((it->first < (static_cast<const uint8_t*>(ptr))) && ((static_cast<const uint8_t*>(ptr)) < (it->first + size)) ) return it;
- }
- }
- std::cerr << "No sycl buffer found. Make sure that you have allocated memory for your buffer by calling malloc-ed function."<< std::endl;
- abort();
- }
-
- // This function checks if the runtime recorded an error for the
- // underlying stream device.
- EIGEN_STRONG_INLINE bool ok() const {
- if (!exception_caught_) {
- m_queue.wait_and_throw();
+ void deallocate_all() const {
+ std::map<const void *, std::shared_ptr<void>>::iterator it=buffer_map.begin();
+ while (it!=buffer_map.end()) {
+ auto p=it->first;
+ buffer_map.erase(it);
+ internal::aligned_free(const_cast<void*>(p));
+ it=buffer_map.begin();
}
- return !exception_caught_;
+ buffer_map.clear();
}
- // destructor
- ~QueueInterface() { buffer_map.clear(); }
-};
-
-struct SyclDevice {
- // class member.
- QueueInterface* m_queue_stream;
- /// QueueInterface is not owned. it is the caller's responsibility to destroy it.
- explicit SyclDevice(QueueInterface* queue_stream) : m_queue_stream(queue_stream){}
-
- /// Creation of sycl accessor for a buffer. This function first tries to find
+ /// creation of sycl accessor for a buffer. This function first tries to find
/// the buffer in the buffer_map. If found it gets the accessor from it, if not,
- /// the function then adds an entry by creating a sycl buffer for that particular pointer.
- template <cl::sycl::access::mode AcMd> EIGEN_STRONG_INLINE cl::sycl::accessor<uint8_t, 1, AcMd, cl::sycl::access::target::global_buffer>
- get_sycl_accessor(cl::sycl::handler &cgh, const void* ptr) const {
- return (get_sycl_buffer(ptr).template get_access<AcMd, cl::sycl::access::target::global_buffer>(cgh));
+ ///the function then adds an entry by creating a sycl buffer for that particular pointer.
+ template <cl::sycl::access::mode AcMd, typename T> inline cl::sycl::accessor<T, 1, AcMd, cl::sycl::access::target::global_buffer>
+ get_sycl_accessor(size_t num_bytes, cl::sycl::handler &cgh, const T * ptr) const {
+ return (get_sycl_buffer<T>(num_bytes, ptr)->template get_access<AcMd, cl::sycl::access::target::global_buffer>(cgh));
}
- /// Accessing the created sycl device buffer for the device pointer
- EIGEN_STRONG_INLINE cl::sycl::buffer<uint8_t, 1>& get_sycl_buffer(const void * ptr) const {
- return m_queue_stream->find_buffer(ptr)->second;
+ template<typename T> inline std::pair<std::map<const void *, std::shared_ptr<void>>::iterator,bool> add_sycl_buffer(const T *ptr, size_t num_bytes) const {
+ using Type = cl::sycl::buffer<T, 1>;
+ std::pair<std::map<const void *, std::shared_ptr<void>>::iterator,bool> ret = buffer_map.insert(std::pair<const void *, std::shared_ptr<void>>(ptr, std::shared_ptr<void>(new Type(cl::sycl::range<1>(num_bytes)),
+ [](void *dataMem) { delete static_cast<Type*>(dataMem); })));
+ (static_cast<Type*>(buffer_map.at(ptr).get()))->set_final_data(nullptr);
+ return ret;
}
- /// This is used to prepare the number of threads and also the number of threads per block for sycl kernels
- template<typename Index>
- EIGEN_STRONG_INLINE void parallel_for_setup(Index n, Index &tileSize, Index &rng, Index &GRange) const {
- tileSize =static_cast<Index>(sycl_queue().get_device(). template get_info<cl::sycl::info::device::max_work_group_size>());
- auto s= sycl_queue().get_device().template get_info<cl::sycl::info::device::vendor>();
- std::transform(s.begin(), s.end(), s.begin(), ::tolower);
- if(sycl_queue().get_device().is_cpu()){ // intel doesnot allow to use max workgroup size
- tileSize=std::min(static_cast<Index>(256), static_cast<Index>(tileSize));
- }
- rng = n;
- if (rng==0) rng=static_cast<Index>(1);
- GRange=rng;
- if (tileSize>GRange) tileSize=GRange;
- else if(GRange>tileSize){
- Index xMode = static_cast<Index>(GRange % tileSize);
- if (xMode != 0) GRange += static_cast<Index>(tileSize - xMode);
- }
- }
-
- /// This is used to prepare the number of threads and also the number of threads per block for sycl kernels
- template<typename Index>
- EIGEN_STRONG_INLINE void parallel_for_setup(Index dim0, Index dim1, Index &tileSize0, Index &tileSize1, Index &rng0, Index &rng1, Index &GRange0, Index &GRange1) const {
- Index max_workgroup_Size = static_cast<Index>(maxSyclThreadsPerBlock());
- if(sycl_queue().get_device().is_cpu()){ // intel doesnot allow to use max workgroup size
- max_workgroup_Size=std::min(static_cast<Index>(256), static_cast<Index>(max_workgroup_Size));
- }
- Index pow_of_2 = static_cast<Index>(std::log2(max_workgroup_Size));
- tileSize1 =static_cast<Index>(std::pow(2, static_cast<Index>(pow_of_2/2)));
- rng1=dim1;
- if (rng1==0 ) rng1=static_cast<Index>(1);
- GRange1=rng1;
- if (tileSize1>GRange1) tileSize1=GRange1;
- else if(GRange1>tileSize1){
- Index xMode = static_cast<Index>(GRange1 % tileSize1);
- if (xMode != 0) GRange1 += static_cast<Index>(tileSize1 - xMode);
- }
- tileSize0 = static_cast<Index>(max_workgroup_Size/tileSize1);
- rng0 = dim0;
- if (rng0==0 ) rng0=static_cast<Index>(1);
- GRange0=rng0;
- if (tileSize0>GRange0) tileSize0=GRange0;
- else if(GRange0>tileSize0){
- Index xMode = static_cast<Index>(GRange0 % tileSize0);
- if (xMode != 0) GRange0 += static_cast<Index>(tileSize0 - xMode);
- }
+ template <typename T> inline cl::sycl::buffer<T, 1>* get_sycl_buffer(size_t num_bytes,const T * ptr) const {
+ return static_cast<cl::sycl::buffer<T, 1>*>(add_sycl_buffer(ptr, num_bytes).first->second.get());
}
-
-
- /// This is used to prepare the number of threads and also the number of threads per block for sycl kernels
- template<typename Index>
- EIGEN_STRONG_INLINE void parallel_for_setup(Index dim0, Index dim1,Index dim2, Index &tileSize0, Index &tileSize1, Index &tileSize2, Index &rng0, Index &rng1, Index &rng2, Index &GRange0, Index &GRange1, Index &GRange2) const {
- Index max_workgroup_Size = static_cast<Index>(maxSyclThreadsPerBlock());
- if(sycl_queue().get_device().is_cpu()){ // intel doesnot allow to use max workgroup size
- max_workgroup_Size=std::min(static_cast<Index>(256), static_cast<Index>(max_workgroup_Size));
- }
- Index pow_of_2 = static_cast<Index>(std::log2(max_workgroup_Size));
- tileSize2 =static_cast<Index>(std::pow(2, static_cast<Index>(pow_of_2/3)));
- rng2=dim2;
- if (rng2==0 ) rng1=static_cast<Index>(1);
- GRange2=rng2;
- if (tileSize2>GRange2) tileSize2=GRange2;
- else if(GRange2>tileSize2){
- Index xMode = static_cast<Index>(GRange2 % tileSize2);
- if (xMode != 0) GRange2 += static_cast<Index>(tileSize2 - xMode);
- }
- pow_of_2 = static_cast<Index>(std::log2(static_cast<Index>(max_workgroup_Size/tileSize2)));
- tileSize1 =static_cast<Index>(std::pow(2, static_cast<Index>(pow_of_2/2)));
- rng1=dim1;
- if (rng1==0 ) rng1=static_cast<Index>(1);
- GRange1=rng1;
- if (tileSize1>GRange1) tileSize1=GRange1;
- else if(GRange1>tileSize1){
- Index xMode = static_cast<Index>(GRange1 % tileSize1);
- if (xMode != 0) GRange1 += static_cast<Index>(tileSize1 - xMode);
- }
- tileSize0 = static_cast<Index>(max_workgroup_Size/(tileSize1*tileSize2));
- rng0 = dim0;
- if (rng0==0 ) rng0=static_cast<Index>(1);
- GRange0=rng0;
- if (tileSize0>GRange0) tileSize0=GRange0;
- else if(GRange0>tileSize0){
- Index xMode = static_cast<Index>(GRange0 % tileSize0);
- if (xMode != 0) GRange0 += static_cast<Index>(tileSize0 - xMode);
- }
- }
- /// allocate device memory
- EIGEN_STRONG_INLINE void *allocate(size_t num_bytes) const {
- return m_queue_stream->allocate(num_bytes);
+ /// allocating memory on the cpu
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void *allocate(size_t) const {
+ return internal::aligned_malloc(8);
}
- /// deallocate device memory
- EIGEN_STRONG_INLINE void deallocate(void *p) const {
- m_queue_stream->deallocate(p);
- }
// some runtime conditions that can be applied here
- EIGEN_STRONG_INLINE bool isDeviceSuitable() const { return true; }
+ bool isDeviceSuitable() const { return true; }
- /// the memcpy function
- template<typename Index> EIGEN_STRONG_INLINE void memcpy(void *dst, const Index *src, size_t n) const {
- auto it1 = m_queue_stream->find_buffer(static_cast<const void*>(src));
- auto it2 = m_queue_stream->find_buffer(dst);
- auto offset= (static_cast<const uint8_t*>(static_cast<const void*>(src))) - it1->first;
- auto i= (static_cast<const uint8_t*>(dst)) - it2->first;
- offset/=sizeof(Index);
- i/=sizeof(Index);
- size_t rng, GRange, tileSize;
- parallel_for_setup(n/sizeof(Index), tileSize, rng, GRange);
- sycl_queue().submit([&](cl::sycl::handler &cgh) {
- auto src_acc =it1->second.template get_access<cl::sycl::access::mode::read, cl::sycl::access::target::global_buffer>(cgh);
- auto dst_acc =it2->second.template get_access<cl::sycl::access::mode::write, cl::sycl::access::target::global_buffer>(cgh);
- typedef decltype(src_acc) read_accessor;
- typedef decltype(dst_acc) write_accessor;
- cgh.parallel_for(cl::sycl::nd_range<1>(cl::sycl::range<1>(GRange), cl::sycl::range<1>(tileSize)), MemCopyFunctor<Index, read_accessor, write_accessor>(src_acc, dst_acc, rng, i, offset));
- });
- synchronize();
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void memcpy(void *dst, const void *src, size_t n) const {
+ ::memcpy(dst, src, n);
}
- /// The memcpyHostToDevice is used to copy the device only pointer to a host pointer. Using the device
- /// pointer created as a key we find the sycl buffer and get the host accessor with discard_write mode
- /// on it. Using a discard_write accessor guarantees that we do not bring back the current value of the
- /// buffer to host. Then we use the memcpy to copy the data to the host accessor. The first time that
- /// this buffer is accessed, the data will be copied to the device.
- template<typename Index> EIGEN_STRONG_INLINE void memcpyHostToDevice(Index *dst, const Index *src, size_t n) const {
- auto host_acc= get_sycl_buffer(dst). template get_access<cl::sycl::access::mode::discard_write, cl::sycl::access::target::host_buffer>();
- ::memcpy(host_acc.get_pointer(), src, n);
+ template<typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void memcpyHostToDevice(T *dst, const T *src, size_t n) const {
+ auto host_acc= (static_cast<cl::sycl::buffer<T, 1>*>(add_sycl_buffer(dst, n).first->second.get()))-> template get_access<cl::sycl::access::mode::discard_write, cl::sycl::access::target::host_buffer>();
+ memcpy(host_acc.get_pointer(), src, n);
}
- /// The memcpyDeviceToHost is used to copy the data from host to device. Here, in order to avoid double copying the data. We create a sycl
- /// buffer with map_allocator for the destination pointer with a discard_write accessor on it. The lifespan of the buffer is bound to the
- /// lifespan of the memcpyDeviceToHost function. We create a kernel to copy the data, from the device- only source buffer to the destination
- /// buffer with map_allocator on the gpu in parallel. At the end of the function call the destination buffer would be destroyed and the data
- /// would be available on the dst pointer using fast copy technique (map_allocator). In this case we can make sure that we copy the data back
- /// to the cpu only once per function call.
- template<typename Index> EIGEN_STRONG_INLINE void memcpyDeviceToHost(void *dst, const Index *src, size_t n) const {
- auto it = m_queue_stream->find_buffer(src);
- auto offset =static_cast<const uint8_t*>(static_cast<const void*>(src))- it->first;
- offset/=sizeof(Index);
- size_t rng, GRange, tileSize;
- parallel_for_setup(n/sizeof(Index), tileSize, rng, GRange);
- // Assuming that the dst is the start of the destination pointer
- auto dest_buf = cl::sycl::buffer<uint8_t, 1, cl::sycl::map_allocator<uint8_t> >(static_cast<uint8_t*>(dst), cl::sycl::range<1>(n));
- sycl_queue().submit([&](cl::sycl::handler &cgh) {
- auto src_acc= it->second.template get_access<cl::sycl::access::mode::read, cl::sycl::access::target::global_buffer>(cgh);
- auto dst_acc =dest_buf.template get_access<cl::sycl::access::mode::discard_write, cl::sycl::access::target::global_buffer>(cgh);
- typedef decltype(src_acc) read_accessor;
- typedef decltype(dst_acc) write_accessor;
- cgh.parallel_for( cl::sycl::nd_range<1>(cl::sycl::range<1>(GRange), cl::sycl::range<1>(tileSize)), MemCopyFunctor<Index, read_accessor, write_accessor>(src_acc, dst_acc, rng, 0, offset));
- });
- synchronize();
- }
- /// returning the sycl queue
- EIGEN_STRONG_INLINE cl::sycl::queue& sycl_queue() const { return m_queue_stream->m_queue;}
- /// Here is the implementation of memset function on sycl.
- EIGEN_STRONG_INLINE void memset(void *data, int c, size_t n) const {
- size_t rng, GRange, tileSize;
- parallel_for_setup(n, tileSize, rng, GRange);
- sycl_queue().submit(memsetCghFunctor(get_sycl_buffer(static_cast<uint8_t*>(static_cast<void*>(data))),rng, GRange, tileSize, c ));
- synchronize();
- }
-
- struct memsetCghFunctor{
- cl::sycl::buffer<uint8_t, 1>& m_buf;
- const size_t& rng , GRange, tileSize;
- const int &c;
- memsetCghFunctor(cl::sycl::buffer<uint8_t, 1>& buff, const size_t& rng_, const size_t& GRange_, const size_t& tileSize_, const int& c_)
- :m_buf(buff), rng(rng_), GRange(GRange_), tileSize(tileSize_), c(c_){}
-
- void operator()(cl::sycl::handler &cgh) const {
- auto buf_acc = m_buf.template get_access<cl::sycl::access::mode::discard_write, cl::sycl::access::target::global_buffer>(cgh);
- cgh.parallel_for(cl::sycl::nd_range<1>(cl::sycl::range<1>(GRange), cl::sycl::range<1>(tileSize)), memsetkernelFunctor(buf_acc, rng, c));
+ /// whith the current implementation of sycl, the data is copied twice from device to host. This will be fixed soon.
+ template<typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void memcpyDeviceToHost(T *dst, const T *src, size_t n) const {
+ auto it = buffer_map.find(src);
+ if (it != buffer_map.end()) {
+ auto host_acc= (static_cast<cl::sycl::buffer<T, 1>*>(it->second.get()))-> template get_access<cl::sycl::access::mode::read, cl::sycl::access::target::host_buffer>();
+ memcpy(dst,host_acc.get_pointer(), n);
+ } else{
+ eigen_assert("no device memory found. The memory might be destroyed before creation");
}
- };
-
- EIGEN_STRONG_INLINE size_t firstLevelCacheSize() const {
- // FIXME
- return 48*1024;
- }
-
- EIGEN_STRONG_INLINE size_t lastLevelCacheSize() const {
- // We won't try to take advantage of the l2 cache for the time being, and
- // there is no l3 cache on cuda devices.
- return firstLevelCacheSize();
- }
- EIGEN_STRONG_INLINE unsigned long getNumSyclMultiProcessors() const {
- return sycl_queue().get_device(). template get_info<cl::sycl::info::device::max_compute_units>();
- // return stream_->deviceProperties().multiProcessorCount;
}
- EIGEN_STRONG_INLINE unsigned long maxSyclThreadsPerBlock() const {
- return sycl_queue().get_device(). template get_info<cl::sycl::info::device::max_work_group_size>();
- // return stream_->deviceProperties().maxThreadsPerBlock;
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void memset(void *buffer, int c, size_t n) const {
+ ::memset(buffer, c, n);
}
- EIGEN_STRONG_INLINE unsigned long maxSyclThreadsPerMultiProcessor() const {
- // OpenCL doesnot have such concept
- return 2;//sycl_queue().get_device(). template get_info<cl::sycl::info::device::max_work_group_size>();
- // return stream_->deviceProperties().maxThreadsPerMultiProcessor;
- }
- EIGEN_STRONG_INLINE size_t sharedMemPerBlock() const {
- return sycl_queue().get_device(). template get_info<cl::sycl::info::device::local_mem_size>();
- // return stream_->deviceProperties().sharedMemPerBlock;
- }
- /// No need for sycl it should act the same as CPU version
- EIGEN_STRONG_INLINE int majorDeviceVersion() const { return 1; }
-
- EIGEN_STRONG_INLINE void synchronize() const {
- sycl_queue().wait_and_throw(); //pass
- }
-
- EIGEN_STRONG_INLINE void asynchronousExec() const {
- ///FIXEDME:: currently there is a race condition regarding the asynch scheduler.
- //sycl_queue().throw_asynchronous();// does not pass. Temporarily disabled
- sycl_queue().wait_and_throw(); //pass
-
- }
- // This function checks if the runtime recorded an error for the
- // underlying stream device.
- EIGEN_STRONG_INLINE bool ok() const {
- return m_queue_stream->ok();
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE int majorDeviceVersion() const {
+ return 1;
}
};
-
-
} // end namespace Eigen
#endif // EIGEN_CXX11_TENSOR_TENSOR_DEVICE_SYCL_H
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h
index 16180ca..069680a 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h
@@ -12,6 +12,17 @@
namespace Eigen {
+// Use the SimpleThreadPool by default. We'll switch to the new non blocking
+// thread pool later.
+#ifndef EIGEN_USE_SIMPLE_THREAD_POOL
+template <typename Env> using ThreadPoolTempl = NonBlockingThreadPoolTempl<Env>;
+typedef NonBlockingThreadPool ThreadPool;
+#else
+template <typename Env> using ThreadPoolTempl = SimpleThreadPoolTempl<Env>;
+typedef SimpleThreadPool ThreadPool;
+#endif
+
+
// Barrier is an object that allows one or more threads to wait until
// Notify has been called a specified number of times.
class Barrier {
@@ -245,7 +256,7 @@ struct ThreadPoolDevice {
// Split into halves and submit to the pool.
Index mid = first + divup((last - first) / 2, block_size) * block_size;
pool_->Schedule([=, &handleRange]() { handleRange(mid, last); });
- handleRange(first, mid);
+ pool_->Schedule([=, &handleRange]() { handleRange(first, mid); });
};
handleRange(0, n);
barrier.Wait();
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h
index 86405e6..b24cdeb 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h
@@ -33,7 +33,7 @@ namespace Eigen {
namespace internal {
template<std::size_t n, typename Dimension> struct dget {
- static const std::ptrdiff_t value = get<n, Dimension>::value;
+ static const std::size_t value = get<n, Dimension>::value;
};
@@ -90,11 +90,9 @@ struct fixed_size_tensor_index_extraction_helper<Index, 0>
// Fixed size
#ifndef EIGEN_EMULATE_CXX11_META_H
template <typename std::ptrdiff_t... Indices>
-struct Sizes {
+struct Sizes : internal::numeric_list<std::ptrdiff_t, Indices...> {
typedef internal::numeric_list<std::ptrdiff_t, Indices...> Base;
- const Base t = Base();
static const std::ptrdiff_t total_size = internal::arg_prod(Indices...);
- static const size_t count = Base::count;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::ptrdiff_t rank() const {
return Base::count;
@@ -122,16 +120,16 @@ struct Sizes {
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::ptrdiff_t operator[] (const std::size_t index) const {
- return internal::fixed_size_tensor_index_extraction_helper<std::ptrdiff_t, Base::count>::run(index, t);
+ return internal::fixed_size_tensor_index_extraction_helper<std::ptrdiff_t, Base::count>::run(index, *this);
}
template <typename DenseIndex> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
size_t IndexOfColMajor(const array<DenseIndex, Base::count>& indices) const {
- return internal::fixed_size_tensor_index_linearization_helper<DenseIndex, Base::count, Base::count, false>::run(indices, t);
+ return internal::fixed_size_tensor_index_linearization_helper<DenseIndex, Base::count, Base::count, false>::run(indices, *static_cast<const Base*>(this));
}
template <typename DenseIndex> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
size_t IndexOfRowMajor(const array<DenseIndex, Base::count>& indices) const {
- return internal::fixed_size_tensor_index_linearization_helper<DenseIndex, Base::count, Base::count, true>::run(indices, t);
+ return internal::fixed_size_tensor_index_linearization_helper<DenseIndex, Base::count, Base::count, true>::run(indices, *static_cast<const Base*>(this));
}
};
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h
index 82dd1e6..0698713 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h
@@ -41,9 +41,6 @@ struct traits<TensorEvalToOp<XprType, MakePointer_> >
// Intermediate typedef to workaround MSVC issue.
typedef MakePointer_<T> MakePointerT;
typedef typename MakePointerT::Type Type;
- typedef typename MakePointerT::RefType RefType;
-
-
};
};
@@ -120,7 +117,7 @@ struct TensorEvaluator<const TensorEvalToOp<ArgType, MakePointer_>, Device>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const XprType& op() const {
return m_op;
}
-
+
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~TensorEvaluator() {
}
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h
index d641581..834ce07 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h
@@ -32,7 +32,6 @@ struct TensorEvaluator
typedef typename Derived::Scalar CoeffReturnType;
typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
typedef typename Derived::Dimensions Dimensions;
- typedef Derived XprType;
// NumDimensions is -1 for variable dim tensors
static const int NumCoords = internal::traits<Derived>::NumDimensions > 0 ?
@@ -69,9 +68,7 @@ struct TensorEvaluator
return m_data[index];
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- typename internal::traits<Derived>::template MakePointer<Scalar>::RefType
- coeffRef(Index index) {
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
eigen_assert(m_data);
return m_data[index];
}
@@ -97,9 +94,7 @@ struct TensorEvaluator
}
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- typename internal::traits<Derived>::template MakePointer<Scalar>::RefType
- coeffRef(const array<DenseIndex, NumCoords>& coords) {
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(const array<DenseIndex, NumCoords>& coords) {
eigen_assert(m_data);
if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) {
return m_data[m_dims.IndexOfColMajor(coords)];
@@ -157,8 +152,6 @@ struct TensorEvaluator<const Derived, Device>
typedef typename Derived::Scalar CoeffReturnType;
typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
typedef typename Derived::Dimensions Dimensions;
- typedef const Derived XprType;
-
// NumDimensions is -1 for variable dim tensors
static const int NumCoords = internal::traits<Derived>::NumDimensions > 0 ?
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h
index f060191..08eb559 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h
@@ -253,7 +253,7 @@ struct TensorEvaluator<const TensorFFTOp<FFT, ArgType, FFTResultType, FFTDir>, D
// get data into line_buf
const Index stride = m_strides[dim];
if (stride == 1) {
- m_device.memcpy(line_buf, &buf[base_offset], line_len*sizeof(ComplexScalar));
+ memcpy(line_buf, &buf[base_offset], line_len*sizeof(ComplexScalar));
} else {
Index offset = base_offset;
for (int j = 0; j < line_len; ++j, offset += stride) {
@@ -271,7 +271,7 @@ struct TensorEvaluator<const TensorFFTOp<FFT, ArgType, FFTResultType, FFTDir>, D
// write back
if (FFTDir == FFT_FORWARD && stride == 1) {
- m_device.memcpy(&buf[base_offset], line_buf, line_len*sizeof(ComplexScalar));
+ memcpy(&buf[base_offset], line_buf, line_len*sizeof(ComplexScalar));
} else {
Index offset = base_offset;
const ComplexScalar div_factor = ComplexScalar(1.0 / line_len, 0);
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h
index abe85c8..bbd5eb3 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h
@@ -26,8 +26,8 @@ namespace Eigen {
/// Therefore, by adding the default value, we managed to convert the type and it does not break any
/// existing code as its default value is T*.
namespace internal {
-template<typename XprType>
-struct traits<TensorForcedEvalOp<XprType> >
+template<typename XprType, template <class> class MakePointer_>
+struct traits<TensorForcedEvalOp<XprType, MakePointer_> >
{
// Type promotion to handle the case where the types of the lhs and the rhs are different.
typedef typename XprType::Scalar Scalar;
@@ -42,26 +42,31 @@ struct traits<TensorForcedEvalOp<XprType> >
enum {
Flags = 0
};
+ template <class T> struct MakePointer {
+ // Intermediate typedef to workaround MSVC issue.
+ typedef MakePointer_<T> MakePointerT;
+ typedef typename MakePointerT::Type Type;
+ };
};
-template<typename XprType>
-struct eval<TensorForcedEvalOp<XprType>, Eigen::Dense>
+template<typename XprType, template <class> class MakePointer_>
+struct eval<TensorForcedEvalOp<XprType, MakePointer_>, Eigen::Dense>
{
- typedef const TensorForcedEvalOp<XprType>& type;
+ typedef const TensorForcedEvalOp<XprType, MakePointer_>& type;
};
-template<typename XprType>
-struct nested<TensorForcedEvalOp<XprType>, 1, typename eval<TensorForcedEvalOp<XprType> >::type>
+template<typename XprType, template <class> class MakePointer_>
+struct nested<TensorForcedEvalOp<XprType, MakePointer_>, 1, typename eval<TensorForcedEvalOp<XprType, MakePointer_> >::type>
{
- typedef TensorForcedEvalOp<XprType> type;
+ typedef TensorForcedEvalOp<XprType, MakePointer_> type;
};
} // end namespace internal
-template<typename XprType>
-class TensorForcedEvalOp : public TensorBase<TensorForcedEvalOp<XprType>, ReadOnlyAccessors>
+template<typename XprType, template <class> class MakePointer_>
+class TensorForcedEvalOp : public TensorBase<TensorForcedEvalOp<XprType, MakePointer_>, ReadOnlyAccessors>
{
public:
typedef typename Eigen::internal::traits<TensorForcedEvalOp>::Scalar Scalar;
@@ -83,10 +88,10 @@ class TensorForcedEvalOp : public TensorBase<TensorForcedEvalOp<XprType>, ReadOn
};
-template<typename ArgType, typename Device>
-struct TensorEvaluator<const TensorForcedEvalOp<ArgType>, Device>
+template<typename ArgType, typename Device, template <class> class MakePointer_>
+struct TensorEvaluator<const TensorForcedEvalOp<ArgType, MakePointer_>, Device>
{
- typedef TensorForcedEvalOp<ArgType> XprType;
+ typedef TensorForcedEvalOp<ArgType, MakePointer_> XprType;
typedef typename ArgType::Scalar Scalar;
typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
typedef typename XprType::Index Index;
@@ -102,7 +107,7 @@ struct TensorEvaluator<const TensorForcedEvalOp<ArgType>, Device>
};
EIGEN_DEVICE_FUNC TensorEvaluator(const XprType& op, const Device& device)
- /// op_ is used for sycl
+ /// op_ is used for sycl
: m_impl(op.expression(), device), m_op(op.expression()), m_device(device), m_buffer(NULL)
{ }
@@ -143,17 +148,17 @@ struct TensorEvaluator<const TensorForcedEvalOp<ArgType>, Device>
return TensorOpCost(sizeof(CoeffReturnType), 0, 0, vectorized, PacketSize);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType* data() const { return m_buffer; }
+ EIGEN_DEVICE_FUNC typename MakePointer<Scalar>::Type data() const { return m_buffer; }
/// required by sycl in order to extract the sycl accessor
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorEvaluator<ArgType, Device>& impl() { return m_impl; }
+ const TensorEvaluator<ArgType, Device>& impl() { return m_impl; }
/// used by sycl in order to build the sycl buffer
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Device& device() const{return m_device;}
+ const Device& device() const{return m_device;}
private:
TensorEvaluator<ArgType, Device> m_impl;
const ArgType m_op;
const Device& m_device;
- CoeffReturnType* m_buffer;
+ typename MakePointer<CoeffReturnType>::Type m_buffer;
};
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h
index 2e63899..52b803d 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h
@@ -20,19 +20,7 @@ namespace Eigen {
// map_allocator.
template<typename T> struct MakePointer {
typedef T* Type;
- typedef T& RefType;
};
-#if defined(EIGEN_USE_SYCL)
-namespace TensorSycl {
-namespace internal{
-template <typename HostExpr, typename FunctorExpr, typename Tuple_of_Acc, typename Dims, typename Op, typename Index> class ReductionFunctor;
-template<typename CoeffReturnType ,typename OutAccessor, typename HostExpr, typename FunctorExpr, typename Op, typename Dims, typename Index, typename TupleType>
-class FullReductionKernelFunctor;
-}
-}
-#endif
-
-
template<typename PlainObjectType, int Options_ = Unaligned, template <class> class MakePointer_ = MakePointer> class TensorMap;
template<typename Scalar_, int NumIndices_, int Options_ = 0, typename IndexType = DenseIndex> class Tensor;
@@ -75,7 +63,7 @@ template<typename CustomUnaryFunc, typename XprType> class TensorCustomUnaryOp;
template<typename CustomBinaryFunc, typename LhsXprType, typename RhsXprType> class TensorCustomBinaryOp;
template<typename XprType, template <class> class MakePointer_ = MakePointer> class TensorEvalToOp;
-template<typename XprType> class TensorForcedEvalOp;
+template<typename XprType, template <class> class MakePointer_ = MakePointer> class TensorForcedEvalOp;
template<typename ExpressionType, typename DeviceType> class TensorDevice;
template<typename Derived, typename Device> struct TensorEvaluator;
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
index 3b4f8ed..d73f6dc 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
@@ -33,7 +33,7 @@ struct functor_traits<scalar_mod_op<Scalar> >
*/
template <typename Scalar>
struct scalar_mod2_op {
- EIGEN_EMPTY_STRUCT_CTOR(scalar_mod2_op)
+ EIGEN_EMPTY_STRUCT_CTOR(scalar_mod2_op);
EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a, const Scalar& b) const { return a % b; }
};
template <typename Scalar>
@@ -42,7 +42,7 @@ struct functor_traits<scalar_mod2_op<Scalar> >
template <typename Scalar>
struct scalar_fmod_op {
- EIGEN_EMPTY_STRUCT_CTOR(scalar_fmod_op)
+ EIGEN_EMPTY_STRUCT_CTOR(scalar_fmod_op);
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar
operator()(const Scalar& a, const Scalar& b) const {
return numext::fmod(a, b);
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h
index ef1c9c4..ede3939 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h
@@ -37,8 +37,6 @@ namespace {
{
#ifdef __CUDA_ARCH__
return __clz(val);
-#elif defined(__SYCL_DEVICE_ONLY__)
- return cl::sycl::clz(val);
#elif EIGEN_COMP_MSVC
unsigned long index;
_BitScanReverse(&index, val);
@@ -55,8 +53,6 @@ namespace {
{
#ifdef __CUDA_ARCH__
return __clzll(val);
-#elif defined(__SYCL_DEVICE_ONLY__)
- return cl::sycl::clz(val);
#elif EIGEN_COMP_MSVC && EIGEN_ARCH_x86_64
unsigned long index;
_BitScanReverse64(&index, val);
@@ -92,8 +88,6 @@ namespace {
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE uint32_t muluh(const uint32_t a, const T b) {
#if defined(__CUDA_ARCH__)
return __umulhi(a, b);
-#elif defined(__SYCL_DEVICE_ONLY__)
- return cl::sycl::mul_hi(a, static_cast<uint32_t>(b));
#else
return (static_cast<uint64_t>(a) * b) >> 32;
#endif
@@ -103,8 +97,6 @@ namespace {
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE uint64_t muluh(const uint64_t a, const T b) {
#if defined(__CUDA_ARCH__)
return __umul64hi(a, b);
-#elif defined(__SYCL_DEVICE_ONLY__)
- return cl::sycl::mul_hi(a, static_cast<uint64_t>(b));
#elif defined(__SIZEOF_INT128__)
__uint128_t v = static_cast<__uint128_t>(a) * static_cast<__uint128_t>(b);
return static_cast<uint64_t>(v >> 64);
@@ -124,7 +116,7 @@ namespace {
template <typename T>
struct DividerHelper<64, T> {
static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE uint64_t computeMultiplier(const int log_div, const T divider) {
-#if defined(__SIZEOF_INT128__) && !defined(__CUDA_ARCH__) && !defined(__SYCL_DEVICE_ONLY__)
+#if defined(__SIZEOF_INT128__) && !defined(__CUDA_ARCH__)
return static_cast<uint64_t>((static_cast<__uint128_t>(1) << (64+log_div)) / static_cast<__uint128_t>(divider) - (static_cast<__uint128_t>(1) << 64) + 1);
#else
const uint64_t shift = 1ULL << log_div;
@@ -205,8 +197,6 @@ class TensorIntDivisor<int32_t, true> {
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE int divide(const int32_t n) const {
#ifdef __CUDA_ARCH__
return (__umulhi(magic, n) >> shift);
-#elif defined(__SYCL_DEVICE_ONLY__)
- return (cl::sycl::mul_hi(static_cast<uint64_t>(magic), static_cast<uint64_t>(n)) >> shift);
#else
uint64_t v = static_cast<uint64_t>(magic) * static_cast<uint64_t>(n);
return (static_cast<uint32_t>(v >> 32) >> shift);
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h
index f92e39d..ee0078b 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h
@@ -51,12 +51,4 @@
#endif
-#if EIGEN_OS_WIN || EIGEN_OS_WIN64
-#define EIGEN_SLEEP(n) Sleep(n)
-#elif EIGEN_OS_GNULINUX
-#define EIGEN_SLEEP(n) usleep(n * 1000);
-#else
-#define EIGEN_SLEEP(n) sleep(std::max<unsigned>(1, n/1000))
-#endif
-
#endif
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h
index b5ef31d..615559d 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h
@@ -75,7 +75,6 @@ struct PacketType<half, GpuDevice> {
HasSqrt = 1,
HasRsqrt = 1,
HasExp = 1,
- HasExpm1 = 0,
HasLog = 1,
HasLog1p = 0,
HasLog10 = 0,
@@ -169,12 +168,12 @@ template <typename Idx> struct IndexPair {
#ifdef EIGEN_HAS_SFINAE
namespace internal {
- template<typename IndexType, typename Index, Index... Is>
+ template<typename IndexType, Index... Is>
EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
array<Index, sizeof...(Is)> customIndices2Array(IndexType& idx, numeric_list<Index, Is...>) {
return { idx[Is]... };
}
- template<typename IndexType, typename Index>
+ template<typename IndexType>
EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
array<Index, 0> customIndices2Array(IndexType&, numeric_list<Index>) {
return array<Index, 0>();
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h
index 6ddd2ca..d34f1e3 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h
@@ -299,16 +299,6 @@ template <typename Index> struct MemcpyTriggerForSlicing<Index, GpuDevice> {
EIGEN_DEVICE_FUNC bool operator ()(Index val) const { return val > 4*1024*1024; }
};
#endif
-
-// It is very expensive to start the memcpy kernel on GPU: we therefore only
-// use it for large copies.
-#ifdef EIGEN_USE_SYCL
-template <typename Index> struct MemcpyTriggerForSlicing<Index, const Eigen::SyclDevice> {
- EIGEN_DEVICE_FUNC MemcpyTriggerForSlicing(const SyclDevice&) { }
- EIGEN_DEVICE_FUNC bool operator ()(Index val) const { return val > 4*1024*1024; }
-};
-#endif
-
}
// Eval as rvalue
@@ -503,14 +493,7 @@ struct TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Devi
}
return NULL;
}
- /// used by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorEvaluator<ArgType, Device>& impl() const{
- return m_impl;
- }
- /// used by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const StartIndices& startIndices() const{
- return m_offsets;
- }
+
protected:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index) const
{
@@ -711,12 +694,6 @@ struct TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices,
{
typedef TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType> XprType;
static const int NumDims = internal::array_size<Strides>::value;
- typedef typename XprType::Index Index;
- typedef typename XprType::Scalar Scalar;
- typedef typename internal::remove_const<Scalar>::type ScalarNonConst;
- typedef typename XprType::CoeffReturnType CoeffReturnType;
- typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
- typedef Strides Dimensions;
enum {
// Alignment can't be guaranteed at compile time since it depends on the
@@ -729,7 +706,7 @@ struct TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices,
};
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
- : m_impl(op.expression(), device), m_device(device), m_strides(op.strides()), m_exprStartIndices(op.startIndices()), m_exprStopIndices(op.stopIndices())
+ : m_impl(op.expression(), device), m_device(device), m_strides(op.strides())
{
// Handle degenerate intervals by gracefully clamping and allowing m_dimensions to be zero
DSizes<Index,NumDims> startIndicesClamped, stopIndicesClamped;
@@ -739,7 +716,7 @@ struct TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices,
startIndicesClamped[i] = clamp(op.startIndices()[i], 0, m_impl.dimensions()[i]);
stopIndicesClamped[i] = clamp(op.stopIndices()[i], 0, m_impl.dimensions()[i]);
}else{
- /* implies m_strides[i]<0 by assert */
+ /* implies m_strides[i]<0 by assert */
startIndicesClamped[i] = clamp(op.startIndices()[i], -1, m_impl.dimensions()[i] - 1);
stopIndicesClamped[i] = clamp(op.stopIndices()[i], -1, m_impl.dimensions()[i] - 1);
}
@@ -802,6 +779,13 @@ struct TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices,
sizeof(Scalar));
}
+ typedef typename XprType::Index Index;
+ typedef typename XprType::Scalar Scalar;
+ typedef typename internal::remove_const<Scalar>::type ScalarNonConst;
+ typedef typename XprType::CoeffReturnType CoeffReturnType;
+ typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
+ typedef Strides Dimensions;
+
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
@@ -827,15 +811,6 @@ struct TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices,
return NULL;
}
- //use by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const StartIndices& exprStartIndices() const { return m_exprStartIndices; }
- //use by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const StartIndices& exprStopIndices() const { return m_exprStopIndices; }
- //use by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const StartIndices& strides() const { return m_strides; }
- /// used by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorEvaluator<ArgType, Device>& impl() const{return m_impl;}
-
protected:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index) const
{
@@ -857,11 +832,7 @@ struct TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices,
}
static EIGEN_STRONG_INLINE Index clamp(Index value, Index min, Index max) {
-#ifndef __SYCL_DEVICE_ONLY__
return numext::maxi(min, numext::mini(max,value));
-#else
- return cl::sycl::clamp(value, min, max);
-#endif
}
array<Index, NumDims> m_outputStrides;
@@ -874,10 +845,6 @@ struct TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices,
DSizes<Index, NumDims> m_offsets; // offset in a flattened shape
const Strides m_strides;
std::size_t m_block_total_size_max;
- //use by sycl
- const StartIndices m_exprStartIndices;
- //use by sycl
- const StopIndices m_exprStopIndices;
};
// Eval as lvalue
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h
index a8e2552..647bcf1 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h
@@ -200,13 +200,6 @@ struct TensorEvaluator<const TensorPaddingOp<PaddingDimensions, ArgType>, Device
EIGEN_DEVICE_FUNC Scalar* data() const { return NULL; }
- /// used by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PaddingDimensions& padding() const { return m_padding; }
- /// used by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& padding_value() const { return m_paddingValue; }
- /// used by sycl
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorEvaluator<ArgType, Device>& impl() const{return m_impl;}
-
private:
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool isPaddingAtIndexForDim(
Index index, int dim_index) const {
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h
index e341e2e..41d0d00 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h
@@ -11,20 +11,8 @@
#ifndef EIGEN_CXX11_TENSOR_TENSOR_REDUCTION_H
#define EIGEN_CXX11_TENSOR_TENSOR_REDUCTION_H
-// clang is incompatible with the CUDA syntax wrt making a kernel a class friend,
-// so we'll use a macro to make clang happy.
-#ifndef KERNEL_FRIEND
-#if defined(__clang__) && defined(__CUDA__)
-#define KERNEL_FRIEND friend __global__
-#else
-#define KERNEL_FRIEND friend
-#endif
-#endif
-
-
namespace Eigen {
-
/** \class TensorReduction
* \ingroup CXX11_Tensor_Module
*
@@ -692,23 +680,17 @@ struct TensorEvaluator<const TensorReductionOp<Op, Dims, ArgType, MakePointer_>,
template <typename S, typename O, bool V> friend struct internal::FullReducerShard;
#endif
#if defined(EIGEN_USE_GPU) && defined(__CUDACC__)
- template <int B, int N, typename S, typename R, typename I> KERNEL_FRIEND void internal::FullReductionKernel(R, const S, I, typename S::CoeffReturnType*, unsigned int*);
+ template <int B, int N, typename S, typename R, typename I> friend void internal::FullReductionKernel(R, const S, I, typename S::CoeffReturnType*, unsigned int*);
#ifdef EIGEN_HAS_CUDA_FP16
- template <typename S, typename R, typename I> KERNEL_FRIEND void internal::ReductionInitFullReduxKernelHalfFloat(R, const S, I, half2*);
- template <int B, int N, typename S, typename R, typename I> KERNEL_FRIEND void internal::FullReductionKernelHalfFloat(R, const S, I, half*, half2*);
- template <int NPT, typename S, typename R, typename I> KERNEL_FRIEND void internal::InnerReductionKernelHalfFloat(R, const S, I, I, half*);
-#endif
- template <int NPT, typename S, typename R, typename I> KERNEL_FRIEND void internal::InnerReductionKernel(R, const S, I, I, typename S::CoeffReturnType*);
-
- template <int NPT, typename S, typename R, typename I> KERNEL_FRIEND void internal::OuterReductionKernel(R, const S, I, I, typename S::CoeffReturnType*);
+ template <typename S, typename R, typename I> friend void internal::ReductionInitFullReduxKernelHalfFloat(R, const S, I, half2*);
+ template <int B, int N, typename S, typename R, typename I> friend void internal::FullReductionKernelHalfFloat(R, const S, I, half*, half2*);
+ template <int NPT, typename S, typename R, typename I> friend void internal::InnerReductionKernelHalfFloat(R, const S, I, I, half*);
#endif
+ template <int NPT, typename S, typename R, typename I> friend void internal::InnerReductionKernel(R, const S, I, I, typename S::CoeffReturnType*);
-#if defined(EIGEN_USE_SYCL)
- template < typename HostExpr_, typename FunctorExpr_, typename Tuple_of_Acc_, typename Dims_, typename Op_, typename Index_> friend class TensorSycl::internal::ReductionFunctor;
- template<typename CoeffReturnType_ ,typename OutAccessor_, typename HostExpr_, typename FunctorExpr_, typename Op_, typename Dims_, typename Index_, typename TupleType_> friend class TensorSycl::internal::FullReductionKernelFunctor;
+ template <int NPT, typename S, typename R, typename I> friend void internal::OuterReductionKernel(R, const S, I, I, typename S::CoeffReturnType*);
#endif
-
template <typename S, typename O, typename D> friend struct internal::InnerReducer;
// Returns the Index in the input tensor of the first value that needs to be
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionCuda.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionCuda.h
index edb0ab2..65638b6 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionCuda.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionCuda.h
@@ -287,6 +287,7 @@ struct FullReductionLauncher<
void>::type> {
static void run(const Self& self, Op& reducer, const GpuDevice& device, OutputType* output, typename Self::Index num_coeffs) {
typedef typename Self::Index Index;
+ typedef typename Self::CoeffReturnType Scalar;
const int block_size = 256;
const int num_per_thread = 128;
const int num_blocks = divup<int>(num_coeffs, block_size * num_per_thread);
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h
index c3ca129..3daecb0 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h
@@ -25,28 +25,61 @@
namespace Eigen {
namespace internal {
-template<typename OP, typename CoeffReturnType> struct syclGenericBufferReducer{
+template<typename CoeffReturnType, typename KernelName> struct syclGenericBufferReducer{
template<typename BufferTOut, typename BufferTIn>
-static void run(OP op, BufferTOut& bufOut, BufferTIn& bufI, const Eigen::SyclDevice& dev, size_t length, size_t local){
+static void run(BufferTOut* bufOut, BufferTIn& bufI, const Eigen::SyclDevice& dev, size_t length, size_t local){
do {
- auto f = [length, local, op, &bufOut, &bufI](cl::sycl::handler& h) mutable {
+ auto f = [length, local, bufOut, &bufI](cl::sycl::handler& h) mutable {
cl::sycl::nd_range<1> r{cl::sycl::range<1>{std::max(length, local)},
cl::sycl::range<1>{std::min(length, local)}};
/* Two accessors are used: one to the buffer that is being reduced,
* and a second to local memory, used to store intermediate data. */
- auto aI =bufI.template get_access<cl::sycl::access::mode::read_write>(h);
- auto aOut =bufOut.template get_access<cl::sycl::access::mode::discard_write>(h);
- typedef decltype(aI) InputAccessor;
- typedef decltype(aOut) OutputAccessor;
- typedef cl::sycl::accessor<CoeffReturnType, 1, cl::sycl::access::mode::read_write,cl::sycl::access::target::local> LocalAccessor;
- LocalAccessor scratch(cl::sycl::range<1>(local), h);
+ auto aI =
+ bufI.template get_access<cl::sycl::access::mode::read_write>(h);
+ auto aOut =
+ bufOut->template get_access<cl::sycl::access::mode::discard_write>(h);
+ cl::sycl::accessor<CoeffReturnType, 1, cl::sycl::access::mode::read_write,
+ cl::sycl::access::target::local>
+ scratch(cl::sycl::range<1>(local), h);
/* The parallel_for invocation chosen is the variant with an nd_item
* parameter, since the code requires barriers for correctness. */
- h.parallel_for(r, TensorSycl::internal::GenericKernelReducer<CoeffReturnType, OP, OutputAccessor, InputAccessor, LocalAccessor>(op, aOut, aI, scratch, length, local));
+ h.parallel_for<KernelName>(
+ r, [aOut, aI, scratch, local, length](cl::sycl::nd_item<1> id) {
+ size_t globalid = id.get_global(0);
+ size_t localid = id.get_local(0);
+ /* All threads collectively read from global memory into local.
+ * The barrier ensures all threads' IO is resolved before
+ * execution continues (strictly speaking, all threads within
+ * a single work-group - there is no co-ordination between
+ * work-groups, only work-items). */
+ if (globalid < length) {
+ scratch[localid] = aI[globalid];
+ }
+ id.barrier(cl::sycl::access::fence_space::local_space);
+
+ /* Apply the reduction operation between the current local
+ * id and the one on the other half of the vector. */
+ if (globalid < length) {
+ int min = (length < local) ? length : local;
+ for (size_t offset = min / 2; offset > 0; offset /= 2) {
+ if (localid < offset) {
+ scratch[localid] += scratch[localid + offset];
+ }
+ id.barrier(cl::sycl::access::fence_space::local_space);
+ }
+ /* The final result will be stored in local id 0. */
+ if (localid == 0) {
+ aI[id.get_group(0)] = scratch[localid];
+ if((length<=local) && globalid ==0){
+ aOut[globalid]=scratch[localid];
+ }
+ }
+ }
+ });
};
- dev.sycl_queue().submit(f);
- dev.asynchronousExec();
+ dev.m_queue.submit(f);
+ dev.m_queue.throw_asynchronous();
/* At this point, you could queue::wait_and_throw() to ensure that
* errors are caught quickly. However, this would likely impact
@@ -54,23 +87,18 @@ static void run(OP op, BufferTOut& bufOut, BufferTIn& bufI, const Eigen::SyclDev
length = length / local;
} while (length > 1);
-}
-};
-template<typename CoeffReturnType> struct syclGenericBufferReducer<Eigen::internal::MeanReducer<CoeffReturnType>, CoeffReturnType>{
-template<typename BufferTOut, typename BufferTIn>
-static void run(Eigen::internal::MeanReducer<CoeffReturnType>, BufferTOut& bufOut, BufferTIn& bufI, const Eigen::SyclDevice& dev, size_t length, size_t local){
- syclGenericBufferReducer<Eigen::internal::SumReducer<CoeffReturnType>, CoeffReturnType>::run(Eigen::internal::SumReducer<CoeffReturnType>(),
- bufOut, bufI, dev, length, local);
+
}
+
};
+/// For now let's start with a full reducer
/// Self is useless here because in expression construction we are going to treat reduction as a leafnode.
/// we want to take reduction child and then build a construction and apply the full reducer function on it. Fullreducre applies the
/// reduction operation on the child of the reduction. once it is done the reduction is an empty shell and can be thrown away and treated as
// a leafNode.
-
template <typename Self, typename Op, bool Vectorizable>
struct FullReducer<Self, Op, const Eigen::SyclDevice, Vectorizable> {
@@ -79,8 +107,8 @@ struct FullReducer<Self, Op, const Eigen::SyclDevice, Vectorizable> {
static void run(const Self& self, Op& reducer, const Eigen::SyclDevice& dev, CoeffReturnType* output) {
typedef const typename Self::ChildType HostExpr; /// this is the child of reduction
- typedef Eigen::TensorSycl::internal::FunctorExtractor<TensorEvaluator<HostExpr, const Eigen::SyclDevice> > FunctorExpr;
- FunctorExpr functors = TensorSycl::internal::extractFunctors(self.impl());
+ typedef typename TensorSycl::internal::createPlaceHolderExpression<HostExpr>::Type PlaceHolderExpr;
+ auto functors = TensorSycl::internal::extractFunctors(self.impl());
int red_factor =256; /// initial reduction. If the size is less than red_factor we only creates one thread.
size_t inputSize =self.impl().dimensions().TotalSize();
size_t rng = inputSize/red_factor; // the total number of thread initially is half the size of the input
@@ -88,7 +116,7 @@ struct FullReducer<Self, Op, const Eigen::SyclDevice, Vectorizable> {
if(rng ==0) {
red_factor=1;
};
- size_t tileSize =dev.sycl_queue().get_device(). template get_info<cl::sycl::info::device::max_work_group_size>()/2;
+ size_t tileSize =dev.m_queue.get_device(). template get_info<cl::sycl::info::device::max_work_group_size>()/2;
size_t GRange=std::max((size_t )1, rng);
// convert global range to power of 2 for redecution
@@ -105,66 +133,105 @@ struct FullReducer<Self, Op, const Eigen::SyclDevice, Vectorizable> {
size_t outTileSize = tileSize;
/// if the shared memory is less than the GRange, we set shared_mem size to the TotalSize and in this case one kernel would be created for recursion to reduce all to one.
if (GRange < outTileSize) outTileSize=GRange;
+ // getting final out buffer at the moment the created buffer is true because there is no need for assign
+ auto out_buffer =dev.template get_sycl_buffer<typename Eigen::internal::remove_all<CoeffReturnType>::type>(self.dimensions().TotalSize(), output);
/// creating the shared memory for calculating reduction.
/// This one is used to collect all the reduced value of shared memory as we dont have global barrier on GPU. Once it is saved we can
/// recursively apply reduction on it in order to reduce the whole.
auto temp_global_buffer =cl::sycl::buffer<CoeffReturnType, 1>(cl::sycl::range<1>(GRange));
typedef typename Eigen::internal::remove_all<decltype(self.xprDims())>::type Dims;
- // Dims dims= self.xprDims();
- //Op functor = reducer;
- dev.sycl_queue().submit([&](cl::sycl::handler &cgh) {
- // this is a workaround for gcc 4.8 bug
- typedef decltype(TensorSycl::internal::createTupleOfAccessors(cgh, self.impl())) TupleType;
+ Dims dims= self.xprDims();
+ Op functor = reducer;
+ dev.m_queue.submit([&](cl::sycl::handler &cgh) {
// create a tuple of accessors from Evaluator
- TupleType tuple_of_accessors = TensorSycl::internal::createTupleOfAccessors(cgh, self.impl());
+ auto tuple_of_accessors = TensorSycl::internal::createTupleOfAccessors(cgh, self.impl());
auto tmp_global_accessor = temp_global_buffer. template get_access<cl::sycl::access::mode::read_write, cl::sycl::access::target::global_buffer>(cgh);
- typedef decltype(tmp_global_accessor) OutAccessor;
- cgh.parallel_for( cl::sycl::nd_range<1>(cl::sycl::range<1>(GRange), cl::sycl::range<1>(outTileSize)),
- TensorSycl::internal::FullReductionKernelFunctor<CoeffReturnType, OutAccessor, HostExpr, FunctorExpr, Op, Dims, size_t, TupleType>
- (tmp_global_accessor, rng, remaining, red_factor, reducer, self.xprDims(), functors, tuple_of_accessors));
+
+ cgh.parallel_for<PlaceHolderExpr>( cl::sycl::nd_range<1>(cl::sycl::range<1>(GRange), cl::sycl::range<1>(outTileSize)), [=](cl::sycl::nd_item<1> itemID) {
+ typedef typename TensorSycl::internal::ConvertToDeviceExpression<const HostExpr>::Type DevExpr;
+ auto device_expr = TensorSycl::internal::createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
+ /// reduction cannot be captured automatically through our device conversion recursion. The reason is that reduction has two behaviour
+ /// the first behaviour is when it is used as a root to lauch the sub-kernel. The second one is when it is treated as a leafnode to pass the
+ /// calculated result to its parent kernel. While the latter is automatically detected through our device expression generator. The former is created here.
+ const auto device_self_expr= TensorReductionOp<Op, Dims, decltype(device_expr.expr) ,MakeGlobalPointer>(device_expr.expr, dims, functor);
+ /// This is the evaluator for device_self_expr. This is exactly similar to the self which has been passed to run function. The difference is
+ /// the device_evaluator is detectable and recognisable on the device.
+ auto device_self_evaluator = Eigen::TensorEvaluator<decltype(device_self_expr), Eigen::DefaultDevice>(device_self_expr, Eigen::DefaultDevice());
+ /// const cast added as a naive solution to solve the qualifier drop error
+ auto globalid=itemID.get_global_linear_id();
+
+ if(globalid<rng)
+ tmp_global_accessor.get_pointer()[globalid]=InnerMostDimReducer<decltype(device_self_evaluator), Op, false>::reduce(device_self_evaluator, red_factor*globalid, red_factor, const_cast<Op&>(functor));
+ else
+ tmp_global_accessor.get_pointer()[globalid]=static_cast<CoeffReturnType>(0);
+
+ if(remaining!=0 && globalid==0 )
+ // this will add the rest of input buffer when the input size is not devidable to red_factor.
+ tmp_global_accessor.get_pointer()[globalid]+=InnerMostDimReducer<decltype(device_self_evaluator), Op, false>::reduce(device_self_evaluator, red_factor*(rng), remaining, const_cast<Op&>(functor));
+ });
});
- dev.asynchronousExec();
+ dev.m_queue.throw_asynchronous();
- // getting final out buffer at the moment the created buffer is true because there is no need for assign
- auto out_buffer =dev.get_sycl_buffer(output);
- /// This is used to recursively reduce the tmp value to an element of 1;
- syclGenericBufferReducer<Op, CoeffReturnType>::run(reducer, out_buffer, temp_global_buffer,dev, GRange, outTileSize);
+/// This is used to recursively reduce the tmp value to an element of 1;
+ syclGenericBufferReducer<CoeffReturnType,HostExpr>::run(out_buffer, temp_global_buffer,dev, GRange, outTileSize);
}
};
-
template <typename Self, typename Op>
struct InnerReducer<Self, Op, const Eigen::SyclDevice> {
typedef typename Self::CoeffReturnType CoeffReturnType;
static const bool HasOptimizedImplementation = false;
- static bool run(const Self& self, Op& reducer, const Eigen::SyclDevice& dev, CoeffReturnType* output, typename Self::Index num_values_to_reduce, typename Self::Index num_coeffs_to_preserve) {
+ static bool run(const Self& self, Op& reducer, const Eigen::SyclDevice& dev, CoeffReturnType* output, typename Self::Index , typename Self::Index num_coeffs_to_preserve) {
typedef const typename Self::ChildType HostExpr; /// this is the child of reduction
- typedef Eigen::TensorSycl::internal::FunctorExtractor<TensorEvaluator<HostExpr, const Eigen::SyclDevice> > FunctorExpr;
- FunctorExpr functors = TensorSycl::internal::extractFunctors(self.impl());
- typename Self::Index range, GRange, tileSize;
- typedef typename Eigen::internal::remove_all<decltype(self.xprDims())>::type Dims;
+ typedef typename TensorSycl::internal::createPlaceHolderExpression<HostExpr>::Type PlaceHolderExpr;
+ auto functors = TensorSycl::internal::extractFunctors(self.impl());
+
+ size_t tileSize =dev.m_queue.get_device(). template get_info<cl::sycl::info::device::max_work_group_size>()/2;
+ size_t GRange=num_coeffs_to_preserve;
+ if (tileSize>GRange) tileSize=GRange;
+ else if(GRange>tileSize){
+ size_t xMode = GRange % tileSize;
+ if (xMode != 0) GRange += (tileSize - xMode);
+ }
// getting final out buffer at the moment the created buffer is true because there is no need for assign
/// creating the shared memory for calculating reduction.
/// This one is used to collect all the reduced value of shared memory as we dont have global barrier on GPU. Once it is saved we can
/// recursively apply reduction on it in order to reduce the whole.
- dev.parallel_for_setup(num_coeffs_to_preserve, tileSize, range, GRange);
- dev.sycl_queue().submit([&](cl::sycl::handler &cgh) {
- // this is workaround for gcc 4.8 bug.
- typedef decltype(TensorSycl::internal::createTupleOfAccessors(cgh, self.impl())) Tuple_of_Acc;
- // create a tuple of accessors from Evaluator
- Tuple_of_Acc tuple_of_accessors = TensorSycl::internal::createTupleOfAccessors(cgh, self.impl());
- auto output_accessor = dev.template get_sycl_accessor<cl::sycl::access::mode::discard_write>(cgh, output);
- Index red_size = (num_values_to_reduce!=0)? num_values_to_reduce : static_cast<Index>(1);
- cgh.parallel_for( cl::sycl::nd_range<1>(cl::sycl::range<1>(GRange), cl::sycl::range<1>(tileSize)),
- TensorSycl::internal::ReductionFunctor<HostExpr, FunctorExpr, Tuple_of_Acc, Dims, Op, typename Self::Index>
- (output_accessor, functors, tuple_of_accessors, self.xprDims(), reducer, range, red_size));
+ typedef typename Eigen::internal::remove_all<decltype(self.xprDims())>::type Dims;
+ Dims dims= self.xprDims();
+ Op functor = reducer;
+ dev.m_queue.submit([&](cl::sycl::handler &cgh) {
+ // create a tuple of accessors from Evaluator
+ auto tuple_of_accessors = TensorSycl::internal::createTupleOfAccessors(cgh, self.impl());
+ auto output_accessor = dev.template get_sycl_accessor<cl::sycl::access::mode::discard_write>(num_coeffs_to_preserve,cgh, output);
+
+ cgh.parallel_for<Self>( cl::sycl::nd_range<1>(cl::sycl::range<1>(GRange), cl::sycl::range<1>(tileSize)), [=](cl::sycl::nd_item<1> itemID) {
+ typedef typename TensorSycl::internal::ConvertToDeviceExpression<const HostExpr>::Type DevExpr;
+ auto device_expr = TensorSycl::internal::createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
+ /// reduction cannot be captured automatically through our device conversion recursion. The reason is that reduction has two behaviour
+ /// the first behaviour is when it is used as a root to lauch the sub-kernel. The second one is when it is treated as a leafnode to pass the
+ /// calculated result to its parent kernel. While the latter is automatically detected through our device expression generator. The former is created here.
+ const auto device_self_expr= TensorReductionOp<Op, Dims, decltype(device_expr.expr) ,MakeGlobalPointer>(device_expr.expr, dims, functor);
+ /// This is the evaluator for device_self_expr. This is exactly similar to the self which has been passed to run function. The difference is
+ /// the device_evaluator is detectable and recognisable on the device.
+ typedef Eigen::TensorEvaluator<decltype(device_self_expr), Eigen::DefaultDevice> DeiceSelf;
+ auto device_self_evaluator = Eigen::TensorEvaluator<decltype(device_self_expr), Eigen::DefaultDevice>(device_self_expr, Eigen::DefaultDevice());
+ /// const cast added as a naive solution to solve the qualifier drop error
+ auto globalid=itemID.get_global_linear_id();
+ if (globalid< static_cast<size_t>(num_coeffs_to_preserve)) {
+ typename DeiceSelf::CoeffReturnType accum = functor.initialize();
+ GenericDimReducer<DeiceSelf::NumReducedDims-1, DeiceSelf, Op>::reduce(device_self_evaluator, device_self_evaluator.firstInput(globalid),const_cast<Op&>(functor), &accum);
+ functor.finalize(accum);
+ output_accessor.get_pointer()[globalid]= accum;
+ }
+ });
});
- dev.asynchronousExec();
+ dev.m_queue.throw_asynchronous();
return false;
}
};
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h
index e430b08..14e392e 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h
@@ -224,11 +224,6 @@ struct TensorEvaluator<const TensorReverseOp<ReverseDimensions, ArgType>, Device
EIGEN_DEVICE_FUNC Scalar* data() const { return NULL; }
- /// required by sycl in order to extract the accessor
- const TensorEvaluator<ArgType, Device> & impl() const { return m_impl; }
- /// added for sycl in order to construct the buffer from sycl device
- ReverseDimensions functor() const { return m_reverse; }
-
protected:
Dimensions m_dimensions;
array<Index, NumDims> m_strides;
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h
index edc9dd3..113c060 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h
@@ -117,7 +117,7 @@ struct TensorEvaluator<const TensorShufflingOp<Shuffle, ArgType>, Device>
};
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
- : m_impl(op.expression(), device), m_shuffle(op.shufflePermutation())
+ : m_impl(op.expression(), device)
{
const typename TensorEvaluator<ArgType, Device>::Dimensions& input_dims = m_impl.dimensions();
const Shuffle& shuffle = op.shufflePermutation();
@@ -187,11 +187,6 @@ struct TensorEvaluator<const TensorShufflingOp<Shuffle, ArgType>, Device>
EIGEN_DEVICE_FUNC Scalar* data() const { return NULL; }
- // required by sycl
- EIGEN_STRONG_INLINE const Shuffle& shufflePermutation() const {return m_shuffle;}
- // required by sycl
- EIGEN_STRONG_INLINE const TensorEvaluator<ArgType, Device>& impl() const {return m_impl;}
-
protected:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index) const {
Index inputIndex = 0;
@@ -211,12 +206,11 @@ struct TensorEvaluator<const TensorShufflingOp<Shuffle, ArgType>, Device>
return inputIndex + index * m_inputStrides[NumDims - 1];
}
}
+
Dimensions m_dimensions;
array<Index, NumDims> m_outputStrides;
array<Index, NumDims> m_inputStrides;
TensorEvaluator<ArgType, Device> m_impl;
- /// required by sycl
- Shuffle m_shuffle;
};
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
index e6a666f..2854a4a 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
@@ -31,12 +31,12 @@ namespace Eigen {
*
* \sa Tensor
*/
-template<typename T, typename Dimensions, int Options> class TensorStorage;
+template<typename T, typename Dimensions, int Options_> class TensorStorage;
// Pure fixed-size storage
-template<typename T, typename FixedDimensions, int Options_>
-class TensorStorage
+template<typename T, int Options_, typename FixedDimensions>
+class TensorStorage<T, FixedDimensions, Options_>
{
private:
static const std::size_t Size = FixedDimensions::total_size;
@@ -66,7 +66,7 @@ class TensorStorage
// pure dynamic
-template<typename T, typename IndexType, int NumIndices_, int Options_>
+template<typename T, int Options_, typename IndexType, int NumIndices_>
class TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_>
{
public:
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h
index 2237140..6c35bfd 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h
@@ -117,11 +117,11 @@ struct TensorEvaluator<const TensorStridingOp<Strides, ArgType>, Device>
};
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
- : m_impl(op.expression(), device), m_strides(op.strides())
+ : m_impl(op.expression(), device)
{
m_dimensions = m_impl.dimensions();
for (int i = 0; i < NumDims; ++i) {
- m_dimensions[i] =Eigen::numext::ceil(static_cast<float>(m_dimensions[i]) / op.strides()[i]);
+ m_dimensions[i] = ceilf(static_cast<float>(m_dimensions[i]) / op.strides()[i]);
}
const typename TensorEvaluator<ArgType, Device>::Dimensions& input_dims = m_impl.dimensions();
@@ -224,11 +224,6 @@ struct TensorEvaluator<const TensorStridingOp<Strides, ArgType>, Device>
EIGEN_DEVICE_FUNC Scalar* data() const { return NULL; }
- /// required by sycl in order to extract the accessor
- const TensorEvaluator<ArgType, Device>& impl() const { return m_impl; }
- /// required by sycl in order to extract the accessor
- Strides functor() const { return m_strides; }
-
protected:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index) const
{
@@ -255,9 +250,9 @@ struct TensorEvaluator<const TensorStridingOp<Strides, ArgType>, Device>
array<Index, NumDims> m_outputStrides;
array<Index, NumDims> m_inputStrides;
TensorEvaluator<ArgType, Device> m_impl;
- const Strides m_strides;
};
+
// Eval as lvalue
template<typename Strides, typename ArgType, typename Device>
struct TensorEvaluator<TensorStridingOp<Strides, ArgType>, Device>
@@ -291,11 +286,6 @@ struct TensorEvaluator<TensorStridingOp<Strides, ArgType>, Device>
return this->m_impl.coeffRef(this->srcCoeff(index));
}
- /// required by sycl in order to extract the accessor
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorEvaluator<ArgType, Device>& impl() const { return this->m_impl; }
- /// required by sycl in order to extract the accessor
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Strides functor() const { return this->m_strides; }
-
template <int StoreMode> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void writePacket(Index index, const PacketReturnType& x)
{
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSycl.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSycl.h
index 9d5a6d4..bb8800d 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSycl.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSycl.h
@@ -20,14 +20,12 @@
template <class T>
struct MakeGlobalPointer {
typedef typename cl::sycl::global_ptr<T>::pointer_t Type;
- typedef typename cl::sycl::global_ptr<T>::reference_t RefType;
};
// global pointer to set different attribute state for a class
template <class T>
struct MakeLocalPointer {
typedef typename cl::sycl::local_ptr<T>::pointer_t Type;
- typedef typename cl::sycl::local_ptr<T>::reference_t RefType;
};
@@ -35,9 +33,6 @@ namespace Eigen {
namespace TensorSycl {
namespace internal {
- template<typename CoeffReturnType, typename OP, typename OutputAccessor, typename InputAccessor, typename LocalAccessor> struct GenericKernelReducer;
-
-
/// This struct is used for special expression nodes with no operations (for example assign and selectOP).
struct NoOP;
@@ -80,15 +75,8 @@ template<typename T> struct GetType<false, T>{
/// this is used for extracting tensor reduction
#include "TensorReductionSycl.h"
-/// this is used for extracting tensor convolution
-#include "TensorConvolutionSycl.h"
-
// kernel execution using fusion
#include "TensorSyclRun.h"
-//sycl functors
-#include "TensorSyclFunctors.h"
-
-#include "TensorContractionSycl.h"
#endif // end of EIGEN_USE_SYCL
#endif // UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCL_H
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclConvertToDeviceExpression.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclConvertToDeviceExpression.h
index ee8f3c9..8729c86 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclConvertToDeviceExpression.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclConvertToDeviceExpression.h
@@ -48,9 +48,9 @@ struct DeviceConvertor{
/// specialisation of the \ref ConvertToDeviceExpression struct when the node
/// type is TensorMap
#define TENSORMAPCONVERT(CVQual)\
-template <typename T, int Options_, template <class> class MakePointer_>\
-struct ConvertToDeviceExpression<CVQual TensorMap<T, Options_, MakePointer_> > {\
- typedef CVQual TensorMap<T, Options_, MakeGlobalPointer> Type;\
+template <typename Scalar_, int Options_, int Options2_, int NumIndices_, typename IndexType_, template <class> class MakePointer_>\
+struct ConvertToDeviceExpression<CVQual TensorMap<Tensor<Scalar_, NumIndices_, Options_, IndexType_>, Options2_, MakePointer_> > {\
+ typedef CVQual TensorMap<Tensor<Scalar_, NumIndices_, Options_, IndexType_>, Options2_, MakeGlobalPointer> Type;\
};
TENSORMAPCONVERT(const)
@@ -97,18 +97,8 @@ template <typename Expr>\
struct ConvertToDeviceExpression<CVQual ExprNode<Expr> > \
: DeviceConvertor<ExprNode, Res, Expr>{};
-/// specialisation of the \ref ConvertToDeviceExpression struct when the node type is TensorForcedEvalOp
-#define KERNELBROKERCONVERTFORCEDEVAL(CVQual)\
-template <typename Expr>\
-struct ConvertToDeviceExpression<CVQual TensorForcedEvalOp<Expr> > {\
- typedef CVQual TensorForcedEvalOp< typename ConvertToDeviceExpression<Expr>::Type> Type;\
-};
-KERNELBROKERCONVERTFORCEDEVAL(const)
-KERNELBROKERCONVERTFORCEDEVAL()
-#undef KERNELBROKERCONVERTFORCEDEVAL
-
-
-
+KERNELBROKERCONVERT(const, true, TensorForcedEvalOp)
+KERNELBROKERCONVERT(, false, TensorForcedEvalOp)
KERNELBROKERCONVERT(const, true, TensorEvalToOp)
KERNELBROKERCONVERT(, false, TensorEvalToOp)
#undef KERNELBROKERCONVERT
@@ -124,40 +114,6 @@ KERNELBROKERCONVERTREDUCTION(const)
KERNELBROKERCONVERTREDUCTION()
#undef KERNELBROKERCONVERTREDUCTION
-#define KERNELBROKERCONVERTSLICEOP(CVQual)\
-template<typename StartIndices, typename Sizes, typename XprType>\
-struct ConvertToDeviceExpression<CVQual TensorSlicingOp <StartIndices, Sizes, XprType> >{\
- typedef CVQual TensorSlicingOp<StartIndices, Sizes, typename ConvertToDeviceExpression<XprType>::Type> Type;\
-};
-
-KERNELBROKERCONVERTSLICEOP(const)
-KERNELBROKERCONVERTSLICEOP()
-#undef KERNELBROKERCONVERTSLICEOP
-
-
-#define KERNELBROKERCONVERTERSLICESTRIDEOP(CVQual)\
-template<typename StartIndices, typename StopIndices, typename Strides, typename XprType>\
-struct ConvertToDeviceExpression<CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> >{\
- typedef CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, typename ConvertToDeviceExpression<XprType>::Type> Type;\
-};
-
-KERNELBROKERCONVERTERSLICESTRIDEOP(const)
-KERNELBROKERCONVERTERSLICESTRIDEOP()
-#undef KERNELBROKERCONVERTERSLICESTRIDEOP
-
-
-/// specialisation of the \ref ConvertToDeviceExpression struct when the node type is TensorChippingOp
-#define KERNELBROKERCONVERTCHIPPINGOP(CVQual)\
-template <DenseIndex DimId, typename Expr>\
-struct ConvertToDeviceExpression<CVQual TensorChippingOp<DimId, Expr> > {\
- typedef CVQual TensorChippingOp<DimId, typename ConvertToDeviceExpression<Expr>::Type> Type;\
-};
-KERNELBROKERCONVERTCHIPPINGOP(const)
-KERNELBROKERCONVERTCHIPPINGOP()
-#undef KERNELBROKERCONVERTCHIPPINGOP
-
-
-
} // namespace internal
} // namespace TensorSycl
} // namespace Eigen
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExprConstructor.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExprConstructor.h
index 3b83b1d..7ed3a3a 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExprConstructor.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExprConstructor.h
@@ -25,21 +25,12 @@
namespace Eigen {
namespace TensorSycl {
namespace internal {
-
-template <typename Expr, typename Dims>
-struct DeviceFixedSizeTensor;
-
-template <typename Expr, typename std::ptrdiff_t... Indices>
-struct DeviceFixedSizeTensor<Expr, Eigen::Sizes<Indices...>>{
- template<typename Data>
- static EIGEN_ALWAYS_INLINE Expr instantiate(Data& dt) {return Expr(ConvertToActualTypeSycl(typename Expr::Scalar, dt), Indices...);}
-};
/// this class is used by EvalToOp in order to create an lhs expression which is
/// a pointer from an accessor on device-only buffer
template <typename PtrType, size_t N, typename... Params>
struct EvalToLHSConstructor {
PtrType expr;
- EvalToLHSConstructor(const utility::tuple::Tuple<Params...> &t) : expr(ConvertToActualTypeSycl(typename Eigen::internal::remove_all<PtrType>::type, utility::tuple::get<N>(t))) {}
+ EvalToLHSConstructor(const utility::tuple::Tuple<Params...> &t): expr((&(*(utility::tuple::get<N>(t).get_pointer())))) {}
};
/// \struct ExprConstructor is used to reconstruct the expression on the device and
@@ -54,39 +45,21 @@ struct ExprConstructor;
/// specialisation of the \ref ExprConstructor struct when the node type is
/// TensorMap
#define TENSORMAP(CVQual)\
-template <typename T, int Options_,\
+template <typename Scalar_, int Options_, int Options2_, int Options3_, int NumIndices_, typename IndexType_,\
template <class> class MakePointer_, size_t N, typename... Params>\
-struct ExprConstructor< CVQual TensorMap<T, Options_, MakeGlobalPointer>,\
-CVQual PlaceHolder<CVQual TensorMap<T, Options_, MakePointer_>, N>, Params...>{\
- typedef CVQual TensorMap<T, Options_, MakeGlobalPointer> Type;\
+struct ExprConstructor< CVQual TensorMap<Tensor<Scalar_, NumIndices_, Options_, IndexType_>, Options2_, MakeGlobalPointer>,\
+CVQual PlaceHolder<CVQual TensorMap<Tensor<Scalar_, NumIndices_, Options_, IndexType_>, Options3_, MakePointer_>, N>, Params...>{\
+ typedef CVQual TensorMap<Tensor<Scalar_, NumIndices_, Options_, IndexType_>, Options2_, MakeGlobalPointer> Type;\
Type expr;\
template <typename FuncDetector>\
ExprConstructor(FuncDetector &fd, const utility::tuple::Tuple<Params...> &t)\
- : expr(Type(ConvertToActualTypeSycl(typename Type::Scalar, utility::tuple::get<N>(t)), fd.dimensions())){}\
+ : expr(Type((&(*(utility::tuple::get<N>(t).get_pointer()))), fd.dimensions())) {}\
};
-
TENSORMAP(const)
TENSORMAP()
#undef TENSORMAP
-/// specialisation of the \ref ExprConstructor struct when the node type is
-/// TensorMap
-#define TENSORMAPFIXEDSIZE(CVQual)\
-template <typename Scalar_, typename Dimensions_, int Options_2, typename IndexType, int Options_,\
-template <class> class MakePointer_, size_t N, typename... Params>\
-struct ExprConstructor< CVQual TensorMap<TensorFixedSize<Scalar_, Dimensions_, Options_2, IndexType>, Options_, MakeGlobalPointer>,\
-CVQual PlaceHolder<CVQual TensorMap<TensorFixedSize<Scalar_, Dimensions_, Options_2, IndexType>, Options_, MakePointer_>, N>, Params...>{\
- typedef CVQual TensorMap<TensorFixedSize<Scalar_, Dimensions_, Options_2, IndexType>, Options_, MakeGlobalPointer> Type;\
- Type expr;\
- template <typename FuncDetector>\
- ExprConstructor(FuncDetector &, const utility::tuple::Tuple<Params...> &t)\
- : expr(DeviceFixedSizeTensor<Type,Dimensions_>::instantiate(utility::tuple::get<N>(t))){}\
-};
-TENSORMAPFIXEDSIZE(const)
-TENSORMAPFIXEDSIZE()
-#undef TENSORMAPFIXEDSIZE
-
#define UNARYCATEGORY(CVQual)\
template <template<class, class> class UnaryCategory, typename OP, typename OrigRHSExpr, typename RHSExpr, typename... Params>\
struct ExprConstructor<CVQual UnaryCategory<OP, OrigRHSExpr>, CVQual UnaryCategory<OP, RHSExpr>, Params...> {\
@@ -188,30 +161,8 @@ struct ExprConstructor<CVQual TensorAssignOp<OrigLHSExpr, OrigRHSExpr>, CVQual
ASSIGN(const)
ASSIGN()
#undef ASSIGN
-
-
-
-
- /// specialisation of the \ref ExprConstructor struct when the node type is
- /// const TensorAssignOp
- #define CONVERSIONEXPRCONST(CVQual)\
- template <typename OrigNestedExpr, typename ConvertType, typename NestedExpr, typename... Params>\
- struct ExprConstructor<CVQual TensorConversionOp<ConvertType, OrigNestedExpr>, CVQual TensorConversionOp<ConvertType, NestedExpr>, Params...> {\
- typedef ExprConstructor<OrigNestedExpr, NestedExpr, Params...> my_nested_type;\
- typedef CVQual TensorConversionOp<ConvertType, typename my_nested_type::Type> Type;\
- my_nested_type nestedExpr;\
- Type expr;\
- template <typename FuncDetector>\
- ExprConstructor(FuncDetector &funcD, const utility::tuple::Tuple<Params...> &t)\
- : nestedExpr(funcD.subExpr, t), expr(nestedExpr.expr) {}\
- };
-
- CONVERSIONEXPRCONST(const)
- CONVERSIONEXPRCONST()
- #undef CONVERSIONEXPRCONST
-
/// specialisation of the \ref ExprConstructor struct when the node type is
-/// TensorEvalToOp /// 0 here is the output number in the buffer
+/// TensorEvalToOp
#define EVALTO(CVQual)\
template <typename OrigExpr, typename Expr, typename... Params>\
struct ExprConstructor<CVQual TensorEvalToOp<OrigExpr, MakeGlobalPointer>, CVQual TensorEvalToOp<Expr>, Params...> {\
@@ -234,14 +185,14 @@ EVALTO()
/// TensorForcedEvalOp
#define FORCEDEVAL(CVQual)\
template <typename OrigExpr, typename DevExpr, size_t N, typename... Params>\
-struct ExprConstructor<CVQual TensorForcedEvalOp<OrigExpr>,\
+struct ExprConstructor<CVQual TensorForcedEvalOp<OrigExpr, MakeGlobalPointer>,\
CVQual PlaceHolder<CVQual TensorForcedEvalOp<DevExpr>, N>, Params...> {\
- typedef CVQual TensorMap<Tensor<typename TensorForcedEvalOp<DevExpr>::Scalar,\
- TensorForcedEvalOp<DevExpr>::NumDimensions, Eigen::internal::traits<TensorForcedEvalOp<DevExpr>>::Layout, typename TensorForcedEvalOp<DevExpr>::Index>, Eigen::internal::traits<TensorForcedEvalOp<DevExpr>>::Layout, MakeGlobalPointer> Type;\
+ typedef CVQual TensorMap<Tensor<typename TensorForcedEvalOp<DevExpr, MakeGlobalPointer>::Scalar,\
+ TensorForcedEvalOp<DevExpr, MakeGlobalPointer>::NumDimensions, 0, typename TensorForcedEvalOp<DevExpr>::Index>, 0, MakeGlobalPointer> Type;\
Type expr;\
template <typename FuncDetector>\
ExprConstructor(FuncDetector &fd, const utility::tuple::Tuple<Params...> &t)\
- : expr(Type(ConvertToActualTypeSycl(typename Type::Scalar, utility::tuple::get<N>(t)), fd.dimensions())) {}\
+ : expr(Type((&(*(utility::tuple::get<N>(t).get_pointer()))), fd.dimensions())) {}\
};
FORCEDEVAL(const)
@@ -262,130 +213,17 @@ struct ExprConstructor<CVQual TensorReductionOp<OP, Dim, OrigExpr, MakeGlobalPoi
CVQual PlaceHolder<CVQual TensorReductionOp<OP, Dim, DevExpr>, N>, Params...> {\
static const size_t NumIndices= ValueCondition< TensorReductionOp<OP, Dim, DevExpr, MakeGlobalPointer>::NumDimensions==0, 1, TensorReductionOp<OP, Dim, DevExpr, MakeGlobalPointer>::NumDimensions >::Res;\
typedef CVQual TensorMap<Tensor<typename TensorReductionOp<OP, Dim, DevExpr, MakeGlobalPointer>::Scalar,\
- NumIndices, Eigen::internal::traits<TensorReductionOp<OP, Dim, DevExpr, MakeGlobalPointer>>::Layout, typename TensorReductionOp<OP, Dim, DevExpr>::Index>, Eigen::internal::traits<TensorReductionOp<OP, Dim, DevExpr, MakeGlobalPointer>>::Layout, MakeGlobalPointer> Type;\
+ NumIndices, 0, typename TensorReductionOp<OP, Dim, DevExpr>::Index>, 0, MakeGlobalPointer> Type;\
Type expr;\
template <typename FuncDetector>\
ExprConstructor(FuncDetector &fd, const utility::tuple::Tuple<Params...> &t)\
- :expr(Type(ConvertToActualTypeSycl(typename Type::Scalar, utility::tuple::get<N>(t)), fd.dimensions())) {}\
+ : expr(Type((&(*(utility::tuple::get<N>(t).get_pointer()))), fd.dimensions())) {}\
};
SYCLREDUCTIONEXPR(const)
SYCLREDUCTIONEXPR()
#undef SYCLREDUCTIONEXPR
-
-/// specialisation of the \ref ExprConstructor struct when the node type is
-/// TensorContractionOp
-#define SYCLCONTRACTIONCONVOLUTION(CVQual, ExprNode)\
-template <typename Indices, typename OrigLhsXprType, typename OrigRhsXprType, typename LhsXprType, typename RhsXprType, size_t N, typename... Params>\
-struct ExprConstructor<CVQual ExprNode<Indices, OrigLhsXprType, OrigRhsXprType>,\
-CVQual PlaceHolder<CVQual ExprNode<Indices, LhsXprType, RhsXprType>, N>, Params...> {\
- static const size_t NumIndices= Eigen::internal::traits<ExprNode<Indices, OrigLhsXprType, OrigRhsXprType> >::NumDimensions;\
- typedef CVQual TensorMap<Tensor<typename ExprNode<Indices, OrigLhsXprType, OrigRhsXprType>::Scalar,\
- NumIndices, Eigen::internal::traits<ExprNode<Indices, OrigRhsXprType, OrigRhsXprType> >::Layout,\
- typename ExprNode<Indices, OrigRhsXprType, OrigRhsXprType>::Index>,\
- Eigen::internal::traits<ExprNode<Indices, OrigRhsXprType, OrigRhsXprType>>::Layout, MakeGlobalPointer> Type;\
- Type expr;\
- template <typename FuncDetector>\
- ExprConstructor(FuncDetector &fd, const utility::tuple::Tuple<Params...> &t)\
- :expr(Type(ConvertToActualTypeSycl(typename Type::Scalar, utility::tuple::get<N>(t)), fd.dimensions())) {}\
-};
-
-SYCLCONTRACTIONCONVOLUTION(const, TensorContractionOp)
-SYCLCONTRACTIONCONVOLUTION(, TensorContractionOp)
-SYCLCONTRACTIONCONVOLUTION(const, TensorConvolutionOp)
-SYCLCONTRACTIONCONVOLUTION(, TensorConvolutionOp)
-#undef SYCLCONTRACTIONCONVOLUTION
-
-
-
-#define SYCLSLICEOPEXPR(CVQual)\
-template<typename StartIndices, typename Sizes, typename OrigXprType, typename XprType, typename... Params>\
-struct ExprConstructor<CVQual TensorSlicingOp <StartIndices, Sizes, OrigXprType> , CVQual TensorSlicingOp<StartIndices, Sizes, XprType>, Params... >{\
- typedef ExprConstructor<OrigXprType, XprType, Params...> my_xpr_type;\
- typedef CVQual TensorSlicingOp<StartIndices, Sizes, typename my_xpr_type::Type> Type;\
- my_xpr_type xprExpr;\
- Type expr;\
- template <typename FuncDetector>\
- ExprConstructor(FuncDetector &funcD, const utility::tuple::Tuple<Params...> &t)\
- : xprExpr(funcD.xprExpr, t), expr(xprExpr.expr, funcD.startIndices(), funcD.dimensions()) {}\
-};
-
-SYCLSLICEOPEXPR(const)
-SYCLSLICEOPEXPR()
-#undef SYCLSLICEOPEXPR
-
-
-#define SYCLSLICESTRIDEOPEXPR(CVQual)\
-template<typename StartIndices, typename StopIndices, typename Strides, typename OrigXprType, typename XprType, typename... Params>\
-struct ExprConstructor<CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, OrigXprType>, CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>, Params... >{\
- typedef ExprConstructor<OrigXprType, XprType, Params...> my_xpr_type;\
- typedef CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, typename my_xpr_type::Type> Type;\
- my_xpr_type xprExpr;\
- Type expr;\
- template <typename FuncDetector>\
- ExprConstructor(FuncDetector &funcD, const utility::tuple::Tuple<Params...> &t)\
- : xprExpr(funcD.xprExpr, t), expr(xprExpr.expr, funcD.startIndices(), funcD.stopIndices(),funcD.strides()) {}\
-};
-
-SYCLSLICESTRIDEOPEXPR(const)
-SYCLSLICESTRIDEOPEXPR()
-#undef SYCLSLICESTRIDEOPEXPR
-
-#define SYCLRESHAPEANDSHUFFLEOPEXPRCONST(OPEXPR, CVQual)\
-template<typename Param, typename OrigXprType, typename XprType, typename... Params>\
-struct ExprConstructor<CVQual OPEXPR <Param, OrigXprType> , CVQual OPEXPR <Param, XprType>, Params... >{\
- typedef ExprConstructor<OrigXprType, XprType, Params...> my_xpr_type;\
- typedef CVQual OPEXPR <Param, typename my_xpr_type::Type> Type ;\
- my_xpr_type xprExpr;\
- Type expr;\
- template <typename FuncDetector>\
- ExprConstructor(FuncDetector &funcD, const utility::tuple::Tuple<Params...> &t)\
- : xprExpr(funcD.xprExpr, t), expr(xprExpr.expr, funcD.param()) {}\
-};
-
-SYCLRESHAPEANDSHUFFLEOPEXPRCONST(TensorReshapingOp, const)
-SYCLRESHAPEANDSHUFFLEOPEXPRCONST(TensorReshapingOp, )
-
-SYCLRESHAPEANDSHUFFLEOPEXPRCONST(TensorShufflingOp, const)
-SYCLRESHAPEANDSHUFFLEOPEXPRCONST(TensorShufflingOp, )
-#undef SYCLRESHAPEANDSHUFFLEOPEXPRCONST
-
-#define SYCLPADDINGOPEXPRCONST(OPEXPR, CVQual)\
-template<typename Param, typename OrigXprType, typename XprType, typename... Params>\
-struct ExprConstructor<CVQual OPEXPR <Param, OrigXprType> , CVQual OPEXPR <Param, XprType>, Params... >{\
- typedef ExprConstructor<OrigXprType, XprType, Params...> my_xpr_type;\
- typedef CVQual OPEXPR <Param, typename my_xpr_type::Type> Type ;\
- my_xpr_type xprExpr;\
- Type expr;\
- template <typename FuncDetector>\
- ExprConstructor(FuncDetector &funcD, const utility::tuple::Tuple<Params...> &t)\
- : xprExpr(funcD.xprExpr, t), expr(xprExpr.expr, funcD.param() , funcD.scalar_param()) {}\
-};
-
-SYCLPADDINGOPEXPRCONST(TensorPaddingOp, const)
-SYCLPADDINGOPEXPRCONST(TensorPaddingOp, )
-#undef SYCLPADDINGOPEXPRCONST
-
-
-// TensorChippingOp
-#define SYCLTENSORCHIPPINGOPEXPR(CVQual)\
-template<DenseIndex DimId, typename OrigXprType, typename XprType, typename... Params>\
-struct ExprConstructor<CVQual TensorChippingOp <DimId, OrigXprType> , CVQual TensorChippingOp<DimId, XprType>, Params... >{\
- typedef ExprConstructor<OrigXprType, XprType, Params...> my_xpr_type;\
- typedef CVQual TensorChippingOp<DimId, typename my_xpr_type::Type> Type;\
- my_xpr_type xprExpr;\
- Type expr;\
- template <typename FuncDetector>\
- ExprConstructor(FuncDetector &funcD, const utility::tuple::Tuple<Params...> &t)\
- : xprExpr(funcD.xprExpr, t), expr(xprExpr.expr, funcD.offset(), funcD.dimId()) {}\
-};
-
-SYCLTENSORCHIPPINGOPEXPR(const)
-SYCLTENSORCHIPPINGOPEXPR()
-#undef SYCLTENSORCHIPPINGOPEXPR
-
-
/// template deduction for \ref ExprConstructor struct
template <typename OrigExpr, typename IndexExpr, typename FuncD, typename... Params>
auto createDeviceExpression(FuncD &funcD, const utility::tuple::Tuple<Params...> &t)
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractAccessor.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractAccessor.h
index b512d43..b1da685 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractAccessor.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractAccessor.h
@@ -35,8 +35,6 @@
namespace Eigen {
namespace TensorSycl {
namespace internal {
-#define RETURN_CPP11(expr) ->decltype(expr) {return expr;}
-
/// \struct ExtractAccessor: Extract Accessor Class is used to extract the
/// accessor from a buffer.
/// Depending on the type of the leaf node we can get a read accessor or a
@@ -45,192 +43,159 @@ template <typename Evaluator>
struct ExtractAccessor;
struct AccessorConstructor{
- template<typename Arg> static inline auto getTuple(cl::sycl::handler& cgh, const Arg& eval)
- RETURN_CPP11(ExtractAccessor<Arg>::getTuple(cgh, eval))
-
- template<typename Arg1, typename Arg2> static inline auto getTuple(cl::sycl::handler& cgh, const Arg1& eval1, const Arg2& eval2)
- RETURN_CPP11(utility::tuple::append(ExtractAccessor<Arg1>::getTuple(cgh, eval1), ExtractAccessor<Arg2>::getTuple(cgh, eval2)))
-
- template<typename Arg1, typename Arg2, typename Arg3> static inline auto getTuple(cl::sycl::handler& cgh, const Arg1& eval1 , const Arg2& eval2 , const Arg3& eval3)
- RETURN_CPP11(utility::tuple::append(ExtractAccessor<Arg1>::getTuple(cgh, eval1),utility::tuple::append(ExtractAccessor<Arg2>::getTuple(cgh, eval2), ExtractAccessor<Arg3>::getTuple(cgh, eval3))))
-
- template< cl::sycl::access::mode AcM, typename Arg> static inline auto getAccessor(cl::sycl::handler& cgh, const Arg& eval)
- RETURN_CPP11(utility::tuple::make_tuple(eval.device().template get_sycl_accessor<AcM>(cgh,eval.data())))
+ template<typename Arg> static inline auto getTuple(cl::sycl::handler& cgh, Arg eval)
+ -> decltype(ExtractAccessor<Arg>::getTuple(cgh, eval)) {
+ return ExtractAccessor<Arg>::getTuple(cgh, eval);
+ }
+
+ template<typename Arg1, typename Arg2> static inline auto getTuple(cl::sycl::handler& cgh, Arg1 eval1, Arg2 eval2)
+ -> decltype(utility::tuple::append(ExtractAccessor<Arg1>::getTuple(cgh, eval1), ExtractAccessor<Arg2>::getTuple(cgh, eval2))) {
+ return utility::tuple::append(ExtractAccessor<Arg1>::getTuple(cgh, eval1), ExtractAccessor<Arg2>::getTuple(cgh, eval2));
+ }
+ template<typename Arg1, typename Arg2, typename Arg3> static inline auto getTuple(cl::sycl::handler& cgh, Arg1 eval1 , Arg2 eval2 , Arg3 eval3)
+ -> decltype(utility::tuple::append(ExtractAccessor<Arg1>::getTuple(cgh, eval1),utility::tuple::append(ExtractAccessor<Arg2>::getTuple(cgh, eval2), ExtractAccessor<Arg3>::getTuple(cgh, eval3)))) {
+ return utility::tuple::append(ExtractAccessor<Arg1>::getTuple(cgh, eval1),utility::tuple::append(ExtractAccessor<Arg2>::getTuple(cgh, eval2), ExtractAccessor<Arg3>::getTuple(cgh, eval3)));
+ }
+ template< cl::sycl::access::mode AcM, typename Arg> static inline auto getAccessor(cl::sycl::handler& cgh, Arg eval)
+ -> decltype(utility::tuple::make_tuple( eval.device().template get_sycl_accessor<AcM,
+ typename Eigen::internal::remove_all<typename Arg::CoeffReturnType>::type>(eval.dimensions().TotalSize(), cgh,eval.data()))){
+ return utility::tuple::make_tuple(eval.device().template get_sycl_accessor<AcM, typename Eigen::internal::remove_all<typename Arg::CoeffReturnType>::type>(eval.dimensions().TotalSize(), cgh,eval.data()));
+ }
};
/// specialisation of the \ref ExtractAccessor struct when the node type is
-/// TensorCwiseNullaryOp, TensorCwiseUnaryOp and TensorBroadcastingOp
-#define SYCLUNARYCATEGORYEXTACC(CVQual)\
-template <template<class, class> class UnaryCategory, typename OP, typename RHSExpr, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual UnaryCategory<OP, RHSExpr>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual UnaryCategory<OP, RHSExpr>, Dev>& eval)\
-RETURN_CPP11(AccessorConstructor::getTuple(cgh, eval.impl()))\
+/// const TensorCwiseNullaryOp, const TensorCwiseUnaryOp and const TensorBroadcastingOp
+template <template<class, class> class UnaryCategory, typename OP, typename RHSExpr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<const UnaryCategory<OP, RHSExpr>, Dev> > {
+ static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<const UnaryCategory<OP, RHSExpr>, Dev> eval)
+ -> decltype(AccessorConstructor::getTuple(cgh, eval.impl())){
+ return AccessorConstructor::getTuple(cgh, eval.impl());
+ }
};
-SYCLUNARYCATEGORYEXTACC(const)
-SYCLUNARYCATEGORYEXTACC()
-#undef SYCLUNARYCATEGORYEXTACC
-
-
-/// specialisation of the \ref ExtractAccessor struct when the node type is TensorCwiseBinaryOp
-#define SYCLBINARYCATEGORYEXTACC(CVQual)\
-template <template<class, class, class> class BinaryCategory, typename OP, typename LHSExpr, typename RHSExpr, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual BinaryCategory<OP, LHSExpr, RHSExpr>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual BinaryCategory<OP, LHSExpr, RHSExpr>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::getTuple(cgh, eval.left_impl(), eval.right_impl()))\
+/// specialisation of the \ref ExtractAccessor struct when the node type is TensorCwiseNullaryOp, TensorCwiseUnaryOp and TensorBroadcastingOp
+template <template<class, class> class UnaryCategory, typename OP, typename RHSExpr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<UnaryCategory<OP, RHSExpr>, Dev> >
+: ExtractAccessor<TensorEvaluator<const UnaryCategory<OP, RHSExpr>, Dev> > {};
+
+/// specialisation of the \ref ExtractAccessor struct when the node type is const TensorCwiseBinaryOp
+template <template<class, class, class> class BinaryCategory, typename OP, typename LHSExpr, typename RHSExpr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<const BinaryCategory<OP, LHSExpr, RHSExpr>, Dev> > {
+ static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<const BinaryCategory<OP, LHSExpr, RHSExpr>, Dev> eval)
+ -> decltype(AccessorConstructor::getTuple(cgh, eval.left_impl(), eval.right_impl())){
+ return AccessorConstructor::getTuple(cgh, eval.left_impl(), eval.right_impl());
+ }
};
-
-SYCLBINARYCATEGORYEXTACC(const)
-SYCLBINARYCATEGORYEXTACC()
-#undef SYCLBINARYCATEGORYEXTACC
+/// specialisation of the \ref ExtractAccessor struct when the node type is TensorCwiseBinaryOp
+template <template<class, class, class> class BinaryCategory, typename OP, typename LHSExpr, typename RHSExpr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<BinaryCategory<OP, LHSExpr, RHSExpr>, Dev> >
+: ExtractAccessor<TensorEvaluator<const BinaryCategory<OP, LHSExpr, RHSExpr>, Dev> >{};
/// specialisation of the \ref ExtractAccessor struct when the node type is
/// const TensorCwiseTernaryOp
-#define SYCLTERNARYCATEGORYEXTACC(CVQual)\
-template <template<class, class, class, class> class TernaryCategory, typename OP, typename Arg1Expr, typename Arg2Expr, typename Arg3Expr, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::getTuple(cgh, eval.arg1Impl(), eval.arg2Impl(), eval.arg3Impl()))\
+template <template<class, class, class, class> class TernaryCategory, typename OP, typename Arg1Expr, typename Arg2Expr, typename Arg3Expr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<const TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev> > {
+ static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<const TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev> eval)
+ -> decltype(AccessorConstructor::getTuple(cgh, eval.arg1Impl(), eval.arg2Impl(), eval.arg3Impl())){
+ return AccessorConstructor::getTuple(cgh, eval.arg1Impl(), eval.arg2Impl(), eval.arg3Impl());
+ }
};
-SYCLTERNARYCATEGORYEXTACC(const)
-SYCLTERNARYCATEGORYEXTACC()
-#undef SYCLTERNARYCATEGORYEXTACC
+/// specialisation of the \ref ExtractAccessor struct when the node type is TensorCwiseTernaryOp
+template <template<class, class, class, class> class TernaryCategory, typename OP, typename Arg1Expr, typename Arg2Expr, typename Arg3Expr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev> >
+: ExtractAccessor<TensorEvaluator<const TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev> >{};
+/// specialisation of the \ref ExtractAccessor struct when the node type is
+/// const TensorCwiseSelectOp. This is a special case where there is no OP
+template <typename IfExpr, typename ThenExpr, typename ElseExpr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<const TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev> > {
+ static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<const TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev> eval)
+ -> decltype(AccessorConstructor::getTuple(cgh, eval.cond_impl(), eval.then_impl(), eval.else_impl())){
+ return AccessorConstructor::getTuple(cgh, eval.cond_impl(), eval.then_impl(), eval.else_impl());
+ }
+};
/// specialisation of the \ref ExtractAccessor struct when the node type is
/// TensorCwiseSelectOp. This is a special case where there is no OP
-#define SYCLSELECTOPEXTACC(CVQual)\
-template <typename IfExpr, typename ThenExpr, typename ElseExpr, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::getTuple(cgh, eval.cond_impl(), eval.then_impl(), eval.else_impl()))\
+template <typename IfExpr, typename ThenExpr, typename ElseExpr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev> >
+: ExtractAccessor<TensorEvaluator<const TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev> >{};
+
+/// specialisation of the \ref ExtractAccessor struct when the node type is const TensorAssignOp
+template <typename LHSExpr, typename RHSExpr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<const TensorAssignOp<LHSExpr, RHSExpr>, Dev> > {
+ static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<const TensorAssignOp<LHSExpr, RHSExpr>, Dev> eval)
+ -> decltype(AccessorConstructor::getTuple(cgh, eval.left_impl(), eval.right_impl())){
+ return AccessorConstructor::getTuple(cgh, eval.left_impl(), eval.right_impl());
+ }
};
-SYCLSELECTOPEXTACC(const)
-SYCLSELECTOPEXTACC()
-#undef SYCLSELECTOPEXTACC
-
/// specialisation of the \ref ExtractAccessor struct when the node type is TensorAssignOp
-#define SYCLTENSORASSIGNOPEXTACC(CVQual)\
-template <typename LHSExpr, typename RHSExpr, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual TensorAssignOp<LHSExpr, RHSExpr>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual TensorAssignOp<LHSExpr, RHSExpr>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::getTuple(cgh, eval.left_impl(), eval.right_impl()))\
-};
-
- SYCLTENSORASSIGNOPEXTACC(const)
- SYCLTENSORASSIGNOPEXTACC()
- #undef SYCLTENSORASSIGNOPEXTACC
+template <typename LHSExpr, typename RHSExpr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<TensorAssignOp<LHSExpr, RHSExpr>, Dev> >
+: ExtractAccessor<TensorEvaluator<const TensorAssignOp<LHSExpr, RHSExpr>, Dev> >{};
/// specialisation of the \ref ExtractAccessor struct when the node type is const TensorMap
#define TENSORMAPEXPR(CVQual, ACCType)\
template <typename PlainObjectType, int Options_, typename Dev>\
struct ExtractAccessor<TensorEvaluator<CVQual TensorMap<PlainObjectType, Options_>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh,const TensorEvaluator<CVQual TensorMap<PlainObjectType, Options_>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::template getAccessor<ACCType>(cgh, eval))\
+ static inline auto getTuple(cl::sycl::handler& cgh,const TensorEvaluator<CVQual TensorMap<PlainObjectType, Options_>, Dev> eval)\
+ -> decltype(AccessorConstructor::template getAccessor<ACCType>(cgh, eval)){\
+ return AccessorConstructor::template getAccessor<ACCType>(cgh, eval);\
+ }\
};
-
TENSORMAPEXPR(const, cl::sycl::access::mode::read)
TENSORMAPEXPR(, cl::sycl::access::mode::read_write)
#undef TENSORMAPEXPR
-/// specialisation of the \ref ExtractAccessor struct when the node type is TensorForcedEvalOp
-#define SYCLFORCEDEVALEXTACC(CVQual)\
-template <typename Expr, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual TensorForcedEvalOp<Expr>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual TensorForcedEvalOp<Expr>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::template getAccessor<cl::sycl::access::mode::read>(cgh, eval))\
+/// specialisation of the \ref ExtractAccessor struct when the node type is const TensorForcedEvalOp
+template <typename Expr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<const TensorForcedEvalOp<Expr>, Dev> > {
+ static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<const TensorForcedEvalOp<Expr>, Dev> eval)
+ -> decltype(AccessorConstructor::template getAccessor<cl::sycl::access::mode::read>(cgh, eval)){
+ return AccessorConstructor::template getAccessor<cl::sycl::access::mode::read>(cgh, eval);
+ }
};
-SYCLFORCEDEVALEXTACC(const)
-SYCLFORCEDEVALEXTACC()
-#undef SYCLFORCEDEVALEXTACC
-
+/// specialisation of the \ref ExtractAccessor struct when the node type is TensorForcedEvalOp
+template <typename Expr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<TensorForcedEvalOp<Expr>, Dev> >
+: ExtractAccessor<TensorEvaluator<const TensorForcedEvalOp<Expr>, Dev> >{};
+
+/// specialisation of the \ref ExtractAccessor struct when the node type is const TensorEvalToOp
+template <typename Expr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<const TensorEvalToOp<Expr>, Dev> > {
+ static inline auto getTuple(cl::sycl::handler& cgh,const TensorEvaluator<const TensorEvalToOp<Expr>, Dev> eval)
+ -> decltype(utility::tuple::append(AccessorConstructor::template getAccessor<cl::sycl::access::mode::write>(cgh, eval), AccessorConstructor::getTuple(cgh, eval.impl()))){
+ return utility::tuple::append(AccessorConstructor::template getAccessor<cl::sycl::access::mode::write>(cgh, eval), AccessorConstructor::getTuple(cgh, eval.impl()));
+ }
+};
/// specialisation of the \ref ExtractAccessor struct when the node type is TensorEvalToOp
-#define SYCLEVALTOEXTACC(CVQual)\
-template <typename Expr, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual TensorEvalToOp<Expr>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh,const TensorEvaluator<CVQual TensorEvalToOp<Expr>, Dev>& eval)\
- RETURN_CPP11(utility::tuple::append(AccessorConstructor::template getAccessor<cl::sycl::access::mode::write>(cgh, eval), AccessorConstructor::getTuple(cgh, eval.impl())))\
+template <typename Expr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<TensorEvalToOp<Expr>, Dev> >
+: ExtractAccessor<TensorEvaluator<const TensorEvalToOp<Expr>, Dev> >{};
+
+/// specialisation of the \ref ExtractAccessor struct when the node type is const TensorReductionOp
+template <typename OP, typename Dim, typename Expr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<const TensorReductionOp<OP, Dim, Expr>, Dev> > {
+ static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<const TensorReductionOp<OP, Dim, Expr>, Dev> eval)
+ -> decltype(AccessorConstructor::template getAccessor<cl::sycl::access::mode::read>(cgh, eval)){
+ return AccessorConstructor::template getAccessor<cl::sycl::access::mode::read>(cgh, eval);
+ }
};
-SYCLEVALTOEXTACC(const)
-SYCLEVALTOEXTACC()
-#undef SYCLEVALTOEXTACC
-
/// specialisation of the \ref ExtractAccessor struct when the node type is TensorReductionOp
-#define SYCLREDUCTIONEXTACC(CVQual)\
-template <typename OP, typename Dim, typename Expr, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual TensorReductionOp<OP, Dim, Expr>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual TensorReductionOp<OP, Dim, Expr>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::template getAccessor<cl::sycl::access::mode::read>(cgh, eval))\
-};
-
-SYCLREDUCTIONEXTACC(const)
-SYCLREDUCTIONEXTACC()
-#undef SYCLREDUCTIONEXTACC
-
-/// specialisation of the \ref ExtractAccessor struct when the node type is TensorContractionOp and TensorConvolutionOp
-#define SYCLCONTRACTIONCONVOLUTIONEXTACC(CVQual, ExprNode)\
-template<typename Indices, typename LhsXprType, typename RhsXprType, typename Dev>\
- struct ExtractAccessor<TensorEvaluator<CVQual ExprNode<Indices, LhsXprType, RhsXprType>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual ExprNode<Indices, LhsXprType, RhsXprType>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::template getAccessor<cl::sycl::access::mode::read>(cgh, eval))\
-};
-
-SYCLCONTRACTIONCONVOLUTIONEXTACC(const,TensorContractionOp)
-SYCLCONTRACTIONCONVOLUTIONEXTACC(,TensorContractionOp)
-SYCLCONTRACTIONCONVOLUTIONEXTACC(const,TensorConvolutionOp)
-SYCLCONTRACTIONCONVOLUTIONEXTACC(,TensorConvolutionOp)
-#undef SYCLCONTRACTIONCONVOLUTIONEXTACC
-
-
-/// specialisation of the \ref ExtractAccessor struct when the node type is
-/// const TensorSlicingOp.
-#define SYCLSLICEOPEXTACC(CVQual)\
-template <typename StartIndices, typename Sizes, typename XprType, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual TensorSlicingOp<StartIndices, Sizes, XprType>, Dev> > {\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual TensorSlicingOp<StartIndices, Sizes, XprType>, Dev>& eval)\
- RETURN_CPP11( AccessorConstructor::getTuple(cgh, eval.impl()))\
-};
-
-SYCLSLICEOPEXTACC(const)
-SYCLSLICEOPEXTACC()
-#undef SYCLSLICEOPEXTACC
-// specialisation of the \ref ExtractAccessor struct when the node type is
-/// TensorStridingSlicingOp.
-#define SYCLSLICESTRIDEOPEXTACC(CVQual)\
-template<typename StartIndices, typename StopIndices, typename Strides, typename XprType, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>, Dev> >{\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::getTuple(cgh, eval.impl()))\
-};
-
-SYCLSLICESTRIDEOPEXTACC(const)
-SYCLSLICESTRIDEOPEXTACC()
-#undef SYCLSLICESTRIDEOPEXTACC
-
-// specialisation of the \ref ExtractAccessor struct when the node type is
-/// TensorChippingOp.
-#define SYCLTENSORCHIPPINGOPEXTACC(CVQual)\
-template<DenseIndex DimId, typename XprType, typename Dev>\
-struct ExtractAccessor<TensorEvaluator<CVQual TensorChippingOp<DimId, XprType>, Dev> >{\
- static inline auto getTuple(cl::sycl::handler& cgh, const TensorEvaluator<CVQual TensorChippingOp<DimId, XprType>, Dev>& eval)\
- RETURN_CPP11(AccessorConstructor::getTuple(cgh, eval.impl()))\
-};
-
-SYCLTENSORCHIPPINGOPEXTACC(const)
-SYCLTENSORCHIPPINGOPEXTACC()
-#undef SYCLTENSORCHIPPINGOPEXTACC
-
+template <typename OP, typename Dim, typename Expr, typename Dev>
+struct ExtractAccessor<TensorEvaluator<TensorReductionOp<OP, Dim, Expr>, Dev> >
+: ExtractAccessor<TensorEvaluator<const TensorReductionOp<OP, Dim, Expr>, Dev> >{};
/// template deduction for \ref ExtractAccessor
template <typename Evaluator>
-auto createTupleOfAccessors(cl::sycl::handler& cgh, const Evaluator& eval)
--> decltype(ExtractAccessor<Evaluator>::getTuple(cgh, eval)) {
- return ExtractAccessor<Evaluator>::getTuple(cgh, eval);
+auto createTupleOfAccessors(cl::sycl::handler& cgh, const Evaluator& expr)
+-> decltype(ExtractAccessor<Evaluator>::getTuple(cgh, expr)) {
+ return ExtractAccessor<Evaluator>::getTuple(cgh, expr);
}
} /// namespace TensorSycl
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractFunctors.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractFunctors.h
index ee02018..4271253 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractFunctors.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclExtractFunctors.h
@@ -36,277 +36,135 @@ namespace internal {
template <typename Evaluator> struct FunctorExtractor{
typedef typename Evaluator::Dimensions Dimensions;
const Dimensions m_dimensions;
- EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
+ const Dimensions& dimensions() const { return m_dimensions; }
FunctorExtractor(const Evaluator& expr)
: m_dimensions(expr.dimensions()) {}
};
-/// specialisation of the \ref FunctorExtractor struct when the node type does not require anything
-///TensorConversionOp
-#define SYCLEXTRFUNCCONVERSION(ExprNode, CVQual)\
-template <typename ArgType1, typename ArgType2, typename Dev>\
-struct FunctorExtractor<TensorEvaluator<CVQual ExprNode<ArgType1, ArgType2>, Dev> > {\
- FunctorExtractor<TensorEvaluator<ArgType2, Dev> > subExpr;\
- FunctorExtractor(const TensorEvaluator<CVQual ExprNode<ArgType1, ArgType2>, Dev>& expr)\
- : subExpr(expr.impl()) {}\
+/// specialisation of the \ref FunctorExtractor struct when the node type is
+/// const TensorCwiseNullaryOp, const TensorCwiseUnaryOp, and const TensorBroadcastingOp
+template <template <class, class> class UnaryCategory, typename OP, typename RHSExpr, typename Dev>
+struct FunctorExtractor<TensorEvaluator<const UnaryCategory<OP, RHSExpr>, Dev> > {
+ FunctorExtractor<TensorEvaluator<RHSExpr, Dev> > rhsExpr;
+ OP func;
+ FunctorExtractor(const TensorEvaluator<const UnaryCategory<OP, RHSExpr>, Dev>& expr)
+ : rhsExpr(expr.impl()), func(expr.functor()) {}
};
+/// specialisation of the \ref FunctorExtractor struct when the node type is
+/// TensorCwiseNullaryOp, TensorCwiseUnaryOp, and TensorBroadcastingOp
+template <template <class, class> class UnaryCategory, typename OP, typename RHSExpr, typename Dev>
+struct FunctorExtractor<TensorEvaluator<UnaryCategory<OP, RHSExpr>, Dev> >
+: FunctorExtractor<TensorEvaluator<const UnaryCategory<OP, RHSExpr>, Dev> >{};
-SYCLEXTRFUNCCONVERSION(TensorConversionOp, const)
-SYCLEXTRFUNCCONVERSION(TensorConversionOp, )
-#undef SYCLEXTRFUNCCONVERSION
-
-#define SYCLEXTRTENSORMAPFIXEDSIZE(CVQual)\
-template <typename Scalar_, typename Dimensions_, int Options_2, typename IndexType, int Options_, template <class> class MakePointer_, typename Dev>\
-struct FunctorExtractor< TensorEvaluator <CVQual TensorMap<TensorFixedSize<Scalar_, Dimensions_, Options_2, IndexType>, Options_, MakePointer_> , Dev> >{\
-FunctorExtractor(const TensorEvaluator <CVQual TensorMap<TensorFixedSize<Scalar_, Dimensions_, Options_2, IndexType>, Options_, MakePointer_> , Dev>& ){}\
+/// specialisation of the \ref FunctorExtractor struct when the node type is
+/// const TensorCwiseBinaryOp
+template <template<class, class, class> class BinaryCategory, typename OP, typename LHSExpr, typename RHSExpr, typename Dev>
+struct FunctorExtractor<TensorEvaluator<const BinaryCategory<OP, LHSExpr, RHSExpr>, Dev> > {
+ FunctorExtractor<TensorEvaluator<LHSExpr, Dev> > lhsExpr;
+ FunctorExtractor<TensorEvaluator<RHSExpr, Dev> > rhsExpr;
+ OP func;
+ FunctorExtractor(const TensorEvaluator<const BinaryCategory<OP, LHSExpr, RHSExpr>, Dev>& expr)
+ : lhsExpr(expr.left_impl()),rhsExpr(expr.right_impl()),func(expr.functor()) {}
};
-SYCLEXTRTENSORMAPFIXEDSIZE(const)
-SYCLEXTRTENSORMAPFIXEDSIZE()
-#undef SYCLEXTRTENSORMAPFIXEDSIZE
+/// specialisation of the \ref FunctorExtractor struct when the node type is
+/// const TensorCwiseBinaryOp
+template <template <class, class, class> class BinaryCategory, typename OP, typename LHSExpr, typename RHSExpr, typename Dev>
+struct FunctorExtractor<TensorEvaluator<BinaryCategory<OP, LHSExpr, RHSExpr>, Dev> >
+: FunctorExtractor<TensorEvaluator<const BinaryCategory<OP, LHSExpr, RHSExpr>, Dev> >{};
/// specialisation of the \ref FunctorExtractor struct when the node type is
-/// TensorCwiseNullaryOp, TensorCwiseUnaryOp, and TensorBroadcastingOp
-#define SYCLEXTRFUNCUNARY(CVQual)\
-template <template <class, class> class UnaryCategory, typename OP, typename RHSExpr, typename Dev>\
-struct FunctorExtractor<TensorEvaluator<CVQual UnaryCategory<OP, RHSExpr>, Dev> > {\
- FunctorExtractor<TensorEvaluator<RHSExpr, Dev> > rhsExpr;\
- const OP func;\
- FunctorExtractor(const TensorEvaluator<CVQual UnaryCategory<OP, RHSExpr>, Dev>& expr)\
- : rhsExpr(expr.impl()), func(expr.functor()) {}\
+/// const TensorCwiseTernaryOp
+template <template <class, class, class, class> class TernaryCategory, typename OP, typename Arg1Expr, typename Arg2Expr, typename Arg3Expr,typename Dev>
+struct FunctorExtractor<TensorEvaluator<const TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev> > {
+ FunctorExtractor<TensorEvaluator<Arg1Expr, Dev> > arg1Expr;
+ FunctorExtractor<TensorEvaluator<Arg2Expr, Dev> > arg2Expr;
+ FunctorExtractor<TensorEvaluator<Arg3Expr, Dev> > arg3Expr;
+ OP func;
+ FunctorExtractor(const TensorEvaluator<const TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev>& expr)
+ : arg1Expr(expr.arg1Impl()), arg2Expr(expr.arg2Impl()), arg3Expr(expr.arg3Impl()), func(expr.functor()) {}
};
-SYCLEXTRFUNCUNARY(const)
-SYCLEXTRFUNCUNARY()
-#undef SYCLEXTRFUNCUNARY
+/// specialisation of the \ref FunctorExtractor struct when the node type is
+/// TensorCwiseTernaryOp
+template <template <class, class, class, class> class TernaryCategory, typename OP, typename Arg1Expr, typename Arg2Expr, typename Arg3Expr, typename Dev>
+struct FunctorExtractor<TensorEvaluator< TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev> >
+:FunctorExtractor<TensorEvaluator<const TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev> >{};
/// specialisation of the \ref FunctorExtractor struct when the node type is
-/// TensorCwiseBinaryOp
-#define SYCLEXTRFUNCBIINARY(CVQual)\
-template <template<class, class, class> class BinaryCategory, typename OP, typename LHSExpr, typename RHSExpr, typename Dev>\
-struct FunctorExtractor<TensorEvaluator<CVQual BinaryCategory<OP, LHSExpr, RHSExpr>, Dev> > {\
- FunctorExtractor<TensorEvaluator<LHSExpr, Dev> > lhsExpr;\
- FunctorExtractor<TensorEvaluator<RHSExpr, Dev> > rhsExpr;\
- const OP func;\
- FunctorExtractor(const TensorEvaluator<CVQual BinaryCategory<OP, LHSExpr, RHSExpr>, Dev>& expr)\
- : lhsExpr(expr.left_impl()),rhsExpr(expr.right_impl()),func(expr.functor()) {}\
+/// const TensorCwiseSelectOp. This is an specialisation without OP so it has to be separated.
+template <typename IfExpr, typename ThenExpr, typename ElseExpr, typename Dev>
+struct FunctorExtractor< TensorEvaluator<const TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev> > {
+ FunctorExtractor<TensorEvaluator<IfExpr, Dev> > ifExpr;
+ FunctorExtractor<TensorEvaluator<ThenExpr, Dev> > thenExpr;
+ FunctorExtractor<TensorEvaluator<ElseExpr, Dev> > elseExpr;
+ FunctorExtractor(const TensorEvaluator<const TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev>& expr)
+ : ifExpr(expr.cond_impl()), thenExpr(expr.then_impl()), elseExpr(expr.else_impl()) {}
};
-SYCLEXTRFUNCBIINARY(const)
-SYCLEXTRFUNCBIINARY()
-#undef SYCLEXTRFUNCBIINARY
+/// specialisation of the \ref FunctorExtractor struct when the node type is
+/// TensorCwiseSelectOp. This is an specialisation without OP so it has to be separated
+template <typename IfExpr, typename ThenExpr, typename ElseExpr, typename Dev>
+struct FunctorExtractor<TensorEvaluator<TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev> >
+:FunctorExtractor< TensorEvaluator<const TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev> > {};
-/// specialisation of the \ref FunctorExtractor struct when the node type is TensorCwiseTernaryOp
-#define SYCLEXTRFUNCTERNARY(CVQual)\
-template <template <class, class, class, class> class TernaryCategory, typename OP, typename Arg1Expr, typename Arg2Expr, typename Arg3Expr,typename Dev>\
-struct FunctorExtractor<TensorEvaluator<CVQual TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev> > {\
- FunctorExtractor<TensorEvaluator<Arg1Expr, Dev> > arg1Expr;\
- FunctorExtractor<TensorEvaluator<Arg2Expr, Dev> > arg2Expr;\
- FunctorExtractor<TensorEvaluator<Arg3Expr, Dev> > arg3Expr;\
- const OP func;\
- FunctorExtractor(const TensorEvaluator<CVQual TernaryCategory<OP, Arg1Expr, Arg2Expr, Arg3Expr>, Dev>& expr)\
- : arg1Expr(expr.arg1Impl()), arg2Expr(expr.arg2Impl()), arg3Expr(expr.arg3Impl()), func(expr.functor()) {}\
+/// specialisation of the \ref FunctorExtractor struct when the node type is
+/// const TensorAssignOp. This is an specialisation without OP so it has to be separated.
+template <typename LHSExpr, typename RHSExpr, typename Dev>
+struct FunctorExtractor<TensorEvaluator<const TensorAssignOp<LHSExpr, RHSExpr>, Dev> > {
+ FunctorExtractor<TensorEvaluator<LHSExpr, Dev> > lhsExpr;
+ FunctorExtractor<TensorEvaluator<RHSExpr, Dev> > rhsExpr;
+ FunctorExtractor(const TensorEvaluator<const TensorAssignOp<LHSExpr, RHSExpr>, Dev>& expr)
+ : lhsExpr(expr.left_impl()), rhsExpr(expr.right_impl()) {}
};
-SYCLEXTRFUNCTERNARY(const)
-SYCLEXTRFUNCTERNARY()
-#undef SYCLEXTRFUNCTERNARY
-
/// specialisation of the \ref FunctorExtractor struct when the node type is
-/// TensorCwiseSelectOp. This is an specialisation without OP so it has to be separated.
-#define SYCLEXTRFUNCSELECTOP(CVQual)\
-template <typename IfExpr, typename ThenExpr, typename ElseExpr, typename Dev>\
-struct FunctorExtractor< TensorEvaluator<CVQual TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev> > {\
- FunctorExtractor<TensorEvaluator<IfExpr, Dev> > ifExpr;\
- FunctorExtractor<TensorEvaluator<ThenExpr, Dev> > thenExpr;\
- FunctorExtractor<TensorEvaluator<ElseExpr, Dev> > elseExpr;\
- FunctorExtractor(const TensorEvaluator<CVQual TensorSelectOp<IfExpr, ThenExpr, ElseExpr>, Dev>& expr)\
- : ifExpr(expr.cond_impl()), thenExpr(expr.then_impl()), elseExpr(expr.else_impl()) {}\
-};
+/// TensorAssignOp. This is an specialisation without OP so it has to be separated.
+template <typename LHSExpr, typename RHSExpr, typename Dev>
+struct FunctorExtractor<TensorEvaluator<TensorAssignOp<LHSExpr, RHSExpr>, Dev> >
+:FunctorExtractor<TensorEvaluator<const TensorAssignOp<LHSExpr, RHSExpr>, Dev> >{};
-SYCLEXTRFUNCSELECTOP(const)
-SYCLEXTRFUNCSELECTOP()
-#undef SYCLEXTRFUNCSELECTOP
/// specialisation of the \ref FunctorExtractor struct when the node type is
-/// const TensorAssignOp. This is an specialisation without OP so it has to be separated.
-#define SYCLEXTRFUNCASSIGNOP(CVQual)\
-template <typename LHSExpr, typename RHSExpr, typename Dev>\
-struct FunctorExtractor<TensorEvaluator<CVQual TensorAssignOp<LHSExpr, RHSExpr>, Dev> > {\
- FunctorExtractor<TensorEvaluator<LHSExpr, Dev> > lhsExpr;\
- FunctorExtractor<TensorEvaluator<RHSExpr, Dev> > rhsExpr;\
- FunctorExtractor(const TensorEvaluator<CVQual TensorAssignOp<LHSExpr, RHSExpr>, Dev>& expr)\
- : lhsExpr(expr.left_impl()), rhsExpr(expr.right_impl()) {}\
+/// const TensorEvalToOp, This is an specialisation without OP so it has to be separated.
+template <typename RHSExpr, typename Dev>
+struct FunctorExtractor<TensorEvaluator<const TensorEvalToOp<RHSExpr>, Dev> > {
+ FunctorExtractor<TensorEvaluator<RHSExpr, Dev> > rhsExpr;
+ FunctorExtractor(const TensorEvaluator<const TensorEvalToOp<RHSExpr>, Dev>& expr)
+ : rhsExpr(expr.impl()) {}
};
-SYCLEXTRFUNCASSIGNOP(const)
-SYCLEXTRFUNCASSIGNOP()
-#undef SYCLEXTRFUNCASSIGNOP
/// specialisation of the \ref FunctorExtractor struct when the node type is
-/// TensorEvalToOp, This is an specialisation without OP so it has to be separated.
-#define SYCLEXTRFUNCEVALTOOP(CVQual)\
-template <typename RHSExpr, typename Dev>\
-struct FunctorExtractor<TensorEvaluator<CVQual TensorEvalToOp<RHSExpr>, Dev> > {\
- FunctorExtractor<TensorEvaluator<RHSExpr, Dev> > rhsExpr;\
- FunctorExtractor(const TensorEvaluator<CVQual TensorEvalToOp<RHSExpr>, Dev>& expr)\
- : rhsExpr(expr.impl()) {}\
-};
-
-SYCLEXTRFUNCEVALTOOP(const)
-SYCLEXTRFUNCEVALTOOP()
-#undef SYCLEXTRFUNCEVALTOOP
+/// TensorEvalToOp. This is a specialisation without OP so it has to be separated.
+template <typename RHSExpr, typename Dev>
+struct FunctorExtractor<TensorEvaluator<TensorEvalToOp<RHSExpr>, Dev> >
+: FunctorExtractor<TensorEvaluator<const TensorEvalToOp<RHSExpr>, Dev> > {};
template<typename Dim, size_t NumOutputDim> struct DimConstr {
template<typename InDim>
- static EIGEN_STRONG_INLINE Dim getDim(InDim dims ) {return dims;}
+ static inline Dim getDim(InDim dims ) {return dims;}
};
template<typename Dim> struct DimConstr<Dim, 0> {
template<typename InDim>
- static EIGEN_STRONG_INLINE Dim getDim(InDim dims ) {return Dim(static_cast<Dim>(dims.TotalSize()));}
-};
-
-#define SYCLEXTRFUNCREDUCTIONOP(CVQual)\
-template<typename Op, typename Dims, typename ArgType, template <class> class MakePointer_, typename Device>\
-struct FunctorExtractor<TensorEvaluator<CVQual TensorReductionOp<Op, Dims, ArgType, MakePointer_>, Device>>{\
- typedef TensorEvaluator<CVQual TensorReductionOp<Op, Dims, ArgType, MakePointer_>, Device> Evaluator;\
- typedef typename Eigen::internal::conditional<Evaluator::NumOutputDims==0, DSizes<typename Evaluator::Index, 1>, typename Evaluator::Dimensions >::type Dimensions;\
- const Dimensions m_dimensions;\
- EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }\
- FunctorExtractor(const TensorEvaluator<CVQual TensorReductionOp<Op, Dims, ArgType, MakePointer_>, Device>& expr)\
- : m_dimensions(DimConstr<Dimensions, Evaluator::NumOutputDims>::getDim(expr.dimensions())) {}\
-};
-
-
-SYCLEXTRFUNCREDUCTIONOP(const)
-SYCLEXTRFUNCREDUCTIONOP()
-#undef SYCLEXTRFUNCREDUCTIONOP
-
-#define SYCLEXTRFUNCCONTRACTCONVOLUTIONOP(CVQual, ExprNode)\
-template<typename Indices, typename LhsXprType, typename RhsXprType, typename Device>\
-struct FunctorExtractor<TensorEvaluator<CVQual ExprNode<Indices, LhsXprType, RhsXprType>, Device>>{\
- typedef TensorEvaluator<CVQual ExprNode<Indices, LhsXprType, RhsXprType>, Device> Evaluator;\
- typedef typename Evaluator::Dimensions Dimensions;\
- const Dimensions m_dimensions;\
- EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }\
- FunctorExtractor(const TensorEvaluator<CVQual ExprNode<Indices, LhsXprType, RhsXprType>, Device>& expr)\
- : m_dimensions(expr.dimensions()) {}\
+ static inline Dim getDim(InDim dims ) {return Dim(dims.TotalSize());}
};
-
-SYCLEXTRFUNCCONTRACTCONVOLUTIONOP(const,TensorContractionOp)
-SYCLEXTRFUNCCONTRACTCONVOLUTIONOP(,TensorContractionOp)
-SYCLEXTRFUNCCONTRACTCONVOLUTIONOP(const,TensorConvolutionOp)
-SYCLEXTRFUNCCONTRACTCONVOLUTIONOP(,TensorConvolutionOp)
-#undef SYCLEXTRFUNCCONTRACTCONVOLUTIONOP
-
-/// specialisation of the \ref FunctorExtractor struct when the node type is
-/// const TensorSlicingOp. This is an specialisation without OP so it has to be separated.
-#define SYCLEXTRFUNCTSLICEOP(CVQual)\
-template <typename StartIndices, typename Sizes, typename XprType, typename Dev>\
-struct FunctorExtractor<TensorEvaluator<CVQual TensorSlicingOp<StartIndices, Sizes, XprType>, Dev> > {\
- FunctorExtractor<TensorEvaluator<XprType, Dev> > xprExpr;\
- const StartIndices m_offsets;\
- const Sizes m_dimensions;\
- FunctorExtractor(const TensorEvaluator<CVQual TensorSlicingOp<StartIndices, Sizes, XprType>, Dev>& expr)\
- : xprExpr(expr.impl()), m_offsets(expr.startIndices()), m_dimensions(expr.dimensions()) {}\
- EIGEN_STRONG_INLINE const StartIndices& startIndices() const {return m_offsets;}\
- EIGEN_STRONG_INLINE const Sizes& dimensions() const {return m_dimensions;}\
-};
-
-SYCLEXTRFUNCTSLICEOP(const)
-SYCLEXTRFUNCTSLICEOP()
-#undef SYCLEXTRFUNCTSLICEOP
-
-#define SYCLEXTRFUNCTSLICESTRIDEOP(CVQual)\
-template<typename StartIndices, typename StopIndices, typename Strides, typename XprType, typename Dev>\
-struct FunctorExtractor<TensorEvaluator<CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>, Dev> >{\
- FunctorExtractor<TensorEvaluator<XprType, Dev> > xprExpr;\
- const StartIndices m_startIndices;\
- const StopIndices m_stopIndices;\
- const Strides m_strides;\
- FunctorExtractor(const TensorEvaluator<CVQual TensorStridingSlicingOp<StartIndices, StopIndices,Strides, XprType>, Dev>& expr)\
- : xprExpr(expr.impl()), m_startIndices(expr.exprStartIndices()), m_stopIndices(expr.exprStopIndices()), m_strides(expr.strides()) {}\
- EIGEN_STRONG_INLINE const StartIndices& startIndices() const { return m_startIndices; }\
- EIGEN_STRONG_INLINE const StartIndices& stopIndices() const { return m_stopIndices; }\
- EIGEN_STRONG_INLINE const StartIndices& strides() const { return m_strides; }\
-};
-
-SYCLEXTRFUNCTSLICESTRIDEOP(const)
-SYCLEXTRFUNCTSLICESTRIDEOP()
-#undef SYCLEXTRFUNCTSLICESTRIDEOP
-
-// Had to separate reshapeOP otherwise it will be mistaken by UnaryCategory
-#define SYCLRESHAPEANDSHUFFLEOPFUNCEXT(OPEXPR, FUNCCALL, CVQual)\
-template<typename Param, typename XprType, typename Dev>\
-struct FunctorExtractor<Eigen::TensorEvaluator<CVQual Eigen::OPEXPR<Param, XprType>, Dev> > {\
- FunctorExtractor<Eigen::TensorEvaluator<XprType, Dev> > xprExpr;\
- const Param m_param;\
- EIGEN_STRONG_INLINE const Param& param() const { return m_param; }\
- FunctorExtractor(const Eigen::TensorEvaluator<CVQual Eigen::OPEXPR<Param, XprType>, Dev>& expr)\
- : xprExpr(expr.impl()), m_param(expr.FUNCCALL) {}\
-};
-
-SYCLRESHAPEANDSHUFFLEOPFUNCEXT(TensorReshapingOp, dimensions(), const)
-SYCLRESHAPEANDSHUFFLEOPFUNCEXT(TensorReshapingOp, dimensions(), )
-
-SYCLRESHAPEANDSHUFFLEOPFUNCEXT(TensorShufflingOp, shufflePermutation(), const)
-SYCLRESHAPEANDSHUFFLEOPFUNCEXT(TensorShufflingOp, shufflePermutation(), )
-#undef SYCLRESHAPEANDSHUFFLEOPFUNCEXT
-
-// Had to separate reshapeOP otherwise it will be mistaken by UnaryCategory
-#define PADDINGOPFUNCEXT(OPEXPR, FUNCCALL, SCALARFUNCCALL, CVQual)\
-template<typename Param, typename XprType, typename Dev>\
-struct FunctorExtractor<Eigen::TensorEvaluator<CVQual Eigen::OPEXPR<Param, XprType>, Dev> > {\
- FunctorExtractor<Eigen::TensorEvaluator<XprType, Dev> > xprExpr;\
- const Param m_param;\
- typedef typename Eigen::TensorEvaluator<CVQual Eigen::OPEXPR<Param, XprType>, Dev>::Scalar Scalar;\
- const Scalar m_scalar_param;\
- EIGEN_STRONG_INLINE const Param& param() const { return m_param; }\
- EIGEN_STRONG_INLINE const Scalar& scalar_param() const { return m_scalar_param; }\
- FunctorExtractor(const Eigen::TensorEvaluator<CVQual Eigen::OPEXPR<Param, XprType>, Dev>& expr)\
- : xprExpr(expr.impl()), m_param(expr.FUNCCALL), m_scalar_param(expr.SCALARFUNCCALL) {}\
-};
-
-PADDINGOPFUNCEXT(TensorPaddingOp, padding(), padding_value(), const)
-PADDINGOPFUNCEXT(TensorPaddingOp, padding(), padding_value(), )
-#undef PADDINGOPFUNCEXT
-
-/// specialisation of the \ref FunctorExtractor struct when the node type is TensorContractionOp and TensorConcatenationOp
-/// for TensorContractionOp the LHS and RHS here are the original one no need to apply condition on their type.
-#define SYCLEXTRFUNCCONTRACTCONCAT(OPEXPR, FUNCCALL, CVQual)\
-template <typename Param, typename LHSExpr, typename RHSExpr, typename Dev>\
-struct FunctorExtractor<TensorEvaluator<CVQual OPEXPR<Param, LHSExpr, RHSExpr>, Dev> > {\
- FunctorExtractor<TensorEvaluator<LHSExpr, Dev> > lhsExpr;\
- FunctorExtractor<TensorEvaluator<RHSExpr, Dev> > rhsExpr;\
- const Param func;\
- FunctorExtractor(const TensorEvaluator<CVQual OPEXPR<Param, LHSExpr, RHSExpr>, Dev>& expr)\
- : lhsExpr(expr.left_impl()),rhsExpr(expr.right_impl()),func(expr.FUNCCALL) {}\
-};
-
-// TensorConcatenationOp
-SYCLEXTRFUNCCONTRACTCONCAT(TensorConcatenationOp, axis(), const)
-SYCLEXTRFUNCCONTRACTCONCAT(TensorConcatenationOp, axis(),)
-#undef SYCLEXTRFUNCCONTRACTCONCAT
-
-//TensorChippingOp
-#define SYCLEXTRFUNCCHIPPINGOP(CVQual)\
-template<DenseIndex DimId, typename XprType, typename Device>\
-struct FunctorExtractor<TensorEvaluator<CVQual TensorChippingOp<DimId, XprType>, Device>>{\
- FunctorExtractor<Eigen::TensorEvaluator<XprType, Device> > xprExpr;\
- const DenseIndex m_dim;\
- const DenseIndex m_offset;\
- EIGEN_STRONG_INLINE const DenseIndex& dimId() const { return m_dim; }\
- EIGEN_STRONG_INLINE const DenseIndex& offset() const { return m_offset; }\
- FunctorExtractor(const TensorEvaluator<CVQual TensorChippingOp<DimId, XprType>, Device>& expr)\
- : xprExpr(expr.impl()), m_dim(expr.dimId()), m_offset(expr.offset()) {}\
+template<typename Op, typename Dims, typename ArgType, template <class> class MakePointer_, typename Device>
+struct FunctorExtractor<TensorEvaluator<const TensorReductionOp<Op, Dims, ArgType, MakePointer_>, Device>>{
+ typedef TensorEvaluator<const TensorReductionOp<Op, Dims, ArgType, MakePointer_>, Device> Evaluator;
+ typedef typename Eigen::internal::conditional<Evaluator::NumOutputDims==0, DSizes<typename Evaluator::Index, 1>, typename Evaluator::Dimensions >::type Dimensions;
+ const Dimensions m_dimensions;
+ const Dimensions& dimensions() const { return m_dimensions; }
+ FunctorExtractor(const TensorEvaluator<const TensorReductionOp<Op, Dims, ArgType, MakePointer_>, Device>& expr)
+ : m_dimensions(DimConstr<Dimensions, Evaluator::NumOutputDims>::getDim(expr.dimensions())) {}
};
-SYCLEXTRFUNCCHIPPINGOP(const)
-SYCLEXTRFUNCCHIPPINGOP()
-#undef SYCLEXTRFUNCCHIPPINGOP
+template<typename Op, typename Dims, typename ArgType, template <class> class MakePointer_, typename Device>
+struct FunctorExtractor<TensorEvaluator<TensorReductionOp<Op, Dims, ArgType, MakePointer_>, Device>>
+: FunctorExtractor<TensorEvaluator<const TensorReductionOp<Op, Dims, ArgType, MakePointer_>, Device>>{};
/// template deduction function for FunctorExtractor
template <typename Evaluator>
auto inline extractFunctors(const Evaluator& evaluator)-> FunctorExtractor<Evaluator> {
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclFunctors.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclFunctors.h
deleted file mode 100644
index 2f77790..0000000
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclFunctors.h
+++ /dev/null
@@ -1,245 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: eigen@codeplay.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/.
-
-// General include header of SYCL target for Tensor Module
-#ifndef UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCLFUNCTORS_H
-#define UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCLFUNCTORS_H
-
-namespace Eigen {
-namespace TensorSycl {
-namespace internal {
-
- template<typename CoeffReturnType, typename OP, typename OutputAccessor, typename InputAccessor, typename LocalAccessor> struct GenericKernelReducer{
- OP op;
- OutputAccessor aOut;
- InputAccessor aI;
- LocalAccessor scratch;
- size_t length, local;
- GenericKernelReducer(OP op_, OutputAccessor aOut_, InputAccessor aI_, LocalAccessor scratch_, size_t length_, size_t local_)
- : op(op_), aOut(aOut_), aI(aI_), scratch(scratch_), length(length_), local(local_){}
- void operator()(cl::sycl::nd_item<1> itemID) {
- size_t globalid = itemID.get_global(0);
- size_t localid = itemID.get_local(0);
- /* All threads collectively read from global memory into local.
- * The barrier ensures all threads' IO is resolved before
- * execution continues (strictly speaking, all threads within
- * a single work-group - there is no co-ordination between
- * work-groups, only work-items). */
- if (globalid < length) {
- scratch[localid] = aI[globalid];
- }
- itemID.barrier(cl::sycl::access::fence_space::local_space);
-
- /* Apply the reduction operation between the current local
- * id and the one on the other half of the vector. */
- if (globalid < length) {
- auto min = (length < local) ? length : local;
- for (size_t offset = min / 2; offset > 0; offset /= 2) {
- if (localid < offset) {
- auto accum = op.initialize();
- op.reduce(scratch[localid], &accum);
- op.reduce(scratch[localid + offset], &accum);
- op.finalize(accum);
- scratch[localid]=accum;
- //scratch[localid] += scratch[localid + offset];
- }
- itemID.barrier(cl::sycl::access::fence_space::local_space);
- }
- /* The final result will be stored in local id 0. */
- if (localid == 0) {
- aI[itemID.get_group(0)] = scratch[localid];
- if((length<=local) && globalid ==0){
- auto aOutPtr = ConvertToActualTypeSycl(CoeffReturnType, aOut);
- aOutPtr[0]=scratch[0];
- }
- }
- }
- }
-
- };
-
-/// ReductionFunctor
-template < typename HostExpr, typename FunctorExpr, typename Tuple_of_Acc, typename Dims, typename Op, typename Index> class ReductionFunctor {
- public:
- typedef typename TensorSycl::internal::createPlaceHolderExpression<HostExpr>::Type PlaceHolderExpr;
- typedef cl::sycl::accessor<uint8_t, 1, cl::sycl::access::mode::discard_write, cl::sycl::access::target::global_buffer> write_accessor;
- ReductionFunctor(write_accessor output_accessor_, FunctorExpr functors_, Tuple_of_Acc tuple_of_accessors_,Dims dims_, Op functor_, Index range_, Index)
- :output_accessor(output_accessor_), functors(functors_), tuple_of_accessors(tuple_of_accessors_), dims(dims_), functor(functor_), range(range_) {}
- void operator()(cl::sycl::nd_item<1> itemID) {
-
- typedef typename ConvertToDeviceExpression<const HostExpr>::Type DevExpr;
- auto device_expr = createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
- /// reduction cannot be captured automatically through our device conversion recursion. The reason is that reduction has two behaviour
- /// the first behaviour is when it is used as a root to lauch the sub-kernel. The second one is when it is treated as a leafnode to pass the
- /// calculated result to its parent kernel. While the latter is automatically detected through our device expression generator. The former is created here.
- const auto device_self_expr= Eigen::TensorReductionOp<Op, Dims, decltype(device_expr.expr) ,MakeGlobalPointer>(device_expr.expr, dims, functor);
- /// This is the evaluator for device_self_expr. This is exactly similar to the self which has been passed to run function. The difference is
- /// the device_evaluator is detectable and recognisable on the device.
- typedef Eigen::TensorEvaluator<decltype(device_self_expr), Eigen::DefaultDevice> DeviceSelf;
- auto device_self_evaluator = Eigen::TensorEvaluator<decltype(device_self_expr), Eigen::DefaultDevice>(device_self_expr, Eigen::DefaultDevice());
- auto output_accessor_ptr =ConvertToActualTypeSycl(typename DeviceSelf::CoeffReturnType, output_accessor);
- /// const cast added as a naive solution to solve the qualifier drop error
- auto globalid=static_cast<Index>(itemID.get_global_linear_id());
- if (globalid< range) {
- typename DeviceSelf::CoeffReturnType accum = functor.initialize();
- Eigen::internal::GenericDimReducer<DeviceSelf::NumReducedDims-1, DeviceSelf, Op>::reduce(device_self_evaluator, device_self_evaluator.firstInput(static_cast<typename DevExpr::Index>(globalid)),const_cast<Op&>(functor), &accum);
- functor.finalize(accum);
- output_accessor_ptr[globalid]= accum;
- }
- }
- private:
- write_accessor output_accessor;
- FunctorExpr functors;
- Tuple_of_Acc tuple_of_accessors;
- Dims dims;
- Op functor;
- Index range;
-};
-
-template < typename HostExpr, typename FunctorExpr, typename Tuple_of_Acc, typename Dims, typename Index>
-class ReductionFunctor<HostExpr, FunctorExpr, Tuple_of_Acc, Dims, Eigen::internal::MeanReducer<typename HostExpr::CoeffReturnType>, Index> {
- public:
- typedef typename TensorSycl::internal::createPlaceHolderExpression<HostExpr>::Type PlaceHolderExpr;
- typedef cl::sycl::accessor<uint8_t, 1, cl::sycl::access::mode::discard_write, cl::sycl::access::target::global_buffer> write_accessor;
- typedef Eigen::internal::SumReducer<typename HostExpr::CoeffReturnType> Op;
- ReductionFunctor(write_accessor output_accessor_, FunctorExpr functors_, Tuple_of_Acc tuple_of_accessors_,Dims dims_,
- Eigen::internal::MeanReducer<typename HostExpr::CoeffReturnType>, Index range_, Index num_values_to_reduce_)
- :output_accessor(output_accessor_), functors(functors_), tuple_of_accessors(tuple_of_accessors_), dims(dims_), functor(Op()), range(range_), num_values_to_reduce(num_values_to_reduce_) {}
- void operator()(cl::sycl::nd_item<1> itemID) {
-
- typedef typename ConvertToDeviceExpression<const HostExpr>::Type DevExpr;
- auto device_expr = createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
- /// reduction cannot be captured automatically through our device conversion recursion. The reason is that reduction has two behaviour
- /// the first behaviour is when it is used as a root to lauch the sub-kernel. The second one is when it is treated as a leafnode to pass the
- /// calculated result to its parent kernel. While the latter is automatically detected through our device expression generator. The former is created here.
- const auto device_self_expr= Eigen::TensorReductionOp<Op, Dims, decltype(device_expr.expr) ,MakeGlobalPointer>(device_expr.expr, dims, functor);
- /// This is the evaluator for device_self_expr. This is exactly similar to the self which has been passed to run function. The difference is
- /// the device_evaluator is detectable and recognisable on the device.
- typedef Eigen::TensorEvaluator<decltype(device_self_expr), Eigen::DefaultDevice> DeviceSelf;
- auto device_self_evaluator = Eigen::TensorEvaluator<decltype(device_self_expr), Eigen::DefaultDevice>(device_self_expr, Eigen::DefaultDevice());
- auto output_accessor_ptr =ConvertToActualTypeSycl(typename DeviceSelf::CoeffReturnType, output_accessor);
- /// const cast added as a naive solution to solve the qualifier drop error
- auto globalid=static_cast<Index>(itemID.get_global_linear_id());
- if (globalid< range) {
- typename DeviceSelf::CoeffReturnType accum = functor.initialize();
- Eigen::internal::GenericDimReducer<DeviceSelf::NumReducedDims-1, DeviceSelf, Op>::reduce(device_self_evaluator, device_self_evaluator.firstInput(static_cast<typename DevExpr::Index>(globalid)),const_cast<Op&>(functor), &accum);
- functor.finalize(accum);
- output_accessor_ptr[globalid]= accum/num_values_to_reduce;
- }
- }
- private:
- write_accessor output_accessor;
- FunctorExpr functors;
- Tuple_of_Acc tuple_of_accessors;
- Dims dims;
- Op functor;
- Index range;
- Index num_values_to_reduce;
-};
-
-template<typename CoeffReturnType ,typename OutAccessor, typename HostExpr, typename FunctorExpr, typename Op, typename Dims, typename Index, typename TupleType>
-class FullReductionKernelFunctor{
-public:
- typedef typename TensorSycl::internal::createPlaceHolderExpression<HostExpr>::Type PlaceHolderExpr;
- OutAccessor tmp_global_accessor;
- Index rng , remaining, red_factor;
- Op op;
- Dims dims;
- FunctorExpr functors;
- TupleType tuple_of_accessors;
-
- FullReductionKernelFunctor(OutAccessor acc, Index rng_, Index remaining_, Index red_factor_, Op op_, Dims dims_, FunctorExpr functors_, TupleType t_acc)
- :tmp_global_accessor(acc), rng(rng_), remaining(remaining_), red_factor(red_factor_),op(op_), dims(dims_), functors(functors_), tuple_of_accessors(t_acc){}
-
- void operator()(cl::sycl::nd_item<1> itemID) {
-
- typedef typename TensorSycl::internal::ConvertToDeviceExpression<const HostExpr>::Type DevExpr;
- auto device_expr = TensorSycl::internal::createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
- /// reduction cannot be captured automatically through our device conversion recursion. The reason is that reduction has two behaviour
- /// the first behaviour is when it is used as a root to lauch the sub-kernel. The second one is when it is treated as a leafnode to pass the
- /// calculated result to its parent kernel. While the latter is automatically detected through our device expression generator. The former is created here.
- const auto device_self_expr= Eigen::TensorReductionOp<Op, Dims, decltype(device_expr.expr) ,MakeGlobalPointer>(device_expr.expr, dims, op);
- /// This is the evaluator for device_self_expr. This is exactly similar to the self which has been passed to run function. The difference is
- /// the device_evaluator is detectable and recognisable on the device.
- auto device_self_evaluator = Eigen::TensorEvaluator<decltype(device_self_expr), Eigen::DefaultDevice>(device_self_expr, Eigen::DefaultDevice());
- /// const cast added as a naive solution to solve the qualifier drop error
- auto globalid=itemID.get_global_linear_id();
-
- tmp_global_accessor.get_pointer()[globalid]=(globalid<rng) ? Eigen::internal::InnerMostDimReducer<decltype(device_self_evaluator), Op, false>::reduce(device_self_evaluator, static_cast<typename DevExpr::Index>(red_factor*globalid), red_factor, const_cast<Op&>(op))
- : static_cast<CoeffReturnType>(op.initialize());
-
- if(remaining!=0 && globalid==0 ){
- // this will add the rest of input buffer when the input size is not devidable to red_factor.
- auto remaining_reduce =Eigen::internal::InnerMostDimReducer<decltype(device_self_evaluator), Op, false>::
- reduce(device_self_evaluator, static_cast<typename DevExpr::Index>(red_factor*(rng)), static_cast<typename DevExpr::Index>(remaining), const_cast<Op&>(op));
- auto accum = op.initialize();
- op.reduce(tmp_global_accessor.get_pointer()[0], &accum);
- op.reduce(remaining_reduce, &accum);
- op.finalize(accum);
- tmp_global_accessor.get_pointer()[0]=accum;
-
- }
- }
-};
-
-template<typename CoeffReturnType ,typename OutAccessor, typename HostExpr, typename FunctorExpr, typename Dims, typename Index, typename TupleType>
-class FullReductionKernelFunctor<CoeffReturnType, OutAccessor, HostExpr, FunctorExpr, Eigen::internal::MeanReducer<CoeffReturnType>, Dims, Index, TupleType>{
-public:
- typedef typename TensorSycl::internal::createPlaceHolderExpression<HostExpr>::Type PlaceHolderExpr;
- typedef Eigen::internal::SumReducer<CoeffReturnType> Op;
-
- OutAccessor tmp_global_accessor;
- Index rng , remaining, red_factor;
- Op op;
- Dims dims;
- FunctorExpr functors;
- TupleType tuple_of_accessors;
-
- FullReductionKernelFunctor(OutAccessor acc, Index rng_, Index remaining_, Index red_factor_, Eigen::internal::MeanReducer<CoeffReturnType>, Dims dims_, FunctorExpr functors_, TupleType t_acc)
- :tmp_global_accessor(acc), rng(rng_), remaining(remaining_), red_factor(red_factor_),op(Op()), dims(dims_), functors(functors_), tuple_of_accessors(t_acc){}
-
- void operator()(cl::sycl::nd_item<1> itemID) {
-
- typedef typename TensorSycl::internal::ConvertToDeviceExpression<const HostExpr>::Type DevExpr;
- auto device_expr = TensorSycl::internal::createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
- /// reduction cannot be captured automatically through our device conversion recursion. The reason is that reduction has two behaviour
- /// the first behaviour is when it is used as a root to lauch the sub-kernel. The second one is when it is treated as a leafnode to pass the
- /// calculated result to its parent kernel. While the latter is automatically detected through our device expression generator. The former is created here.
- const auto device_self_expr= Eigen::TensorReductionOp<Op, Dims, decltype(device_expr.expr) ,MakeGlobalPointer>(device_expr.expr, dims, op);
- /// This is the evaluator for device_self_expr. This is exactly similar to the self which has been passed to run function. The difference is
- /// the device_evaluator is detectable and recognisable on the device.
- auto device_self_evaluator = Eigen::TensorEvaluator<decltype(device_self_expr), Eigen::DefaultDevice>(device_self_expr, Eigen::DefaultDevice());
- /// const cast added as a naive solution to solve the qualifier drop error
- auto globalid=itemID.get_global_linear_id();
- auto scale = (rng*red_factor) + remaining;
-
- tmp_global_accessor.get_pointer()[globalid]= (globalid<rng)? ((Eigen::internal::InnerMostDimReducer<decltype(device_self_evaluator), Op, false>::reduce(device_self_evaluator, static_cast<typename DevExpr::Index>(red_factor*globalid), red_factor, const_cast<Op&>(op)))/scale)
- :static_cast<CoeffReturnType>(op.initialize())/scale;
-
- if(remaining!=0 && globalid==0 ){
- // this will add the rest of input buffer when the input size is not devidable to red_factor.
- auto remaining_reduce =Eigen::internal::InnerMostDimReducer<decltype(device_self_evaluator), Op, false>::reduce(device_self_evaluator, static_cast<typename DevExpr::Index>(red_factor*(rng)), static_cast<typename DevExpr::Index>(remaining), const_cast<Op&>(op));
- auto accum = op.initialize();
- tmp_global_accessor.get_pointer()[0]= tmp_global_accessor.get_pointer()[0]*scale;
- op.reduce(tmp_global_accessor.get_pointer()[0], &accum);
- op.reduce(remaining_reduce, &accum);
- op.finalize(accum);
- tmp_global_accessor.get_pointer()[0]=accum/scale;
-
- }
- }
-};
-
-}
-}
-}
-#endif // UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCLFUNCTORS_H
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclLeafCount.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclLeafCount.h
index a1c112f..25d1fac 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclLeafCount.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclLeafCount.h
@@ -44,120 +44,68 @@ struct CategoryCount<Arg,Args...>{
};
/// specialisation of the \ref LeafCount struct when the node type is const TensorMap
-#define SYCLTENSORMAPLEAFCOUNT(CVQual)\
-template <typename PlainObjectType, int Options_, template <class> class MakePointer_>\
-struct LeafCount<CVQual TensorMap<PlainObjectType, Options_, MakePointer_> > {\
- static const size_t Count =1;\
+template <typename PlainObjectType, int Options_, template <class> class MakePointer_>
+struct LeafCount<const TensorMap<PlainObjectType, Options_, MakePointer_> > {
+ static const size_t Count =1;
};
-SYCLTENSORMAPLEAFCOUNT(const)
-SYCLTENSORMAPLEAFCOUNT()
-#undef SYCLTENSORMAPLEAFCOUNT
+/// specialisation of the \ref LeafCount struct when the node type is TensorMap
+template <typename PlainObjectType, int Options_, template <class> class MakePointer_>
+struct LeafCount<TensorMap<PlainObjectType, Options_, MakePointer_> > :LeafCount<const TensorMap<PlainObjectType, Options_, MakePointer_> >{};
-// TensorCwiseUnaryOp, TensorCwiseNullaryOp, TensorCwiseBinaryOp, TensorCwiseTernaryOp, and TensorBroadcastingOp
-#define SYCLCATEGORYLEAFCOUNT(CVQual)\
-template <template <class, class...> class CategoryExpr, typename OP, typename... RHSExpr>\
-struct LeafCount<CVQual CategoryExpr<OP, RHSExpr...> >: CategoryCount<RHSExpr...> {};
-
-SYCLCATEGORYLEAFCOUNT(const)
-SYCLCATEGORYLEAFCOUNT()
-#undef SYCLCATEGORYLEAFCOUNT
+// const TensorCwiseUnaryOp, const TensorCwiseNullaryOp, const TensorCwiseBinaryOp, const TensorCwiseTernaryOp, and Const TensorBroadcastingOp
+template <template <class, class...> class CategoryExpr, typename OP, typename... RHSExpr>
+struct LeafCount<const CategoryExpr<OP, RHSExpr...> >: CategoryCount<RHSExpr...> {};
+// TensorCwiseUnaryOp, TensorCwiseNullaryOp, TensorCwiseBinaryOp, TensorCwiseTernaryOp, and TensorBroadcastingOp
+template <template <class, class...> class CategoryExpr, typename OP, typename... RHSExpr>
+struct LeafCount<CategoryExpr<OP, RHSExpr...> > :LeafCount<const CategoryExpr<OP, RHSExpr...> >{};
/// specialisation of the \ref LeafCount struct when the node type is const TensorSelectOp is an exception
-#define SYCLSELECTOPLEAFCOUNT(CVQual)\
-template <typename IfExpr, typename ThenExpr, typename ElseExpr>\
-struct LeafCount<CVQual TensorSelectOp<IfExpr, ThenExpr, ElseExpr> > : CategoryCount<IfExpr, ThenExpr, ElseExpr> {};
-
-SYCLSELECTOPLEAFCOUNT(const)
-SYCLSELECTOPLEAFCOUNT()
-#undef SYCLSELECTOPLEAFCOUNT
+template <typename IfExpr, typename ThenExpr, typename ElseExpr>
+struct LeafCount<const TensorSelectOp<IfExpr, ThenExpr, ElseExpr> > : CategoryCount<IfExpr, ThenExpr, ElseExpr> {};
+/// specialisation of the \ref LeafCount struct when the node type is TensorSelectOp
+template <typename IfExpr, typename ThenExpr, typename ElseExpr>
+struct LeafCount<TensorSelectOp<IfExpr, ThenExpr, ElseExpr> >: LeafCount<const TensorSelectOp<IfExpr, ThenExpr, ElseExpr> > {};
-/// specialisation of the \ref LeafCount struct when the node type is TensorAssignOp
-#define SYCLLEAFCOUNTASSIGNOP(CVQual)\
-template <typename LHSExpr, typename RHSExpr>\
-struct LeafCount<CVQual TensorAssignOp<LHSExpr, RHSExpr> >: CategoryCount<LHSExpr,RHSExpr> {};
+/// specialisation of the \ref LeafCount struct when the node type is const TensorAssignOp
+template <typename LHSExpr, typename RHSExpr>
+struct LeafCount<const TensorAssignOp<LHSExpr, RHSExpr> >: CategoryCount<LHSExpr,RHSExpr> {};
-SYCLLEAFCOUNTASSIGNOP(const)
-SYCLLEAFCOUNTASSIGNOP()
-#undef SYCLLEAFCOUNTASSIGNOP
+/// specialisation of the \ref LeafCount struct when the node type is
+/// TensorAssignOp is an exception. It is not the same as Unary
+template <typename LHSExpr, typename RHSExpr>
+struct LeafCount<TensorAssignOp<LHSExpr, RHSExpr> > :LeafCount<const TensorAssignOp<LHSExpr, RHSExpr> >{};
/// specialisation of the \ref LeafCount struct when the node type is const TensorForcedEvalOp
-#define SYCLFORCEDEVALLEAFCOUNT(CVQual)\
-template <typename Expr>\
-struct LeafCount<CVQual TensorForcedEvalOp<Expr> > {\
- static const size_t Count =1;\
+template <typename Expr>
+struct LeafCount<const TensorForcedEvalOp<Expr> > {
+ static const size_t Count =1;
};
-SYCLFORCEDEVALLEAFCOUNT(const)
-SYCLFORCEDEVALLEAFCOUNT()
-#undef SYCLFORCEDEVALLEAFCOUNT
+/// specialisation of the \ref LeafCount struct when the node type is TensorForcedEvalOp
+template <typename Expr>
+struct LeafCount<TensorForcedEvalOp<Expr> >: LeafCount<const TensorForcedEvalOp<Expr> > {};
-/// specialisation of the \ref LeafCount struct when the node type is TensorEvalToOp
-#define EVALTOLEAFCOUNT(CVQual)\
-template <typename Expr>\
-struct LeafCount<CVQual TensorEvalToOp<Expr> > {\
- static const size_t Count = 1 + CategoryCount<Expr>::Count;\
+/// specialisation of the \ref LeafCount struct when the node type is const TensorEvalToOp
+template <typename Expr>
+struct LeafCount<const TensorEvalToOp<Expr> > {
+ static const size_t Count = 1 + CategoryCount<Expr>::Count;
};
-EVALTOLEAFCOUNT(const)
-EVALTOLEAFCOUNT()
-#undef EVALTOLEAFCOUNT
-
/// specialisation of the \ref LeafCount struct when the node type is const TensorReductionOp
-#define REDUCTIONLEAFCOUNT(CVQual)\
-template <typename OP, typename Dim, typename Expr>\
-struct LeafCount<CVQual TensorReductionOp<OP, Dim, Expr> > {\
- static const size_t Count =1;\
+template <typename OP, typename Dim, typename Expr>
+struct LeafCount<const TensorReductionOp<OP, Dim, Expr> > {
+ static const size_t Count =1;
};
-REDUCTIONLEAFCOUNT(const)
-REDUCTIONLEAFCOUNT()
-#undef REDUCTIONLEAFCOUNT
-
-/// specialisation of the \ref LeafCount struct when the node type is const TensorContractionOp
-#define CONTRACTIONCONVOLUTIONLEAFCOUNT(CVQual, ExprNode)\
-template <typename Indices, typename LhsXprType, typename RhsXprType>\
-struct LeafCount<CVQual ExprNode<Indices, LhsXprType, RhsXprType> > {\
- static const size_t Count =1;\
-};
-
-CONTRACTIONCONVOLUTIONLEAFCOUNT(const,TensorContractionOp)
-CONTRACTIONCONVOLUTIONLEAFCOUNT(,TensorContractionOp)
-CONTRACTIONCONVOLUTIONLEAFCOUNT(const,TensorConvolutionOp)
-CONTRACTIONCONVOLUTIONLEAFCOUNT(,TensorConvolutionOp)
-#undef CONTRACTIONCONVOLUTIONLEAFCOUNT
-
-
-
-/// specialisation of the \ref LeafCount struct when the node type is TensorSlicingOp
-#define SLICEOPLEAFCOUNT(CVQual)\
-template <typename StartIndices, typename Sizes, typename XprType>\
-struct LeafCount<CVQual TensorSlicingOp<StartIndices, Sizes, XprType> >:CategoryCount<XprType>{};
-
-SLICEOPLEAFCOUNT(const)
-SLICEOPLEAFCOUNT()
-#undef SLICEOPLEAFCOUNT
-
-
-/// specialisation of the \ref LeafCount struct when the node type is TensorChippingOp
-#define CHIPPINGOPLEAFCOUNT(CVQual)\
-template <DenseIndex DimId, typename XprType>\
-struct LeafCount<CVQual TensorChippingOp<DimId, XprType> >:CategoryCount<XprType>{};
-
-CHIPPINGOPLEAFCOUNT(const)
-CHIPPINGOPLEAFCOUNT()
-#undef CHIPPINGOPLEAFCOUNT
-
-
-#define SLICESTRIDEOPLEAFCOUNT(CVQual)\
-template<typename StartIndices, typename StopIndices, typename Strides, typename XprType>\
-struct LeafCount<CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> >:CategoryCount<XprType>{};
-
-SLICESTRIDEOPLEAFCOUNT(const)
-SLICESTRIDEOPLEAFCOUNT()
-#undef SLICESTRIDEOPLEAFCOUNT
+/// specialisation of the \ref LeafCount struct when the node type is TensorReductionOp
+template <typename OP, typename Dim, typename Expr>
+struct LeafCount<TensorReductionOp<OP, Dim, Expr> >: LeafCount<const TensorReductionOp<OP, Dim, Expr> >{};
+/// specialisation of the \ref LeafCount struct when the node type is TensorEvalToOp
+template <typename Expr>
+struct LeafCount<TensorEvalToOp<Expr> >: LeafCount<const TensorEvalToOp<Expr> >{};
} /// namespace TensorSycl
} /// namespace internal
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclPlaceHolderExpr.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclPlaceHolderExpr.h
index 74566dc..d4c250c 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclPlaceHolderExpr.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclPlaceHolderExpr.h
@@ -122,9 +122,9 @@ ASSIGNEXPR()
/// specialisation of the \ref PlaceHolderExpression when the node is
/// TensorMap
#define TENSORMAPEXPR(CVQual)\
-template <typename T, int Options_, template <class> class MakePointer_, size_t N>\
-struct PlaceHolderExpression< CVQual TensorMap< T, Options_, MakePointer_>, N> {\
- typedef CVQual PlaceHolder<CVQual TensorMap<T, Options_, MakePointer_>, N> Type;\
+template <typename Scalar_, int Options_, int Options2_, int NumIndices_, typename IndexType_, template <class> class MakePointer_, size_t N>\
+struct PlaceHolderExpression< CVQual TensorMap< Tensor<Scalar_, NumIndices_, Options_, IndexType_>, Options2_, MakePointer_>, N> {\
+ typedef CVQual PlaceHolder<CVQual TensorMap<Tensor<Scalar_, NumIndices_, Options_, IndexType_>, Options2_, MakePointer_>, N> Type;\
};
TENSORMAPEXPR(const)
@@ -157,18 +157,6 @@ EVALTO()
/// specialisation of the \ref PlaceHolderExpression when the node is
-/// TensorChippingOp
-#define CHIPPINGOP(CVQual)\
-template <DenseIndex DimId, typename Expr, size_t N>\
-struct PlaceHolderExpression<CVQual TensorChippingOp<DimId, Expr>, N> {\
- typedef CVQual TensorChippingOp< DimId, typename CalculateIndex <N, Expr>::ArgType> Type;\
-};
-
-CHIPPINGOP(const)
-CHIPPINGOP()
-#undef CHIPPINGOP
-
-/// specialisation of the \ref PlaceHolderExpression when the node is
/// TensorReductionOp
#define SYCLREDUCTION(CVQual)\
template <typename OP, typename Dims, typename Expr, size_t N>\
@@ -179,45 +167,6 @@ SYCLREDUCTION(const)
SYCLREDUCTION()
#undef SYCLREDUCTION
-
-/// specialisation of the \ref PlaceHolderExpression when the node is
-/// TensorReductionOp
-#define SYCLCONTRACTIONCONVOLUTIONPLH(CVQual, ExprNode)\
-template <typename Indices, typename LhsXprType, typename RhsXprType, size_t N>\
-struct PlaceHolderExpression<CVQual ExprNode<Indices, LhsXprType, RhsXprType>, N>{\
- typedef CVQual PlaceHolder<CVQual ExprNode<Indices, LhsXprType, RhsXprType>, N> Type;\
-};
-SYCLCONTRACTIONCONVOLUTIONPLH(const, TensorContractionOp)
-SYCLCONTRACTIONCONVOLUTIONPLH(,TensorContractionOp)
-SYCLCONTRACTIONCONVOLUTIONPLH(const, TensorConvolutionOp)
-SYCLCONTRACTIONCONVOLUTIONPLH(,TensorConvolutionOp)
-#undef SYCLCONTRACTIONCONVOLUTIONPLH
-
-
-/// specialisation of the \ref PlaceHolderExpression when the node is
-/// TensorCwiseSelectOp
-#define SLICEOPEXPR(CVQual)\
-template <typename StartIndices, typename Sizes, typename XprType, size_t N>\
-struct PlaceHolderExpression<CVQual TensorSlicingOp<StartIndices, Sizes, XprType>, N> {\
- typedef CVQual TensorSlicingOp<StartIndices, Sizes, typename CalculateIndex<N, XprType>::ArgType> Type;\
-};
-
-SLICEOPEXPR(const)
-SLICEOPEXPR()
-#undef SLICEOPEXPR
-
-
-#define SYCLSLICESTRIDEOPPLH(CVQual)\
-template<typename StartIndices, typename StopIndices, typename Strides, typename XprType, size_t N>\
-struct PlaceHolderExpression<CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>, N> {\
- typedef CVQual TensorStridingSlicingOp<StartIndices, StopIndices, Strides, typename CalculateIndex<N, XprType>::ArgType> Type;\
-};
-
-SYCLSLICESTRIDEOPPLH(const)
-SYCLSLICESTRIDEOPPLH()
-#undef SYCLSLICESTRIDEOPPLH
-
-
/// template deduction for \ref PlaceHolderExpression struct
template <typename Expr>
struct createPlaceHolderExpression {
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclRun.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclRun.h
index cac7855..7914b6f 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclRun.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclRun.h
@@ -25,70 +25,43 @@
namespace Eigen {
namespace TensorSycl {
-
-template<typename Expr, typename FunctorExpr, typename TupleType > struct ExecExprFunctorKernel{
- typedef typename internal::createPlaceHolderExpression<Expr>::Type PlaceHolderExpr;
-
- typedef typename Expr::Index Index;
- FunctorExpr functors;
- TupleType tuple_of_accessors;
- Index range;
- ExecExprFunctorKernel(Index range_, FunctorExpr functors_, TupleType tuple_of_accessors_)
- : functors(functors_), tuple_of_accessors(tuple_of_accessors_), range(range_){}
- void operator()(cl::sycl::nd_item<1> itemID) {
- typedef typename internal::ConvertToDeviceExpression<Expr>::Type DevExpr;
- auto device_expr =internal::createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
- auto device_evaluator = Eigen::TensorEvaluator<decltype(device_expr.expr), Eigen::DefaultDevice>(device_expr.expr, Eigen::DefaultDevice());
- typename DevExpr::Index gId = static_cast<typename DevExpr::Index>(itemID.get_global_linear_id());
- if (gId < range)
- device_evaluator.evalScalar(gId);
- }
-};
-
/// The run function in tensor sycl convert the expression tree to a buffer
/// based expression tree;
/// creates the expression tree for the device with accessor to buffers;
/// construct the kernel and submit it to the sycl queue.
-/// std::array does not have TotalSize. So I have to get the size through template specialisation.
-template<typename , typename Dimensions> struct DimensionSize{
- static auto getDimSize(const Dimensions& dim)->decltype(dim.TotalSize()){
- return dim.TotalSize();
- }
-};
-#define DIMSIZEMACRO(CVQual)\
-template<typename Index, size_t NumDims> struct DimensionSize<Index, CVQual std::array<Index, NumDims>>{\
- static inline Index getDimSize(const std::array<Index, NumDims>& dim){\
- return (NumDims == 0) ? 1 : ::Eigen::internal::array_prod(dim);\
- }\
-};
-
-DIMSIZEMACRO(const)
-DIMSIZEMACRO()
-#undef DIMSIZEMACRO
-
-
template <typename Expr, typename Dev>
void run(Expr &expr, Dev &dev) {
Eigen::TensorEvaluator<Expr, Dev> evaluator(expr, dev);
const bool needs_assign = evaluator.evalSubExprsIfNeeded(NULL);
if (needs_assign) {
- typedef Eigen::TensorSycl::internal::FunctorExtractor<Eigen::TensorEvaluator<Expr, Dev> > FunctorExpr;
- FunctorExpr functors = internal::extractFunctors(evaluator);
- dev.sycl_queue().submit([&](cl::sycl::handler &cgh) {
- // create a tuple of accessors from Evaluator
- typedef decltype(internal::createTupleOfAccessors<Eigen::TensorEvaluator<Expr, Dev> >(cgh, evaluator)) TupleType;
- TupleType tuple_of_accessors = internal::createTupleOfAccessors<Eigen::TensorEvaluator<Expr, Dev> >(cgh, evaluator);
- typename Expr::Index range, GRange, tileSize;
- typename Expr::Index total_size = static_cast<typename Expr::Index>(DimensionSize<typename Expr::Index, typename Eigen::TensorEvaluator<Expr, Dev>::Dimensions>::getDimSize(evaluator.dimensions()));
- dev.parallel_for_setup(total_size, tileSize, range, GRange);
+ typedef typename internal::createPlaceHolderExpression<Expr>::Type PlaceHolderExpr;
+ auto functors = internal::extractFunctors(evaluator);
- cgh.parallel_for(cl::sycl::nd_range<1>(cl::sycl::range<1>(GRange), cl::sycl::range<1>(tileSize)),
- ExecExprFunctorKernel<Expr,FunctorExpr,TupleType>(range
- , functors, tuple_of_accessors
- ));
+ size_t tileSize =dev.m_queue.get_device(). template get_info<cl::sycl::info::device::max_work_group_size>()/2;
+ dev.m_queue.submit([&](cl::sycl::handler &cgh) {
+
+ // create a tuple of accessors from Evaluator
+ auto tuple_of_accessors = internal::createTupleOfAccessors<decltype(evaluator)>(cgh, evaluator);
+ const auto range = utility::tuple::get<0>(tuple_of_accessors).get_range()[0];
+ size_t GRange=range;
+ if (tileSize>GRange) tileSize=GRange;
+ else if(GRange>tileSize){
+ size_t xMode = GRange % tileSize;
+ if (xMode != 0) GRange += (tileSize - xMode);
+ }
+ // run the kernel
+ cgh.parallel_for<PlaceHolderExpr>( cl::sycl::nd_range<1>(cl::sycl::range<1>(GRange), cl::sycl::range<1>(tileSize)), [=](cl::sycl::nd_item<1> itemID) {
+ typedef typename internal::ConvertToDeviceExpression<Expr>::Type DevExpr;
+ auto device_expr =internal::createDeviceExpression<DevExpr, PlaceHolderExpr>(functors, tuple_of_accessors);
+ auto device_evaluator = Eigen::TensorEvaluator<decltype(device_expr.expr), Eigen::DefaultDevice>(device_expr.expr, Eigen::DefaultDevice());
+ if (itemID.get_global_linear_id() < range) {
+ device_evaluator.evalScalar(static_cast<int>(itemID.get_global_linear_id()));
+ }
+ });
});
- dev.asynchronousExec();
+ dev.m_queue.throw_asynchronous();
}
+
evaluator.cleanup();
}
} // namespace TensorSycl
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclTuple.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclTuple.h
index 58ab0f0..063b027 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclTuple.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorSyclTuple.h
@@ -20,7 +20,6 @@
#ifndef UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCL_TUPLE_HPP
#define UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCL_TUPLE_HPP
-
namespace utility {
namespace tuple {
/// \struct StaticIf
@@ -232,5 +231,4 @@ Tuple<Args1..., Args2...> append(Tuple<Args1...> t1,Tuple<Args2...> t2) {
}
} // tuple
} // utility
-
#endif // UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCL_TUPLE_HPP
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h
index a1e944e..ffcf8b0 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h
@@ -58,8 +58,6 @@ struct traits<Tensor<Scalar_, NumIndices_, Options_, IndexType_> >
};
template <typename T> struct MakePointer {
typedef T* Type;
- typedef T& RefType;
-
};
};
@@ -78,8 +76,6 @@ struct traits<TensorFixedSize<Scalar_, Dimensions, Options_, IndexType_> >
};
template <typename T> struct MakePointer {
typedef T* Type;
- typedef T& RefType;
-
};
};
@@ -102,8 +98,6 @@ struct traits<TensorMap<PlainObjectType, Options_, MakePointer_> >
// Intermediate typedef to workaround MSVC issue.
typedef MakePointer_<T> MakePointerT;
typedef typename MakePointerT::Type Type;
- typedef typename MakePointerT::RefType RefType;
-
};
};
diff --git a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h
index d23f2e4..3523e7c 100644
--- a/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h
+++ b/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h
@@ -23,7 +23,6 @@ struct static_val {
template <typename T>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static_val(const T& v) {
- EIGEN_UNUSED_VARIABLE(v);
eigen_assert(v == n);
}
};
diff --git a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h
index 9dcc9da..354bce5 100644
--- a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h
+++ b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h
@@ -20,13 +20,7 @@ class NonBlockingThreadPoolTempl : public Eigen::ThreadPoolInterface {
typedef RunQueue<Task, 1024> Queue;
NonBlockingThreadPoolTempl(int num_threads, Environment env = Environment())
- : NonBlockingThreadPoolTempl(num_threads, true, env) {}
-
- NonBlockingThreadPoolTempl(int num_threads, bool allow_spinning,
- Environment env = Environment())
- : num_threads_(num_threads),
- allow_spinning_(allow_spinning),
- env_(env),
+ : env_(env),
threads_(num_threads),
queues_(num_threads),
coprimes_(num_threads),
@@ -34,20 +28,19 @@ class NonBlockingThreadPoolTempl : public Eigen::ThreadPoolInterface {
blocked_(0),
spinning_(0),
done_(false),
- cancelled_(false),
ec_(waiters_) {
- waiters_.resize(num_threads_);
+ waiters_.resize(num_threads);
- // Calculate coprimes of num_threads_.
+ // Calculate coprimes of num_threads.
// Coprimes are used for a random walk over all threads in Steal
// and NonEmptyQueueIndex. Iteration is based on the fact that if we take
// a walk starting thread index t and calculate num_threads - 1 subsequent
// indices as (t + coprime) % num_threads, we will cover all threads without
// repetitions (effectively getting a presudo-random permutation of thread
// indices).
- for (int i = 1; i <= num_threads_; i++) {
+ for (int i = 1; i <= num_threads; i++) {
unsigned a = i;
- unsigned b = num_threads_;
+ unsigned b = num_threads;
// If GCD(a, b) == 1, then a and b are coprimes.
while (b != 0) {
unsigned tmp = a;
@@ -58,33 +51,24 @@ class NonBlockingThreadPoolTempl : public Eigen::ThreadPoolInterface {
coprimes_.push_back(i);
}
}
- for (int i = 0; i < num_threads_; i++) {
+ for (int i = 0; i < num_threads; i++) {
queues_.push_back(new Queue());
}
- for (int i = 0; i < num_threads_; i++) {
+ for (int i = 0; i < num_threads; i++) {
threads_.push_back(env_.CreateThread([this, i]() { WorkerLoop(i); }));
}
}
~NonBlockingThreadPoolTempl() {
done_ = true;
-
// Now if all threads block without work, they will start exiting.
// But note that threads can continue to work arbitrary long,
// block, submit new work, unblock and otherwise live full life.
- if (!cancelled_) {
- ec_.Notify(true);
- } else {
- // Since we were cancelled, there might be entries in the queues.
- // Empty them to prevent their destructor from asserting.
- for (size_t i = 0; i < queues_.size(); i++) {
- queues_[i]->Flush();
- }
- }
+ ec_.Notify(true);
// Join threads explicitly to avoid destruction order issues.
- for (size_t i = 0; i < num_threads_; i++) delete threads_[i];
- for (size_t i = 0; i < num_threads_; i++) delete queues_[i];
+ for (size_t i = 0; i < threads_.size(); i++) delete threads_[i];
+ for (size_t i = 0; i < threads_.size(); i++) delete queues_[i];
}
void Schedule(std::function<void()> fn) {
@@ -107,31 +91,14 @@ class NonBlockingThreadPoolTempl : public Eigen::ThreadPoolInterface {
// completes overall computations, which in turn leads to destruction of
// this. We expect that such scenario is prevented by program, that is,
// this is kept alive while any threads can potentially be in Schedule.
- if (!t.f) {
+ if (!t.f)
ec_.Notify(false);
- }
- else {
+ else
env_.ExecuteTask(t); // Push failed, execute directly.
- }
- }
-
- void Cancel() {
- cancelled_ = true;
- done_ = true;
-
- // Let each thread know it's been cancelled.
-#ifdef EIGEN_THREAD_ENV_SUPPORTS_CANCELLATION
- for (size_t i = 0; i < threads_.size(); i++) {
- threads_[i]->OnCancel();
- }
-#endif
-
- // Wake up the threads without work to let them exit on their own.
- ec_.Notify(true);
}
int NumThreads() const final {
- return num_threads_;
+ return static_cast<int>(threads_.size());
}
int CurrentThreadId() const final {
@@ -155,8 +122,6 @@ class NonBlockingThreadPoolTempl : public Eigen::ThreadPoolInterface {
};
Environment env_;
- const int num_threads_;
- const bool allow_spinning_;
MaxSizeVector<Thread*> threads_;
MaxSizeVector<Queue*> queues_;
MaxSizeVector<unsigned> coprimes_;
@@ -164,7 +129,6 @@ class NonBlockingThreadPoolTempl : public Eigen::ThreadPoolInterface {
std::atomic<unsigned> blocked_;
std::atomic<bool> spinning_;
std::atomic<bool> done_;
- std::atomic<bool> cancelled_;
EventCount ec_;
// Main worker thread loop.
@@ -175,62 +139,32 @@ class NonBlockingThreadPoolTempl : public Eigen::ThreadPoolInterface {
pt->thread_id = thread_id;
Queue* q = queues_[thread_id];
EventCount::Waiter* waiter = &waiters_[thread_id];
- // TODO(dvyukov,rmlarsen): The time spent in Steal() is proportional
- // to num_threads_ and we assume that new work is scheduled at a
- // constant rate, so we set spin_count to 5000 / num_threads_. The
- // constant was picked based on a fair dice roll, tune it.
- const int spin_count =
- allow_spinning_ && num_threads_ > 0 ? 5000 / num_threads_ : 0;
- if (num_threads_ == 1) {
- // For num_threads_ == 1 there is no point in going through the expensive
- // steal loop. Moreover, since Steal() calls PopBack() on the victim
- // queues it might reverse the order in which ops are executed compared to
- // the order in which they are scheduled, which tends to be
- // counter-productive for the types of I/O workloads the single thread
- // pools tend to be used for.
- while (!cancelled_) {
- Task t = q->PopFront();
- for (int i = 0; i < spin_count && !t.f; i++) {
- if (!cancelled_.load(std::memory_order_relaxed)) {
- t = q->PopFront();
- }
- }
+ for (;;) {
+ Task t = q->PopFront();
+ if (!t.f) {
+ t = Steal();
if (!t.f) {
- if (!WaitForWork(waiter, &t)) {
- return;
+ // Leave one thread spinning. This reduces latency.
+ // TODO(dvyukov): 1000 iterations is based on fair dice roll, tune it.
+ // Also, the time it takes to attempt to steal work 1000 times depends
+ // on the size of the thread pool. However the speed at which the user
+ // of the thread pool submit tasks is independent of the size of the
+ // pool. Consider a time based limit instead.
+ if (!spinning_ && !spinning_.exchange(true)) {
+ for (int i = 0; i < 1000 && !t.f; i++) {
+ t = Steal();
+ }
+ spinning_ = false;
}
- }
- if (t.f) {
- env_.ExecuteTask(t);
- }
- }
- } else {
- while (!cancelled_) {
- Task t = q->PopFront();
- if (!t.f) {
- t = Steal();
if (!t.f) {
- // Leave one thread spinning. This reduces latency.
- if (allow_spinning_ && !spinning_ && !spinning_.exchange(true)) {
- for (int i = 0; i < spin_count && !t.f; i++) {
- if (!cancelled_.load(std::memory_order_relaxed)) {
- t = Steal();
- } else {
- return;
- }
- }
- spinning_ = false;
- }
- if (!t.f) {
- if (!WaitForWork(waiter, &t)) {
- return;
- }
+ if (!WaitForWork(waiter, &t)) {
+ return;
}
}
}
- if (t.f) {
- env_.ExecuteTask(t);
- }
+ }
+ if (t.f) {
+ env_.ExecuteTask(t);
}
}
}
@@ -267,18 +201,14 @@ class NonBlockingThreadPoolTempl : public Eigen::ThreadPoolInterface {
int victim = NonEmptyQueueIndex();
if (victim != -1) {
ec_.CancelWait(waiter);
- if (cancelled_) {
- return false;
- } else {
- *t = queues_[victim]->PopBack();
- return true;
- }
+ *t = queues_[victim]->PopBack();
+ return true;
}
// Number of blocked threads is used as termination condition.
// If we are shutting down and all worker threads blocked without work,
// that's we are done.
blocked_++;
- if (done_ && blocked_ == num_threads_) {
+ if (done_ && blocked_ == threads_.size()) {
ec_.CancelWait(waiter);
// Almost done, but need to re-check queues.
// Consider that all queues are empty and all worker threads are preempted
diff --git a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h
index 49d0cdc..05ed76c 100644
--- a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h
+++ b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h
@@ -177,13 +177,6 @@ class RunQueue {
// Can be called by any thread at any time.
bool Empty() const { return Size() == 0; }
- // Delete all the elements from the queue.
- void Flush() {
- while (!Empty()) {
- PopFront();
- }
- }
-
private:
static const unsigned kMask = kSize - 1;
static const unsigned kMask2 = (kSize << 1) - 1;
diff --git a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h
index 3357286..e75d0f4 100644
--- a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h
+++ b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h
@@ -69,14 +69,6 @@ class SimpleThreadPoolTempl : public ThreadPoolInterface {
}
}
- void Cancel() {
-#ifdef EIGEN_THREAD_ENV_SUPPORTS_CANCELLATION
- for (size_t i = 0; i < threads_.size(); i++) {
- threads_[i]->OnCancel();
- }
-#endif
- }
-
int NumThreads() const final {
return static_cast<int>(threads_.size());
}
diff --git a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadCancel.h b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadCancel.h
deleted file mode 100644
index a05685f..0000000
--- a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadCancel.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016 Benoit Steiner <benoit.steiner.goog@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_CXX11_THREADPOOL_THREAD_CANCEL_H
-#define EIGEN_CXX11_THREADPOOL_THREAD_CANCEL_H
-
-// Try to come up with a portable way to cancel a thread
-#if EIGEN_OS_GNULINUX
- #define EIGEN_THREAD_CANCEL(t) \
- pthread_cancel(t.native_handle());
- #define EIGEN_SUPPORTS_THREAD_CANCELLATION 1
-#else
-#define EIGEN_THREAD_CANCEL(t)
-#endif
-
-
-#endif // EIGEN_CXX11_THREADPOOL_THREAD_CANCEL_H
diff --git a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h
index d94a064..399f95c 100644
--- a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h
+++ b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h
@@ -23,8 +23,6 @@ struct StlThreadEnvironment {
public:
EnvThread(std::function<void()> f) : thr_(std::move(f)) {}
~EnvThread() { thr_.join(); }
- // This function is called when the threadpool is cancelled.
- void OnCancel() { }
private:
std::thread thr_;
diff --git a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h
index 84e1e6c..a65ee97 100644
--- a/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h
+++ b/eigen/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h
@@ -16,14 +16,8 @@ namespace Eigen {
// custom thread pools underneath.
class ThreadPoolInterface {
public:
- // Submits a closure to be run by a thread in the pool.
virtual void Schedule(std::function<void()> fn) = 0;
- // If implemented, stop processing the closures that have been enqueued.
- // Currently running closures may still be processed.
- // If not implemented, does nothing.
- virtual void Cancel() {}
-
// Returns the number of threads in the pool.
virtual int NumThreads() const = 0;
diff --git a/eigen/unsupported/Eigen/CXX11/src/util/CXX11Meta.h b/eigen/unsupported/Eigen/CXX11/src/util/CXX11Meta.h
index 49d315a..ec27edd 100644
--- a/eigen/unsupported/Eigen/CXX11/src/util/CXX11Meta.h
+++ b/eigen/unsupported/Eigen/CXX11/src/util/CXX11Meta.h
@@ -40,7 +40,7 @@ template<typename T, T... nn>
struct numeric_list { constexpr static std::size_t count = sizeof...(nn); };
template<typename T, T n, T... nn>
-struct numeric_list<T, n, nn...> { static const std::size_t count = sizeof...(nn) + 1; const static T first_value = n; };
+struct numeric_list<T, n, nn...> { constexpr static std::size_t count = sizeof...(nn) + 1; constexpr static T first_value = n; };
/* numeric list constructors
*
@@ -123,10 +123,6 @@ template<typename a, typename... as> struct get<0, type_lis
template<typename T, int n, T a, T... as> struct get<n, numeric_list<T, a, as...>> : get<n-1, numeric_list<T, as...>> {};
template<typename T, T a, T... as> struct get<0, numeric_list<T, a, as...>> { constexpr static T value = a; };
-template<std::size_t n, typename T, T a, T... as> constexpr T array_get(const numeric_list<T, a, as...>&) {
- return get<(int)n, numeric_list<T, a, as...>>::value;
-}
-
/* always get type, regardless of dummy; good for parameter pack expansion */
template<typename T, T dummy, typename t> struct id_numeric { typedef t type; };
diff --git a/eigen/unsupported/Eigen/CXX11/src/util/EmulateArray.h b/eigen/unsupported/Eigen/CXX11/src/util/EmulateArray.h
index 573ca43..30d3ebc 100644
--- a/eigen/unsupported/Eigen/CXX11/src/util/EmulateArray.h
+++ b/eigen/unsupported/Eigen/CXX11/src/util/EmulateArray.h
@@ -169,7 +169,6 @@ template <typename T> class array<T, 0> {
#if EIGEN_HAS_VARIADIC_TEMPLATES
EIGEN_DEVICE_FUNC array(std::initializer_list<T> l) : dummy() {
- EIGEN_UNUSED_VARIABLE(l);
eigen_assert(l.size() == 0);
}
#endif
@@ -201,15 +200,19 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T,N>& a) {
return a[I];
}
+template <typename T> struct array_size;
template<class T, std::size_t N> struct array_size<array<T,N> > {
static const size_t value = N;
};
+template <typename T> struct array_size;
template<class T, std::size_t N> struct array_size<array<T,N>& > {
static const size_t value = N;
};
+template <typename T> struct array_size;
template<class T, std::size_t N> struct array_size<const array<T,N> > {
static const size_t value = N;
};
+template <typename T> struct array_size;
template<class T, std::size_t N> struct array_size<const array<T,N>& > {
static const size_t value = N;
};
@@ -248,6 +251,14 @@ template<std::size_t I, class T, std::size_t N> constexpr inline T const& array_
#undef STD_GET_ARR_HACK
+template <typename T> struct array_size;
+template<class T, std::size_t N> struct array_size<const std::array<T,N> > {
+ static const size_t value = N;
+};
+template <typename T> struct array_size;
+template<class T, std::size_t N> struct array_size<std::array<T,N> > {
+ static const size_t value = N;
+};
} // end namespace internal
} // end namespace Eigen
diff --git a/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
index d280886..279fe5c 100644
--- a/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
+++ b/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
@@ -683,4 +683,11 @@ template<typename DerType> struct NumTraits<AutoDiffScalar<DerType> >
}
+namespace std {
+template <typename T>
+class numeric_limits<Eigen::AutoDiffScalar<T> >
+ : public numeric_limits<typename T::Scalar> {};
+
+} // namespace std
+
#endif // EIGEN_AUTODIFF_SCALAR_H
diff --git a/eigen/unsupported/Eigen/src/EulerAngles/EulerAngles.h b/eigen/unsupported/Eigen/src/EulerAngles/EulerAngles.h
index a5d034d..13a0da1 100644
--- a/eigen/unsupported/Eigen/src/EulerAngles/EulerAngles.h
+++ b/eigen/unsupported/Eigen/src/EulerAngles/EulerAngles.h
@@ -12,6 +12,11 @@
namespace Eigen
{
+ /*template<typename Other,
+ int OtherRows=Other::RowsAtCompileTime,
+ int OtherCols=Other::ColsAtCompileTime>
+ struct ei_eulerangles_assign_impl;*/
+
/** \class EulerAngles
*
* \ingroup EulerAngles_Module
@@ -31,7 +36,7 @@ namespace Eigen
* ### Rotation representation and conversions ###
*
* It has been proved(see Wikipedia link below) that every rotation can be represented
- * by Euler angles, but there is no single representation (e.g. unlike rotation matrices).
+ * by Euler angles, but there is no singular representation (e.g. unlike rotation matrices).
* Therefore, you can convert from Eigen rotation and to them
* (including rotation matrices, which is not called "rotations" by Eigen design).
*
@@ -50,27 +55,33 @@ namespace Eigen
* Additionally, some axes related computation is done in compile time.
*
* #### Euler angles ranges in conversions ####
- * Rotations representation as EulerAngles are not single (unlike matrices),
- * and even have infinite EulerAngles representations.<BR>
- * For example, add or subtract 2*PI from either angle of EulerAngles
- * and you'll get the same rotation.
- * This is the general reason for infinite representation,
- * but it's not the only general reason for not having a single representation.
*
- * When converting rotation to EulerAngles, this class convert it to specific ranges
- * When converting some rotation to EulerAngles, the rules for ranges are as follow:
- * - If the rotation we converting from is an EulerAngles
- * (even when it represented as RotationBase explicitly), angles ranges are __undefined__.
- * - otherwise, alpha and gamma angles will be in the range [-PI, PI].<BR>
- * As for Beta angle:
- * - If the system is Tait-Bryan, the beta angle will be in the range [-PI/2, PI/2].
- * - otherwise:
- * - If the beta axis is positive, the beta angle will be in the range [0, PI]
- * - If the beta axis is negative, the beta angle will be in the range [-PI, 0]
+ * When converting some rotation to Euler angles, there are some ways you can guarantee
+ * the Euler angles ranges.
*
+ * #### implicit ranges ####
+ * When using implicit ranges, all angles are guarantee to be in the range [-PI, +PI],
+ * unless you convert from some other Euler angles.
+ * In this case, the range is __undefined__ (might be even less than -PI or greater than +2*PI).
* \sa EulerAngles(const MatrixBase<Derived>&)
* \sa EulerAngles(const RotationBase<Derived, 3>&)
*
+ * #### explicit ranges ####
+ * When using explicit ranges, all angles are guarantee to be in the range you choose.
+ * In the range Boolean parameter, you're been ask whether you prefer the positive range or not:
+ * - _true_ - force the range between [0, +2*PI]
+ * - _false_ - force the range between [-PI, +PI]
+ *
+ * ##### compile time ranges #####
+ * This is when you have compile time ranges and you prefer to
+ * use template parameter. (e.g. for performance)
+ * \sa FromRotation()
+ *
+ * ##### run-time time ranges #####
+ * Run-time ranges are also supported.
+ * \sa EulerAngles(const MatrixBase<Derived>&, bool, bool, bool)
+ * \sa EulerAngles(const RotationBase<Derived, 3>&, bool, bool, bool)
+ *
* ### Convenient user typedefs ###
*
* Convenient typedefs for EulerAngles exist for float and double scalar,
@@ -92,7 +103,7 @@ namespace Eigen
*
* More information about Euler angles: https://en.wikipedia.org/wiki/Euler_angles
*
- * \tparam _Scalar the scalar type, i.e. the type of the angles.
+ * \tparam _Scalar the scalar type, i.e., the type of the angles.
*
* \tparam _System the EulerSystem to use, which represents the axes of rotation.
*/
@@ -100,11 +111,8 @@ namespace Eigen
class EulerAngles : public RotationBase<EulerAngles<_Scalar, _System>, 3>
{
public:
- typedef RotationBase<EulerAngles<_Scalar, _System>, 3> Base;
-
/** the scalar type of the angles */
typedef _Scalar Scalar;
- typedef typename NumTraits<Scalar>::Real RealScalar;
/** the EulerSystem to use, which represents the axes of rotation. */
typedef _System System;
@@ -138,56 +146,67 @@ namespace Eigen
public:
/** Default constructor without initialization. */
EulerAngles() {}
- /** Constructs and initialize an EulerAngles (\p alpha, \p beta, \p gamma). */
+ /** Constructs and initialize Euler angles(\p alpha, \p beta, \p gamma). */
EulerAngles(const Scalar& alpha, const Scalar& beta, const Scalar& gamma) :
m_angles(alpha, beta, gamma) {}
- // TODO: Test this constructor
- /** Constructs and initialize an EulerAngles from the array data {alpha, beta, gamma} */
- explicit EulerAngles(const Scalar* data) : m_angles(data) {}
+ /** Constructs and initialize Euler angles from a 3x3 rotation matrix \p m.
+ *
+ * \note All angles will be in the range [-PI, PI].
+ */
+ template<typename Derived>
+ EulerAngles(const MatrixBase<Derived>& m) { *this = m; }
- /** Constructs and initializes an EulerAngles from either:
- * - a 3x3 rotation matrix expression(i.e. pure orthogonal matrix with determinant of +1),
- * - a 3D vector expression representing Euler angles.
+ /** Constructs and initialize Euler angles from a 3x3 rotation matrix \p m,
+ * with options to choose for each angle the requested range.
+ *
+ * If positive range is true, then the specified angle will be in the range [0, +2*PI].
+ * Otherwise, the specified angle will be in the range [-PI, +PI].
*
- * \note If \p other is a 3x3 rotation matrix, the angles range rules will be as follow:<BR>
- * Alpha and gamma angles will be in the range [-PI, PI].<BR>
- * As for Beta angle:
- * - If the system is Tait-Bryan, the beta angle will be in the range [-PI/2, PI/2].
- * - otherwise:
- * - If the beta axis is positive, the beta angle will be in the range [0, PI]
- * - If the beta axis is negative, the beta angle will be in the range [-PI, 0]
- */
+ * \param m The 3x3 rotation matrix to convert
+ * \param positiveRangeAlpha If true, alpha will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ * \param positiveRangeBeta If true, beta will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ * \param positiveRangeGamma If true, gamma will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ */
template<typename Derived>
- explicit EulerAngles(const MatrixBase<Derived>& other) { *this = other; }
+ EulerAngles(
+ const MatrixBase<Derived>& m,
+ bool positiveRangeAlpha,
+ bool positiveRangeBeta,
+ bool positiveRangeGamma) {
+
+ System::CalcEulerAngles(*this, m, positiveRangeAlpha, positiveRangeBeta, positiveRangeGamma);
+ }
/** Constructs and initialize Euler angles from a rotation \p rot.
*
- * \note If \p rot is an EulerAngles (even when it represented as RotationBase explicitly),
- * angles ranges are __undefined__.
- * Otherwise, alpha and gamma angles will be in the range [-PI, PI].<BR>
- * As for Beta angle:
- * - If the system is Tait-Bryan, the beta angle will be in the range [-PI/2, PI/2].
- * - otherwise:
- * - If the beta axis is positive, the beta angle will be in the range [0, PI]
- * - If the beta axis is negative, the beta angle will be in the range [-PI, 0]
+ * \note All angles will be in the range [-PI, PI], unless \p rot is an EulerAngles.
+ * If rot is an EulerAngles, expected EulerAngles range is __undefined__.
+ * (Use other functions here for enforcing range if this effect is desired)
*/
template<typename Derived>
- EulerAngles(const RotationBase<Derived, 3>& rot) { System::CalcEulerAngles(*this, rot.toRotationMatrix()); }
+ EulerAngles(const RotationBase<Derived, 3>& rot) { *this = rot; }
- /*EulerAngles(const QuaternionType& q)
- {
- // TODO: Implement it in a faster way for quaternions
- // According to http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
- // we can compute only the needed matrix cells and then convert to euler angles. (see ZYX example below)
- // Currently we compute all matrix cells from quaternion.
-
- // Special case only for ZYX
- //Scalar y2 = q.y() * q.y();
- //m_angles[0] = std::atan2(2*(q.w()*q.z() + q.x()*q.y()), (1 - 2*(y2 + q.z()*q.z())));
- //m_angles[1] = std::asin( 2*(q.w()*q.y() - q.z()*q.x()));
- //m_angles[2] = std::atan2(2*(q.w()*q.x() + q.y()*q.z()), (1 - 2*(q.x()*q.x() + y2)));
- }*/
+ /** Constructs and initialize Euler angles from a rotation \p rot,
+ * with options to choose for each angle the requested range.
+ *
+ * If positive range is true, then the specified angle will be in the range [0, +2*PI].
+ * Otherwise, the specified angle will be in the range [-PI, +PI].
+ *
+ * \param rot The 3x3 rotation matrix to convert
+ * \param positiveRangeAlpha If true, alpha will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ * \param positiveRangeBeta If true, beta will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ * \param positiveRangeGamma If true, gamma will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ */
+ template<typename Derived>
+ EulerAngles(
+ const RotationBase<Derived, 3>& rot,
+ bool positiveRangeAlpha,
+ bool positiveRangeBeta,
+ bool positiveRangeGamma) {
+
+ System::CalcEulerAngles(*this, rot.toRotationMatrix(), positiveRangeAlpha, positiveRangeBeta, positiveRangeGamma);
+ }
/** \returns The angle values stored in a vector (alpha, beta, gamma). */
const Vector3& angles() const { return m_angles; }
@@ -227,48 +246,90 @@ namespace Eigen
return inverse();
}
- /** Set \c *this from either:
- * - a 3x3 rotation matrix expression(i.e. pure orthogonal matrix with determinant of +1),
- * - a 3D vector expression representing Euler angles.
+ /** Constructs and initialize Euler angles from a 3x3 rotation matrix \p m,
+ * with options to choose for each angle the requested range (__only in compile time__).
*
- * See EulerAngles(const MatrixBase<Derived, 3>&) for more information about
- * angles ranges output.
+ * If positive range is true, then the specified angle will be in the range [0, +2*PI].
+ * Otherwise, the specified angle will be in the range [-PI, +PI].
+ *
+ * \param m The 3x3 rotation matrix to convert
+ * \tparam positiveRangeAlpha If true, alpha will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ * \tparam positiveRangeBeta If true, beta will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ * \tparam positiveRangeGamma If true, gamma will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ */
+ template<
+ bool PositiveRangeAlpha,
+ bool PositiveRangeBeta,
+ bool PositiveRangeGamma,
+ typename Derived>
+ static EulerAngles FromRotation(const MatrixBase<Derived>& m)
+ {
+ EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3)
+
+ EulerAngles e;
+ System::template CalcEulerAngles<
+ PositiveRangeAlpha, PositiveRangeBeta, PositiveRangeGamma, _Scalar>(e, m);
+ return e;
+ }
+
+ /** Constructs and initialize Euler angles from a rotation \p rot,
+ * with options to choose for each angle the requested range (__only in compile time__).
+ *
+ * If positive range is true, then the specified angle will be in the range [0, +2*PI].
+ * Otherwise, the specified angle will be in the range [-PI, +PI].
+ *
+ * \param rot The 3x3 rotation matrix to convert
+ * \tparam positiveRangeAlpha If true, alpha will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ * \tparam positiveRangeBeta If true, beta will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
+ * \tparam positiveRangeGamma If true, gamma will be in [0, 2*PI]. Otherwise, in [-PI, +PI].
*/
- template<class Derived>
- EulerAngles& operator=(const MatrixBase<Derived>& other)
+ template<
+ bool PositiveRangeAlpha,
+ bool PositiveRangeBeta,
+ bool PositiveRangeGamma,
+ typename Derived>
+ static EulerAngles FromRotation(const RotationBase<Derived, 3>& rot)
+ {
+ return FromRotation<PositiveRangeAlpha, PositiveRangeBeta, PositiveRangeGamma>(rot.toRotationMatrix());
+ }
+
+ /*EulerAngles& fromQuaternion(const QuaternionType& q)
{
- EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename Derived::Scalar>::value),
- YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+ // TODO: Implement it in a faster way for quaternions
+ // According to http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
+ // we can compute only the needed matrix cells and then convert to euler angles. (see ZYX example below)
+ // Currently we compute all matrix cells from quaternion.
+
+ // Special case only for ZYX
+ //Scalar y2 = q.y() * q.y();
+ //m_angles[0] = std::atan2(2*(q.w()*q.z() + q.x()*q.y()), (1 - 2*(y2 + q.z()*q.z())));
+ //m_angles[1] = std::asin( 2*(q.w()*q.y() - q.z()*q.x()));
+ //m_angles[2] = std::atan2(2*(q.w()*q.x() + q.y()*q.z()), (1 - 2*(q.x()*q.x() + y2)));
+ }*/
+
+ /** Set \c *this from a rotation matrix(i.e. pure orthogonal matrix with determinant of +1). */
+ template<typename Derived>
+ EulerAngles& operator=(const MatrixBase<Derived>& m) {
+ EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3)
- internal::eulerangles_assign_impl<System, Derived>::run(*this, other.derived());
+ System::CalcEulerAngles(*this, m);
return *this;
}
// TODO: Assign and construct from another EulerAngles (with different system)
- /** Set \c *this from a rotation.
- *
- * See EulerAngles(const RotationBase<Derived, 3>&) for more information about
- * angles ranges output.
- */
+ /** Set \c *this from a rotation. */
template<typename Derived>
EulerAngles& operator=(const RotationBase<Derived, 3>& rot) {
System::CalcEulerAngles(*this, rot.toRotationMatrix());
return *this;
}
- /** \returns \c true if \c *this is approximately equal to \a other, within the precision
- * determined by \a prec.
- *
- * \sa MatrixBase::isApprox() */
- bool isApprox(const EulerAngles& other,
- const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
- { return angles().isApprox(other.angles(), prec); }
+ // TODO: Support isApprox function
/** \returns an equivalent 3x3 rotation matrix. */
Matrix3 toRotationMatrix() const
{
- // TODO: Calc it faster
return static_cast<QuaternionType>(*this).toRotationMatrix();
}
@@ -286,15 +347,6 @@ namespace Eigen
s << eulerAngles.angles().transpose();
return s;
}
-
- /** \returns \c *this with scalar type casted to \a NewScalarType */
- template <typename NewScalarType>
- EulerAngles<NewScalarType, System> cast() const
- {
- EulerAngles<NewScalarType, System> e;
- e.angles() = angles().template cast<NewScalarType>();
- return e;
- }
};
#define EIGEN_EULER_ANGLES_SINGLE_TYPEDEF(AXES, SCALAR_TYPE, SCALAR_POSTFIX) \
@@ -327,29 +379,8 @@ EIGEN_EULER_ANGLES_TYPEDEFS(double, d)
{
typedef _Scalar Scalar;
};
-
- // set from a rotation matrix
- template<class System, class Other>
- struct eulerangles_assign_impl<System,Other,3,3>
- {
- typedef typename Other::Scalar Scalar;
- static void run(EulerAngles<Scalar, System>& e, const Other& m)
- {
- System::CalcEulerAngles(e, m);
- }
- };
-
- // set from a vector of Euler angles
- template<class System, class Other>
- struct eulerangles_assign_impl<System,Other,4,1>
- {
- typedef typename Other::Scalar Scalar;
- static void run(EulerAngles<Scalar, System>& e, const Other& vec)
- {
- e.angles() = vec;
- }
- };
}
+
}
#endif // EIGEN_EULERANGLESCLASS_H
diff --git a/eigen/unsupported/Eigen/src/EulerAngles/EulerSystem.h b/eigen/unsupported/Eigen/src/EulerAngles/EulerSystem.h
index 28f52da..98f9f64 100644
--- a/eigen/unsupported/Eigen/src/EulerAngles/EulerSystem.h
+++ b/eigen/unsupported/Eigen/src/EulerAngles/EulerSystem.h
@@ -18,7 +18,7 @@ namespace Eigen
namespace internal
{
- // TODO: Add this trait to the Eigen internal API?
+ // TODO: Check if already exists on the rest API
template <int Num, bool IsPositive = (Num > 0)>
struct Abs
{
@@ -36,12 +36,6 @@ namespace Eigen
{
enum { value = Axis != 0 && Abs<Axis>::value <= 3 };
};
-
- template<typename System,
- typename Other,
- int OtherRows=Other::RowsAtCompileTime,
- int OtherCols=Other::ColsAtCompileTime>
- struct eulerangles_assign_impl;
}
#define EIGEN_EULER_ANGLES_CLASS_STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(COND)?1:-1]
@@ -75,7 +69,7 @@ namespace Eigen
*
* You can use this class to get two things:
* - Build an Euler system, and then pass it as a template parameter to EulerAngles.
- * - Query some compile time data about an Euler system. (e.g. Whether it's Tait-Bryan)
+ * - Query some compile time data about an Euler system. (e.g. Whether it's tait bryan)
*
* Euler rotation is a set of three rotation on fixed axes. (see \ref EulerAngles)
* This meta-class store constantly those signed axes. (see \ref EulerAxis)
@@ -86,7 +80,7 @@ namespace Eigen
* signed axes{+X,+Y,+Z,-X,-Y,-Z} are supported:
* - all axes X, Y, Z in each valid order (see below what order is valid)
* - rotation over the axis is supported both over the positive and negative directions.
- * - both Tait-Bryan and proper/classic Euler angles (i.e. the opposite).
+ * - both tait bryan and proper/classic Euler angles (i.e. the opposite).
*
* Since EulerSystem support both positive and negative directions,
* you may call this rotation distinction in other names:
@@ -96,7 +90,7 @@ namespace Eigen
* Notice all axed combination are valid, and would trigger a static assertion.
* Same unsigned axes can't be neighbors, e.g. {X,X,Y} is invalid.
* This yield two and only two classes:
- * - _Tait-Bryan_ - all unsigned axes are distinct, e.g. {X,Y,Z}
+ * - _tait bryan_ - all unsigned axes are distinct, e.g. {X,Y,Z}
* - _proper/classic Euler angles_ - The first and the third unsigned axes is equal,
* and the second is different, e.g. {X,Y,X}
*
@@ -118,9 +112,9 @@ namespace Eigen
*
* \tparam _AlphaAxis the first fixed EulerAxis
*
- * \tparam _BetaAxis the second fixed EulerAxis
+ * \tparam _AlphaAxis the second fixed EulerAxis
*
- * \tparam _GammaAxis the third fixed EulerAxis
+ * \tparam _AlphaAxis the third fixed EulerAxis
*/
template <int _AlphaAxis, int _BetaAxis, int _GammaAxis>
class EulerSystem
@@ -144,16 +138,14 @@ namespace Eigen
BetaAxisAbs = internal::Abs<BetaAxis>::value, /*!< the second rotation axis unsigned */
GammaAxisAbs = internal::Abs<GammaAxis>::value, /*!< the third rotation axis unsigned */
- IsAlphaOpposite = (AlphaAxis < 0) ? 1 : 0, /*!< whether alpha axis is negative */
- IsBetaOpposite = (BetaAxis < 0) ? 1 : 0, /*!< whether beta axis is negative */
- IsGammaOpposite = (GammaAxis < 0) ? 1 : 0, /*!< whether gamma axis is negative */
-
- // Parity is even if alpha axis X is followed by beta axis Y, or Y is followed
- // by Z, or Z is followed by X; otherwise it is odd.
- IsOdd = ((AlphaAxisAbs)%3 == (BetaAxisAbs - 1)%3) ? 0 : 1, /*!< whether the Euler system is odd */
- IsEven = IsOdd ? 0 : 1, /*!< whether the Euler system is even */
+ IsAlphaOpposite = (AlphaAxis < 0) ? 1 : 0, /*!< weather alpha axis is negative */
+ IsBetaOpposite = (BetaAxis < 0) ? 1 : 0, /*!< weather beta axis is negative */
+ IsGammaOpposite = (GammaAxis < 0) ? 1 : 0, /*!< weather gamma axis is negative */
+
+ IsOdd = ((AlphaAxisAbs)%3 == (BetaAxisAbs - 1)%3) ? 0 : 1, /*!< weather the Euler system is odd */
+ IsEven = IsOdd ? 0 : 1, /*!< weather the Euler system is even */
- IsTaitBryan = ((unsigned)AlphaAxisAbs != (unsigned)GammaAxisAbs) ? 1 : 0 /*!< whether the Euler system is Tait-Bryan */
+ IsTaitBryan = ((unsigned)AlphaAxisAbs != (unsigned)GammaAxisAbs) ? 1 : 0 /*!< weather the Euler system is tait bryan */
};
private:
@@ -188,70 +180,71 @@ namespace Eigen
static void CalcEulerAngles_imp(Matrix<typename MatrixBase<Derived>::Scalar, 3, 1>& res, const MatrixBase<Derived>& mat, internal::true_type /*isTaitBryan*/)
{
using std::atan2;
- using std::sqrt;
+ using std::sin;
+ using std::cos;
typedef typename Derived::Scalar Scalar;
-
- const Scalar plusMinus = IsEven? 1 : -1;
- const Scalar minusPlus = IsOdd? 1 : -1;
-
- const Scalar Rsum = sqrt((mat(I,I) * mat(I,I) + mat(I,J) * mat(I,J) + mat(J,K) * mat(J,K) + mat(K,K) * mat(K,K))/2);
- res[1] = atan2(plusMinus * mat(I,K), Rsum);
-
- // There is a singularity when cos(beta) == 0
- if(Rsum > 4 * NumTraits<Scalar>::epsilon()) {// cos(beta) != 0
- res[0] = atan2(minusPlus * mat(J, K), mat(K, K));
- res[2] = atan2(minusPlus * mat(I, J), mat(I, I));
- }
- else if(plusMinus * mat(I, K) > 0) {// cos(beta) == 0 and sin(beta) == 1
- Scalar spos = mat(J, I) + plusMinus * mat(K, J); // 2*sin(alpha + plusMinus * gamma
- Scalar cpos = mat(J, J) + minusPlus * mat(K, I); // 2*cos(alpha + plusMinus * gamma)
- Scalar alphaPlusMinusGamma = atan2(spos, cpos);
- res[0] = alphaPlusMinusGamma;
- res[2] = 0;
- }
- else {// cos(beta) == 0 and sin(beta) == -1
- Scalar sneg = plusMinus * (mat(K, J) + minusPlus * mat(J, I)); // 2*sin(alpha + minusPlus*gamma)
- Scalar cneg = mat(J, J) + plusMinus * mat(K, I); // 2*cos(alpha + minusPlus*gamma)
- Scalar alphaMinusPlusBeta = atan2(sneg, cneg);
- res[0] = alphaMinusPlusBeta;
- res[2] = 0;
+ typedef Matrix<Scalar,2,1> Vector2;
+
+ res[0] = atan2(mat(J,K), mat(K,K));
+ Scalar c2 = Vector2(mat(I,I), mat(I,J)).norm();
+ if((IsOdd && res[0]<Scalar(0)) || ((!IsOdd) && res[0]>Scalar(0))) {
+ if(res[0] > Scalar(0)) {
+ res[0] -= Scalar(EIGEN_PI);
+ }
+ else {
+ res[0] += Scalar(EIGEN_PI);
+ }
+ res[1] = atan2(-mat(I,K), -c2);
}
+ else
+ res[1] = atan2(-mat(I,K), c2);
+ Scalar s1 = sin(res[0]);
+ Scalar c1 = cos(res[0]);
+ res[2] = atan2(s1*mat(K,I)-c1*mat(J,I), c1*mat(J,J) - s1 * mat(K,J));
}
template <typename Derived>
- static void CalcEulerAngles_imp(Matrix<typename MatrixBase<Derived>::Scalar,3,1>& res,
- const MatrixBase<Derived>& mat, internal::false_type /*isTaitBryan*/)
+ static void CalcEulerAngles_imp(Matrix<typename MatrixBase<Derived>::Scalar,3,1>& res, const MatrixBase<Derived>& mat, internal::false_type /*isTaitBryan*/)
{
using std::atan2;
- using std::sqrt;
+ using std::sin;
+ using std::cos;
typedef typename Derived::Scalar Scalar;
-
- const Scalar plusMinus = IsEven? 1 : -1;
- const Scalar minusPlus = IsOdd? 1 : -1;
-
- const Scalar Rsum = sqrt((mat(I, J) * mat(I, J) + mat(I, K) * mat(I, K) + mat(J, I) * mat(J, I) + mat(K, I) * mat(K, I)) / 2);
-
- res[1] = atan2(Rsum, mat(I, I));
-
- // There is a singularity when sin(beta) == 0
- if(Rsum > 4 * NumTraits<Scalar>::epsilon()) {// sin(beta) != 0
- res[0] = atan2(mat(J, I), minusPlus * mat(K, I));
- res[2] = atan2(mat(I, J), plusMinus * mat(I, K));
- }
- else if(mat(I, I) > 0) {// sin(beta) == 0 and cos(beta) == 1
- Scalar spos = plusMinus * mat(K, J) + minusPlus * mat(J, K); // 2*sin(alpha + gamma)
- Scalar cpos = mat(J, J) + mat(K, K); // 2*cos(alpha + gamma)
- res[0] = atan2(spos, cpos);
- res[2] = 0;
+ typedef Matrix<Scalar,2,1> Vector2;
+
+ res[0] = atan2(mat(J,I), mat(K,I));
+ if((IsOdd && res[0]<Scalar(0)) || ((!IsOdd) && res[0]>Scalar(0)))
+ {
+ if(res[0] > Scalar(0)) {
+ res[0] -= Scalar(EIGEN_PI);
+ }
+ else {
+ res[0] += Scalar(EIGEN_PI);
+ }
+ Scalar s2 = Vector2(mat(J,I), mat(K,I)).norm();
+ res[1] = -atan2(s2, mat(I,I));
}
- else {// sin(beta) == 0 and cos(beta) == -1
- Scalar sneg = plusMinus * mat(K, J) + plusMinus * mat(J, K); // 2*sin(alpha - gamma)
- Scalar cneg = mat(J, J) - mat(K, K); // 2*cos(alpha - gamma)
- res[0] = atan2(sneg, cneg);
- res[2] = 0;
+ else
+ {
+ Scalar s2 = Vector2(mat(J,I), mat(K,I)).norm();
+ res[1] = atan2(s2, mat(I,I));
}
+
+ // With a=(0,1,0), we have i=0; j=1; k=2, and after computing the first two angles,
+ // we can compute their respective rotation, and apply its inverse to M. Since the result must
+ // be a rotation around x, we have:
+ //
+ // c2 s1.s2 c1.s2 1 0 0
+ // 0 c1 -s1 * M = 0 c3 s3
+ // -s2 s1.c2 c1.c2 0 -s3 c3
+ //
+ // Thus: m11.c1 - m21.s1 = c3 & m12.c1 - m22.s1 = s3
+
+ Scalar s1 = sin(res[0]);
+ Scalar c1 = cos(res[0]);
+ res[2] = atan2(c1*mat(J,K)-s1*mat(K,K), c1*mat(J,J) - s1 * mat(K,J));
}
template<typename Scalar>
@@ -259,28 +252,55 @@ namespace Eigen
EulerAngles<Scalar, EulerSystem>& res,
const typename EulerAngles<Scalar, EulerSystem>::Matrix3& mat)
{
+ CalcEulerAngles(res, mat, false, false, false);
+ }
+
+ template<
+ bool PositiveRangeAlpha,
+ bool PositiveRangeBeta,
+ bool PositiveRangeGamma,
+ typename Scalar>
+ static void CalcEulerAngles(
+ EulerAngles<Scalar, EulerSystem>& res,
+ const typename EulerAngles<Scalar, EulerSystem>::Matrix3& mat)
+ {
+ CalcEulerAngles(res, mat, PositiveRangeAlpha, PositiveRangeBeta, PositiveRangeGamma);
+ }
+
+ template<typename Scalar>
+ static void CalcEulerAngles(
+ EulerAngles<Scalar, EulerSystem>& res,
+ const typename EulerAngles<Scalar, EulerSystem>::Matrix3& mat,
+ bool PositiveRangeAlpha,
+ bool PositiveRangeBeta,
+ bool PositiveRangeGamma)
+ {
CalcEulerAngles_imp(
res.angles(), mat,
typename internal::conditional<IsTaitBryan, internal::true_type, internal::false_type>::type());
- if (IsAlphaOpposite)
+ if (IsAlphaOpposite == IsOdd)
res.alpha() = -res.alpha();
- if (IsBetaOpposite)
+ if (IsBetaOpposite == IsOdd)
res.beta() = -res.beta();
- if (IsGammaOpposite)
+ if (IsGammaOpposite == IsOdd)
res.gamma() = -res.gamma();
+
+ // Saturate results to the requested range
+ if (PositiveRangeAlpha && (res.alpha() < 0))
+ res.alpha() += Scalar(2 * EIGEN_PI);
+
+ if (PositiveRangeBeta && (res.beta() < 0))
+ res.beta() += Scalar(2 * EIGEN_PI);
+
+ if (PositiveRangeGamma && (res.gamma() < 0))
+ res.gamma() += Scalar(2 * EIGEN_PI);
}
template <typename _Scalar, class _System>
friend class Eigen::EulerAngles;
-
- template<typename System,
- typename Other,
- int OtherRows,
- int OtherCols>
- friend struct internal::eulerangles_assign_impl;
};
#define EIGEN_EULER_SYSTEM_TYPEDEF(A, B, C) \
diff --git a/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h b/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
index db2449d..3f7d777 100644
--- a/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
+++ b/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
@@ -398,8 +398,8 @@ struct matrix_function_compute
template <typename MatrixType>
struct matrix_function_compute<MatrixType, 0>
{
- template <typename AtomicType, typename ResultType>
- static void run(const MatrixType& A, AtomicType& atomic, ResultType &result)
+ template <typename MatA, typename AtomicType, typename ResultType>
+ static void run(const MatA& A, AtomicType& atomic, ResultType &result)
{
typedef internal::traits<MatrixType> Traits;
typedef typename Traits::Scalar Scalar;
@@ -422,11 +422,10 @@ struct matrix_function_compute<MatrixType, 0>
template <typename MatrixType>
struct matrix_function_compute<MatrixType, 1>
{
- template <typename AtomicType, typename ResultType>
- static void run(const MatrixType& A, AtomicType& atomic, ResultType &result)
+ template <typename MatA, typename AtomicType, typename ResultType>
+ static void run(const MatA& A, AtomicType& atomic, ResultType &result)
{
typedef internal::traits<MatrixType> Traits;
- typedef typename MatrixType::Index Index;
// compute Schur decomposition of A
const ComplexSchur<MatrixType> schurOfA(A);
@@ -514,7 +513,7 @@ template<typename Derived> class MatrixFunctionReturnValue
typedef internal::MatrixFunctionAtomic<DynMatrixType> AtomicType;
AtomicType atomic(m_f);
- internal::matrix_function_compute<NestedEvalTypeClean>::run(m_A, atomic, result);
+ internal::matrix_function_compute<typename NestedEvalTypeClean::PlainObject>::run(m_A, atomic, result);
}
Index rows() const { return m_A.rows(); }
diff --git a/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h b/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
index 1acfbed..ff8f6e7 100644
--- a/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
+++ b/eigen/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
@@ -339,7 +339,7 @@ public:
typedef internal::MatrixLogarithmAtomic<DynMatrixType> AtomicType;
AtomicType atomic;
- internal::matrix_function_compute<DerivedEvalTypeClean>::run(m_A, atomic, result);
+ internal::matrix_function_compute<typename DerivedEvalTypeClean::PlainObject>::run(m_A, atomic, result);
}
Index rows() const { return m_A.rows(); }
diff --git a/eigen/unsupported/Eigen/src/Polynomials/Companion.h b/eigen/unsupported/Eigen/src/Polynomials/Companion.h
index e0af6eb..b515c29 100644
--- a/eigen/unsupported/Eigen/src/Polynomials/Companion.h
+++ b/eigen/unsupported/Eigen/src/Polynomials/Companion.h
@@ -75,7 +75,7 @@ class companion
void setPolynomial( const VectorType& poly )
{
const Index deg = poly.size()-1;
- m_monic = Scalar(-1)/poly[deg] * poly.head(deg);
+ m_monic = -1/poly[deg] * poly.head(deg);
//m_bl_diag.setIdentity( deg-1 );
m_bl_diag.setOnes(deg-1);
}
@@ -107,8 +107,8 @@ class companion
* colB and rowB are repectively the multipliers for
* the column and the row in order to balance them.
* */
- bool balanced( RealScalar colNorm, RealScalar rowNorm,
- bool& isBalanced, RealScalar& colB, RealScalar& rowB );
+ bool balanced( Scalar colNorm, Scalar rowNorm,
+ bool& isBalanced, Scalar& colB, Scalar& rowB );
/** Helper function for the balancing algorithm.
* \returns true if the row and the column, having colNorm and rowNorm
@@ -116,8 +116,8 @@ class companion
* colB and rowB are repectively the multipliers for
* the column and the row in order to balance them.
* */
- bool balancedR( RealScalar colNorm, RealScalar rowNorm,
- bool& isBalanced, RealScalar& colB, RealScalar& rowB );
+ bool balancedR( Scalar colNorm, Scalar rowNorm,
+ bool& isBalanced, Scalar& colB, Scalar& rowB );
public:
/**
@@ -139,10 +139,10 @@ class companion
template< typename _Scalar, int _Deg >
inline
-bool companion<_Scalar,_Deg>::balanced( RealScalar colNorm, RealScalar rowNorm,
- bool& isBalanced, RealScalar& colB, RealScalar& rowB )
+bool companion<_Scalar,_Deg>::balanced( Scalar colNorm, Scalar rowNorm,
+ bool& isBalanced, Scalar& colB, Scalar& rowB )
{
- if( RealScalar(0) == colNorm || RealScalar(0) == rowNorm ){ return true; }
+ if( Scalar(0) == colNorm || Scalar(0) == rowNorm ){ return true; }
else
{
//To find the balancing coefficients, if the radix is 2,
@@ -150,29 +150,29 @@ bool companion<_Scalar,_Deg>::balanced( RealScalar colNorm, RealScalar rowNorm,
// \f$ 2^{2\sigma-1} < rowNorm / colNorm \le 2^{2\sigma+1} \f$
// then the balancing coefficient for the row is \f$ 1/2^{\sigma} \f$
// and the balancing coefficient for the column is \f$ 2^{\sigma} \f$
- rowB = rowNorm / radix<RealScalar>();
- colB = RealScalar(1);
- const RealScalar s = colNorm + rowNorm;
+ rowB = rowNorm / radix<Scalar>();
+ colB = Scalar(1);
+ const Scalar s = colNorm + rowNorm;
while (colNorm < rowB)
{
- colB *= radix<RealScalar>();
- colNorm *= radix2<RealScalar>();
+ colB *= radix<Scalar>();
+ colNorm *= radix2<Scalar>();
}
- rowB = rowNorm * radix<RealScalar>();
+ rowB = rowNorm * radix<Scalar>();
while (colNorm >= rowB)
{
- colB /= radix<RealScalar>();
- colNorm /= radix2<RealScalar>();
+ colB /= radix<Scalar>();
+ colNorm /= radix2<Scalar>();
}
//This line is used to avoid insubstantial balancing
- if ((rowNorm + colNorm) < RealScalar(0.95) * s * colB)
+ if ((rowNorm + colNorm) < Scalar(0.95) * s * colB)
{
isBalanced = false;
- rowB = RealScalar(1) / colB;
+ rowB = Scalar(1) / colB;
return false;
}
else{
@@ -182,21 +182,21 @@ bool companion<_Scalar,_Deg>::balanced( RealScalar colNorm, RealScalar rowNorm,
template< typename _Scalar, int _Deg >
inline
-bool companion<_Scalar,_Deg>::balancedR( RealScalar colNorm, RealScalar rowNorm,
- bool& isBalanced, RealScalar& colB, RealScalar& rowB )
+bool companion<_Scalar,_Deg>::balancedR( Scalar colNorm, Scalar rowNorm,
+ bool& isBalanced, Scalar& colB, Scalar& rowB )
{
- if( RealScalar(0) == colNorm || RealScalar(0) == rowNorm ){ return true; }
+ if( Scalar(0) == colNorm || Scalar(0) == rowNorm ){ return true; }
else
{
/**
* Set the norm of the column and the row to the geometric mean
* of the row and column norm
*/
- const RealScalar q = colNorm/rowNorm;
+ const _Scalar q = colNorm/rowNorm;
if( !isApprox( q, _Scalar(1) ) )
{
rowB = sqrt( colNorm/rowNorm );
- colB = RealScalar(1)/rowB;
+ colB = Scalar(1)/rowB;
isBalanced = false;
return false;
@@ -219,8 +219,8 @@ void companion<_Scalar,_Deg>::balance()
while( !hasConverged )
{
hasConverged = true;
- RealScalar colNorm,rowNorm;
- RealScalar colB,rowB;
+ Scalar colNorm,rowNorm;
+ Scalar colB,rowB;
//First row, first column excluding the diagonal
//==============================================
diff --git a/eigen/unsupported/Eigen/src/Polynomials/PolynomialSolver.h b/eigen/unsupported/Eigen/src/Polynomials/PolynomialSolver.h
index 7885942..03198ec 100644
--- a/eigen/unsupported/Eigen/src/Polynomials/PolynomialSolver.h
+++ b/eigen/unsupported/Eigen/src/Polynomials/PolynomialSolver.h
@@ -99,7 +99,7 @@ class PolynomialSolverBase
*/
inline const RootType& greatestRoot() const
{
- std::greater<RealScalar> greater;
+ std::greater<Scalar> greater;
return selectComplexRoot_withRespectToNorm( greater );
}
@@ -108,7 +108,7 @@ class PolynomialSolverBase
*/
inline const RootType& smallestRoot() const
{
- std::less<RealScalar> less;
+ std::less<Scalar> less;
return selectComplexRoot_withRespectToNorm( less );
}
@@ -213,7 +213,7 @@ class PolynomialSolverBase
bool& hasArealRoot,
const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
{
- std::greater<RealScalar> greater;
+ std::greater<Scalar> greater;
return selectRealRoot_withRespectToAbsRealPart( greater, hasArealRoot, absImaginaryThreshold );
}
@@ -236,7 +236,7 @@ class PolynomialSolverBase
bool& hasArealRoot,
const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
{
- std::less<RealScalar> less;
+ std::less<Scalar> less;
return selectRealRoot_withRespectToAbsRealPart( less, hasArealRoot, absImaginaryThreshold );
}
@@ -259,7 +259,7 @@ class PolynomialSolverBase
bool& hasArealRoot,
const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
{
- std::greater<RealScalar> greater;
+ std::greater<Scalar> greater;
return selectRealRoot_withRespectToRealPart( greater, hasArealRoot, absImaginaryThreshold );
}
@@ -282,7 +282,7 @@ class PolynomialSolverBase
bool& hasArealRoot,
const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
{
- std::less<RealScalar> less;
+ std::less<Scalar> less;
return selectRealRoot_withRespectToRealPart( less, hasArealRoot, absImaginaryThreshold );
}
@@ -327,7 +327,7 @@ class PolynomialSolverBase
* However, almost always, correct accuracy is reached even in these cases for 64bit
* (double) floating types and small polynomial degree (<20).
*/
-template<typename _Scalar, int _Deg>
+template< typename _Scalar, int _Deg >
class PolynomialSolver : public PolynomialSolverBase<_Scalar,_Deg>
{
public:
@@ -337,9 +337,7 @@ class PolynomialSolver : public PolynomialSolverBase<_Scalar,_Deg>
EIGEN_POLYNOMIAL_SOLVER_BASE_INHERITED_TYPES( PS_Base )
typedef Matrix<Scalar,_Deg,_Deg> CompanionMatrixType;
- typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
- ComplexEigenSolver<CompanionMatrixType>,
- EigenSolver<CompanionMatrixType> >::type EigenSolverType;
+ typedef EigenSolver<CompanionMatrixType> EigenSolverType;
public:
/** Computes the complex roots of a new polynomial. */
diff --git a/eigen/unsupported/Eigen/src/SparseExtra/MarketIO.h b/eigen/unsupported/Eigen/src/SparseExtra/MarketIO.h
index fc70a24..cdc14f8 100644
--- a/eigen/unsupported/Eigen/src/SparseExtra/MarketIO.h
+++ b/eigen/unsupported/Eigen/src/SparseExtra/MarketIO.h
@@ -12,38 +12,38 @@
#define EIGEN_SPARSE_MARKET_IO_H
#include <iostream>
-#include <vector>
namespace Eigen {
namespace internal
{
- template <typename Scalar, typename StorageIndex>
- inline void GetMarketLine (const char* line, StorageIndex& i, StorageIndex& j, Scalar& value)
+ template <typename Scalar>
+ inline bool GetMarketLine (std::stringstream& line, Index& M, Index& N, Index& i, Index& j, Scalar& value)
{
- std::stringstream sline(line);
- sline >> i >> j >> value;
+ line >> i >> j >> value;
+ i--;
+ j--;
+ if(i>=0 && j>=0 && i<M && j<N)
+ {
+ return true;
+ }
+ else
+ return false;
}
-
- template<> inline void GetMarketLine (const char* line, int& i, int& j, float& value)
- { std::sscanf(line, "%d %d %g", &i, &j, &value); }
-
- template<> inline void GetMarketLine (const char* line, int& i, int& j, double& value)
- { std::sscanf(line, "%d %d %lg", &i, &j, &value); }
-
- template<> inline void GetMarketLine (const char* line, int& i, int& j, std::complex<float>& value)
- { std::sscanf(line, "%d %d %g %g", &i, &j, &numext::real_ref(value), &numext::imag_ref(value)); }
-
- template<> inline void GetMarketLine (const char* line, int& i, int& j, std::complex<double>& value)
- { std::sscanf(line, "%d %d %lg %lg", &i, &j, &numext::real_ref(value), &numext::imag_ref(value)); }
-
- template <typename Scalar, typename StorageIndex>
- inline void GetMarketLine (const char* line, StorageIndex& i, StorageIndex& j, std::complex<Scalar>& value)
+ template <typename Scalar>
+ inline bool GetMarketLine (std::stringstream& line, Index& M, Index& N, Index& i, Index& j, std::complex<Scalar>& value)
{
- std::stringstream sline(line);
Scalar valR, valI;
- sline >> i >> j >> valR >> valI;
- value = std::complex<Scalar>(valR,valI);
+ line >> i >> j >> valR >> valI;
+ i--;
+ j--;
+ if(i>=0 && j>=0 && i<M && j<N)
+ {
+ value = std::complex<Scalar>(valR, valI);
+ return true;
+ }
+ else
+ return false;
}
template <typename RealScalar>
@@ -81,13 +81,13 @@ namespace internal
}
}
- template<typename Scalar, typename StorageIndex>
- inline void PutMatrixElt(Scalar value, StorageIndex row, StorageIndex col, std::ofstream& out)
+ template<typename Scalar>
+ inline void PutMatrixElt(Scalar value, int row, int col, std::ofstream& out)
{
out << row << " "<< col << " " << value << "\n";
}
- template<typename Scalar, typename StorageIndex>
- inline void PutMatrixElt(std::complex<Scalar> value, StorageIndex row, StorageIndex col, std::ofstream& out)
+ template<typename Scalar>
+ inline void PutMatrixElt(std::complex<Scalar> value, int row, int col, std::ofstream& out)
{
out << row << " " << col << " " << value.real() << " " << value.imag() << "\n";
}
@@ -133,20 +133,17 @@ template<typename SparseMatrixType>
bool loadMarket(SparseMatrixType& mat, const std::string& filename)
{
typedef typename SparseMatrixType::Scalar Scalar;
- typedef typename SparseMatrixType::StorageIndex StorageIndex;
+ typedef typename SparseMatrixType::Index Index;
std::ifstream input(filename.c_str(),std::ios::in);
if(!input)
return false;
-
- char rdbuffer[4096];
- input.rdbuf()->pubsetbuf(rdbuffer, 4096);
const int maxBuffersize = 2048;
char buffer[maxBuffersize];
bool readsizes = false;
- typedef Triplet<Scalar,StorageIndex> T;
+ typedef Triplet<Scalar,Index> T;
std::vector<T> elements;
Index M(-1), N(-1), NNZ(-1);
@@ -157,36 +154,33 @@ bool loadMarket(SparseMatrixType& mat, const std::string& filename)
//NOTE An appropriate test should be done on the header to get the symmetry
if(buffer[0]=='%')
continue;
-
+
+ std::stringstream line(buffer);
+
if(!readsizes)
{
- std::stringstream line(buffer);
line >> M >> N >> NNZ;
if(M > 0 && N > 0 && NNZ > 0)
{
readsizes = true;
+ //std::cout << "sizes: " << M << "," << N << "," << NNZ << "\n";
mat.resize(M,N);
mat.reserve(NNZ);
}
}
else
{
- StorageIndex i(-1), j(-1);
+ Index i(-1), j(-1);
Scalar value;
- internal::GetMarketLine(buffer, i, j, value);
-
- i--;
- j--;
- if(i>=0 && j>=0 && i<M && j<N)
+ if( internal::GetMarketLine(line, M, N, i, j, value) )
{
- ++count;
+ ++ count;
elements.push_back(T(i,j,value));
}
- else
+ else
std::cerr << "Invalid read: " << i << "," << j << "\n";
}
}
-
mat.setFromTriplets(elements.begin(), elements.end());
if(count!=NNZ)
std::cerr << count << "!=" << NNZ << "\n";
@@ -231,13 +225,12 @@ template<typename SparseMatrixType>
bool saveMarket(const SparseMatrixType& mat, const std::string& filename, int sym = 0)
{
typedef typename SparseMatrixType::Scalar Scalar;
- typedef typename SparseMatrixType::RealScalar RealScalar;
std::ofstream out(filename.c_str(),std::ios::out);
if(!out)
return false;
out.flags(std::ios_base::scientific);
- out.precision(std::numeric_limits<RealScalar>::digits10 + 2);
+ out.precision(64);
std::string header;
internal::putMarketHeader<Scalar>(header, sym);
out << header << std::endl;
@@ -248,6 +241,7 @@ bool saveMarket(const SparseMatrixType& mat, const std::string& filename, int sy
{
++ count;
internal::PutMatrixElt(it.value(), it.row()+1, it.col()+1, out);
+ // out << it.row()+1 << " " << it.col()+1 << " " << it.value() << "\n";
}
out.close();
return true;
@@ -256,14 +250,13 @@ bool saveMarket(const SparseMatrixType& mat, const std::string& filename, int sy
template<typename VectorType>
bool saveMarketVector (const VectorType& vec, const std::string& filename)
{
- typedef typename VectorType::Scalar Scalar;
- typedef typename VectorType::RealScalar RealScalar;
+ typedef typename VectorType::Scalar Scalar;
std::ofstream out(filename.c_str(),std::ios::out);
if(!out)
return false;
out.flags(std::ios_base::scientific);
- out.precision(std::numeric_limits<RealScalar>::digits10 + 2);
+ out.precision(64);
if(internal::is_same<Scalar, std::complex<float> >::value || internal::is_same<Scalar, std::complex<double> >::value)
out << "%%MatrixMarket matrix array complex general\n";
else
diff --git a/eigen/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h b/eigen/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h
index 369ad97..f524d71 100644
--- a/eigen/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h
+++ b/eigen/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h
@@ -122,8 +122,8 @@ struct lgamma_impl<float> {
EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE float run(float x) {
#if !defined(__CUDA_ARCH__) && (defined(_BSD_SOURCE) || defined(_SVID_SOURCE)) && !defined(__APPLE__)
- int dummy;
- return ::lgammaf_r(x, &dummy);
+ int signgam;
+ return ::lgammaf_r(x, &signgam);
#else
return ::lgammaf(x);
#endif
@@ -135,8 +135,8 @@ struct lgamma_impl<double> {
EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE double run(double x) {
#if !defined(__CUDA_ARCH__) && (defined(_BSD_SOURCE) || defined(_SVID_SOURCE)) && !defined(__APPLE__)
- int dummy;
- return ::lgamma_r(x, &dummy);
+ int signgam;
+ return ::lgamma_r(x, &signgam);
#else
return ::lgamma(x);
#endif
diff --git a/eigen/unsupported/doc/examples/EulerAngles.cpp b/eigen/unsupported/doc/examples/EulerAngles.cpp
index 3f8ca8c..1ef6aee 100644
--- a/eigen/unsupported/doc/examples/EulerAngles.cpp
+++ b/eigen/unsupported/doc/examples/EulerAngles.cpp
@@ -23,7 +23,7 @@ int main()
// Some Euler angles representation that our plane use.
EulerAnglesZYZd planeAngles(0.78474, 0.5271, -0.513794);
- MyArmyAngles planeAnglesInMyArmyAngles(planeAngles);
+ MyArmyAngles planeAnglesInMyArmyAngles = MyArmyAngles::FromRotation<true, false, false>(planeAngles);
std::cout << "vehicle angles(MyArmy): " << vehicleAngles << std::endl;
std::cout << "plane angles(ZYZ): " << planeAngles << std::endl;
@@ -37,7 +37,7 @@ int main()
Quaterniond planeRotated = AngleAxisd(-0.342, Vector3d::UnitY()) * planeAngles;
planeAngles = planeRotated;
- planeAnglesInMyArmyAngles = planeRotated;
+ planeAnglesInMyArmyAngles = MyArmyAngles::FromRotation<true, false, false>(planeRotated);
std::cout << "new plane angles(ZYZ): " << planeAngles << std::endl;
std::cout << "new plane angles(MyArmy): " << planeAnglesInMyArmyAngles << std::endl;
diff --git a/eigen/unsupported/test/CMakeLists.txt b/eigen/unsupported/test/CMakeLists.txt
index 003c9de..b5fa1c8 100644
--- a/eigen/unsupported/test/CMakeLists.txt
+++ b/eigen/unsupported/test/CMakeLists.txt
@@ -21,17 +21,6 @@ include_directories(../../test ../../unsupported ../../Eigen
find_package (Threads)
-find_package(Xsmm)
-if(XSMM_FOUND)
- add_definitions("-DEIGEN_USE_LIBXSMM")
- include_directories(${XSMM_INCLUDES})
- link_directories(${XSMM_LIBRARIES})
- set(EXTERNAL_LIBS ${EXTERNAL_LIBS} xsmm)
- ei_add_property(EIGEN_TESTED_BACKENDS "Xsmm, ")
-else(XSMM_FOUND)
- ei_add_property(EIGEN_MISSING_BACKENDS "Xsmm, ")
-endif(XSMM_FOUND)
-
find_package(GoogleHash)
if(GOOGLEHASH_FOUND)
add_definitions("-DEIGEN_GOOGLEHASH_SUPPORT")
@@ -157,16 +146,6 @@ if(EIGEN_TEST_CXX11)
ei_add_test_sycl(cxx11_tensor_broadcast_sycl "-std=c++11")
ei_add_test_sycl(cxx11_tensor_device_sycl "-std=c++11")
ei_add_test_sycl(cxx11_tensor_reduction_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_morphing_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_shuffling_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_padding_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_builtins_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_contract_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_concatenation_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_reverse_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_convolution_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_striding_sycl "-std=c++11")
- ei_add_test_sycl(cxx11_tensor_chipping_sycl "-std=c++11")
endif(EIGEN_TEST_SYCL)
# It should be safe to always run these tests as there is some fallback code for
# older compiler that don't support cxx11.
diff --git a/eigen/unsupported/test/EulerAngles.cpp b/eigen/unsupported/test/EulerAngles.cpp
index 79ee728..a8cb528 100644
--- a/eigen/unsupported/test/EulerAngles.cpp
+++ b/eigen/unsupported/test/EulerAngles.cpp
@@ -13,219 +13,146 @@
using namespace Eigen;
-// Unfortunately, we need to specialize it in order to work. (We could add it in main.h test framework)
-template <typename Scalar, class System>
-bool verifyIsApprox(const Eigen::EulerAngles<Scalar, System>& a, const Eigen::EulerAngles<Scalar, System>& b)
-{
- return verifyIsApprox(a.angles(), b.angles());
-}
-
-// Verify that x is in the approxed range [a, b]
-#define VERIFY_APPROXED_RANGE(a, x, b) \
- do { \
- VERIFY_IS_APPROX_OR_LESS_THAN(a, x); \
- VERIFY_IS_APPROX_OR_LESS_THAN(x, b); \
- } while(0)
-
-const char X = EULER_X;
-const char Y = EULER_Y;
-const char Z = EULER_Z;
-
-template<typename Scalar, class EulerSystem>
-void verify_euler(const EulerAngles<Scalar, EulerSystem>& e)
+template<typename EulerSystem, typename Scalar>
+void verify_euler_ranged(const Matrix<Scalar,3,1>& ea,
+ bool positiveRangeAlpha, bool positiveRangeBeta, bool positiveRangeGamma)
{
typedef EulerAngles<Scalar, EulerSystem> EulerAnglesType;
typedef Matrix<Scalar,3,3> Matrix3;
typedef Matrix<Scalar,3,1> Vector3;
typedef Quaternion<Scalar> QuaternionType;
typedef AngleAxis<Scalar> AngleAxisType;
+ using std::abs;
- const Scalar ONE = Scalar(1);
- const Scalar HALF_PI = Scalar(EIGEN_PI / 2);
- const Scalar PI = Scalar(EIGEN_PI);
+ Scalar alphaRangeStart, alphaRangeEnd;
+ Scalar betaRangeStart, betaRangeEnd;
+ Scalar gammaRangeStart, gammaRangeEnd;
- // It's very important calc the acceptable precision depending on the distance from the pole.
- const Scalar longitudeRadius = std::abs(
- EulerSystem::IsTaitBryan ?
- std::cos(e.beta()) :
- std::sin(e.beta())
- );
- Scalar precision = test_precision<Scalar>() / longitudeRadius;
+ if (positiveRangeAlpha)
+ {
+ alphaRangeStart = Scalar(0);
+ alphaRangeEnd = Scalar(2 * EIGEN_PI);
+ }
+ else
+ {
+ alphaRangeStart = -Scalar(EIGEN_PI);
+ alphaRangeEnd = Scalar(EIGEN_PI);
+ }
- Scalar betaRangeStart, betaRangeEnd;
- if (EulerSystem::IsTaitBryan)
+ if (positiveRangeBeta)
+ {
+ betaRangeStart = Scalar(0);
+ betaRangeEnd = Scalar(2 * EIGEN_PI);
+ }
+ else
+ {
+ betaRangeStart = -Scalar(EIGEN_PI);
+ betaRangeEnd = Scalar(EIGEN_PI);
+ }
+
+ if (positiveRangeGamma)
{
- betaRangeStart = -HALF_PI;
- betaRangeEnd = HALF_PI;
+ gammaRangeStart = Scalar(0);
+ gammaRangeEnd = Scalar(2 * EIGEN_PI);
}
else
{
- if (!EulerSystem::IsBetaOpposite)
- {
- betaRangeStart = 0;
- betaRangeEnd = PI;
- }
- else
- {
- betaRangeStart = -PI;
- betaRangeEnd = 0;
- }
+ gammaRangeStart = -Scalar(EIGEN_PI);
+ gammaRangeEnd = Scalar(EIGEN_PI);
}
+ const int i = EulerSystem::AlphaAxisAbs - 1;
+ const int j = EulerSystem::BetaAxisAbs - 1;
+ const int k = EulerSystem::GammaAxisAbs - 1;
+
+ const int iFactor = EulerSystem::IsAlphaOpposite ? -1 : 1;
+ const int jFactor = EulerSystem::IsBetaOpposite ? -1 : 1;
+ const int kFactor = EulerSystem::IsGammaOpposite ? -1 : 1;
+
const Vector3 I = EulerAnglesType::AlphaAxisVector();
const Vector3 J = EulerAnglesType::BetaAxisVector();
const Vector3 K = EulerAnglesType::GammaAxisVector();
- // Is approx checks
- VERIFY(e.isApprox(e));
- VERIFY_IS_APPROX(e, e);
- VERIFY_IS_NOT_APPROX(e, EulerAnglesType(e.alpha() + ONE, e.beta() + ONE, e.gamma() + ONE));
-
- const Matrix3 m(e);
- VERIFY_IS_APPROX(Scalar(m.determinant()), ONE);
-
- EulerAnglesType ebis(m);
+ EulerAnglesType e(ea[0], ea[1], ea[2]);
- // When no roll(acting like polar representation), we have the best precision.
- // One of those cases is when the Euler angles are on the pole, and because it's singular case,
- // the computation returns no roll.
- if (ebis.beta() == 0)
- precision = test_precision<Scalar>();
+ Matrix3 m(e);
+ Vector3 eabis = EulerAnglesType(m, positiveRangeAlpha, positiveRangeBeta, positiveRangeGamma).angles();
// Check that eabis in range
- VERIFY_APPROXED_RANGE(-PI, ebis.alpha(), PI);
- VERIFY_APPROXED_RANGE(betaRangeStart, ebis.beta(), betaRangeEnd);
- VERIFY_APPROXED_RANGE(-PI, ebis.gamma(), PI);
-
- const Matrix3 mbis(AngleAxisType(ebis.alpha(), I) * AngleAxisType(ebis.beta(), J) * AngleAxisType(ebis.gamma(), K));
- VERIFY_IS_APPROX(Scalar(mbis.determinant()), ONE);
- VERIFY_IS_APPROX(mbis, ebis.toRotationMatrix());
- /*std::cout << "===================\n" <<
- "e: " << e << std::endl <<
- "eabis: " << eabis.transpose() << std::endl <<
- "m: " << m << std::endl <<
- "mbis: " << mbis << std::endl <<
- "X: " << (m * Vector3::UnitX()).transpose() << std::endl <<
- "X: " << (mbis * Vector3::UnitX()).transpose() << std::endl;*/
- VERIFY(m.isApprox(mbis, precision));
-
- // Test if ea and eabis are the same
- // Need to check both singular and non-singular cases
- // There are two singular cases.
- // 1. When I==K and sin(ea(1)) == 0
- // 2. When I!=K and cos(ea(1)) == 0
-
- // TODO: Make this test work well, and use range saturation function.
- /*// If I==K, and ea[1]==0, then there no unique solution.
- // The remark apply in the case where I!=K, and |ea[1]| is close to +-pi/2.
- if( (i!=k || ea[1]!=0) && (i==k || !internal::isApprox(abs(ea[1]),Scalar(EIGEN_PI/2),test_precision<Scalar>())) )
- VERIFY_IS_APPROX(ea, eabis);*/
+ VERIFY(alphaRangeStart <= eabis[0] && eabis[0] <= alphaRangeEnd);
+ VERIFY(betaRangeStart <= eabis[1] && eabis[1] <= betaRangeEnd);
+ VERIFY(gammaRangeStart <= eabis[2] && eabis[2] <= gammaRangeEnd);
- // Quaternions
- const QuaternionType q(e);
- ebis = q;
- const QuaternionType qbis(ebis);
- VERIFY(internal::isApprox<Scalar>(std::abs(q.dot(qbis)), ONE, precision));
- //VERIFY_IS_APPROX(eabis, eabis2);// Verify that the euler angles are still the same
+ Vector3 eabis2 = m.eulerAngles(i, j, k);
- // A suggestion for simple product test when will be supported.
- /*EulerAnglesType e2(PI/2, PI/2, PI/2);
- Matrix3 m2(e2);
- VERIFY_IS_APPROX(e*e2, m*m2);*/
-}
-
-template<signed char A, signed char B, signed char C, typename Scalar>
-void verify_euler_vec(const Matrix<Scalar,3,1>& ea)
-{
- verify_euler(EulerAngles<Scalar, EulerSystem<A, B, C> >(ea[0], ea[1], ea[2]));
-}
-
-template<signed char A, signed char B, signed char C, typename Scalar>
-void verify_euler_all_neg(const Matrix<Scalar,3,1>& ea)
-{
- verify_euler_vec<+A,+B,+C>(ea);
- verify_euler_vec<+A,+B,-C>(ea);
- verify_euler_vec<+A,-B,+C>(ea);
- verify_euler_vec<+A,-B,-C>(ea);
+ // Invert the relevant axes
+ eabis2[0] *= iFactor;
+ eabis2[1] *= jFactor;
+ eabis2[2] *= kFactor;
- verify_euler_vec<-A,+B,+C>(ea);
- verify_euler_vec<-A,+B,-C>(ea);
- verify_euler_vec<-A,-B,+C>(ea);
- verify_euler_vec<-A,-B,-C>(ea);
-}
-
-template<typename Scalar> void check_all_var(const Matrix<Scalar,3,1>& ea)
-{
- verify_euler_all_neg<X,Y,Z>(ea);
- verify_euler_all_neg<X,Y,X>(ea);
- verify_euler_all_neg<X,Z,Y>(ea);
- verify_euler_all_neg<X,Z,X>(ea);
+ // Saturate the angles to the correct range
+ if (positiveRangeAlpha && (eabis2[0] < 0))
+ eabis2[0] += Scalar(2 * EIGEN_PI);
+ if (positiveRangeBeta && (eabis2[1] < 0))
+ eabis2[1] += Scalar(2 * EIGEN_PI);
+ if (positiveRangeGamma && (eabis2[2] < 0))
+ eabis2[2] += Scalar(2 * EIGEN_PI);
- verify_euler_all_neg<Y,Z,X>(ea);
- verify_euler_all_neg<Y,Z,Y>(ea);
- verify_euler_all_neg<Y,X,Z>(ea);
- verify_euler_all_neg<Y,X,Y>(ea);
+ VERIFY_IS_APPROX(eabis, eabis2);// Verify that our estimation is the same as m.eulerAngles() is
- verify_euler_all_neg<Z,X,Y>(ea);
- verify_euler_all_neg<Z,X,Z>(ea);
- verify_euler_all_neg<Z,Y,X>(ea);
- verify_euler_all_neg<Z,Y,Z>(ea);
-}
-
-template<typename Scalar> void check_singular_cases(const Scalar& singularBeta)
-{
- typedef Matrix<Scalar,3,1> Vector3;
- const Scalar PI = Scalar(EIGEN_PI);
+ Matrix3 mbis(AngleAxisType(eabis[0], I) * AngleAxisType(eabis[1], J) * AngleAxisType(eabis[2], K));
+ VERIFY_IS_APPROX(m, mbis);
- for (Scalar epsilon = NumTraits<Scalar>::epsilon(); epsilon < 1; epsilon *= Scalar(1.2))
+ // Tests that are only relevant for no possitive range
+ if (!(positiveRangeAlpha || positiveRangeBeta || positiveRangeGamma))
{
- check_all_var(Vector3(PI/4, singularBeta, PI/3));
- check_all_var(Vector3(PI/4, singularBeta - epsilon, PI/3));
- check_all_var(Vector3(PI/4, singularBeta - Scalar(1.5)*epsilon, PI/3));
- check_all_var(Vector3(PI/4, singularBeta - 2*epsilon, PI/3));
- check_all_var(Vector3(PI*Scalar(0.8), singularBeta - epsilon, Scalar(0.9)*PI));
- check_all_var(Vector3(PI*Scalar(-0.9), singularBeta + epsilon, PI*Scalar(0.3)));
- check_all_var(Vector3(PI*Scalar(-0.6), singularBeta + Scalar(1.5)*epsilon, PI*Scalar(0.3)));
- check_all_var(Vector3(PI*Scalar(-0.5), singularBeta + 2*epsilon, PI*Scalar(0.4)));
- check_all_var(Vector3(PI*Scalar(0.9), singularBeta + epsilon, Scalar(0.8)*PI));
+ /* If I==K, and ea[1]==0, then there no unique solution. */
+ /* The remark apply in the case where I!=K, and |ea[1]| is close to pi/2. */
+ if( (i!=k || ea[1]!=0) && (i==k || !internal::isApprox(abs(ea[1]),Scalar(EIGEN_PI/2),test_precision<Scalar>())) )
+ VERIFY((ea-eabis).norm() <= test_precision<Scalar>());
+
+ // approx_or_less_than does not work for 0
+ VERIFY(0 < eabis[0] || test_isMuchSmallerThan(eabis[0], Scalar(1)));
}
- // This one for sanity, it had a problem with near pole cases in float scalar.
- check_all_var(Vector3(PI*Scalar(0.8), singularBeta - Scalar(1E-6), Scalar(0.9)*PI));
+ // Quaternions
+ QuaternionType q(e);
+ eabis = EulerAnglesType(q, positiveRangeAlpha, positiveRangeBeta, positiveRangeGamma).angles();
+ VERIFY_IS_APPROX(eabis, eabis2);// Verify that the euler angles are still the same
}
-template<typename Scalar> void eulerangles_manual()
+template<typename EulerSystem, typename Scalar>
+void verify_euler(const Matrix<Scalar,3,1>& ea)
{
- typedef Matrix<Scalar,3,1> Vector3;
- const Vector3 Zero = Vector3::Zero();
- const Scalar PI = Scalar(EIGEN_PI);
-
- check_all_var(Zero);
-
- // singular cases
- check_singular_cases(PI/2);
- check_singular_cases(-PI/2);
-
- check_singular_cases(Scalar(0));
- check_singular_cases(Scalar(-0));
-
- check_singular_cases(PI);
- check_singular_cases(-PI);
-
- // non-singular cases
- VectorXd alpha = VectorXd::LinSpaced(Eigen::Sequential, 20, Scalar(-0.99) * PI, PI);
- VectorXd beta = VectorXd::LinSpaced(Eigen::Sequential, 20, Scalar(-0.49) * PI, Scalar(0.49) * PI);
- VectorXd gamma = VectorXd::LinSpaced(Eigen::Sequential, 20, Scalar(-0.99) * PI, PI);
- for (int i = 0; i < alpha.size(); ++i) {
- for (int j = 0; j < beta.size(); ++j) {
- for (int k = 0; k < gamma.size(); ++k) {
- check_all_var(Vector3d(alpha(i), beta(j), gamma(k)));
- }
- }
- }
+ verify_euler_ranged<EulerSystem>(ea, false, false, false);
+ verify_euler_ranged<EulerSystem>(ea, false, false, true);
+ verify_euler_ranged<EulerSystem>(ea, false, true, false);
+ verify_euler_ranged<EulerSystem>(ea, false, true, true);
+ verify_euler_ranged<EulerSystem>(ea, true, false, false);
+ verify_euler_ranged<EulerSystem>(ea, true, false, true);
+ verify_euler_ranged<EulerSystem>(ea, true, true, false);
+ verify_euler_ranged<EulerSystem>(ea, true, true, true);
}
-template<typename Scalar> void eulerangles_rand()
+template<typename Scalar> void check_all_var(const Matrix<Scalar,3,1>& ea)
+{
+ verify_euler<EulerSystemXYZ>(ea);
+ verify_euler<EulerSystemXYX>(ea);
+ verify_euler<EulerSystemXZY>(ea);
+ verify_euler<EulerSystemXZX>(ea);
+
+ verify_euler<EulerSystemYZX>(ea);
+ verify_euler<EulerSystemYZY>(ea);
+ verify_euler<EulerSystemYXZ>(ea);
+ verify_euler<EulerSystemYXY>(ea);
+
+ verify_euler<EulerSystemZXY>(ea);
+ verify_euler<EulerSystemZXZ>(ea);
+ verify_euler<EulerSystemZYX>(ea);
+ verify_euler<EulerSystemZYZ>(ea);
+}
+
+template<typename Scalar> void eulerangles()
{
typedef Matrix<Scalar,3,3> Matrix3;
typedef Matrix<Scalar,3,1> Vector3;
@@ -274,19 +201,8 @@ template<typename Scalar> void eulerangles_rand()
void test_EulerAngles()
{
- // Simple cast test
- EulerAnglesXYZd onesEd(1, 1, 1);
- EulerAnglesXYZf onesEf = onesEd.cast<float>();
- VERIFY_IS_APPROX(onesEd, onesEf.cast<double>());
-
- CALL_SUBTEST_1( eulerangles_manual<float>() );
- CALL_SUBTEST_2( eulerangles_manual<double>() );
-
for(int i = 0; i < g_repeat; i++) {
- CALL_SUBTEST_3( eulerangles_rand<float>() );
- CALL_SUBTEST_4( eulerangles_rand<double>() );
+ CALL_SUBTEST_1( eulerangles<float>() );
+ CALL_SUBTEST_2( eulerangles<double>() );
}
-
- // TODO: Add tests for auto diff
- // TODO: Add tests for complex numbers
}
diff --git a/eigen/unsupported/test/autodiff_scalar.cpp b/eigen/unsupported/test/autodiff_scalar.cpp
index 4df2f5c..9cf1128 100644
--- a/eigen/unsupported/test/autodiff_scalar.cpp
+++ b/eigen/unsupported/test/autodiff_scalar.cpp
@@ -72,6 +72,20 @@ template<typename Scalar> void check_hyperbolic_functions()
VERIFY_IS_APPROX(res3.derivatives().x(), Scalar(0.339540557256150));
}
+template <typename Scalar>
+void check_limits_specialization()
+{
+ typedef Eigen::Matrix<Scalar, 1, 1> Deriv;
+ typedef Eigen::AutoDiffScalar<Deriv> AD;
+
+ typedef std::numeric_limits<AD> A;
+ typedef std::numeric_limits<Scalar> B;
+
+#if EIGEN_HAS_CXX11
+ VERIFY(bool(std::is_base_of<B, A>::value));
+#endif
+}
+
void test_autodiff_scalar()
{
for(int i = 0; i < g_repeat; i++) {
@@ -79,5 +93,6 @@ void test_autodiff_scalar()
CALL_SUBTEST_2( check_atan2<double>() );
CALL_SUBTEST_3( check_hyperbolic_functions<float>() );
CALL_SUBTEST_4( check_hyperbolic_functions<double>() );
+ CALL_SUBTEST_5( check_limits_specialization<double>());
}
}
diff --git a/eigen/unsupported/test/cxx11_non_blocking_thread_pool.cpp b/eigen/unsupported/test/cxx11_non_blocking_thread_pool.cpp
index 48cd2d4..5f9bb93 100644
--- a/eigen/unsupported/test/cxx11_non_blocking_thread_pool.cpp
+++ b/eigen/unsupported/test/cxx11_non_blocking_thread_pool.cpp
@@ -11,7 +11,6 @@
#define EIGEN_USE_THREADS
#include "main.h"
#include "Eigen/CXX11/ThreadPool"
-#include "Eigen/CXX11/Tensor"
static void test_create_destroy_empty_pool()
{
@@ -23,11 +22,11 @@ static void test_create_destroy_empty_pool()
}
-static void test_parallelism(bool allow_spinning)
+static void test_parallelism()
{
// Test we never-ever fail to match available tasks with idle threads.
const int kThreads = 16; // code below expects that this is a multiple of 4
- NonBlockingThreadPool tp(kThreads, allow_spinning);
+ NonBlockingThreadPool tp(kThreads);
VERIFY_IS_EQUAL(tp.NumThreads(), kThreads);
VERIFY_IS_EQUAL(tp.CurrentThreadId(), -1);
for (int iter = 0; iter < 100; ++iter) {
@@ -101,25 +100,8 @@ static void test_parallelism(bool allow_spinning)
}
}
-
-static void test_cancel()
-{
- NonBlockingThreadPool tp(2);
-
- // Schedule a large number of closure that each sleeps for one second. This
- // will keep the thread pool busy for much longer than the default test timeout.
- for (int i = 0; i < 1000; ++i) {
- tp.Schedule([]() { EIGEN_SLEEP(2000); });
- }
-
- // Cancel the processing of all the closures that are still pending.
- tp.Cancel();
-}
-
void test_cxx11_non_blocking_thread_pool()
{
CALL_SUBTEST(test_create_destroy_empty_pool());
- CALL_SUBTEST(test_parallelism(true));
- CALL_SUBTEST(test_parallelism(false));
- CALL_SUBTEST(test_cancel());
+ CALL_SUBTEST(test_parallelism());
}
diff --git a/eigen/unsupported/test/cxx11_tensor_broadcast_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_broadcast_sycl.cpp
index 21fdfca..7201bfe 100644
--- a/eigen/unsupported/test/cxx11_tensor_broadcast_sycl.cpp
+++ b/eigen/unsupported/test/cxx11_tensor_broadcast_sycl.cpp
@@ -14,7 +14,7 @@
#define EIGEN_TEST_NO_LONGDOUBLE
#define EIGEN_TEST_NO_COMPLEX
#define EIGEN_TEST_FUNC cxx11_tensor_broadcast_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
+#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
#define EIGEN_USE_SYCL
#include "main.h"
@@ -25,99 +25,39 @@ using Eigen::SyclDevice;
using Eigen::Tensor;
using Eigen::TensorMap;
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_broadcast_sycl_fixed(const Eigen::SyclDevice &sycl_device){
-
- // BROADCAST test:
- IndexType inDim1=2;
- IndexType inDim2=3;
- IndexType inDim3=5;
- IndexType inDim4=7;
- IndexType bDim1=2;
- IndexType bDim2=3;
- IndexType bDim3=1;
- IndexType bDim4=4;
- array<IndexType, 4> in_range = {{inDim1, inDim2, inDim3, inDim4}};
- array<IndexType, 4> broadcasts = {{bDim1, bDim2, bDim3, bDim4}};
- array<IndexType, 4> out_range; // = in_range * broadcasts
- for (size_t i = 0; i < out_range.size(); ++i)
- out_range[i] = in_range[i] * broadcasts[i];
-
- Tensor<DataType, 4, DataLayout, IndexType> input(in_range);
- Tensor<DataType, 4, DataLayout, IndexType> out(out_range);
-
- for (size_t i = 0; i < in_range.size(); ++i)
- VERIFY_IS_EQUAL(out.dimension(i), out_range[i]);
-
-
- for (IndexType i = 0; i < input.size(); ++i)
- input(i) = static_cast<DataType>(i);
-
- DataType * gpu_in_data = static_cast<DataType*>(sycl_device.allocate(input.dimensions().TotalSize()*sizeof(DataType)));
- DataType * gpu_out_data = static_cast<DataType*>(sycl_device.allocate(out.dimensions().TotalSize()*sizeof(DataType)));
-
- TensorMap<TensorFixedSize<DataType, Sizes<2, 3, 5, 7>, DataLayout, IndexType>> gpu_in(gpu_in_data, in_range);
- TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu_out(gpu_out_data, out_range);
- sycl_device.memcpyHostToDevice(gpu_in_data, input.data(),(input.dimensions().TotalSize())*sizeof(DataType));
- gpu_out.device(sycl_device) = gpu_in.broadcast(broadcasts);
- sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.dimensions().TotalSize())*sizeof(DataType));
-
- for (IndexType i = 0; i < inDim1*bDim1; ++i) {
- for (IndexType j = 0; j < inDim2*bDim2; ++j) {
- for (IndexType k = 0; k < inDim3*bDim3; ++k) {
- for (IndexType l = 0; l < inDim4*bDim4; ++l) {
- VERIFY_IS_APPROX(input(i%2,j%3,k%5,l%7), out(i,j,k,l));
- }
- }
- }
- }
- printf("Broadcast Test with fixed size Passed\n");
- sycl_device.deallocate(gpu_in_data);
- sycl_device.deallocate(gpu_out_data);
-}
-
-template <typename DataType, int DataLayout, typename IndexType>
static void test_broadcast_sycl(const Eigen::SyclDevice &sycl_device){
// BROADCAST test:
- IndexType inDim1=2;
- IndexType inDim2=3;
- IndexType inDim3=5;
- IndexType inDim4=7;
- IndexType bDim1=2;
- IndexType bDim2=3;
- IndexType bDim3=1;
- IndexType bDim4=4;
- array<IndexType, 4> in_range = {{inDim1, inDim2, inDim3, inDim4}};
- array<IndexType, 4> broadcasts = {{bDim1, bDim2, bDim3, bDim4}};
- array<IndexType, 4> out_range; // = in_range * broadcasts
+ array<int, 4> in_range = {{2, 3, 5, 7}};
+ array<int, 4> broadcasts = {{2, 3, 1, 4}};
+ array<int, 4> out_range; // = in_range * broadcasts
for (size_t i = 0; i < out_range.size(); ++i)
out_range[i] = in_range[i] * broadcasts[i];
- Tensor<DataType, 4, DataLayout, IndexType> input(in_range);
- Tensor<DataType, 4, DataLayout, IndexType> out(out_range);
+ Tensor<float, 4> input(in_range);
+ Tensor<float, 4> out(out_range);
for (size_t i = 0; i < in_range.size(); ++i)
VERIFY_IS_EQUAL(out.dimension(i), out_range[i]);
- for (IndexType i = 0; i < input.size(); ++i)
- input(i) = static_cast<DataType>(i);
+ for (int i = 0; i < input.size(); ++i)
+ input(i) = static_cast<float>(i);
- DataType * gpu_in_data = static_cast<DataType*>(sycl_device.allocate(input.dimensions().TotalSize()*sizeof(DataType)));
- DataType * gpu_out_data = static_cast<DataType*>(sycl_device.allocate(out.dimensions().TotalSize()*sizeof(DataType)));
+ float * gpu_in_data = static_cast<float*>(sycl_device.allocate(input.dimensions().TotalSize()*sizeof(float)));
+ float * gpu_out_data = static_cast<float*>(sycl_device.allocate(out.dimensions().TotalSize()*sizeof(float)));
- TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu_in(gpu_in_data, in_range);
- TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu_out(gpu_out_data, out_range);
- sycl_device.memcpyHostToDevice(gpu_in_data, input.data(),(input.dimensions().TotalSize())*sizeof(DataType));
+ TensorMap<Tensor<float, 4>> gpu_in(gpu_in_data, in_range);
+ TensorMap<Tensor<float, 4>> gpu_out(gpu_out_data, out_range);
+ sycl_device.memcpyHostToDevice(gpu_in_data, input.data(),(input.dimensions().TotalSize())*sizeof(float));
gpu_out.device(sycl_device) = gpu_in.broadcast(broadcasts);
- sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.dimensions().TotalSize())*sizeof(DataType));
+ sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.dimensions().TotalSize())*sizeof(float));
- for (IndexType i = 0; i < inDim1*bDim1; ++i) {
- for (IndexType j = 0; j < inDim2*bDim2; ++j) {
- for (IndexType k = 0; k < inDim3*bDim3; ++k) {
- for (IndexType l = 0; l < inDim4*bDim4; ++l) {
- VERIFY_IS_APPROX(input(i%inDim1,j%inDim2,k%inDim3,l%inDim4), out(i,j,k,l));
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 9; ++j) {
+ for (int k = 0; k < 5; ++k) {
+ for (int l = 0; l < 28; ++l) {
+ VERIFY_IS_APPROX(input(i%2,j%3,k%5,l%7), out(i,j,k,l));
}
}
}
@@ -127,18 +67,8 @@ static void test_broadcast_sycl(const Eigen::SyclDevice &sycl_device){
sycl_device.deallocate(gpu_out_data);
}
-template<typename DataType> void sycl_broadcast_test_per_device(const cl::sycl::device& d){
- std::cout << "Running on " << d.template get_info<cl::sycl::info::device::name>() << std::endl;
- QueueInterface queueInterface(d);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_broadcast_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_broadcast_sycl<DataType, ColMajor, int64_t>(sycl_device);
- test_broadcast_sycl_fixed<DataType, RowMajor, int64_t>(sycl_device);
- test_broadcast_sycl_fixed<DataType, ColMajor, int64_t>(sycl_device);
-}
-
void test_cxx11_tensor_broadcast_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(sycl_broadcast_test_per_device<float>(device));
- }
+ cl::sycl::gpu_selector s;
+ Eigen::SyclDevice sycl_device(s);
+ CALL_SUBTEST(test_broadcast_sycl(sycl_device));
}
diff --git a/eigen/unsupported/test/cxx11_tensor_builtins_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_builtins_sycl.cpp
deleted file mode 100644
index 400a31d..0000000
--- a/eigen/unsupported/test/cxx11_tensor_builtins_sycl.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.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/.
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_builtins_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-#include "main.h"
-#include <unsupported/Eigen/CXX11/Tensor>
-
-using Eigen::array;
-using Eigen::SyclDevice;
-using Eigen::Tensor;
-using Eigen::TensorMap;
-
-namespace std {
-template <typename T> T rsqrt(T x) { return 1 / std::sqrt(x); }
-template <typename T> T square(T x) { return x * x; }
-template <typename T> T cube(T x) { return x * x * x; }
-template <typename T> T inverse(T x) { return 1 / x; }
-}
-
-#define TEST_UNARY_BUILTINS_FOR_SCALAR(FUNC, SCALAR, OPERATOR, Layout) \
- { \
- /* out OPERATOR in.FUNC() */ \
- Tensor<SCALAR, 3, Layout, int64_t> in(tensorRange); \
- Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
- in = in.random() + static_cast<SCALAR>(0.01); \
- out = out.random() + static_cast<SCALAR>(0.01); \
- Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
- SCALAR *gpu_data = static_cast<SCALAR *>( \
- sycl_device.allocate(in.size() * sizeof(SCALAR))); \
- SCALAR *gpu_data_out = static_cast<SCALAR *>( \
- sycl_device.allocate(out.size() * sizeof(SCALAR))); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu(gpu_data, tensorRange); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
- sycl_device.memcpyHostToDevice(gpu_data, in.data(), \
- (in.size()) * sizeof(SCALAR)); \
- sycl_device.memcpyHostToDevice(gpu_data_out, out.data(), \
- (out.size()) * sizeof(SCALAR)); \
- gpu_out.device(sycl_device) OPERATOR gpu.FUNC(); \
- sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
- (out.size()) * sizeof(SCALAR)); \
- for (int64_t i = 0; i < out.size(); ++i) { \
- SCALAR ver = reference(i); \
- ver OPERATOR std::FUNC(in(i)); \
- VERIFY_IS_APPROX(out(i), ver); \
- } \
- sycl_device.deallocate(gpu_data); \
- sycl_device.deallocate(gpu_data_out); \
- } \
- { \
- /* out OPERATOR out.FUNC() */ \
- Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
- out = out.random() + static_cast<SCALAR>(0.01); \
- Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
- SCALAR *gpu_data_out = static_cast<SCALAR *>( \
- sycl_device.allocate(out.size() * sizeof(SCALAR))); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
- sycl_device.memcpyHostToDevice(gpu_data_out, out.data(), \
- (out.size()) * sizeof(SCALAR)); \
- gpu_out.device(sycl_device) OPERATOR gpu_out.FUNC(); \
- sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
- (out.size()) * sizeof(SCALAR)); \
- for (int64_t i = 0; i < out.size(); ++i) { \
- SCALAR ver = reference(i); \
- ver OPERATOR std::FUNC(reference(i)); \
- VERIFY_IS_APPROX(out(i), ver); \
- } \
- sycl_device.deallocate(gpu_data_out); \
- }
-
-#define TEST_UNARY_BUILTINS_OPERATOR(SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(abs, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(sqrt, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(rsqrt, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(square, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(cube, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(inverse, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(tanh, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(exp, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(expm1, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(log, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(abs, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(ceil, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(floor, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(round, SCALAR, OPERATOR , Layout) \
- TEST_UNARY_BUILTINS_FOR_SCALAR(log1p, SCALAR, OPERATOR , Layout)
-
-#define TEST_IS_THAT_RETURNS_BOOL(SCALAR, FUNC, Layout) \
- { \
- /* out = in.FUNC() */ \
- Tensor<SCALAR, 3, Layout, int64_t> in(tensorRange); \
- Tensor<bool, 3, Layout, int64_t> out(tensorRange); \
- in = in.random() + static_cast<SCALAR>(0.01); \
- SCALAR *gpu_data = static_cast<SCALAR *>( \
- sycl_device.allocate(in.size() * sizeof(SCALAR))); \
- bool *gpu_data_out = \
- static_cast<bool *>(sycl_device.allocate(out.size() * sizeof(bool))); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu(gpu_data, tensorRange); \
- TensorMap<Tensor<bool, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
- sycl_device.memcpyHostToDevice(gpu_data, in.data(), \
- (in.size()) * sizeof(SCALAR)); \
- gpu_out.device(sycl_device) = gpu.FUNC(); \
- sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
- (out.size()) * sizeof(bool)); \
- for (int64_t i = 0; i < out.size(); ++i) { \
- VERIFY_IS_EQUAL(out(i), std::FUNC(in(i))); \
- } \
- sycl_device.deallocate(gpu_data); \
- sycl_device.deallocate(gpu_data_out); \
- }
-
-#define TEST_UNARY_BUILTINS(SCALAR, Layout) \
- TEST_UNARY_BUILTINS_OPERATOR(SCALAR, +=, Layout) \
- TEST_UNARY_BUILTINS_OPERATOR(SCALAR, =, Layout) \
- TEST_IS_THAT_RETURNS_BOOL(SCALAR, isnan, Layout) \
- TEST_IS_THAT_RETURNS_BOOL(SCALAR, isfinite, Layout) \
- TEST_IS_THAT_RETURNS_BOOL(SCALAR, isinf, Layout)
-
-static void test_builtin_unary_sycl(const Eigen::SyclDevice &sycl_device) {
- int64_t sizeDim1 = 10;
- int64_t sizeDim2 = 10;
- int64_t sizeDim3 = 10;
- array<int64_t, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
-
- TEST_UNARY_BUILTINS(float, RowMajor)
- TEST_UNARY_BUILTINS(float, ColMajor)
-}
-
-namespace std {
-template <typename T> T cwiseMax(T x, T y) { return std::max(x, y); }
-template <typename T> T cwiseMin(T x, T y) { return std::min(x, y); }
-}
-
-#define TEST_BINARY_BUILTINS_FUNC(SCALAR, FUNC, Layout) \
- { \
- /* out = in_1.FUNC(in_2) */ \
- Tensor<SCALAR, 3, Layout, int64_t> in_1(tensorRange); \
- Tensor<SCALAR, 3, Layout, int64_t> in_2(tensorRange); \
- Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
- in_1 = in_1.random() + static_cast<SCALAR>(0.01); \
- in_2 = in_2.random() + static_cast<SCALAR>(0.01); \
- Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
- SCALAR *gpu_data_1 = static_cast<SCALAR *>( \
- sycl_device.allocate(in_1.size() * sizeof(SCALAR))); \
- SCALAR *gpu_data_2 = static_cast<SCALAR *>( \
- sycl_device.allocate(in_2.size() * sizeof(SCALAR))); \
- SCALAR *gpu_data_out = static_cast<SCALAR *>( \
- sycl_device.allocate(out.size() * sizeof(SCALAR))); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_1(gpu_data_1, tensorRange); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_2(gpu_data_2, tensorRange); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
- sycl_device.memcpyHostToDevice(gpu_data_1, in_1.data(), \
- (in_1.size()) * sizeof(SCALAR)); \
- sycl_device.memcpyHostToDevice(gpu_data_2, in_2.data(), \
- (in_2.size()) * sizeof(SCALAR)); \
- gpu_out.device(sycl_device) = gpu_1.FUNC(gpu_2); \
- sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
- (out.size()) * sizeof(SCALAR)); \
- for (int64_t i = 0; i < out.size(); ++i) { \
- SCALAR ver = reference(i); \
- ver = std::FUNC(in_1(i), in_2(i)); \
- VERIFY_IS_APPROX(out(i), ver); \
- } \
- sycl_device.deallocate(gpu_data_1); \
- sycl_device.deallocate(gpu_data_2); \
- sycl_device.deallocate(gpu_data_out); \
- }
-
-#define TEST_BINARY_BUILTINS_OPERATORS(SCALAR, OPERATOR, Layout) \
- { \
- /* out = in_1 OPERATOR in_2 */ \
- Tensor<SCALAR, 3, Layout, int64_t> in_1(tensorRange); \
- Tensor<SCALAR, 3, Layout, int64_t> in_2(tensorRange); \
- Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
- in_1 = in_1.random() + static_cast<SCALAR>(0.01); \
- in_2 = in_2.random() + static_cast<SCALAR>(0.01); \
- Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
- SCALAR *gpu_data_1 = static_cast<SCALAR *>( \
- sycl_device.allocate(in_1.size() * sizeof(SCALAR))); \
- SCALAR *gpu_data_2 = static_cast<SCALAR *>( \
- sycl_device.allocate(in_2.size() * sizeof(SCALAR))); \
- SCALAR *gpu_data_out = static_cast<SCALAR *>( \
- sycl_device.allocate(out.size() * sizeof(SCALAR))); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_1(gpu_data_1, tensorRange); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_2(gpu_data_2, tensorRange); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
- sycl_device.memcpyHostToDevice(gpu_data_1, in_1.data(), \
- (in_1.size()) * sizeof(SCALAR)); \
- sycl_device.memcpyHostToDevice(gpu_data_2, in_2.data(), \
- (in_2.size()) * sizeof(SCALAR)); \
- gpu_out.device(sycl_device) = gpu_1 OPERATOR gpu_2; \
- sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
- (out.size()) * sizeof(SCALAR)); \
- for (int64_t i = 0; i < out.size(); ++i) { \
- VERIFY_IS_APPROX(out(i), in_1(i) OPERATOR in_2(i)); \
- } \
- sycl_device.deallocate(gpu_data_1); \
- sycl_device.deallocate(gpu_data_2); \
- sycl_device.deallocate(gpu_data_out); \
- }
-
-#define TEST_BINARY_BUILTINS_OPERATORS_THAT_TAKES_SCALAR(SCALAR, OPERATOR, Layout) \
- { \
- /* out = in_1 OPERATOR 2 */ \
- Tensor<SCALAR, 3, Layout, int64_t> in_1(tensorRange); \
- Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
- in_1 = in_1.random() + static_cast<SCALAR>(0.01); \
- Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
- SCALAR *gpu_data_1 = static_cast<SCALAR *>( \
- sycl_device.allocate(in_1.size() * sizeof(SCALAR))); \
- SCALAR *gpu_data_out = static_cast<SCALAR *>( \
- sycl_device.allocate(out.size() * sizeof(SCALAR))); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_1(gpu_data_1, tensorRange); \
- TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
- sycl_device.memcpyHostToDevice(gpu_data_1, in_1.data(), \
- (in_1.size()) * sizeof(SCALAR)); \
- gpu_out.device(sycl_device) = gpu_1 OPERATOR 2; \
- sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
- (out.size()) * sizeof(SCALAR)); \
- for (int64_t i = 0; i < out.size(); ++i) { \
- VERIFY_IS_APPROX(out(i), in_1(i) OPERATOR 2); \
- } \
- sycl_device.deallocate(gpu_data_1); \
- sycl_device.deallocate(gpu_data_out); \
- }
-
-#define TEST_BINARY_BUILTINS(SCALAR, Layout) \
- TEST_BINARY_BUILTINS_FUNC(SCALAR, cwiseMax , Layout) \
- TEST_BINARY_BUILTINS_FUNC(SCALAR, cwiseMin , Layout) \
- TEST_BINARY_BUILTINS_OPERATORS(SCALAR, + , Layout) \
- TEST_BINARY_BUILTINS_OPERATORS(SCALAR, - , Layout) \
- TEST_BINARY_BUILTINS_OPERATORS(SCALAR, * , Layout) \
- TEST_BINARY_BUILTINS_OPERATORS(SCALAR, / , Layout)
-
-static void test_builtin_binary_sycl(const Eigen::SyclDevice &sycl_device) {
- int64_t sizeDim1 = 10;
- int64_t sizeDim2 = 10;
- int64_t sizeDim3 = 10;
- array<int64_t, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
- TEST_BINARY_BUILTINS(float, RowMajor)
- TEST_BINARY_BUILTINS_OPERATORS_THAT_TAKES_SCALAR(int, %, RowMajor)
- TEST_BINARY_BUILTINS(float, ColMajor)
- TEST_BINARY_BUILTINS_OPERATORS_THAT_TAKES_SCALAR(int, %, ColMajor)
-}
-
-void test_cxx11_tensor_builtins_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- QueueInterface queueInterface(device);
- Eigen::SyclDevice sycl_device(&queueInterface);
- CALL_SUBTEST(test_builtin_unary_sycl(sycl_device));
- CALL_SUBTEST(test_builtin_binary_sycl(sycl_device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_chipping.cpp b/eigen/unsupported/test/cxx11_tensor_chipping.cpp
index 89cf5c7..1832dec 100644
--- a/eigen/unsupported/test/cxx11_tensor_chipping.cpp
+++ b/eigen/unsupported/test/cxx11_tensor_chipping.cpp
@@ -43,7 +43,7 @@ static void test_simple_chip()
VERIFY_IS_EQUAL(chip2.dimension(2), 7);
VERIFY_IS_EQUAL(chip2.dimension(3), 11);
for (int i = 0; i < 2; ++i) {
- for (int j = 0; j < 5; ++j) {
+ for (int j = 0; j < 3; ++j) {
for (int k = 0; k < 7; ++k) {
for (int l = 0; l < 11; ++l) {
VERIFY_IS_EQUAL(chip2(i,j,k,l), tensor(i,1,j,k,l));
@@ -75,7 +75,7 @@ static void test_simple_chip()
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
for (int k = 0; k < 5; ++k) {
- for (int l = 0; l < 11; ++l) {
+ for (int l = 0; l < 7; ++l) {
VERIFY_IS_EQUAL(chip4(i,j,k,l), tensor(i,j,k,5,l));
}
}
@@ -126,7 +126,7 @@ static void test_dynamic_chip()
VERIFY_IS_EQUAL(chip2.dimension(2), 7);
VERIFY_IS_EQUAL(chip2.dimension(3), 11);
for (int i = 0; i < 2; ++i) {
- for (int j = 0; j < 5; ++j) {
+ for (int j = 0; j < 3; ++j) {
for (int k = 0; k < 7; ++k) {
for (int l = 0; l < 11; ++l) {
VERIFY_IS_EQUAL(chip2(i,j,k,l), tensor(i,1,j,k,l));
@@ -158,7 +158,7 @@ static void test_dynamic_chip()
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
for (int k = 0; k < 5; ++k) {
- for (int l = 0; l < 11; ++l) {
+ for (int l = 0; l < 7; ++l) {
VERIFY_IS_EQUAL(chip4(i,j,k,l), tensor(i,j,k,5,l));
}
}
diff --git a/eigen/unsupported/test/cxx11_tensor_chipping_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_chipping_sycl.cpp
deleted file mode 100644
index 39e4f0a..0000000
--- a/eigen/unsupported/test/cxx11_tensor_chipping_sycl.cpp
+++ /dev/null
@@ -1,622 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.com>
-// Benoit Steiner <benoit.steiner.goog@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/.
-
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_chipping_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-#include "main.h"
-
-#include <Eigen/CXX11/Tensor>
-
-using Eigen::Tensor;
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_static_chip_sycl(const Eigen::SyclDevice& sycl_device)
-{
- IndexType sizeDim1 = 2;
- IndexType sizeDim2 = 3;
- IndexType sizeDim3 = 5;
- IndexType sizeDim4 = 7;
- IndexType sizeDim5 = 11;
-
- array<IndexType, 5> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
- array<IndexType, 4> chip1TensorRange = {{sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
-
- Tensor<DataType, 5, DataLayout,IndexType> tensor(tensorRange);
- Tensor<DataType, 4, DataLayout,IndexType> chip1(chip1TensorRange);
-
- tensor.setRandom();
-
- const size_t tensorBuffSize =tensor.size()*sizeof(DataType);
- const size_t chip1TensorBuffSize =chip1.size()*sizeof(DataType);
- DataType* gpu_data_tensor = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize));
- DataType* gpu_data_chip1 = static_cast<DataType*>(sycl_device.allocate(chip1TensorBuffSize));
-
- TensorMap<Tensor<DataType, 5, DataLayout,IndexType>> gpu_tensor(gpu_data_tensor, tensorRange);
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip1(gpu_data_chip1, chip1TensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data_tensor, tensor.data(), tensorBuffSize);
- gpu_chip1.device(sycl_device)=gpu_tensor.template chip<0l>(1l);
- sycl_device.memcpyDeviceToHost(chip1.data(), gpu_data_chip1, chip1TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip1.dimension(0), sizeDim2);
- VERIFY_IS_EQUAL(chip1.dimension(1), sizeDim3);
- VERIFY_IS_EQUAL(chip1.dimension(2), sizeDim4);
- VERIFY_IS_EQUAL(chip1.dimension(3), sizeDim5);
-
- for (IndexType i = 0; i < sizeDim2; ++i) {
- for (IndexType j = 0; j < sizeDim3; ++j) {
- for (IndexType k = 0; k < sizeDim4; ++k) {
- for (IndexType l = 0; l < sizeDim5; ++l) {
- VERIFY_IS_EQUAL(chip1(i,j,k,l), tensor(1l,i,j,k,l));
- }
- }
- }
- }
-
- array<IndexType, 4> chip2TensorRange = {{sizeDim1, sizeDim3, sizeDim4, sizeDim5}};
- Tensor<DataType, 4, DataLayout,IndexType> chip2(chip2TensorRange);
- const size_t chip2TensorBuffSize =chip2.size()*sizeof(DataType);
- DataType* gpu_data_chip2 = static_cast<DataType*>(sycl_device.allocate(chip2TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip2(gpu_data_chip2, chip2TensorRange);
-
- gpu_chip2.device(sycl_device)=gpu_tensor.template chip<1l>(1l);
- sycl_device.memcpyDeviceToHost(chip2.data(), gpu_data_chip2, chip2TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip2.dimension(0), sizeDim1);
- VERIFY_IS_EQUAL(chip2.dimension(1), sizeDim3);
- VERIFY_IS_EQUAL(chip2.dimension(2), sizeDim4);
- VERIFY_IS_EQUAL(chip2.dimension(3), sizeDim5);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim3; ++j) {
- for (IndexType k = 0; k < sizeDim4; ++k) {
- for (IndexType l = 0; l < sizeDim5; ++l) {
- VERIFY_IS_EQUAL(chip2(i,j,k,l), tensor(i,1l,j,k,l));
- }
- }
- }
- }
-
- array<IndexType, 4> chip3TensorRange = {{sizeDim1, sizeDim2, sizeDim4, sizeDim5}};
- Tensor<DataType, 4, DataLayout,IndexType> chip3(chip3TensorRange);
- const size_t chip3TensorBuffSize =chip3.size()*sizeof(DataType);
- DataType* gpu_data_chip3 = static_cast<DataType*>(sycl_device.allocate(chip3TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip3(gpu_data_chip3, chip3TensorRange);
-
- gpu_chip3.device(sycl_device)=gpu_tensor.template chip<2l>(2l);
- sycl_device.memcpyDeviceToHost(chip3.data(), gpu_data_chip3, chip3TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip3.dimension(0), sizeDim1);
- VERIFY_IS_EQUAL(chip3.dimension(1), sizeDim2);
- VERIFY_IS_EQUAL(chip3.dimension(2), sizeDim4);
- VERIFY_IS_EQUAL(chip3.dimension(3), sizeDim5);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim4; ++k) {
- for (IndexType l = 0; l < sizeDim5; ++l) {
- VERIFY_IS_EQUAL(chip3(i,j,k,l), tensor(i,j,2l,k,l));
- }
- }
- }
- }
-
- array<IndexType, 4> chip4TensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim5}};
- Tensor<DataType, 4, DataLayout,IndexType> chip4(chip4TensorRange);
- const size_t chip4TensorBuffSize =chip4.size()*sizeof(DataType);
- DataType* gpu_data_chip4 = static_cast<DataType*>(sycl_device.allocate(chip4TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip4(gpu_data_chip4, chip4TensorRange);
-
- gpu_chip4.device(sycl_device)=gpu_tensor.template chip<3l>(5l);
- sycl_device.memcpyDeviceToHost(chip4.data(), gpu_data_chip4, chip4TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip4.dimension(0), sizeDim1);
- VERIFY_IS_EQUAL(chip4.dimension(1), sizeDim2);
- VERIFY_IS_EQUAL(chip4.dimension(2), sizeDim3);
- VERIFY_IS_EQUAL(chip4.dimension(3), sizeDim5);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
- for (IndexType l = 0; l < sizeDim5; ++l) {
- VERIFY_IS_EQUAL(chip4(i,j,k,l), tensor(i,j,k,5l,l));
- }
- }
- }
- }
-
-
- array<IndexType, 4> chip5TensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
- Tensor<DataType, 4, DataLayout,IndexType> chip5(chip5TensorRange);
- const size_t chip5TensorBuffSize =chip5.size()*sizeof(DataType);
- DataType* gpu_data_chip5 = static_cast<DataType*>(sycl_device.allocate(chip5TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip5(gpu_data_chip5, chip5TensorRange);
-
- gpu_chip5.device(sycl_device)=gpu_tensor.template chip<4l>(7l);
- sycl_device.memcpyDeviceToHost(chip5.data(), gpu_data_chip5, chip5TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip5.dimension(0), sizeDim1);
- VERIFY_IS_EQUAL(chip5.dimension(1), sizeDim2);
- VERIFY_IS_EQUAL(chip5.dimension(2), sizeDim3);
- VERIFY_IS_EQUAL(chip5.dimension(3), sizeDim4);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
- for (IndexType l = 0; l < sizeDim4; ++l) {
- VERIFY_IS_EQUAL(chip5(i,j,k,l), tensor(i,j,k,l,7l));
- }
- }
- }
- }
-
- sycl_device.deallocate(gpu_data_tensor);
- sycl_device.deallocate(gpu_data_chip1);
- sycl_device.deallocate(gpu_data_chip2);
- sycl_device.deallocate(gpu_data_chip3);
- sycl_device.deallocate(gpu_data_chip4);
- sycl_device.deallocate(gpu_data_chip5);
-}
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_dynamic_chip_sycl(const Eigen::SyclDevice& sycl_device)
-{
- IndexType sizeDim1 = 2;
- IndexType sizeDim2 = 3;
- IndexType sizeDim3 = 5;
- IndexType sizeDim4 = 7;
- IndexType sizeDim5 = 11;
-
- array<IndexType, 5> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
- array<IndexType, 4> chip1TensorRange = {{sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
-
- Tensor<DataType, 5, DataLayout,IndexType> tensor(tensorRange);
- Tensor<DataType, 4, DataLayout,IndexType> chip1(chip1TensorRange);
-
- tensor.setRandom();
-
- const size_t tensorBuffSize =tensor.size()*sizeof(DataType);
- const size_t chip1TensorBuffSize =chip1.size()*sizeof(DataType);
- DataType* gpu_data_tensor = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize));
- DataType* gpu_data_chip1 = static_cast<DataType*>(sycl_device.allocate(chip1TensorBuffSize));
-
- TensorMap<Tensor<DataType, 5, DataLayout,IndexType>> gpu_tensor(gpu_data_tensor, tensorRange);
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip1(gpu_data_chip1, chip1TensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data_tensor, tensor.data(), tensorBuffSize);
- gpu_chip1.device(sycl_device)=gpu_tensor.chip(1l,0l);
- sycl_device.memcpyDeviceToHost(chip1.data(), gpu_data_chip1, chip1TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip1.dimension(0), sizeDim2);
- VERIFY_IS_EQUAL(chip1.dimension(1), sizeDim3);
- VERIFY_IS_EQUAL(chip1.dimension(2), sizeDim4);
- VERIFY_IS_EQUAL(chip1.dimension(3), sizeDim5);
-
- for (IndexType i = 0; i < sizeDim2; ++i) {
- for (IndexType j = 0; j < sizeDim3; ++j) {
- for (IndexType k = 0; k < sizeDim4; ++k) {
- for (IndexType l = 0; l < sizeDim5; ++l) {
- VERIFY_IS_EQUAL(chip1(i,j,k,l), tensor(1l,i,j,k,l));
- }
- }
- }
- }
-
- array<IndexType, 4> chip2TensorRange = {{sizeDim1, sizeDim3, sizeDim4, sizeDim5}};
- Tensor<DataType, 4, DataLayout,IndexType> chip2(chip2TensorRange);
- const size_t chip2TensorBuffSize =chip2.size()*sizeof(DataType);
- DataType* gpu_data_chip2 = static_cast<DataType*>(sycl_device.allocate(chip2TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip2(gpu_data_chip2, chip2TensorRange);
-
- gpu_chip2.device(sycl_device)=gpu_tensor.chip(1l,1l);
- sycl_device.memcpyDeviceToHost(chip2.data(), gpu_data_chip2, chip2TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip2.dimension(0), sizeDim1);
- VERIFY_IS_EQUAL(chip2.dimension(1), sizeDim3);
- VERIFY_IS_EQUAL(chip2.dimension(2), sizeDim4);
- VERIFY_IS_EQUAL(chip2.dimension(3), sizeDim5);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim3; ++j) {
- for (IndexType k = 0; k < sizeDim4; ++k) {
- for (IndexType l = 0; l < sizeDim5; ++l) {
- VERIFY_IS_EQUAL(chip2(i,j,k,l), tensor(i,1l,j,k,l));
- }
- }
- }
- }
-
- array<IndexType, 4> chip3TensorRange = {{sizeDim1, sizeDim2, sizeDim4, sizeDim5}};
- Tensor<DataType, 4, DataLayout,IndexType> chip3(chip3TensorRange);
- const size_t chip3TensorBuffSize =chip3.size()*sizeof(DataType);
- DataType* gpu_data_chip3 = static_cast<DataType*>(sycl_device.allocate(chip3TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip3(gpu_data_chip3, chip3TensorRange);
-
- gpu_chip3.device(sycl_device)=gpu_tensor.chip(2l,2l);
- sycl_device.memcpyDeviceToHost(chip3.data(), gpu_data_chip3, chip3TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip3.dimension(0), sizeDim1);
- VERIFY_IS_EQUAL(chip3.dimension(1), sizeDim2);
- VERIFY_IS_EQUAL(chip3.dimension(2), sizeDim4);
- VERIFY_IS_EQUAL(chip3.dimension(3), sizeDim5);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim4; ++k) {
- for (IndexType l = 0; l < sizeDim5; ++l) {
- VERIFY_IS_EQUAL(chip3(i,j,k,l), tensor(i,j,2l,k,l));
- }
- }
- }
- }
-
- array<IndexType, 4> chip4TensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim5}};
- Tensor<DataType, 4, DataLayout,IndexType> chip4(chip4TensorRange);
- const size_t chip4TensorBuffSize =chip4.size()*sizeof(DataType);
- DataType* gpu_data_chip4 = static_cast<DataType*>(sycl_device.allocate(chip4TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip4(gpu_data_chip4, chip4TensorRange);
-
- gpu_chip4.device(sycl_device)=gpu_tensor.chip(5l,3l);
- sycl_device.memcpyDeviceToHost(chip4.data(), gpu_data_chip4, chip4TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip4.dimension(0), sizeDim1);
- VERIFY_IS_EQUAL(chip4.dimension(1), sizeDim2);
- VERIFY_IS_EQUAL(chip4.dimension(2), sizeDim3);
- VERIFY_IS_EQUAL(chip4.dimension(3), sizeDim5);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
- for (IndexType l = 0; l < sizeDim5; ++l) {
- VERIFY_IS_EQUAL(chip4(i,j,k,l), tensor(i,j,k,5l,l));
- }
- }
- }
- }
-
-
- array<IndexType, 4> chip5TensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
- Tensor<DataType, 4, DataLayout,IndexType> chip5(chip5TensorRange);
- const size_t chip5TensorBuffSize =chip5.size()*sizeof(DataType);
- DataType* gpu_data_chip5 = static_cast<DataType*>(sycl_device.allocate(chip5TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip5(gpu_data_chip5, chip5TensorRange);
-
- gpu_chip5.device(sycl_device)=gpu_tensor.chip(7l,4l);
- sycl_device.memcpyDeviceToHost(chip5.data(), gpu_data_chip5, chip5TensorBuffSize);
-
- VERIFY_IS_EQUAL(chip5.dimension(0), sizeDim1);
- VERIFY_IS_EQUAL(chip5.dimension(1), sizeDim2);
- VERIFY_IS_EQUAL(chip5.dimension(2), sizeDim3);
- VERIFY_IS_EQUAL(chip5.dimension(3), sizeDim4);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
- for (IndexType l = 0; l < sizeDim4; ++l) {
- VERIFY_IS_EQUAL(chip5(i,j,k,l), tensor(i,j,k,l,7l));
- }
- }
- }
- }
- sycl_device.deallocate(gpu_data_tensor);
- sycl_device.deallocate(gpu_data_chip1);
- sycl_device.deallocate(gpu_data_chip2);
- sycl_device.deallocate(gpu_data_chip3);
- sycl_device.deallocate(gpu_data_chip4);
- sycl_device.deallocate(gpu_data_chip5);
-}
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_chip_in_expr(const Eigen::SyclDevice& sycl_device) {
-
- IndexType sizeDim1 = 2;
- IndexType sizeDim2 = 3;
- IndexType sizeDim3 = 5;
- IndexType sizeDim4 = 7;
- IndexType sizeDim5 = 11;
-
- array<IndexType, 5> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
- array<IndexType, 4> chip1TensorRange = {{sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
-
- Tensor<DataType, 5, DataLayout,IndexType> tensor(tensorRange);
-
- Tensor<DataType, 4, DataLayout,IndexType> chip1(chip1TensorRange);
- Tensor<DataType, 4, DataLayout,IndexType> tensor1(chip1TensorRange);
- tensor.setRandom();
- tensor1.setRandom();
-
- const size_t tensorBuffSize =tensor.size()*sizeof(DataType);
- const size_t chip1TensorBuffSize =chip1.size()*sizeof(DataType);
- DataType* gpu_data_tensor = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize));
- DataType* gpu_data_chip1 = static_cast<DataType*>(sycl_device.allocate(chip1TensorBuffSize));
- DataType* gpu_data_tensor1 = static_cast<DataType*>(sycl_device.allocate(chip1TensorBuffSize));
-
- TensorMap<Tensor<DataType, 5, DataLayout,IndexType>> gpu_tensor(gpu_data_tensor, tensorRange);
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_chip1(gpu_data_chip1, chip1TensorRange);
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_tensor1(gpu_data_tensor1, chip1TensorRange);
-
-
- sycl_device.memcpyHostToDevice(gpu_data_tensor, tensor.data(), tensorBuffSize);
- sycl_device.memcpyHostToDevice(gpu_data_tensor1, tensor1.data(), chip1TensorBuffSize);
- gpu_chip1.device(sycl_device)=gpu_tensor.template chip<0l>(0l) + gpu_tensor1;
- sycl_device.memcpyDeviceToHost(chip1.data(), gpu_data_chip1, chip1TensorBuffSize);
-
- for (int i = 0; i < sizeDim2; ++i) {
- for (int j = 0; j < sizeDim3; ++j) {
- for (int k = 0; k < sizeDim4; ++k) {
- for (int l = 0; l < sizeDim5; ++l) {
- float expected = tensor(0l,i,j,k,l) + tensor1(i,j,k,l);
- VERIFY_IS_EQUAL(chip1(i,j,k,l), expected);
- }
- }
- }
- }
-
- array<IndexType, 3> chip2TensorRange = {{sizeDim2, sizeDim4, sizeDim5}};
- Tensor<DataType, 3, DataLayout,IndexType> tensor2(chip2TensorRange);
- Tensor<DataType, 3, DataLayout,IndexType> chip2(chip2TensorRange);
- tensor2.setRandom();
- const size_t chip2TensorBuffSize =tensor2.size()*sizeof(DataType);
- DataType* gpu_data_tensor2 = static_cast<DataType*>(sycl_device.allocate(chip2TensorBuffSize));
- DataType* gpu_data_chip2 = static_cast<DataType*>(sycl_device.allocate(chip2TensorBuffSize));
- TensorMap<Tensor<DataType, 3, DataLayout,IndexType>> gpu_tensor2(gpu_data_tensor2, chip2TensorRange);
- TensorMap<Tensor<DataType, 3, DataLayout,IndexType>> gpu_chip2(gpu_data_chip2, chip2TensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data_tensor2, tensor2.data(), chip2TensorBuffSize);
- gpu_chip2.device(sycl_device)=gpu_tensor.template chip<0l>(0l).template chip<1l>(2l) + gpu_tensor2;
- sycl_device.memcpyDeviceToHost(chip2.data(), gpu_data_chip2, chip2TensorBuffSize);
-
- for (int i = 0; i < sizeDim2; ++i) {
- for (int j = 0; j < sizeDim4; ++j) {
- for (int k = 0; k < sizeDim5; ++k) {
- float expected = tensor(0l,i,2l,j,k) + tensor2(i,j,k);
- VERIFY_IS_EQUAL(chip2(i,j,k), expected);
- }
- }
- }
- sycl_device.deallocate(gpu_data_tensor);
- sycl_device.deallocate(gpu_data_tensor1);
- sycl_device.deallocate(gpu_data_chip1);
- sycl_device.deallocate(gpu_data_tensor2);
- sycl_device.deallocate(gpu_data_chip2);
-}
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_chip_as_lvalue_sycl(const Eigen::SyclDevice& sycl_device)
-{
-
- IndexType sizeDim1 = 2;
- IndexType sizeDim2 = 3;
- IndexType sizeDim3 = 5;
- IndexType sizeDim4 = 7;
- IndexType sizeDim5 = 11;
-
- array<IndexType, 5> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
- array<IndexType, 4> input2TensorRange = {{sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
-
- Tensor<DataType, 5, DataLayout,IndexType> tensor(tensorRange);
- Tensor<DataType, 5, DataLayout,IndexType> input1(tensorRange);
- Tensor<DataType, 4, DataLayout,IndexType> input2(input2TensorRange);
- input1.setRandom();
- input2.setRandom();
-
-
- const size_t tensorBuffSize =tensor.size()*sizeof(DataType);
- const size_t input2TensorBuffSize =input2.size()*sizeof(DataType);
- DataType* gpu_data_tensor = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize));
- DataType* gpu_data_input1 = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize));
- DataType* gpu_data_input2 = static_cast<DataType*>(sycl_device.allocate(input2TensorBuffSize));
-
- TensorMap<Tensor<DataType, 5, DataLayout,IndexType>> gpu_tensor(gpu_data_tensor, tensorRange);
- TensorMap<Tensor<DataType, 5, DataLayout,IndexType>> gpu_input1(gpu_data_input1, tensorRange);
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_input2(gpu_data_input2, input2TensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data_input1, input1.data(), tensorBuffSize);
- gpu_tensor.device(sycl_device)=gpu_input1;
- sycl_device.memcpyHostToDevice(gpu_data_input2, input2.data(), input2TensorBuffSize);
- gpu_tensor.template chip<0l>(1l).device(sycl_device)=gpu_input2;
- sycl_device.memcpyDeviceToHost(tensor.data(), gpu_data_tensor, tensorBuffSize);
-
- for (int i = 0; i < sizeDim1; ++i) {
- for (int j = 0; j < sizeDim2; ++j) {
- for (int k = 0; k < sizeDim3; ++k) {
- for (int l = 0; l < sizeDim4; ++l) {
- for (int m = 0; m < sizeDim5; ++m) {
- if (i != 1) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input1(i,j,k,l,m));
- } else {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input2(j,k,l,m));
- }
- }
- }
- }
- }
- }
-
- gpu_tensor.device(sycl_device)=gpu_input1;
- array<IndexType, 4> input3TensorRange = {{sizeDim1, sizeDim3, sizeDim4, sizeDim5}};
- Tensor<DataType, 4, DataLayout,IndexType> input3(input3TensorRange);
- input3.setRandom();
-
- const size_t input3TensorBuffSize =input3.size()*sizeof(DataType);
- DataType* gpu_data_input3 = static_cast<DataType*>(sycl_device.allocate(input3TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_input3(gpu_data_input3, input3TensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data_input3, input3.data(), input3TensorBuffSize);
- gpu_tensor.template chip<1l>(1l).device(sycl_device)=gpu_input3;
- sycl_device.memcpyDeviceToHost(tensor.data(), gpu_data_tensor, tensorBuffSize);
-
- for (int i = 0; i < sizeDim1; ++i) {
- for (int j = 0; j < sizeDim2; ++j) {
- for (int k = 0; k <sizeDim3; ++k) {
- for (int l = 0; l < sizeDim4; ++l) {
- for (int m = 0; m < sizeDim5; ++m) {
- if (j != 1) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input1(i,j,k,l,m));
- } else {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input3(i,k,l,m));
- }
- }
- }
- }
- }
- }
-
- gpu_tensor.device(sycl_device)=gpu_input1;
- array<IndexType, 4> input4TensorRange = {{sizeDim1, sizeDim2, sizeDim4, sizeDim5}};
- Tensor<DataType, 4, DataLayout,IndexType> input4(input4TensorRange);
- input4.setRandom();
-
- const size_t input4TensorBuffSize =input4.size()*sizeof(DataType);
- DataType* gpu_data_input4 = static_cast<DataType*>(sycl_device.allocate(input4TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_input4(gpu_data_input4, input4TensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data_input4, input4.data(), input4TensorBuffSize);
- gpu_tensor.template chip<2l>(3l).device(sycl_device)=gpu_input4;
- sycl_device.memcpyDeviceToHost(tensor.data(), gpu_data_tensor, tensorBuffSize);
-
- for (int i = 0; i < sizeDim1; ++i) {
- for (int j = 0; j < sizeDim2; ++j) {
- for (int k = 0; k <sizeDim3; ++k) {
- for (int l = 0; l < sizeDim4; ++l) {
- for (int m = 0; m < sizeDim5; ++m) {
- if (k != 3) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input1(i,j,k,l,m));
- } else {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input4(i,j,l,m));
- }
- }
- }
- }
- }
- }
-
- gpu_tensor.device(sycl_device)=gpu_input1;
- array<IndexType, 4> input5TensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim5}};
- Tensor<DataType, 4, DataLayout,IndexType> input5(input5TensorRange);
- input5.setRandom();
-
- const size_t input5TensorBuffSize =input5.size()*sizeof(DataType);
- DataType* gpu_data_input5 = static_cast<DataType*>(sycl_device.allocate(input5TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_input5(gpu_data_input5, input5TensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data_input5, input5.data(), input5TensorBuffSize);
- gpu_tensor.template chip<3l>(4l).device(sycl_device)=gpu_input5;
- sycl_device.memcpyDeviceToHost(tensor.data(), gpu_data_tensor, tensorBuffSize);
-
- for (int i = 0; i < sizeDim1; ++i) {
- for (int j = 0; j < sizeDim2; ++j) {
- for (int k = 0; k <sizeDim3; ++k) {
- for (int l = 0; l < sizeDim4; ++l) {
- for (int m = 0; m < sizeDim5; ++m) {
- if (l != 4) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input1(i,j,k,l,m));
- } else {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input5(i,j,k,m));
- }
- }
- }
- }
- }
- }
- gpu_tensor.device(sycl_device)=gpu_input1;
- array<IndexType, 4> input6TensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
- Tensor<DataType, 4, DataLayout,IndexType> input6(input6TensorRange);
- input6.setRandom();
-
- const size_t input6TensorBuffSize =input6.size()*sizeof(DataType);
- DataType* gpu_data_input6 = static_cast<DataType*>(sycl_device.allocate(input6TensorBuffSize));
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu_input6(gpu_data_input6, input6TensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data_input6, input6.data(), input6TensorBuffSize);
- gpu_tensor.template chip<4l>(5l).device(sycl_device)=gpu_input6;
- sycl_device.memcpyDeviceToHost(tensor.data(), gpu_data_tensor, tensorBuffSize);
-
- for (int i = 0; i < sizeDim1; ++i) {
- for (int j = 0; j < sizeDim2; ++j) {
- for (int k = 0; k <sizeDim3; ++k) {
- for (int l = 0; l < sizeDim4; ++l) {
- for (int m = 0; m < sizeDim5; ++m) {
- if (m != 5) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input1(i,j,k,l,m));
- } else {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input6(i,j,k,l));
- }
- }
- }
- }
- }
- }
-
-
- gpu_tensor.device(sycl_device)=gpu_input1;
- Tensor<DataType, 5, DataLayout,IndexType> input7(tensorRange);
- input7.setRandom();
-
- DataType* gpu_data_input7 = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize));
- TensorMap<Tensor<DataType, 5, DataLayout,IndexType>> gpu_input7(gpu_data_input7, tensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data_input7, input7.data(), tensorBuffSize);
- gpu_tensor.chip(0l,0l).device(sycl_device)=gpu_input7.chip(0l,0l);
- sycl_device.memcpyDeviceToHost(tensor.data(), gpu_data_tensor, tensorBuffSize);
-
- for (int i = 0; i < sizeDim1; ++i) {
- for (int j = 0; j < sizeDim2; ++j) {
- for (int k = 0; k <sizeDim3; ++k) {
- for (int l = 0; l < sizeDim4; ++l) {
- for (int m = 0; m < sizeDim5; ++m) {
- if (i != 0) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input1(i,j,k,l,m));
- } else {
- VERIFY_IS_EQUAL(tensor(i,j,k,l,m), input7(i,j,k,l,m));
- }
- }
- }
- }
- }
- }
- sycl_device.deallocate(gpu_data_tensor);
- sycl_device.deallocate(gpu_data_input1);
- sycl_device.deallocate(gpu_data_input2);
- sycl_device.deallocate(gpu_data_input3);
- sycl_device.deallocate(gpu_data_input4);
- sycl_device.deallocate(gpu_data_input5);
- sycl_device.deallocate(gpu_data_input6);
- sycl_device.deallocate(gpu_data_input7);
-
-}
-
-template<typename DataType, typename dev_Selector> void sycl_chipping_test_per_device(dev_Selector s){
- QueueInterface queueInterface(s);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_static_chip_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_static_chip_sycl<DataType, ColMajor, int64_t>(sycl_device);
- test_dynamic_chip_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_dynamic_chip_sycl<DataType, ColMajor, int64_t>(sycl_device);
- test_chip_in_expr<DataType, RowMajor, int64_t>(sycl_device);
- test_chip_in_expr<DataType, ColMajor, int64_t>(sycl_device);
- test_chip_as_lvalue_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_chip_as_lvalue_sycl<DataType, ColMajor, int64_t>(sycl_device);
-}
-void test_cxx11_tensor_chipping_sycl()
-{
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(sycl_chipping_test_per_device<float>(device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_concatenation_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_concatenation_sycl.cpp
deleted file mode 100644
index e3023a3..0000000
--- a/eigen/unsupported/test/cxx11_tensor_concatenation_sycl.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.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/.
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_concatenation_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-#include "main.h"
-#include <unsupported/Eigen/CXX11/Tensor>
-
-using Eigen::Tensor;
-
-template<typename DataType, int DataLayout, typename IndexType>
-static void test_simple_concatenation(const Eigen::SyclDevice& sycl_device)
-{
- IndexType leftDim1 = 2;
- IndexType leftDim2 = 3;
- IndexType leftDim3 = 1;
- Eigen::array<IndexType, 3> leftRange = {{leftDim1, leftDim2, leftDim3}};
- IndexType rightDim1 = 2;
- IndexType rightDim2 = 3;
- IndexType rightDim3 = 1;
- Eigen::array<IndexType, 3> rightRange = {{rightDim1, rightDim2, rightDim3}};
-
- //IndexType concatDim1 = 3;
-// IndexType concatDim2 = 3;
-// IndexType concatDim3 = 1;
- //Eigen::array<IndexType, 3> concatRange = {{concatDim1, concatDim2, concatDim3}};
-
- Tensor<DataType, 3, DataLayout, IndexType> left(leftRange);
- Tensor<DataType, 3, DataLayout, IndexType> right(rightRange);
- left.setRandom();
- right.setRandom();
-
- DataType * gpu_in1_data = static_cast<DataType*>(sycl_device.allocate(left.dimensions().TotalSize()*sizeof(DataType)));
- DataType * gpu_in2_data = static_cast<DataType*>(sycl_device.allocate(right.dimensions().TotalSize()*sizeof(DataType)));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType>> gpu_in1(gpu_in1_data, leftRange);
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType>> gpu_in2(gpu_in2_data, rightRange);
- sycl_device.memcpyHostToDevice(gpu_in1_data, left.data(),(left.dimensions().TotalSize())*sizeof(DataType));
- sycl_device.memcpyHostToDevice(gpu_in2_data, right.data(),(right.dimensions().TotalSize())*sizeof(DataType));
- ///
- Tensor<DataType, 3, DataLayout, IndexType> concatenation1(leftDim1+rightDim1, leftDim2, leftDim3);
- DataType * gpu_out_data1 = static_cast<DataType*>(sycl_device.allocate(concatenation1.dimensions().TotalSize()*sizeof(DataType)));
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType>> gpu_out1(gpu_out_data1, concatenation1.dimensions());
-
- //concatenation = left.concatenate(right, 0);
- gpu_out1.device(sycl_device) =gpu_in1.concatenate(gpu_in2, 0);
- sycl_device.memcpyDeviceToHost(concatenation1.data(), gpu_out_data1,(concatenation1.dimensions().TotalSize())*sizeof(DataType));
-
- VERIFY_IS_EQUAL(concatenation1.dimension(0), 4);
- VERIFY_IS_EQUAL(concatenation1.dimension(1), 3);
- VERIFY_IS_EQUAL(concatenation1.dimension(2), 1);
- for (IndexType j = 0; j < 3; ++j) {
- for (IndexType i = 0; i < 2; ++i) {
- VERIFY_IS_EQUAL(concatenation1(i, j, 0), left(i, j, 0));
- }
- for (IndexType i = 2; i < 4; ++i) {
- VERIFY_IS_EQUAL(concatenation1(i, j, 0), right(i - 2, j, 0));
- }
- }
-
- sycl_device.deallocate(gpu_out_data1);
- Tensor<DataType, 3, DataLayout, IndexType> concatenation2(leftDim1, leftDim2 +rightDim2, leftDim3);
- DataType * gpu_out_data2 = static_cast<DataType*>(sycl_device.allocate(concatenation2.dimensions().TotalSize()*sizeof(DataType)));
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType>> gpu_out2(gpu_out_data2, concatenation2.dimensions());
- gpu_out2.device(sycl_device) =gpu_in1.concatenate(gpu_in2, 1);
- sycl_device.memcpyDeviceToHost(concatenation2.data(), gpu_out_data2,(concatenation2.dimensions().TotalSize())*sizeof(DataType));
-
- //concatenation = left.concatenate(right, 1);
- VERIFY_IS_EQUAL(concatenation2.dimension(0), 2);
- VERIFY_IS_EQUAL(concatenation2.dimension(1), 6);
- VERIFY_IS_EQUAL(concatenation2.dimension(2), 1);
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 3; ++j) {
- VERIFY_IS_EQUAL(concatenation2(i, j, 0), left(i, j, 0));
- }
- for (IndexType j = 3; j < 6; ++j) {
- VERIFY_IS_EQUAL(concatenation2(i, j, 0), right(i, j - 3, 0));
- }
- }
- sycl_device.deallocate(gpu_out_data2);
- Tensor<DataType, 3, DataLayout, IndexType> concatenation3(leftDim1, leftDim2, leftDim3+rightDim3);
- DataType * gpu_out_data3 = static_cast<DataType*>(sycl_device.allocate(concatenation3.dimensions().TotalSize()*sizeof(DataType)));
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType>> gpu_out3(gpu_out_data3, concatenation3.dimensions());
- gpu_out3.device(sycl_device) =gpu_in1.concatenate(gpu_in2, 2);
- sycl_device.memcpyDeviceToHost(concatenation3.data(), gpu_out_data3,(concatenation3.dimensions().TotalSize())*sizeof(DataType));
-
- //concatenation = left.concatenate(right, 2);
- VERIFY_IS_EQUAL(concatenation3.dimension(0), 2);
- VERIFY_IS_EQUAL(concatenation3.dimension(1), 3);
- VERIFY_IS_EQUAL(concatenation3.dimension(2), 2);
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 3; ++j) {
- VERIFY_IS_EQUAL(concatenation3(i, j, 0), left(i, j, 0));
- VERIFY_IS_EQUAL(concatenation3(i, j, 1), right(i, j, 0));
- }
- }
- sycl_device.deallocate(gpu_out_data3);
- sycl_device.deallocate(gpu_in1_data);
- sycl_device.deallocate(gpu_in2_data);
-}
-template<typename DataType, int DataLayout, typename IndexType>
-static void test_concatenation_as_lvalue(const Eigen::SyclDevice& sycl_device)
-{
-
- IndexType leftDim1 = 2;
- IndexType leftDim2 = 3;
- Eigen::array<IndexType, 2> leftRange = {{leftDim1, leftDim2}};
-
- IndexType rightDim1 = 2;
- IndexType rightDim2 = 3;
- Eigen::array<IndexType, 2> rightRange = {{rightDim1, rightDim2}};
-
- IndexType concatDim1 = 4;
- IndexType concatDim2 = 3;
- Eigen::array<IndexType, 2> resRange = {{concatDim1, concatDim2}};
-
- Tensor<DataType, 2, DataLayout, IndexType> left(leftRange);
- Tensor<DataType, 2, DataLayout, IndexType> right(rightRange);
- Tensor<DataType, 2, DataLayout, IndexType> result(resRange);
-
- left.setRandom();
- right.setRandom();
- result.setRandom();
-
- DataType * gpu_in1_data = static_cast<DataType*>(sycl_device.allocate(left.dimensions().TotalSize()*sizeof(DataType)));
- DataType * gpu_in2_data = static_cast<DataType*>(sycl_device.allocate(right.dimensions().TotalSize()*sizeof(DataType)));
- DataType * gpu_out_data = static_cast<DataType*>(sycl_device.allocate(result.dimensions().TotalSize()*sizeof(DataType)));
-
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType>> gpu_in1(gpu_in1_data, leftRange);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType>> gpu_in2(gpu_in2_data, rightRange);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType>> gpu_out(gpu_out_data, resRange);
-
- sycl_device.memcpyHostToDevice(gpu_in1_data, left.data(),(left.dimensions().TotalSize())*sizeof(DataType));
- sycl_device.memcpyHostToDevice(gpu_in2_data, right.data(),(right.dimensions().TotalSize())*sizeof(DataType));
- sycl_device.memcpyHostToDevice(gpu_out_data, result.data(),(result.dimensions().TotalSize())*sizeof(DataType));
-
-// t1.concatenate(t2, 0) = result;
- gpu_in1.concatenate(gpu_in2, 0).device(sycl_device) =gpu_out;
- sycl_device.memcpyDeviceToHost(left.data(), gpu_in1_data,(left.dimensions().TotalSize())*sizeof(DataType));
- sycl_device.memcpyDeviceToHost(right.data(), gpu_in2_data,(right.dimensions().TotalSize())*sizeof(DataType));
-
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 3; ++j) {
- VERIFY_IS_EQUAL(left(i, j), result(i, j));
- VERIFY_IS_EQUAL(right(i, j), result(i+2, j));
- }
- }
- sycl_device.deallocate(gpu_in1_data);
- sycl_device.deallocate(gpu_in2_data);
- sycl_device.deallocate(gpu_out_data);
-}
-
-
-template <typename DataType, typename Dev_selector> void tensorConcat_perDevice(Dev_selector s){
- QueueInterface queueInterface(s);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_simple_concatenation<DataType, RowMajor, int64_t>(sycl_device);
- test_simple_concatenation<DataType, ColMajor, int64_t>(sycl_device);
- test_concatenation_as_lvalue<DataType, ColMajor, int64_t>(sycl_device);
-}
-void test_cxx11_tensor_concatenation_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(tensorConcat_perDevice<float>(device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_contract_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_contract_sycl.cpp
deleted file mode 100644
index 5bace66..0000000
--- a/eigen/unsupported/test/cxx11_tensor_contract_sycl.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.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/.
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_contract_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-#include <iostream>
-#include <chrono>
-#include <ctime>
-
-#include "main.h"
-#include <unsupported/Eigen/CXX11/Tensor>
-
-using Eigen::array;
-using Eigen::SyclDevice;
-using Eigen::Tensor;
-using Eigen::TensorMap;
-template<int DataLayout, typename DataType, typename IndexType, typename Device>
-void static test_sycl_contraction(const Device& sycl_device, IndexType m_size, IndexType k_size, IndexType n_size)
-{
- typedef typename Tensor<DataType, 1, DataLayout, IndexType>::DimensionPair DimPair;
- static const DataType error_threshold =1e-4f;
-// std::cout << "Testing for (" << m_size << "," << k_size << "," << n_size << ")" << std::endl;
- // with these dimensions, the output has 300 * 140 elements, which is
- // more than 30 * 1024, which is the number of threads in blocks on
- // a 15 SM GK110 GPU
- Tensor<DataType, 2, DataLayout, IndexType> t_left(m_size, k_size);
- Tensor<DataType, 2, DataLayout, IndexType> t_right(k_size, n_size);
- Tensor<DataType, 2, DataLayout, IndexType> t_result(m_size, n_size);
- Tensor<DataType, 2, DataLayout, IndexType> t_result_gpu(m_size, n_size);
-// Eigen::array<DimPair, 1> dims(DimPair(1, 0));
- Eigen::array<DimPair, 1> dims = {{DimPair(1, 0)}};
- Eigen::array<IndexType, 2> left_dims = {{m_size, k_size}};
- Eigen::array<IndexType, 2> right_dims = {{k_size, n_size}};
- Eigen::array<IndexType, 2> result_dims = {{m_size, n_size}};
-
- t_left.setRandom();
- t_right.setRandom();
-
- std::size_t t_left_bytes = t_left.size() * sizeof(DataType);
- std::size_t t_right_bytes = t_right.size() * sizeof(DataType);
- std::size_t t_result_bytes = t_result.size() * sizeof(DataType);
-
- DataType * d_t_left = static_cast<DataType*>(sycl_device.allocate(t_left_bytes));
- DataType * d_t_right = static_cast<DataType*>(sycl_device.allocate(t_right_bytes));
- DataType * d_t_result = static_cast<DataType*>(sycl_device.allocate(t_result_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_t_left(d_t_left, left_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_t_right(d_t_right, right_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_t_result(d_t_result, result_dims);
-
- sycl_device.memcpyHostToDevice(d_t_left, t_left.data(),t_left_bytes);
- sycl_device.memcpyHostToDevice(d_t_right, t_right.data(),t_right_bytes);
-
- gpu_t_result.device(sycl_device) = gpu_t_left.contract(gpu_t_right, dims);
- sycl_device.memcpyDeviceToHost(t_result_gpu.data(), d_t_result, t_result_bytes);
-
- t_result = t_left.contract(t_right, dims);
-
- for (IndexType i = 0; i < t_result.size(); i++) {
- if (static_cast<DataType>(fabs(t_result(i) - t_result_gpu(i))) < error_threshold) {
- continue;
- }
- if (Eigen::internal::isApprox(t_result(i), t_result_gpu(i), error_threshold)) {
- continue;
- }
- std::cout << "mismatch detected at IndexType " << i << ": " << t_result(i)
- << " vs " << t_result_gpu(i) << std::endl;
- assert(false);
- }
- sycl_device.deallocate(d_t_left);
- sycl_device.deallocate(d_t_right);
- sycl_device.deallocate(d_t_result);
-}
-
-template<int DataLayout, typename DataType, typename IndexType, typename Device>
-void test_TF(const Device& sycl_device)
-{
- typedef typename Tensor<DataType, 1, DataLayout, IndexType>::DimensionPair DimPair;
- static const DataType error_threshold =1e-4f;
- Eigen::array<IndexType, 2> left_dims = {{2, 3}};
- Eigen::array<IndexType, 2> right_dims = {{3, 1}};
- Eigen::array<IndexType, 2> res_dims = {{2, 1}};
- Eigen::array<DimPair, 1> dims = {{DimPair(1, 0)}};
-
-
- Tensor<DataType, 2, DataLayout, IndexType> t_left(left_dims);
- Tensor<DataType, 2, DataLayout, IndexType> t_right(right_dims);
- Tensor<DataType, 2, DataLayout, IndexType> t_result_gpu(res_dims);
- Tensor<DataType, 2, DataLayout, IndexType> t_result(res_dims);
-
- t_left.data()[0] = 1.0f;
- t_left.data()[1] = 2.0f;
- t_left.data()[2] = 3.0f;
- t_left.data()[3] = 4.0f;
- t_left.data()[4] = 5.0f;
- t_left.data()[5] = 6.0f;
-
- t_right.data()[0] = -1.0f;
- t_right.data()[1] = 0.5f;
- t_right.data()[2] = 2.0f;
-
- std::size_t t_left_bytes = t_left.size() * sizeof(DataType);
- std::size_t t_right_bytes = t_right.size() * sizeof(DataType);
- std::size_t t_result_bytes = t_result.size()*sizeof(DataType);
-
-
- DataType * d_t_left = static_cast<DataType*>(sycl_device.allocate(t_left_bytes));
- DataType * d_t_right = static_cast<DataType*>(sycl_device.allocate(t_right_bytes));
- DataType * d_t_result = static_cast<DataType*>(sycl_device.allocate(t_result_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_t_left(d_t_left, left_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_t_right(d_t_right, right_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_t_result(d_t_result, res_dims);
-
- sycl_device.memcpyHostToDevice(d_t_left, t_left.data(),t_left_bytes);
- sycl_device.memcpyHostToDevice(d_t_right, t_right.data(),t_right_bytes);
-
- gpu_t_result.device(sycl_device) = gpu_t_left.contract(gpu_t_right, dims);
- sycl_device.memcpyDeviceToHost(t_result_gpu.data(), d_t_result, t_result_bytes);
-
- t_result = t_left.contract(t_right, dims);
-
- for (IndexType i = 0; i < t_result.size(); i++) {
- if (static_cast<DataType>(fabs(t_result(i) - t_result_gpu(i))) < error_threshold) {
- continue;
- }
- if (Eigen::internal::isApprox(t_result(i), t_result_gpu(i), error_threshold)) {
- continue;
- }
- std::cout << "mismatch detected at IndexType " << i << ": " << t_result(i)
- << " vs " << t_result_gpu(i) << std::endl;
- assert(false);
- }
- sycl_device.deallocate(d_t_left);
- sycl_device.deallocate(d_t_right);
- sycl_device.deallocate(d_t_result);
-
-
-}
-
-template<int DataLayout, typename DataType, typename IndexType, typename Device>
-void test_scalar(const Device& sycl_device, IndexType m_size, IndexType k_size, IndexType n_size)
-{
- //std::cout << "Testing for (" << m_size << "," << k_size << "," << n_size << ")" << std::endl;
- // with these dimensions, the output has 300 * 140 elements, which is
- // more than 30 * 1024, which is the number of threads in blocks on
- // a 15 SM GK110 GPU
- typedef typename Tensor<DataType, 1, DataLayout, IndexType>::DimensionPair DimPair;
- static const DataType error_threshold =1e-4f;
- Tensor<DataType, 2, DataLayout, IndexType> t_left(m_size, k_size);
- Tensor<DataType, 2, DataLayout, IndexType> t_right(k_size, n_size);
- Tensor<DataType, 0, DataLayout, IndexType> t_result;
- Tensor<DataType, 0, DataLayout, IndexType> t_result_gpu;
- Eigen::array<DimPair, 2> dims = {{DimPair(0, 0), DimPair(1, 1)}};
- Eigen::array<IndexType, 2> left_dims = {{m_size, k_size}};
- Eigen::array<IndexType, 2> right_dims = {{k_size, n_size}};
- t_left.setRandom();
- t_right.setRandom();
-
- std::size_t t_left_bytes = t_left.size() * sizeof(DataType);
- std::size_t t_right_bytes = t_right.size() * sizeof(DataType);
- std::size_t t_result_bytes = sizeof(DataType);
-
-
- DataType * d_t_left = static_cast<DataType*>(sycl_device.allocate(t_left_bytes));
- DataType * d_t_right = static_cast<DataType*>(sycl_device.allocate(t_right_bytes));
- DataType * d_t_result = static_cast<DataType*>(sycl_device.allocate(t_result_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_t_left(d_t_left, left_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_t_right(d_t_right, right_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 0, DataLayout, IndexType> > gpu_t_result(d_t_result);
-
- sycl_device.memcpyHostToDevice(d_t_left, t_left.data(),t_left_bytes);
- sycl_device.memcpyHostToDevice(d_t_right, t_right.data(),t_right_bytes);
-
- gpu_t_result.device(sycl_device) = gpu_t_left.contract(gpu_t_right, dims);
- sycl_device.memcpyDeviceToHost(t_result_gpu.data(), d_t_result, t_result_bytes);
-
- t_result = t_left.contract(t_right, dims);
-
- if (static_cast<DataType>(fabs(t_result() - t_result_gpu())) > error_threshold &&
- !Eigen::internal::isApprox(t_result(), t_result_gpu(), error_threshold)) {
- std::cout << "mismatch detected: " << t_result()
- << " vs " << t_result_gpu() << std::endl;
- assert(false);
- }
-
- sycl_device.deallocate(d_t_left);
- sycl_device.deallocate(d_t_right);
- sycl_device.deallocate(d_t_result);
-}
-
-
-template<int DataLayout, typename DataType, typename IndexType, typename Device>
-void test_sycl_contraction_m(const Device& sycl_device) {
- for (IndexType k = 32; k < 256; k++) {
- test_sycl_contraction<DataLayout, DataType, IndexType>(sycl_device, k, 128, 128);
- }
-}
-
-template<int DataLayout, typename DataType, typename IndexType, typename Device>
-void test_sycl_contraction_k(const Device& sycl_device) {
- for (IndexType k = 32; k < 256; k++) {
- test_sycl_contraction<DataLayout, DataType, IndexType>(sycl_device, 128, k, 128);
- }
-}
-
-template<int DataLayout, typename DataType, typename IndexType, typename Device>
-void test_sycl_contraction_n(const Device& sycl_device) {
- for (IndexType k = 32; k < 256; k++) {
- test_sycl_contraction<DataLayout, DataType, IndexType>(sycl_device, 128, 128, k);
- }
-}
-
-
-template<int DataLayout, typename DataType, typename IndexType, typename Device>
-void test_sycl_contraction_sizes(const Device& sycl_device) {
- IndexType m_sizes[] = { 31, 39, 63, 64, 65,
- 127, 129, 255, 257 , 511,
- 512, 513, 1023, 1024, 1025};
-
- IndexType n_sizes[] = { 31, 39, 63, 64, 65,
- 127, 129, 255, 257, 511,
- 512, 513, 1023, 1024, 1025};
-
- IndexType k_sizes[] = { 31, 39, 63, 64, 65,
- 95, 96, 127, 129, 255,
- 257, 511, 512, 513, 1023,
- 1024, 1025};
-
- for (IndexType i = 0; i < 15; i++) {
- for (IndexType j = 0; j < 15; j++) {
- for (IndexType k = 0; k < 17; k++) {
- test_sycl_contraction<DataLayout, DataType,IndexType>(sycl_device, m_sizes[i], n_sizes[j], k_sizes[k]);
- }
- }
- }
-}
-
-template <typename Dev_selector> void tensorContractionPerDevice(Dev_selector& s){
- QueueInterface queueInterface(s);
- auto sycl_device=Eigen::SyclDevice(&queueInterface);
- test_sycl_contraction<ColMajor, float,int64_t>(sycl_device, 32, 32, 32);
- test_sycl_contraction<RowMajor,float,int64_t>(sycl_device, 32, 32, 32);
- test_scalar<ColMajor,float,int64_t>(sycl_device, 32, 32, 32);
- test_scalar<RowMajor,float,int64_t>(sycl_device, 32, 32, 32);
- std::chrono::time_point<std::chrono::system_clock> start, end;
- start = std::chrono::system_clock::now();
- test_sycl_contraction<ColMajor,float,int64_t>(sycl_device, 128, 128, 128);
- test_sycl_contraction<RowMajor,float,int64_t>(sycl_device, 128, 128, 128);
- test_scalar<ColMajor,float,int64_t>(sycl_device, 128, 128, 128);
- test_scalar<RowMajor,float,int64_t>(sycl_device, 128, 128, 128);
- test_sycl_contraction_m<ColMajor, float, int64_t>(sycl_device);
- test_sycl_contraction_m<RowMajor, float, int64_t>(sycl_device);
- test_sycl_contraction_n<ColMajor, float, int64_t>(sycl_device);
- test_sycl_contraction_n<RowMajor, float, int64_t>(sycl_device);
- test_sycl_contraction_k<ColMajor, float, int64_t>(sycl_device);
- test_sycl_contraction_k<RowMajor, float, int64_t>(sycl_device);
- test_sycl_contraction_sizes<ColMajor, float, int64_t>(sycl_device);
- test_sycl_contraction_sizes<RowMajor, float, int64_t>(sycl_device);
- test_TF<RowMajor, float, int64_t>(sycl_device);
- test_TF<ColMajor, float, int64_t>(sycl_device);
-
- end = std::chrono::system_clock::now();
- std::chrono::duration<double> elapsed_seconds = end-start;
- std::time_t end_time = std::chrono::system_clock::to_time_t(end);
- std::cout << "finished computation at " << std::ctime(&end_time)
- << "elapsed time: " << elapsed_seconds.count() << "s\n";
-
-}
-
-void test_cxx11_tensor_contract_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(tensorContractionPerDevice(device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_convolution_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_convolution_sycl.cpp
deleted file mode 100644
index a4226a6..0000000
--- a/eigen/unsupported/test/cxx11_tensor_convolution_sycl.cpp
+++ /dev/null
@@ -1,469 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.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/.
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_convolution_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-#include <iostream>
-#include <chrono>
-#include <ctime>
-
-#include "main.h"
-#include <unsupported/Eigen/CXX11/Tensor>
-#include <iomanip>
-
-using Eigen::array;
-using Eigen::SyclDevice;
-using Eigen::Tensor;
-using Eigen::TensorMap;
-static const float error_threshold =1e-4f;
-
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_larg_expr1D(const Eigen::SyclDevice& sycl_device)
-{
- IndexType indim0 =53;
- IndexType indim1= 55;
- IndexType indim2= 51;
- IndexType outdim0=50;
- IndexType outdim1=55;
- IndexType outdim2=51;
- Eigen::array<IndexType, 3> input_dims = {{indim0, indim1, indim2}};
- Eigen::array<IndexType, 1> kernel_dims = {{4}};
- Eigen::array<IndexType, 3> result_dims = {{outdim0, outdim1, outdim2}};
-
- Tensor<DataType, 3, DataLayout, IndexType> input(input_dims);
- Tensor<DataType, 1, DataLayout,IndexType> kernel(kernel_dims);
- Tensor<DataType, 3, DataLayout,IndexType> result(result_dims);
- Tensor<DataType, 3, DataLayout,IndexType> result_host(result_dims);
-
- Eigen::array<IndexType, 1> dims3{{0}};
-
- input.setRandom();
- kernel.setRandom();
- result.setZero();
- result_host.setZero();
-
- std::size_t input_bytes = input.size() * sizeof(DataType);
- std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
- std::size_t result_bytes = result.size() * sizeof(DataType);
-
- DataType * d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
- DataType * d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
- DataType * d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_input(d_input, input_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_result(d_result, result_dims);
- sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
- sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);
-
- gpu_result.device(sycl_device)=gpu_input.convolve(gpu_kernel, dims3);
- sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);
-
- result_host=input.convolve(kernel, dims3);
-
-for(IndexType i=0; i< outdim0; i++ ){
- for(IndexType j=0; j< outdim1; j++ ){
- for(IndexType k=0; k< outdim2; k++ ){
- if (!(Eigen::internal::isApprox(result(i,j,k), result_host(i,j,k), error_threshold))) {
- std::cout <<std::setprecision(16)<< "mismatch detected at index ( "<< i << " , " << j << ", " << k << " ) " << " \t " << result(i,j,k) << " vs "<< result_host(i,j,k) << std::endl;
- assert(false);
- }
- }
- }
-}
- sycl_device.deallocate(d_input);
- sycl_device.deallocate(d_kernel);
- sycl_device.deallocate(d_result);
-
-}
-
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_larg_expr2D(const Eigen::SyclDevice& sycl_device)
-{
- IndexType indim0 =53;
- IndexType indim1= 55;
- IndexType indim2= 51;
- IndexType outdim0=50;
- IndexType outdim1=51;
- IndexType outdim2=51;
- Eigen::array<IndexType, 3> input_dims = {{indim0, indim1, indim2}};
- Eigen::array<IndexType, 2> kernel_dims = {{4,5}};
- Eigen::array<IndexType, 3> result_dims = {{outdim0, outdim1, outdim2}};
-
- Tensor<DataType, 3, DataLayout, IndexType> input(input_dims);
- Tensor<DataType, 2, DataLayout,IndexType> kernel(kernel_dims);
- Tensor<DataType, 3, DataLayout,IndexType> result(result_dims);
- Tensor<DataType, 3, DataLayout,IndexType> result_host(result_dims);
-
- Eigen::array<IndexType, 2> dims3{{0,1}};
-
- input.setRandom();
- kernel.setRandom();
- result.setZero();
- result_host.setZero();
-
- std::size_t input_bytes = input.size() * sizeof(DataType);
- std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
- std::size_t result_bytes = result.size() * sizeof(DataType);
-
- DataType * d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
- DataType * d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
- DataType * d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_input(d_input, input_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_result(d_result, result_dims);
- sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
- sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);
-
- gpu_result.device(sycl_device)=gpu_input.convolve(gpu_kernel, dims3);
- sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);
-
- result_host=input.convolve(kernel, dims3);
-
-for(IndexType i=0; i< outdim0; i++ ){
- for(IndexType j=0; j< outdim1; j++ ){
- for(IndexType k=0; k< outdim2; k++ ){
- if (!(Eigen::internal::isApprox(result(i,j,k), result_host(i,j,k), error_threshold))) {
- std::cout <<std::setprecision(16)<< "mismatch detected at index ( "<< i << " , " << j << ", " << k << " ) " << " \t " << result(i,j,k) << " vs "<< result_host(i,j,k) << std::endl;
- assert(false);
- }
- }
- }
-}
- sycl_device.deallocate(d_input);
- sycl_device.deallocate(d_kernel);
- sycl_device.deallocate(d_result);
-
-}
-
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_larg_expr3D(const Eigen::SyclDevice& sycl_device)
-{
- IndexType indim0 =53;
- IndexType indim1= 55;
- IndexType indim2= 51;
- IndexType outdim0=50;
- IndexType outdim1=51;
- IndexType outdim2=49;
- Eigen::array<IndexType, 3> input_dims = {{indim0, indim1, indim2}};
- Eigen::array<IndexType, 3> kernel_dims = {{4,5,3}};
- Eigen::array<IndexType, 3> result_dims = {{outdim0, outdim1, outdim2}};
-
- Tensor<DataType, 3, DataLayout, IndexType> input(input_dims);
- Tensor<DataType, 3, DataLayout,IndexType> kernel(kernel_dims);
- Tensor<DataType, 3, DataLayout,IndexType> result(result_dims);
- Tensor<DataType, 3, DataLayout,IndexType> result_host(result_dims);
-
- Eigen::array<IndexType, 3> dims3{{0,1,2}};
-
- input.setRandom();
- kernel.setRandom();
- result.setZero();
- result_host.setZero();
-
- std::size_t input_bytes = input.size() * sizeof(DataType);
- std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
- std::size_t result_bytes = result.size() * sizeof(DataType);
-
- DataType * d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
- DataType * d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
- DataType * d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_input(d_input, input_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_result(d_result, result_dims);
- sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
- sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);
-
- gpu_result.device(sycl_device)=gpu_input.convolve(gpu_kernel, dims3);
- sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);
-
- result_host=input.convolve(kernel, dims3);
-
-for(IndexType i=0; i< outdim0; i++ ){
- for(IndexType j=0; j< outdim1; j++ ){
- for(IndexType k=0; k< outdim2; k++ ){
- if (!(Eigen::internal::isApprox(result(i,j,k), result_host(i,j,k), error_threshold))) {
- std::cout <<std::setprecision(16)<< "mismatch detected at index ( "<< i << " , " << j << ", " << k << " ) " << " \t " << result(i,j,k) << " vs "<< result_host(i,j,k) << std::endl;
- assert(false);
- }
- }
- }
-}
- sycl_device.deallocate(d_input);
- sycl_device.deallocate(d_kernel);
- sycl_device.deallocate(d_result);
-
-}
-
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_evals(const Eigen::SyclDevice& sycl_device)
-{
- Eigen::array<IndexType, 2> input_dims = {{3, 3}};
- Eigen::array<IndexType, 1> kernel_dims = {{2}};
- Eigen::array<IndexType, 2> result_dims = {{2, 3}};
-
- Tensor<DataType, 2, DataLayout, IndexType> input(input_dims);
- Tensor<DataType, 1, DataLayout,IndexType> kernel(kernel_dims);
- Tensor<DataType, 2, DataLayout,IndexType> result(result_dims);
-
- Eigen::array<IndexType, 1> dims3{{0}};
-
- input.setRandom();
- kernel.setRandom();
- result.setZero();
-
- std::size_t input_bytes = input.size() * sizeof(DataType);
- std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
- std::size_t result_bytes = result.size() * sizeof(DataType);
-
- DataType * d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
- DataType * d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
- DataType * d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_input(d_input, input_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_result(d_result, result_dims);
- sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
- sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);
-
- gpu_result.device(sycl_device)=gpu_input.convolve(gpu_kernel, dims3);
- sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);
-
- VERIFY_IS_APPROX(result(0,0), input(0,0)*kernel(0) + input(1,0)*kernel(1)); // index 0
- VERIFY_IS_APPROX(result(0,1), input(0,1)*kernel(0) + input(1,1)*kernel(1)); // index 2
- VERIFY_IS_APPROX(result(0,2), input(0,2)*kernel(0) + input(1,2)*kernel(1)); // index 4
- VERIFY_IS_APPROX(result(1,0), input(1,0)*kernel(0) + input(2,0)*kernel(1)); // index 1
- VERIFY_IS_APPROX(result(1,1), input(1,1)*kernel(0) + input(2,1)*kernel(1)); // index 3
- VERIFY_IS_APPROX(result(1,2), input(1,2)*kernel(0) + input(2,2)*kernel(1)); // index 5
-
- sycl_device.deallocate(d_input);
- sycl_device.deallocate(d_kernel);
- sycl_device.deallocate(d_result);
-}
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_expr(const Eigen::SyclDevice& sycl_device)
-{
- Eigen::array<IndexType, 2> input_dims = {{3, 3}};
- Eigen::array<IndexType, 2> kernel_dims = {{2, 2}};
- Eigen::array<IndexType, 2> result_dims = {{2, 2}};
-
- Tensor<DataType, 2, DataLayout, IndexType> input(input_dims);
- Tensor<DataType, 2, DataLayout, IndexType> kernel(kernel_dims);
- Tensor<DataType, 2, DataLayout, IndexType> result(result_dims);
-
- input.setRandom();
- kernel.setRandom();
- Eigen::array<IndexType, 2> dims;
- dims[0] = 0;
- dims[1] = 1;
-
- std::size_t input_bytes = input.size() * sizeof(DataType);
- std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
- std::size_t result_bytes = result.size() * sizeof(DataType);
-
- DataType * d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
- DataType * d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
- DataType * d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout,IndexType> > gpu_input(d_input, input_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout,IndexType> > gpu_kernel(d_kernel, kernel_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout,IndexType> > gpu_result(d_result, result_dims);
- sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
- sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);
-
- gpu_result.device(sycl_device)=gpu_input.convolve(gpu_kernel, dims);
- sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);
-
- VERIFY_IS_APPROX(result(0,0), input(0,0)*kernel(0,0) + input(0,1)*kernel(0,1) +
- input(1,0)*kernel(1,0) + input(1,1)*kernel(1,1));
- VERIFY_IS_APPROX(result(0,1), input(0,1)*kernel(0,0) + input(0,2)*kernel(0,1) +
- input(1,1)*kernel(1,0) + input(1,2)*kernel(1,1));
- VERIFY_IS_APPROX(result(1,0), input(1,0)*kernel(0,0) + input(1,1)*kernel(0,1) +
- input(2,0)*kernel(1,0) + input(2,1)*kernel(1,1));
- VERIFY_IS_APPROX(result(1,1), input(1,1)*kernel(0,0) + input(1,2)*kernel(0,1) +
- input(2,1)*kernel(1,0) + input(2,2)*kernel(1,1));
-
- sycl_device.deallocate(d_input);
- sycl_device.deallocate(d_kernel);
- sycl_device.deallocate(d_result);
-}
-
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_modes(const Eigen::SyclDevice& sycl_device){
-
-Eigen::array<IndexType, 1> input_dims = {{3}};
-Eigen::array<IndexType, 1> kernel_dims = {{3}};
-
-Tensor<DataType, 1, DataLayout, IndexType> input(input_dims);
-Tensor<DataType, 1, DataLayout, IndexType> kernel(kernel_dims);
-
-input.setRandom();
-kernel.setRandom();
-Eigen::array<IndexType, 1> dims;
-dims[0] = 0;
-
- input(0) = 1.0f;
- input(1) = 2.0f;
- input(2) = 3.0f;
- kernel(0) = 0.5f;
- kernel(1) = 1.0f;
- kernel(2) = 0.0f;
-
- Eigen::array<std::pair<IndexType, IndexType>, 1> padding;
-
- // Emulate VALID mode (as defined in
- // http://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html).
- padding[0] = std::make_pair(0, 0);
- Tensor<DataType, 1, DataLayout, IndexType> valid(1);
-
- std::size_t input_bytes = input.size() * sizeof(DataType);
- std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
- std::size_t valid_bytes = valid.size() * sizeof(DataType);
-
- DataType * d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
- DataType * d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
- DataType * d_valid = static_cast<DataType*>(sycl_device.allocate(valid_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout,IndexType> > gpu_input(d_input, input_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout,IndexType> > gpu_kernel(d_kernel, kernel_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout,IndexType> > gpu_valid(d_valid, valid.dimensions());
- sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
- sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);
-
- gpu_valid.device(sycl_device)=gpu_input.pad(padding).convolve(gpu_kernel, dims);
- sycl_device.memcpyDeviceToHost(valid.data(), d_valid, valid_bytes);
-
- VERIFY_IS_EQUAL(valid.dimension(0), 1);
- VERIFY_IS_APPROX(valid(0), 2.5f);
-
- // Emulate SAME mode (as defined in
- // http://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html).
- padding[0] = std::make_pair(1, 1);
- Tensor<DataType, 1, DataLayout, IndexType> same(3);
- std::size_t same_bytes = same.size() * sizeof(DataType);
- DataType * d_same = static_cast<DataType*>(sycl_device.allocate(same_bytes));
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout,IndexType> > gpu_same(d_same, same.dimensions());
- gpu_same.device(sycl_device)=gpu_input.pad(padding).convolve(gpu_kernel, dims);
- sycl_device.memcpyDeviceToHost(same.data(), d_same, same_bytes);
-
- VERIFY_IS_EQUAL(same.dimension(0), 3);
- VERIFY_IS_APPROX(same(0), 1.0f);
- VERIFY_IS_APPROX(same(1), 2.5f);
- VERIFY_IS_APPROX(same(2), 4.0f);
-
- // Emulate FULL mode (as defined in
- // http://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html).
- padding[0] = std::make_pair(2, 2);
-
- Tensor<DataType, 1, DataLayout, IndexType> full(5);
- std::size_t full_bytes = full.size() * sizeof(DataType);
- DataType * d_full = static_cast<DataType*>(sycl_device.allocate(full_bytes));
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout,IndexType> > gpu_full(d_full, full.dimensions());
- gpu_full.device(sycl_device)=gpu_input.pad(padding).convolve(gpu_kernel, dims);
- sycl_device.memcpyDeviceToHost(full.data(), d_full, full_bytes);
-
- VERIFY_IS_EQUAL(full.dimension(0), 5);
- VERIFY_IS_APPROX(full(0), 0.0f);
- VERIFY_IS_APPROX(full(1), 1.0f);
- VERIFY_IS_APPROX(full(2), 2.5f);
- VERIFY_IS_APPROX(full(3), 4.0f);
- VERIFY_IS_APPROX(full(4), 1.5f);
-
- sycl_device.deallocate(d_input);
- sycl_device.deallocate(d_kernel);
- sycl_device.deallocate(d_valid);
- sycl_device.deallocate(d_same);
- sycl_device.deallocate(d_full);
-
-}
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_strides(const Eigen::SyclDevice& sycl_device){
-
- Eigen::array<IndexType, 1> input_dims = {{13}};
- Eigen::array<IndexType, 1> kernel_dims = {{3}};
-
- Tensor<DataType, 1, DataLayout, IndexType> input(input_dims);
- Tensor<DataType, 1, DataLayout, IndexType> kernel(kernel_dims);
- Tensor<DataType, 1, DataLayout, IndexType> result(2);
-
- input.setRandom();
- kernel.setRandom();
- Eigen::array<IndexType, 1> dims;
- dims[0] = 0;
-
- Eigen::array<IndexType, 1> stride_of_3;
- stride_of_3[0] = 3;
- Eigen::array<IndexType, 1> stride_of_2;
- stride_of_2[0] = 2;
-
- std::size_t input_bytes = input.size() * sizeof(DataType);
- std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
- std::size_t result_bytes = result.size() * sizeof(DataType);
-
- DataType * d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
- DataType * d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
- DataType * d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout,IndexType> > gpu_input(d_input, input_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout,IndexType> > gpu_kernel(d_kernel, kernel_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout,IndexType> > gpu_result(d_result, result.dimensions());
- sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
- sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);
-
- gpu_result.device(sycl_device)=gpu_input.stride(stride_of_3).convolve(gpu_kernel, dims).stride(stride_of_2);
- sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);
-
- VERIFY_IS_EQUAL(result.dimension(0), 2);
- VERIFY_IS_APPROX(result(0), (input(0)*kernel(0) + input(3)*kernel(1) +
- input(6)*kernel(2)));
- VERIFY_IS_APPROX(result(1), (input(6)*kernel(0) + input(9)*kernel(1) +
- input(12)*kernel(2)));
-}
-
-template <typename Dev_selector> void tensorConvolutionPerDevice(Dev_selector& s){
- QueueInterface queueInterface(s);
- auto sycl_device=Eigen::SyclDevice(&queueInterface);
- test_larg_expr1D<float, RowMajor, int64_t>(sycl_device);
- test_larg_expr1D<float, ColMajor, int64_t>(sycl_device);
- test_larg_expr2D<float, RowMajor, int64_t>(sycl_device);
- test_larg_expr2D<float, ColMajor, int64_t>(sycl_device);
- test_larg_expr3D<float, RowMajor, int64_t>(sycl_device);
- test_larg_expr3D<float, ColMajor, int64_t>(sycl_device);
- test_evals<float, ColMajor, int64_t>(sycl_device);
- test_evals<float, RowMajor, int64_t>(sycl_device);
- test_expr<float, ColMajor, int64_t>(sycl_device);
- test_expr<float, RowMajor, int64_t>(sycl_device);
- test_modes<float, ColMajor, int64_t>(sycl_device);
- test_modes<float, RowMajor, int64_t>(sycl_device);
- test_strides<float, ColMajor, int64_t>(sycl_device);
- test_strides<float, RowMajor, int64_t>(sycl_device);
-}
-
-void test_cxx11_tensor_convolution_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(tensorConvolutionPerDevice(device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_device_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_device_sycl.cpp
index 3ecc68d..7f79753 100644
--- a/eigen/unsupported/test/cxx11_tensor_device_sycl.cpp
+++ b/eigen/unsupported/test/cxx11_tensor_device_sycl.cpp
@@ -14,64 +14,18 @@
#define EIGEN_TEST_NO_LONGDOUBLE
#define EIGEN_TEST_NO_COMPLEX
#define EIGEN_TEST_FUNC cxx11_tensor_device_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
+#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
#define EIGEN_USE_SYCL
#include "main.h"
#include <unsupported/Eigen/CXX11/Tensor>
-#include <stdint.h>
-#include <iostream>
-template <typename DataType, int DataLayout, typename IndexType>
-void test_device_memory(const Eigen::SyclDevice &sycl_device) {
- std::cout << "Running on : "
- << sycl_device.sycl_queue().get_device(). template get_info<cl::sycl::info::device::name>()
- <<std::endl;
- IndexType sizeDim1 = 100;
- array<IndexType, 1> tensorRange = {{sizeDim1}};
- Tensor<DataType, 1, DataLayout,IndexType> in(tensorRange);
- Tensor<DataType, 1, DataLayout,IndexType> in1(tensorRange);
- memset(in1.data(), 1, in1.size() * sizeof(DataType));
- DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.size()*sizeof(DataType)));
- sycl_device.memset(gpu_in_data, 1, in.size()*sizeof(DataType));
- sycl_device.memcpyDeviceToHost(in.data(), gpu_in_data, in.size()*sizeof(DataType));
- for (IndexType i=0; i<in.size(); i++) {
- VERIFY_IS_EQUAL(in(i), in1(i));
- }
- sycl_device.deallocate(gpu_in_data);
+void test_device_sycl(const Eigen::SyclDevice &sycl_device) {
+ std::cout <<"Helo from ComputeCpp: the requested device exists and the device name is : "
+ << sycl_device.m_queue.get_device(). template get_info<cl::sycl::info::device::name>() <<std::endl;;
}
-
-template <typename DataType, int DataLayout, typename IndexType>
-void test_device_exceptions(const Eigen::SyclDevice &sycl_device) {
- VERIFY(sycl_device.ok());
- IndexType sizeDim1 = 100;
- array<IndexType, 1> tensorDims = {{sizeDim1}};
- DataType* gpu_data = static_cast<DataType*>(sycl_device.allocate(sizeDim1*sizeof(DataType)));
- sycl_device.memset(gpu_data, 1, sizeDim1*sizeof(DataType));
-
- TensorMap<Tensor<DataType, 1, DataLayout,IndexType>> in(gpu_data, tensorDims);
- TensorMap<Tensor<DataType, 1, DataLayout,IndexType>> out(gpu_data, tensorDims);
- out.device(sycl_device) = in / in.constant(0);
-
- sycl_device.synchronize();
- VERIFY(!sycl_device.ok());
- sycl_device.deallocate(gpu_data);
-}
-
-template<typename DataType> void sycl_device_test_per_device(const cl::sycl::device& d){
- std::cout << "Running on " << d.template get_info<cl::sycl::info::device::name>() << std::endl;
- QueueInterface queueInterface(d);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_device_memory<DataType, RowMajor, int64_t>(sycl_device);
- test_device_memory<DataType, ColMajor, int64_t>(sycl_device);
- /// this test throw an exception. enable it if you want to see the exception
- //test_device_exceptions<DataType, RowMajor>(sycl_device);
- /// this test throw an exception. enable it if you want to see the exception
- //test_device_exceptions<DataType, ColMajor>(sycl_device);
-}
-
void test_cxx11_tensor_device_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(sycl_device_test_per_device<float>(device));
- }
+ cl::sycl::gpu_selector s;
+ Eigen::SyclDevice sycl_device(s);
+ CALL_SUBTEST(test_device_sycl(sycl_device));
}
diff --git a/eigen/unsupported/test/cxx11_tensor_expr.cpp b/eigen/unsupported/test/cxx11_tensor_expr.cpp
index 129b4e6..77e24cb 100644
--- a/eigen/unsupported/test/cxx11_tensor_expr.cpp
+++ b/eigen/unsupported/test/cxx11_tensor_expr.cpp
@@ -300,51 +300,6 @@ static void test_select()
}
}
-template <typename Scalar>
-void test_minmax_nan_propagation_templ() {
- for (int size = 1; size < 17; ++size) {
- const Scalar kNan = std::numeric_limits<Scalar>::quiet_NaN();
- Tensor<Scalar, 1> vec_nan(size);
- Tensor<Scalar, 1> vec_zero(size);
- Tensor<Scalar, 1> vec_res(size);
- vec_nan.setConstant(kNan);
- vec_zero.setZero();
- vec_res.setZero();
-
- // Test that we propagate NaNs in the tensor when applying the
- // cwiseMax(scalar) operator, which is used for the Relu operator.
- vec_res = vec_nan.cwiseMax(Scalar(0));
- for (int i = 0; i < size; ++i) {
- VERIFY((numext::isnan)(vec_res(i)));
- }
-
- // Test that NaNs do not propagate if we reverse the arguments.
- vec_res = vec_zero.cwiseMax(kNan);
- for (int i = 0; i < size; ++i) {
- VERIFY_IS_EQUAL(vec_res(i), Scalar(0));
- }
-
- // Test that we propagate NaNs in the tensor when applying the
- // cwiseMin(scalar) operator.
- vec_res.setZero();
- vec_res = vec_nan.cwiseMin(Scalar(0));
- for (int i = 0; i < size; ++i) {
- VERIFY((numext::isnan)(vec_res(i)));
- }
-
- // Test that NaNs do not propagate if we reverse the arguments.
- vec_res = vec_zero.cwiseMin(kNan);
- for (int i = 0; i < size; ++i) {
- VERIFY_IS_EQUAL(vec_res(i), Scalar(0));
- }
- }
-}
-
-static void test_minmax_nan_propagation()
-{
- test_minmax_nan_propagation_templ<float>();
- test_minmax_nan_propagation_templ<double>();
-}
void test_cxx11_tensor_expr()
{
@@ -356,5 +311,4 @@ void test_cxx11_tensor_expr()
CALL_SUBTEST(test_functors());
CALL_SUBTEST(test_type_casting());
CALL_SUBTEST(test_select());
- CALL_SUBTEST(test_minmax_nan_propagation());
}
diff --git a/eigen/unsupported/test/cxx11_tensor_fixed_size.cpp b/eigen/unsupported/test/cxx11_tensor_fixed_size.cpp
index e6274f8..4c660de 100644
--- a/eigen/unsupported/test/cxx11_tensor_fixed_size.cpp
+++ b/eigen/unsupported/test/cxx11_tensor_fixed_size.cpp
@@ -21,7 +21,7 @@ static void test_0d()
TensorFixedSize<float, Sizes<>, RowMajor> scalar2;
VERIFY_IS_EQUAL(scalar1.rank(), 0);
VERIFY_IS_EQUAL(scalar1.size(), 1);
- VERIFY_IS_EQUAL(internal::array_prod(scalar1.dimensions()), 1);
+ VERIFY_IS_EQUAL(array_prod(scalar1.dimensions()), 1);
scalar1() = 7.0;
scalar2() = 13.0;
diff --git a/eigen/unsupported/test/cxx11_tensor_forced_eval_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_forced_eval_sycl.cpp
index aca036c..5690da7 100644
--- a/eigen/unsupported/test/cxx11_tensor_forced_eval_sycl.cpp
+++ b/eigen/unsupported/test/cxx11_tensor_forced_eval_sycl.cpp
@@ -14,43 +14,43 @@
#define EIGEN_TEST_NO_LONGDOUBLE
#define EIGEN_TEST_NO_COMPLEX
#define EIGEN_TEST_FUNC cxx11_tensor_forced_eval_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
+#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
#define EIGEN_USE_SYCL
#include "main.h"
#include <unsupported/Eigen/CXX11/Tensor>
using Eigen::Tensor;
-template <typename DataType, int DataLayout, typename IndexType>
+
void test_forced_eval_sycl(const Eigen::SyclDevice &sycl_device) {
- IndexType sizeDim1 = 100;
- IndexType sizeDim2 = 20;
- IndexType sizeDim3 = 20;
- Eigen::array<IndexType, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
- Eigen::Tensor<DataType, 3, DataLayout, IndexType> in1(tensorRange);
- Eigen::Tensor<DataType, 3, DataLayout, IndexType> in2(tensorRange);
- Eigen::Tensor<DataType, 3, DataLayout, IndexType> out(tensorRange);
+ int sizeDim1 = 100;
+ int sizeDim2 = 200;
+ int sizeDim3 = 200;
+ Eigen::array<int, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
+ Eigen::Tensor<float, 3> in1(tensorRange);
+ Eigen::Tensor<float, 3> in2(tensorRange);
+ Eigen::Tensor<float, 3> out(tensorRange);
- DataType * gpu_in1_data = static_cast<DataType*>(sycl_device.allocate(in1.dimensions().TotalSize()*sizeof(DataType)));
- DataType * gpu_in2_data = static_cast<DataType*>(sycl_device.allocate(in2.dimensions().TotalSize()*sizeof(DataType)));
- DataType * gpu_out_data = static_cast<DataType*>(sycl_device.allocate(out.dimensions().TotalSize()*sizeof(DataType)));
+ float * gpu_in1_data = static_cast<float*>(sycl_device.allocate(in1.dimensions().TotalSize()*sizeof(float)));
+ float * gpu_in2_data = static_cast<float*>(sycl_device.allocate(in2.dimensions().TotalSize()*sizeof(float)));
+ float * gpu_out_data = static_cast<float*>(sycl_device.allocate(out.dimensions().TotalSize()*sizeof(float)));
in1 = in1.random() + in1.constant(10.0f);
in2 = in2.random() + in2.constant(10.0f);
// creating TensorMap from tensor
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType>> gpu_in1(gpu_in1_data, tensorRange);
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType>> gpu_in2(gpu_in2_data, tensorRange);
- Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType>> gpu_out(gpu_out_data, tensorRange);
- sycl_device.memcpyHostToDevice(gpu_in1_data, in1.data(),(in1.dimensions().TotalSize())*sizeof(DataType));
- sycl_device.memcpyHostToDevice(gpu_in2_data, in2.data(),(in1.dimensions().TotalSize())*sizeof(DataType));
+ Eigen::TensorMap<Eigen::Tensor<float, 3>> gpu_in1(gpu_in1_data, tensorRange);
+ Eigen::TensorMap<Eigen::Tensor<float, 3>> gpu_in2(gpu_in2_data, tensorRange);
+ Eigen::TensorMap<Eigen::Tensor<float, 3>> gpu_out(gpu_out_data, tensorRange);
+ sycl_device.memcpyHostToDevice(gpu_in1_data, in1.data(),(in1.dimensions().TotalSize())*sizeof(float));
+ sycl_device.memcpyHostToDevice(gpu_in2_data, in2.data(),(in1.dimensions().TotalSize())*sizeof(float));
/// c=(a+b)*b
gpu_out.device(sycl_device) =(gpu_in1 + gpu_in2).eval() * gpu_in2;
- sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.dimensions().TotalSize())*sizeof(DataType));
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
+ sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.dimensions().TotalSize())*sizeof(float));
+ for (int i = 0; i < sizeDim1; ++i) {
+ for (int j = 0; j < sizeDim2; ++j) {
+ for (int k = 0; k < sizeDim3; ++k) {
VERIFY_IS_APPROX(out(i, j, k),
(in1(i, j, k) + in2(i, j, k)) * in2(i, j, k));
}
@@ -63,14 +63,8 @@ void test_forced_eval_sycl(const Eigen::SyclDevice &sycl_device) {
}
-template <typename DataType, typename Dev_selector> void tensorForced_evalperDevice(Dev_selector s){
- QueueInterface queueInterface(s);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_forced_eval_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_forced_eval_sycl<DataType, ColMajor, int64_t>(sycl_device);
-}
void test_cxx11_tensor_forced_eval_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(tensorForced_evalperDevice<float>(device));
- }
+ cl::sycl::gpu_selector s;
+ Eigen::SyclDevice sycl_device(s);
+ CALL_SUBTEST(test_forced_eval_sycl(sycl_device));
}
diff --git a/eigen/unsupported/test/cxx11_tensor_morphing_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_morphing_sycl.cpp
deleted file mode 100644
index 9b521bc..0000000
--- a/eigen/unsupported/test/cxx11_tensor_morphing_sycl.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.com>
-// Benoit Steiner <benoit.steiner.goog@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/.
-
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_morphing_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-
-#include "main.h"
-#include <unsupported/Eigen/CXX11/Tensor>
-
-using Eigen::array;
-using Eigen::SyclDevice;
-using Eigen::Tensor;
-using Eigen::TensorMap;
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_simple_reshape(const Eigen::SyclDevice& sycl_device)
-{
- typename Tensor<DataType, 5 ,DataLayout, IndexType>::Dimensions dim1(2,3,1,7,1);
- typename Tensor<DataType, 3 ,DataLayout, IndexType>::Dimensions dim2(2,3,7);
- typename Tensor<DataType, 2 ,DataLayout, IndexType>::Dimensions dim3(6,7);
- typename Tensor<DataType, 2 ,DataLayout, IndexType>::Dimensions dim4(2,21);
-
- Tensor<DataType, 5, DataLayout, IndexType> tensor1(dim1);
- Tensor<DataType, 3, DataLayout, IndexType> tensor2(dim2);
- Tensor<DataType, 2, DataLayout, IndexType> tensor3(dim3);
- Tensor<DataType, 2, DataLayout, IndexType> tensor4(dim4);
-
- tensor1.setRandom();
-
- DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor1.size()*sizeof(DataType)));
- DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(tensor2.size()*sizeof(DataType)));
- DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(tensor3.size()*sizeof(DataType)));
- DataType* gpu_data4 = static_cast<DataType*>(sycl_device.allocate(tensor4.size()*sizeof(DataType)));
-
- TensorMap<Tensor<DataType, 5,DataLayout, IndexType>> gpu1(gpu_data1, dim1);
- TensorMap<Tensor<DataType, 3,DataLayout, IndexType>> gpu2(gpu_data2, dim2);
- TensorMap<Tensor<DataType, 2,DataLayout, IndexType>> gpu3(gpu_data3, dim3);
- TensorMap<Tensor<DataType, 2,DataLayout, IndexType>> gpu4(gpu_data4, dim4);
-
- sycl_device.memcpyHostToDevice(gpu_data1, tensor1.data(),(tensor1.size())*sizeof(DataType));
-
- gpu2.device(sycl_device)=gpu1.reshape(dim2);
- sycl_device.memcpyDeviceToHost(tensor2.data(), gpu_data2,(tensor1.size())*sizeof(DataType));
-
- gpu3.device(sycl_device)=gpu1.reshape(dim3);
- sycl_device.memcpyDeviceToHost(tensor3.data(), gpu_data3,(tensor3.size())*sizeof(DataType));
-
- gpu4.device(sycl_device)=gpu1.reshape(dim2).reshape(dim4);
- sycl_device.memcpyDeviceToHost(tensor4.data(), gpu_data4,(tensor4.size())*sizeof(DataType));
- for (IndexType i = 0; i < 2; ++i){
- for (IndexType j = 0; j < 3; ++j){
- for (IndexType k = 0; k < 7; ++k){
- VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor2(i,j,k)); ///ColMajor
- if (static_cast<int>(DataLayout) == static_cast<int>(ColMajor)) {
- VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor3(i+2*j,k)); ///ColMajor
- VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor4(i,j+3*k)); ///ColMajor
- }
- else{
- //VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor2(i,j,k)); /// RowMajor
- VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor4(i,j*7 +k)); /// RowMajor
- VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor3(i*3 +j,k)); /// RowMajor
- }
- }
- }
- }
- sycl_device.deallocate(gpu_data1);
- sycl_device.deallocate(gpu_data2);
- sycl_device.deallocate(gpu_data3);
- sycl_device.deallocate(gpu_data4);
-}
-
-
-template<typename DataType, int DataLayout, typename IndexType>
-static void test_reshape_as_lvalue(const Eigen::SyclDevice& sycl_device)
-{
- typename Tensor<DataType, 3, DataLayout, IndexType>::Dimensions dim1(2,3,7);
- typename Tensor<DataType, 2, DataLayout, IndexType>::Dimensions dim2(6,7);
- typename Tensor<DataType, 5, DataLayout, IndexType>::Dimensions dim3(2,3,1,7,1);
- Tensor<DataType, 3, DataLayout, IndexType> tensor(dim1);
- Tensor<DataType, 2, DataLayout, IndexType> tensor2d(dim2);
- Tensor<DataType, 5, DataLayout, IndexType> tensor5d(dim3);
-
- tensor.setRandom();
-
- DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor.size()*sizeof(DataType)));
- DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(tensor2d.size()*sizeof(DataType)));
- DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(tensor5d.size()*sizeof(DataType)));
-
- TensorMap< Tensor<DataType, 3, DataLayout, IndexType> > gpu1(gpu_data1, dim1);
- TensorMap< Tensor<DataType, 2, DataLayout, IndexType> > gpu2(gpu_data2, dim2);
- TensorMap< Tensor<DataType, 5, DataLayout, IndexType> > gpu3(gpu_data3, dim3);
-
- sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(),(tensor.size())*sizeof(DataType));
-
- gpu2.reshape(dim1).device(sycl_device)=gpu1;
- sycl_device.memcpyDeviceToHost(tensor2d.data(), gpu_data2,(tensor2d.size())*sizeof(DataType));
-
- gpu3.reshape(dim1).device(sycl_device)=gpu1;
- sycl_device.memcpyDeviceToHost(tensor5d.data(), gpu_data3,(tensor5d.size())*sizeof(DataType));
-
-
- for (IndexType i = 0; i < 2; ++i){
- for (IndexType j = 0; j < 3; ++j){
- for (IndexType k = 0; k < 7; ++k){
- VERIFY_IS_EQUAL(tensor5d(i,j,0,k,0), tensor(i,j,k));
- if (static_cast<int>(DataLayout) == static_cast<int>(ColMajor)) {
- VERIFY_IS_EQUAL(tensor2d(i+2*j,k), tensor(i,j,k)); ///ColMajor
- }
- else{
- VERIFY_IS_EQUAL(tensor2d(i*3 +j,k),tensor(i,j,k)); /// RowMajor
- }
- }
- }
- }
- sycl_device.deallocate(gpu_data1);
- sycl_device.deallocate(gpu_data2);
- sycl_device.deallocate(gpu_data3);
-}
-
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_simple_slice(const Eigen::SyclDevice &sycl_device)
-{
- IndexType sizeDim1 = 2;
- IndexType sizeDim2 = 3;
- IndexType sizeDim3 = 5;
- IndexType sizeDim4 = 7;
- IndexType sizeDim5 = 11;
- array<IndexType, 5> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
- Tensor<DataType, 5,DataLayout, IndexType> tensor(tensorRange);
- tensor.setRandom();
- array<IndexType, 5> slice1_range ={{1, 1, 1, 1, 1}};
- Tensor<DataType, 5,DataLayout, IndexType> slice1(slice1_range);
-
- DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor.size()*sizeof(DataType)));
- DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(slice1.size()*sizeof(DataType)));
- TensorMap<Tensor<DataType, 5,DataLayout, IndexType>> gpu1(gpu_data1, tensorRange);
- TensorMap<Tensor<DataType, 5,DataLayout, IndexType>> gpu2(gpu_data2, slice1_range);
- Eigen::DSizes<IndexType, 5> indices(1,2,3,4,5);
- Eigen::DSizes<IndexType, 5> sizes(1,1,1,1,1);
- sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(),(tensor.size())*sizeof(DataType));
- gpu2.device(sycl_device)=gpu1.slice(indices, sizes);
- sycl_device.memcpyDeviceToHost(slice1.data(), gpu_data2,(slice1.size())*sizeof(DataType));
- VERIFY_IS_EQUAL(slice1(0,0,0,0,0), tensor(1,2,3,4,5));
-
-
- array<IndexType, 5> slice2_range ={{1,1,2,2,3}};
- Tensor<DataType, 5,DataLayout, IndexType> slice2(slice2_range);
- DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(slice2.size()*sizeof(DataType)));
- TensorMap<Tensor<DataType, 5,DataLayout, IndexType>> gpu3(gpu_data3, slice2_range);
- Eigen::DSizes<IndexType, 5> indices2(1,1,3,4,5);
- Eigen::DSizes<IndexType, 5> sizes2(1,1,2,2,3);
- gpu3.device(sycl_device)=gpu1.slice(indices2, sizes2);
- sycl_device.memcpyDeviceToHost(slice2.data(), gpu_data3,(slice2.size())*sizeof(DataType));
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 2; ++j) {
- for (IndexType k = 0; k < 3; ++k) {
- VERIFY_IS_EQUAL(slice2(0,0,i,j,k), tensor(1,1,3+i,4+j,5+k));
- }
- }
- }
- sycl_device.deallocate(gpu_data1);
- sycl_device.deallocate(gpu_data2);
- sycl_device.deallocate(gpu_data3);
-}
-
-template<typename DataType, int DataLayout, typename IndexType>
-static void test_strided_slice_write_sycl(const Eigen::SyclDevice& sycl_device)
-{
- typedef Tensor<DataType, 2, DataLayout, IndexType> Tensor2f;
- typedef Eigen::DSizes<IndexType, 2> Index2;
- IndexType sizeDim1 = 7L;
- IndexType sizeDim2 = 11L;
- array<IndexType, 2> tensorRange = {{sizeDim1, sizeDim2}};
- Tensor<DataType, 2, DataLayout, IndexType> tensor(tensorRange),tensor2(tensorRange);
- IndexType sliceDim1 = 2;
- IndexType sliceDim2 = 3;
- array<IndexType, 2> sliceRange = {{sliceDim1, sliceDim2}};
- Tensor2f slice(sliceRange);
- Index2 strides(1L,1L);
- Index2 indicesStart(3L,4L);
- Index2 indicesStop(5L,7L);
- Index2 lengths(2L,3L);
-
- DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor.size()*sizeof(DataType)));
- DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(tensor2.size()*sizeof(DataType)));
- DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(slice.size()*sizeof(DataType)));
- TensorMap<Tensor<DataType, 2,DataLayout,IndexType>> gpu1(gpu_data1, tensorRange);
- TensorMap<Tensor<DataType, 2,DataLayout,IndexType>> gpu2(gpu_data2, tensorRange);
- TensorMap<Tensor<DataType, 2,DataLayout,IndexType>> gpu3(gpu_data3, sliceRange);
-
-
- tensor.setRandom();
- sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(),(tensor.size())*sizeof(DataType));
- gpu2.device(sycl_device)=gpu1;
-
- slice.setRandom();
- sycl_device.memcpyHostToDevice(gpu_data3, slice.data(),(slice.size())*sizeof(DataType));
-
-
- gpu1.slice(indicesStart,lengths).device(sycl_device)=gpu3;
- gpu2.stridedSlice(indicesStart,indicesStop,strides).device(sycl_device)=gpu3;
- sycl_device.memcpyDeviceToHost(tensor.data(), gpu_data1,(tensor.size())*sizeof(DataType));
- sycl_device.memcpyDeviceToHost(tensor2.data(), gpu_data2,(tensor2.size())*sizeof(DataType));
-
- for(IndexType i=0;i<sizeDim1;i++)
- for(IndexType j=0;j<sizeDim2;j++){
- VERIFY_IS_EQUAL(tensor(i,j), tensor2(i,j));
- }
- sycl_device.deallocate(gpu_data1);
- sycl_device.deallocate(gpu_data2);
- sycl_device.deallocate(gpu_data3);
-}
-
-template<typename DataType, typename dev_Selector> void sycl_morphing_test_per_device(dev_Selector s){
- QueueInterface queueInterface(s);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_simple_slice<DataType, RowMajor, int64_t>(sycl_device);
- test_simple_slice<DataType, ColMajor, int64_t>(sycl_device);
- test_simple_reshape<DataType, RowMajor, int64_t>(sycl_device);
- test_simple_reshape<DataType, ColMajor, int64_t>(sycl_device);
- test_reshape_as_lvalue<DataType, RowMajor, int64_t>(sycl_device);
- test_reshape_as_lvalue<DataType, ColMajor, int64_t>(sycl_device);
- test_strided_slice_write_sycl<DataType, ColMajor, int64_t>(sycl_device);
- test_strided_slice_write_sycl<DataType, RowMajor, int64_t>(sycl_device);
-}
-void test_cxx11_tensor_morphing_sycl()
-{
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(sycl_morphing_test_per_device<float>(device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_notification.cpp b/eigen/unsupported/test/cxx11_tensor_notification.cpp
index 183ef02..c946007 100644
--- a/eigen/unsupported/test/cxx11_tensor_notification.cpp
+++ b/eigen/unsupported/test/cxx11_tensor_notification.cpp
@@ -13,6 +13,15 @@
#include "main.h"
#include <Eigen/CXX11/Tensor>
+#if EIGEN_OS_WIN || EIGEN_OS_WIN64
+#include <windows.h>
+void sleep(int seconds) {
+ Sleep(seconds*1000);
+}
+#else
+#include <unistd.h>
+#endif
+
namespace {
@@ -31,7 +40,7 @@ static void test_notification_single()
Eigen::Notification n;
std::function<void()> func = std::bind(&WaitAndAdd, &n, &counter);
thread_pool.Schedule(func);
- EIGEN_SLEEP(1000);
+ sleep(1);
// The thread should be waiting for the notification.
VERIFY_IS_EQUAL(counter, 0);
@@ -39,7 +48,7 @@ static void test_notification_single()
// Unblock the thread
n.Notify();
- EIGEN_SLEEP(1000);
+ sleep(1);
// Verify the counter has been incremented
VERIFY_IS_EQUAL(counter, 1);
@@ -58,10 +67,10 @@ static void test_notification_multiple()
thread_pool.Schedule(func);
thread_pool.Schedule(func);
thread_pool.Schedule(func);
- EIGEN_SLEEP(1000);
+ sleep(1);
VERIFY_IS_EQUAL(counter, 0);
n.Notify();
- EIGEN_SLEEP(1000);
+ sleep(1);
VERIFY_IS_EQUAL(counter, 4);
}
diff --git a/eigen/unsupported/test/cxx11_tensor_of_float16_cuda.cu b/eigen/unsupported/test/cxx11_tensor_of_float16_cuda.cu
index 908a5e5..2f86980 100644
--- a/eigen/unsupported/test/cxx11_tensor_of_float16_cuda.cu
+++ b/eigen/unsupported/test/cxx11_tensor_of_float16_cuda.cu
@@ -200,8 +200,6 @@ void test_cuda_trancendental() {
Eigen::TensorMap<Eigen::Tensor<Eigen::half, 1>, Eigen::Aligned> gpu_res2_float(d_res2_float, num_elem);
Eigen::TensorMap<Eigen::Tensor<Eigen::half, 1>, Eigen::Aligned> gpu_res3_half(d_res3_half, num_elem);
Eigen::TensorMap<Eigen::Tensor<Eigen::half, 1>, Eigen::Aligned> gpu_res3_float(d_res3_float, num_elem);
- Eigen::TensorMap<Eigen::Tensor<Eigen::half, 1>, Eigen::Aligned> gpu_res4_half(d_res3_half, num_elem);
- Eigen::TensorMap<Eigen::Tensor<Eigen::half, 1>, Eigen::Aligned> gpu_res4_float(d_res3_float, num_elem);
gpu_float1.device(gpu_device) = gpu_float1.random() - gpu_float1.constant(0.5f);
gpu_float2.device(gpu_device) = gpu_float2.random() + gpu_float1.constant(0.5f);
@@ -209,7 +207,6 @@ void test_cuda_trancendental() {
gpu_res1_float.device(gpu_device) = gpu_float1.exp().cast<Eigen::half>();
gpu_res2_float.device(gpu_device) = gpu_float2.log().cast<Eigen::half>();
gpu_res3_float.device(gpu_device) = gpu_float3.log1p().cast<Eigen::half>();
- gpu_res4_float.device(gpu_device) = gpu_float3.expm1().cast<Eigen::half>();
gpu_res1_half.device(gpu_device) = gpu_float1.cast<Eigen::half>();
gpu_res1_half.device(gpu_device) = gpu_res1_half.exp();
@@ -220,9 +217,6 @@ void test_cuda_trancendental() {
gpu_res3_half.device(gpu_device) = gpu_float3.cast<Eigen::half>();
gpu_res3_half.device(gpu_device) = gpu_res3_half.log1p();
- gpu_res3_half.device(gpu_device) = gpu_float3.cast<Eigen::half>();
- gpu_res3_half.device(gpu_device) = gpu_res3_half.expm1();
-
Tensor<float, 1> input1(num_elem);
Tensor<Eigen::half, 1> half_prec1(num_elem);
Tensor<Eigen::half, 1> full_prec1(num_elem);
diff --git a/eigen/unsupported/test/cxx11_tensor_padding_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_padding_sycl.cpp
deleted file mode 100644
index dc748b7..0000000
--- a/eigen/unsupported/test/cxx11_tensor_padding_sycl.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.com>
-// Benoit Steiner <benoit.steiner.goog@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/.
-
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_padding_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-
-#include "main.h"
-#include <unsupported/Eigen/CXX11/Tensor>
-
-using Eigen::array;
-using Eigen::SyclDevice;
-using Eigen::Tensor;
-using Eigen::TensorMap;
-
-
-template<typename DataType, int DataLayout, typename IndexType>
-static void test_simple_padding(const Eigen::SyclDevice& sycl_device)
-{
-
- IndexType sizeDim1 = 2;
- IndexType sizeDim2 = 3;
- IndexType sizeDim3 = 5;
- IndexType sizeDim4 = 7;
- array<IndexType, 4> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
-
- Tensor<DataType, 4, DataLayout, IndexType> tensor(tensorRange);
- tensor.setRandom();
-
- array<std::pair<IndexType, IndexType>, 4> paddings;
- paddings[0] = std::make_pair(0, 0);
- paddings[1] = std::make_pair(2, 1);
- paddings[2] = std::make_pair(3, 4);
- paddings[3] = std::make_pair(0, 0);
-
- IndexType padedSizeDim1 = 2;
- IndexType padedSizeDim2 = 6;
- IndexType padedSizeDim3 = 12;
- IndexType padedSizeDim4 = 7;
- array<IndexType, 4> padedtensorRange = {{padedSizeDim1, padedSizeDim2, padedSizeDim3, padedSizeDim4}};
-
- Tensor<DataType, 4, DataLayout, IndexType> padded(padedtensorRange);
-
-
- DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor.size()*sizeof(DataType)));
- DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(padded.size()*sizeof(DataType)));
- TensorMap<Tensor<DataType, 4,DataLayout,IndexType>> gpu1(gpu_data1, tensorRange);
- TensorMap<Tensor<DataType, 4,DataLayout,IndexType>> gpu2(gpu_data2, padedtensorRange);
-
- VERIFY_IS_EQUAL(padded.dimension(0), 2+0);
- VERIFY_IS_EQUAL(padded.dimension(1), 3+3);
- VERIFY_IS_EQUAL(padded.dimension(2), 5+7);
- VERIFY_IS_EQUAL(padded.dimension(3), 7+0);
- sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(),(tensor.size())*sizeof(DataType));
- gpu2.device(sycl_device)=gpu1.pad(paddings);
- sycl_device.memcpyDeviceToHost(padded.data(), gpu_data2,(padded.size())*sizeof(DataType));
- for (IndexType i = 0; i < padedSizeDim1; ++i) {
- for (IndexType j = 0; j < padedSizeDim2; ++j) {
- for (IndexType k = 0; k < padedSizeDim3; ++k) {
- for (IndexType l = 0; l < padedSizeDim4; ++l) {
- if (j >= 2 && j < 5 && k >= 3 && k < 8) {
- VERIFY_IS_EQUAL(padded(i,j,k,l), tensor(i,j-2,k-3,l));
- } else {
- VERIFY_IS_EQUAL(padded(i,j,k,l), 0.0f);
- }
- }
- }
- }
- }
- sycl_device.deallocate(gpu_data1);
- sycl_device.deallocate(gpu_data2);
-}
-
-template<typename DataType, int DataLayout, typename IndexType>
-static void test_padded_expr(const Eigen::SyclDevice& sycl_device)
-{
- IndexType sizeDim1 = 2;
- IndexType sizeDim2 = 3;
- IndexType sizeDim3 = 5;
- IndexType sizeDim4 = 7;
- array<IndexType, 4> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
-
- Tensor<DataType, 4, DataLayout, IndexType> tensor(tensorRange);
- tensor.setRandom();
-
- array<std::pair<IndexType, IndexType>, 4> paddings;
- paddings[0] = std::make_pair(0, 0);
- paddings[1] = std::make_pair(2, 1);
- paddings[2] = std::make_pair(3, 4);
- paddings[3] = std::make_pair(0, 0);
-
- Eigen::DSizes<IndexType, 2> reshape_dims;
- reshape_dims[0] = 12;
- reshape_dims[1] = 84;
-
-
- Tensor<DataType, 2, DataLayout, IndexType> result(reshape_dims);
-
- DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor.size()*sizeof(DataType)));
- DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(result.size()*sizeof(DataType)));
- TensorMap<Tensor<DataType, 4,DataLayout,IndexType>> gpu1(gpu_data1, tensorRange);
- TensorMap<Tensor<DataType, 2,DataLayout,IndexType>> gpu2(gpu_data2, reshape_dims);
-
-
- sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(),(tensor.size())*sizeof(DataType));
- gpu2.device(sycl_device)=gpu1.pad(paddings).reshape(reshape_dims);
- sycl_device.memcpyDeviceToHost(result.data(), gpu_data2,(result.size())*sizeof(DataType));
-
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 6; ++j) {
- for (IndexType k = 0; k < 12; ++k) {
- for (IndexType l = 0; l < 7; ++l) {
- const float result_value = DataLayout == ColMajor ?
- result(i+2*j,k+12*l) : result(j+6*i,l+7*k);
- if (j >= 2 && j < 5 && k >= 3 && k < 8) {
- VERIFY_IS_EQUAL(result_value, tensor(i,j-2,k-3,l));
- } else {
- VERIFY_IS_EQUAL(result_value, 0.0f);
- }
- }
- }
- }
- }
- sycl_device.deallocate(gpu_data1);
- sycl_device.deallocate(gpu_data2);
-}
-
-template<typename DataType, typename dev_Selector> void sycl_padding_test_per_device(dev_Selector s){
- QueueInterface queueInterface(s);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_simple_padding<DataType, RowMajor, int64_t>(sycl_device);
- test_simple_padding<DataType, ColMajor, int64_t>(sycl_device);
- test_padded_expr<DataType, RowMajor, int64_t>(sycl_device);
- test_padded_expr<DataType, ColMajor, int64_t>(sycl_device);
-
-}
-void test_cxx11_tensor_padding_sycl()
-{
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(sycl_padding_test_per_device<float>(device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_reduction_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_reduction_sycl.cpp
index 440d48b..a9ef829 100644
--- a/eigen/unsupported/test/cxx11_tensor_reduction_sycl.cpp
+++ b/eigen/unsupported/test/cxx11_tensor_reduction_sycl.cpp
@@ -14,168 +14,125 @@
#define EIGEN_TEST_NO_LONGDOUBLE
#define EIGEN_TEST_NO_COMPLEX
#define EIGEN_TEST_FUNC cxx11_tensor_reduction_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
+#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
#define EIGEN_USE_SYCL
#include "main.h"
#include <unsupported/Eigen/CXX11/Tensor>
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_full_reductions_mean_sycl(const Eigen::SyclDevice& sycl_device) {
- const IndexType num_rows = 452;
- const IndexType num_cols = 765;
- array<IndexType, 2> tensorRange = {{num_rows, num_cols}};
+static void test_full_reductions_sycl(const Eigen::SyclDevice& sycl_device) {
- Tensor<DataType, 2, DataLayout, IndexType> in(tensorRange);
- Tensor<DataType, 0, DataLayout, IndexType> full_redux;
- Tensor<DataType, 0, DataLayout, IndexType> full_redux_gpu;
-
- in.setRandom();
-
- full_redux = in.mean();
-
- DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize()*sizeof(DataType)));
- DataType* gpu_out_data =(DataType*)sycl_device.allocate(sizeof(DataType));
-
- TensorMap<Tensor<DataType, 2, DataLayout, IndexType> > in_gpu(gpu_in_data, tensorRange);
- TensorMap<Tensor<DataType, 0, DataLayout, IndexType> > out_gpu(gpu_out_data);
-
- sycl_device.memcpyHostToDevice(gpu_in_data, in.data(),(in.dimensions().TotalSize())*sizeof(DataType));
- out_gpu.device(sycl_device) = in_gpu.mean();
- sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(DataType));
- // Check that the CPU and GPU reductions return the same result.
- VERIFY_IS_APPROX(full_redux_gpu(), full_redux());
- sycl_device.deallocate(gpu_in_data);
- sycl_device.deallocate(gpu_out_data);
-}
+ const int num_rows = 452;
+ const int num_cols = 765;
+ array<int, 2> tensorRange = {{num_rows, num_cols}};
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_full_reductions_min_sycl(const Eigen::SyclDevice& sycl_device) {
-
- const IndexType num_rows = 876;
- const IndexType num_cols = 953;
- array<IndexType, 2> tensorRange = {{num_rows, num_cols}};
-
- Tensor<DataType, 2, DataLayout, IndexType> in(tensorRange);
- Tensor<DataType, 0, DataLayout, IndexType> full_redux;
- Tensor<DataType, 0, DataLayout, IndexType> full_redux_gpu;
+ Tensor<float, 2> in(tensorRange);
+ Tensor<float, 0> full_redux;
+ Tensor<float, 0> full_redux_gpu;
in.setRandom();
- full_redux = in.minimum();
+ full_redux = in.sum();
- DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize()*sizeof(DataType)));
- DataType* gpu_out_data =(DataType*)sycl_device.allocate(sizeof(DataType));
+ float* gpu_in_data = static_cast<float*>(sycl_device.allocate(in.dimensions().TotalSize()*sizeof(float)));
+ float* gpu_out_data =(float*)sycl_device.allocate(sizeof(float));
- TensorMap<Tensor<DataType, 2, DataLayout, IndexType> > in_gpu(gpu_in_data, tensorRange);
- TensorMap<Tensor<DataType, 0, DataLayout, IndexType> > out_gpu(gpu_out_data);
+ TensorMap<Tensor<float, 2> > in_gpu(gpu_in_data, tensorRange);
+ TensorMap<Tensor<float, 0> > out_gpu(gpu_out_data);
- sycl_device.memcpyHostToDevice(gpu_in_data, in.data(),(in.dimensions().TotalSize())*sizeof(DataType));
- out_gpu.device(sycl_device) = in_gpu.minimum();
- sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(DataType));
+ sycl_device.memcpyHostToDevice(gpu_in_data, in.data(),(in.dimensions().TotalSize())*sizeof(float));
+ out_gpu.device(sycl_device) = in_gpu.sum();
+ sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(float));
// Check that the CPU and GPU reductions return the same result.
VERIFY_IS_APPROX(full_redux_gpu(), full_redux());
+
sycl_device.deallocate(gpu_in_data);
sycl_device.deallocate(gpu_out_data);
}
+static void test_first_dim_reductions_sycl(const Eigen::SyclDevice& sycl_device) {
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_first_dim_reductions_max_sycl(const Eigen::SyclDevice& sycl_device) {
-
- IndexType dim_x = 145;
- IndexType dim_y = 1;
- IndexType dim_z = 67;
+ int dim_x = 145;
+ int dim_y = 1;
+ int dim_z = 67;
- array<IndexType, 3> tensorRange = {{dim_x, dim_y, dim_z}};
- Eigen::array<IndexType, 1> red_axis;
+ array<int, 3> tensorRange = {{dim_x, dim_y, dim_z}};
+ Eigen::array<int, 1> red_axis;
red_axis[0] = 0;
- array<IndexType, 2> reduced_tensorRange = {{dim_y, dim_z}};
+ array<int, 2> reduced_tensorRange = {{dim_y, dim_z}};
- Tensor<DataType, 3, DataLayout, IndexType> in(tensorRange);
- Tensor<DataType, 2, DataLayout, IndexType> redux(reduced_tensorRange);
- Tensor<DataType, 2, DataLayout, IndexType> redux_gpu(reduced_tensorRange);
+ Tensor<float, 3> in(tensorRange);
+ Tensor<float, 2> redux(reduced_tensorRange);
+ Tensor<float, 2> redux_gpu(reduced_tensorRange);
in.setRandom();
- redux= in.maximum(red_axis);
+ redux= in.sum(red_axis);
- DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize()*sizeof(DataType)));
- DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(redux_gpu.dimensions().TotalSize()*sizeof(DataType)));
+ float* gpu_in_data = static_cast<float*>(sycl_device.allocate(in.dimensions().TotalSize()*sizeof(float)));
+ float* gpu_out_data = static_cast<float*>(sycl_device.allocate(redux_gpu.dimensions().TotalSize()*sizeof(float)));
- TensorMap<Tensor<DataType, 3, DataLayout, IndexType> > in_gpu(gpu_in_data, tensorRange);
- TensorMap<Tensor<DataType, 2, DataLayout, IndexType> > out_gpu(gpu_out_data, reduced_tensorRange);
+ TensorMap<Tensor<float, 3> > in_gpu(gpu_in_data, tensorRange);
+ TensorMap<Tensor<float, 2> > out_gpu(gpu_out_data, reduced_tensorRange);
- sycl_device.memcpyHostToDevice(gpu_in_data, in.data(),(in.dimensions().TotalSize())*sizeof(DataType));
- out_gpu.device(sycl_device) = in_gpu.maximum(red_axis);
- sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, redux_gpu.dimensions().TotalSize()*sizeof(DataType));
+ sycl_device.memcpyHostToDevice(gpu_in_data, in.data(),(in.dimensions().TotalSize())*sizeof(float));
+ out_gpu.device(sycl_device) = in_gpu.sum(red_axis);
+ sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, redux_gpu.dimensions().TotalSize()*sizeof(float));
// Check that the CPU and GPU reductions return the same result.
- for(IndexType j=0; j<reduced_tensorRange[0]; j++ )
- for(IndexType k=0; k<reduced_tensorRange[1]; k++ )
+ for(int j=0; j<reduced_tensorRange[0]; j++ )
+ for(int k=0; k<reduced_tensorRange[1]; k++ )
VERIFY_IS_APPROX(redux_gpu(j,k), redux(j,k));
sycl_device.deallocate(gpu_in_data);
sycl_device.deallocate(gpu_out_data);
}
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_last_dim_reductions_sum_sycl(const Eigen::SyclDevice &sycl_device) {
+static void test_last_dim_reductions_sycl(const Eigen::SyclDevice &sycl_device) {
- IndexType dim_x = 567;
- IndexType dim_y = 1;
- IndexType dim_z = 47;
+ int dim_x = 567;
+ int dim_y = 1;
+ int dim_z = 47;
- array<IndexType, 3> tensorRange = {{dim_x, dim_y, dim_z}};
- Eigen::array<IndexType, 1> red_axis;
+ array<int, 3> tensorRange = {{dim_x, dim_y, dim_z}};
+ Eigen::array<int, 1> red_axis;
red_axis[0] = 2;
- array<IndexType, 2> reduced_tensorRange = {{dim_x, dim_y}};
+ array<int, 2> reduced_tensorRange = {{dim_x, dim_y}};
- Tensor<DataType, 3, DataLayout, IndexType> in(tensorRange);
- Tensor<DataType, 2, DataLayout, IndexType> redux(reduced_tensorRange);
- Tensor<DataType, 2, DataLayout, IndexType> redux_gpu(reduced_tensorRange);
+ Tensor<float, 3> in(tensorRange);
+ Tensor<float, 2> redux(reduced_tensorRange);
+ Tensor<float, 2> redux_gpu(reduced_tensorRange);
in.setRandom();
redux= in.sum(red_axis);
- DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize()*sizeof(DataType)));
- DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(redux_gpu.dimensions().TotalSize()*sizeof(DataType)));
+ float* gpu_in_data = static_cast<float*>(sycl_device.allocate(in.dimensions().TotalSize()*sizeof(float)));
+ float* gpu_out_data = static_cast<float*>(sycl_device.allocate(redux_gpu.dimensions().TotalSize()*sizeof(float)));
- TensorMap<Tensor<DataType, 3, DataLayout, IndexType> > in_gpu(gpu_in_data, tensorRange);
- TensorMap<Tensor<DataType, 2, DataLayout, IndexType> > out_gpu(gpu_out_data, reduced_tensorRange);
+ TensorMap<Tensor<float, 3> > in_gpu(gpu_in_data, tensorRange);
+ TensorMap<Tensor<float, 2> > out_gpu(gpu_out_data, reduced_tensorRange);
- sycl_device.memcpyHostToDevice(gpu_in_data, in.data(),(in.dimensions().TotalSize())*sizeof(DataType));
+ sycl_device.memcpyHostToDevice(gpu_in_data, in.data(),(in.dimensions().TotalSize())*sizeof(float));
out_gpu.device(sycl_device) = in_gpu.sum(red_axis);
- sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, redux_gpu.dimensions().TotalSize()*sizeof(DataType));
+ sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, redux_gpu.dimensions().TotalSize()*sizeof(float));
// Check that the CPU and GPU reductions return the same result.
- for(IndexType j=0; j<reduced_tensorRange[0]; j++ )
- for(IndexType k=0; k<reduced_tensorRange[1]; k++ )
+ for(int j=0; j<reduced_tensorRange[0]; j++ )
+ for(int k=0; k<reduced_tensorRange[1]; k++ )
VERIFY_IS_APPROX(redux_gpu(j,k), redux(j,k));
sycl_device.deallocate(gpu_in_data);
sycl_device.deallocate(gpu_out_data);
}
-template<typename DataType> void sycl_reduction_test_per_device(const cl::sycl::device& d){
- std::cout << "Running on " << d.template get_info<cl::sycl::info::device::name>() << std::endl;
- QueueInterface queueInterface(d);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
-
- test_full_reductions_mean_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_full_reductions_min_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_first_dim_reductions_max_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_last_dim_reductions_sum_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_full_reductions_mean_sycl<DataType, ColMajor, int64_t>(sycl_device);
- test_full_reductions_min_sycl<DataType, ColMajor, int64_t>(sycl_device);
- test_first_dim_reductions_max_sycl<DataType, ColMajor, int64_t>(sycl_device);
- test_last_dim_reductions_sum_sycl<DataType, ColMajor, int64_t>(sycl_device);
-}
+
void test_cxx11_tensor_reduction_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(sycl_reduction_test_per_device<float>(device));
- }
+ cl::sycl::gpu_selector s;
+ Eigen::SyclDevice sycl_device(s);
+ CALL_SUBTEST((test_full_reductions_sycl(sycl_device)));
+ CALL_SUBTEST((test_first_dim_reductions_sycl(sycl_device)));
+ CALL_SUBTEST((test_last_dim_reductions_sycl(sycl_device)));
+
}
diff --git a/eigen/unsupported/test/cxx11_tensor_reverse_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_reverse_sycl.cpp
deleted file mode 100644
index 2f54844..0000000
--- a/eigen/unsupported/test/cxx11_tensor_reverse_sycl.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2015
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.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/.
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_reverse_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-#include "main.h"
-#include <unsupported/Eigen/CXX11/Tensor>
-
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_simple_reverse(const Eigen::SyclDevice& sycl_device) {
-
- IndexType dim1 = 2;
- IndexType dim2 = 3;
- IndexType dim3 = 5;
- IndexType dim4 = 7;
-
- array<IndexType, 4> tensorRange = {{dim1, dim2, dim3, dim4}};
- Tensor<DataType, 4, DataLayout, IndexType> tensor(tensorRange);
- Tensor<DataType, 4, DataLayout, IndexType> reversed_tensor(tensorRange);
- tensor.setRandom();
-
- array<bool, 4> dim_rev;
- dim_rev[0] = false;
- dim_rev[1] = true;
- dim_rev[2] = true;
- dim_rev[3] = false;
-
- DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(tensor.dimensions().TotalSize()*sizeof(DataType)));
- DataType* gpu_out_data =static_cast<DataType*>(sycl_device.allocate(reversed_tensor.dimensions().TotalSize()*sizeof(DataType)));
-
- TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > in_gpu(gpu_in_data, tensorRange);
- TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > out_gpu(gpu_out_data, tensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_in_data, tensor.data(),(tensor.dimensions().TotalSize())*sizeof(DataType));
- out_gpu.device(sycl_device) = in_gpu.reverse(dim_rev);
- sycl_device.memcpyDeviceToHost(reversed_tensor.data(), gpu_out_data, reversed_tensor.dimensions().TotalSize()*sizeof(DataType));
- // Check that the CPU and GPU reductions return the same result.
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 3; ++j) {
- for (IndexType k = 0; k < 5; ++k) {
- for (IndexType l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), reversed_tensor(i,2-j,4-k,l));
- }
- }
- }
- }
- dim_rev[0] = true;
- dim_rev[1] = false;
- dim_rev[2] = false;
- dim_rev[3] = false;
-
- out_gpu.device(sycl_device) = in_gpu.reverse(dim_rev);
- sycl_device.memcpyDeviceToHost(reversed_tensor.data(), gpu_out_data, reversed_tensor.dimensions().TotalSize()*sizeof(DataType));
-
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 3; ++j) {
- for (IndexType k = 0; k < 5; ++k) {
- for (IndexType l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), reversed_tensor(1-i,j,k,l));
- }
- }
- }
- }
-
- dim_rev[0] = true;
- dim_rev[1] = false;
- dim_rev[2] = false;
- dim_rev[3] = true;
- out_gpu.device(sycl_device) = in_gpu.reverse(dim_rev);
- sycl_device.memcpyDeviceToHost(reversed_tensor.data(), gpu_out_data, reversed_tensor.dimensions().TotalSize()*sizeof(DataType));
-
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 3; ++j) {
- for (IndexType k = 0; k < 5; ++k) {
- for (IndexType l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), reversed_tensor(1-i,j,k,6-l));
- }
- }
- }
- }
-
- sycl_device.deallocate(gpu_in_data);
- sycl_device.deallocate(gpu_out_data);
-}
-
-
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_expr_reverse(const Eigen::SyclDevice& sycl_device, bool LValue)
-{
- IndexType dim1 = 2;
- IndexType dim2 = 3;
- IndexType dim3 = 5;
- IndexType dim4 = 7;
-
- array<IndexType, 4> tensorRange = {{dim1, dim2, dim3, dim4}};
- Tensor<DataType, 4, DataLayout, IndexType> tensor(tensorRange);
- Tensor<DataType, 4, DataLayout, IndexType> expected(tensorRange);
- Tensor<DataType, 4, DataLayout, IndexType> result(tensorRange);
- tensor.setRandom();
-
- array<bool, 4> dim_rev;
- dim_rev[0] = false;
- dim_rev[1] = true;
- dim_rev[2] = false;
- dim_rev[3] = true;
-
- DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(tensor.dimensions().TotalSize()*sizeof(DataType)));
- DataType* gpu_out_data_expected =static_cast<DataType*>(sycl_device.allocate(expected.dimensions().TotalSize()*sizeof(DataType)));
- DataType* gpu_out_data_result =static_cast<DataType*>(sycl_device.allocate(result.dimensions().TotalSize()*sizeof(DataType)));
-
- TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > in_gpu(gpu_in_data, tensorRange);
- TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > out_gpu_expected(gpu_out_data_expected, tensorRange);
- TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > out_gpu_result(gpu_out_data_result, tensorRange);
-
-
- sycl_device.memcpyHostToDevice(gpu_in_data, tensor.data(),(tensor.dimensions().TotalSize())*sizeof(DataType));
-
- if (LValue) {
- out_gpu_expected.reverse(dim_rev).device(sycl_device) = in_gpu;
- } else {
- out_gpu_expected.device(sycl_device) = in_gpu.reverse(dim_rev);
- }
- sycl_device.memcpyDeviceToHost(expected.data(), gpu_out_data_expected, expected.dimensions().TotalSize()*sizeof(DataType));
-
-
- array<IndexType, 4> src_slice_dim;
- src_slice_dim[0] = 2;
- src_slice_dim[1] = 3;
- src_slice_dim[2] = 1;
- src_slice_dim[3] = 7;
- array<IndexType, 4> src_slice_start;
- src_slice_start[0] = 0;
- src_slice_start[1] = 0;
- src_slice_start[2] = 0;
- src_slice_start[3] = 0;
- array<IndexType, 4> dst_slice_dim = src_slice_dim;
- array<IndexType, 4> dst_slice_start = src_slice_start;
-
- for (IndexType i = 0; i < 5; ++i) {
- if (LValue) {
- out_gpu_result.slice(dst_slice_start, dst_slice_dim).reverse(dim_rev).device(sycl_device) =
- in_gpu.slice(src_slice_start, src_slice_dim);
- } else {
- out_gpu_result.slice(dst_slice_start, dst_slice_dim).device(sycl_device) =
- in_gpu.slice(src_slice_start, src_slice_dim).reverse(dim_rev);
- }
- src_slice_start[2] += 1;
- dst_slice_start[2] += 1;
- }
- sycl_device.memcpyDeviceToHost(result.data(), gpu_out_data_result, result.dimensions().TotalSize()*sizeof(DataType));
-
- for (IndexType i = 0; i < expected.dimension(0); ++i) {
- for (IndexType j = 0; j < expected.dimension(1); ++j) {
- for (IndexType k = 0; k < expected.dimension(2); ++k) {
- for (IndexType l = 0; l < expected.dimension(3); ++l) {
- VERIFY_IS_EQUAL(result(i,j,k,l), expected(i,j,k,l));
- }
- }
- }
- }
-
- dst_slice_start[2] = 0;
- result.setRandom();
- sycl_device.memcpyHostToDevice(gpu_out_data_result, result.data(),(result.dimensions().TotalSize())*sizeof(DataType));
- for (IndexType i = 0; i < 5; ++i) {
- if (LValue) {
- out_gpu_result.slice(dst_slice_start, dst_slice_dim).reverse(dim_rev).device(sycl_device) =
- in_gpu.slice(dst_slice_start, dst_slice_dim);
- } else {
- out_gpu_result.slice(dst_slice_start, dst_slice_dim).device(sycl_device) =
- in_gpu.reverse(dim_rev).slice(dst_slice_start, dst_slice_dim);
- }
- dst_slice_start[2] += 1;
- }
- sycl_device.memcpyDeviceToHost(result.data(), gpu_out_data_result, result.dimensions().TotalSize()*sizeof(DataType));
-
- for (IndexType i = 0; i < expected.dimension(0); ++i) {
- for (IndexType j = 0; j < expected.dimension(1); ++j) {
- for (IndexType k = 0; k < expected.dimension(2); ++k) {
- for (IndexType l = 0; l < expected.dimension(3); ++l) {
- VERIFY_IS_EQUAL(result(i,j,k,l), expected(i,j,k,l));
- }
- }
- }
- }
-}
-
-
-
-template<typename DataType> void sycl_reverse_test_per_device(const cl::sycl::device& d){
- std::cout << "Running on " << d.template get_info<cl::sycl::info::device::name>() << std::endl;
- QueueInterface queueInterface(d);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_simple_reverse<DataType, RowMajor, int64_t>(sycl_device);
- test_simple_reverse<DataType, ColMajor, int64_t>(sycl_device);
- test_expr_reverse<DataType, RowMajor, int64_t>(sycl_device, false);
- test_expr_reverse<DataType, ColMajor, int64_t>(sycl_device, false);
- test_expr_reverse<DataType, RowMajor, int64_t>(sycl_device, true);
- test_expr_reverse<DataType, ColMajor, int64_t>(sycl_device, true);
-}
-void test_cxx11_tensor_reverse_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(sycl_reverse_test_per_device<float>(device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_shuffling_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_shuffling_sycl.cpp
deleted file mode 100644
index c88db7c..0000000
--- a/eigen/unsupported/test/cxx11_tensor_shuffling_sycl.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.com>
-// Benoit Steiner <benoit.steiner.goog@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/.
-
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_shuffling_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-
-#include "main.h"
-#include <unsupported/Eigen/CXX11/Tensor>
-
-using Eigen::array;
-using Eigen::SyclDevice;
-using Eigen::Tensor;
-using Eigen::TensorMap;
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_simple_shuffling_sycl(const Eigen::SyclDevice& sycl_device)
-{
- IndexType sizeDim1 = 2;
- IndexType sizeDim2 = 3;
- IndexType sizeDim3 = 5;
- IndexType sizeDim4 = 7;
- array<IndexType, 4> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
- Tensor<DataType, 4, DataLayout,IndexType> tensor(tensorRange);
- Tensor<DataType, 4, DataLayout,IndexType> no_shuffle(tensorRange);
- tensor.setRandom();
-
- const size_t buffSize =tensor.size()*sizeof(DataType);
- array<IndexType, 4> shuffles;
- shuffles[0] = 0;
- shuffles[1] = 1;
- shuffles[2] = 2;
- shuffles[3] = 3;
- DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(buffSize));
- DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(buffSize));
-
-
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu1(gpu_data1, tensorRange);
- TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu2(gpu_data2, tensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(), buffSize);
-
- gpu2.device(sycl_device)=gpu1.shuffle(shuffles);
- sycl_device.memcpyDeviceToHost(no_shuffle.data(), gpu_data2, buffSize);
- sycl_device.synchronize();
-
- VERIFY_IS_EQUAL(no_shuffle.dimension(0), sizeDim1);
- VERIFY_IS_EQUAL(no_shuffle.dimension(1), sizeDim2);
- VERIFY_IS_EQUAL(no_shuffle.dimension(2), sizeDim3);
- VERIFY_IS_EQUAL(no_shuffle.dimension(3), sizeDim4);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
- for (IndexType l = 0; l < sizeDim4; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), no_shuffle(i,j,k,l));
- }
- }
- }
- }
-
- shuffles[0] = 2;
- shuffles[1] = 3;
- shuffles[2] = 1;
- shuffles[3] = 0;
- array<IndexType, 4> tensorrangeShuffle = {{sizeDim3, sizeDim4, sizeDim2, sizeDim1}};
- Tensor<DataType, 4, DataLayout,IndexType> shuffle(tensorrangeShuffle);
- DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(buffSize));
- TensorMap<Tensor<DataType, 4,DataLayout,IndexType>> gpu3(gpu_data3, tensorrangeShuffle);
-
- gpu3.device(sycl_device)=gpu1.shuffle(shuffles);
- sycl_device.memcpyDeviceToHost(shuffle.data(), gpu_data3, buffSize);
- sycl_device.synchronize();
-
- VERIFY_IS_EQUAL(shuffle.dimension(0), sizeDim3);
- VERIFY_IS_EQUAL(shuffle.dimension(1), sizeDim4);
- VERIFY_IS_EQUAL(shuffle.dimension(2), sizeDim2);
- VERIFY_IS_EQUAL(shuffle.dimension(3), sizeDim1);
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
- for (IndexType l = 0; l < sizeDim4; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), shuffle(k,l,j,i));
- }
- }
- }
- }
-}
-
-
-template<typename DataType, typename dev_Selector> void sycl_shuffling_test_per_device(dev_Selector s){
- QueueInterface queueInterface(s);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_simple_shuffling_sycl<DataType, RowMajor, int64_t>(sycl_device);
- test_simple_shuffling_sycl<DataType, ColMajor, int64_t>(sycl_device);
-
-}
-void test_cxx11_tensor_shuffling_sycl()
-{
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(sycl_shuffling_test_per_device<float>(device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_striding_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_striding_sycl.cpp
deleted file mode 100644
index 603c374..0000000
--- a/eigen/unsupported/test/cxx11_tensor_striding_sycl.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016
-// Mehdi Goli Codeplay Software Ltd.
-// Ralph Potter Codeplay Software Ltd.
-// Luke Iwanski Codeplay Software Ltd.
-// Contact: <eigen@codeplay.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/.
-
-#define EIGEN_TEST_NO_LONGDOUBLE
-#define EIGEN_TEST_NO_COMPLEX
-#define EIGEN_TEST_FUNC cxx11_tensor_striding_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
-#define EIGEN_USE_SYCL
-
-#include <iostream>
-#include <chrono>
-#include <ctime>
-
-#include "main.h"
-#include <unsupported/Eigen/CXX11/Tensor>
-
-using Eigen::array;
-using Eigen::SyclDevice;
-using Eigen::Tensor;
-using Eigen::TensorMap;
-
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_simple_striding(const Eigen::SyclDevice& sycl_device)
-{
-
- Eigen::array<IndexType, 4> tensor_dims = {{2,3,5,7}};
- Eigen::array<IndexType, 4> stride_dims = {{1,1,3,3}};
-
-
- Tensor<DataType, 4, DataLayout, IndexType> tensor(tensor_dims);
- Tensor<DataType, 4, DataLayout,IndexType> no_stride(tensor_dims);
- Tensor<DataType, 4, DataLayout,IndexType> stride(stride_dims);
-
-
- std::size_t tensor_bytes = tensor.size() * sizeof(DataType);
- std::size_t no_stride_bytes = no_stride.size() * sizeof(DataType);
- std::size_t stride_bytes = stride.size() * sizeof(DataType);
- DataType * d_tensor = static_cast<DataType*>(sycl_device.allocate(tensor_bytes));
- DataType * d_no_stride = static_cast<DataType*>(sycl_device.allocate(no_stride_bytes));
- DataType * d_stride = static_cast<DataType*>(sycl_device.allocate(stride_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, IndexType> > gpu_tensor(d_tensor, tensor_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, IndexType> > gpu_no_stride(d_no_stride, tensor_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, IndexType> > gpu_stride(d_stride, stride_dims);
-
-
- tensor.setRandom();
- array<IndexType, 4> strides;
- strides[0] = 1;
- strides[1] = 1;
- strides[2] = 1;
- strides[3] = 1;
- sycl_device.memcpyHostToDevice(d_tensor, tensor.data(), tensor_bytes);
- gpu_no_stride.device(sycl_device)=gpu_tensor.stride(strides);
- sycl_device.memcpyDeviceToHost(no_stride.data(), d_no_stride, no_stride_bytes);
-
- //no_stride = tensor.stride(strides);
-
- VERIFY_IS_EQUAL(no_stride.dimension(0), 2);
- VERIFY_IS_EQUAL(no_stride.dimension(1), 3);
- VERIFY_IS_EQUAL(no_stride.dimension(2), 5);
- VERIFY_IS_EQUAL(no_stride.dimension(3), 7);
-
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 3; ++j) {
- for (IndexType k = 0; k < 5; ++k) {
- for (IndexType l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), no_stride(i,j,k,l));
- }
- }
- }
- }
-
- strides[0] = 2;
- strides[1] = 4;
- strides[2] = 2;
- strides[3] = 3;
-//Tensor<float, 4, DataLayout> stride;
-// stride = tensor.stride(strides);
-
- gpu_stride.device(sycl_device)=gpu_tensor.stride(strides);
- sycl_device.memcpyDeviceToHost(stride.data(), d_stride, stride_bytes);
-
- VERIFY_IS_EQUAL(stride.dimension(0), 1);
- VERIFY_IS_EQUAL(stride.dimension(1), 1);
- VERIFY_IS_EQUAL(stride.dimension(2), 3);
- VERIFY_IS_EQUAL(stride.dimension(3), 3);
-
- for (IndexType i = 0; i < 1; ++i) {
- for (IndexType j = 0; j < 1; ++j) {
- for (IndexType k = 0; k < 3; ++k) {
- for (IndexType l = 0; l < 3; ++l) {
- VERIFY_IS_EQUAL(tensor(2*i,4*j,2*k,3*l), stride(i,j,k,l));
- }
- }
- }
- }
-
- sycl_device.deallocate(d_tensor);
- sycl_device.deallocate(d_no_stride);
- sycl_device.deallocate(d_stride);
-}
-
-template <typename DataType, int DataLayout, typename IndexType>
-static void test_striding_as_lvalue(const Eigen::SyclDevice& sycl_device)
-{
-
- Eigen::array<IndexType, 4> tensor_dims = {{2,3,5,7}};
- Eigen::array<IndexType, 4> stride_dims = {{3,12,10,21}};
-
-
- Tensor<DataType, 4, DataLayout, IndexType> tensor(tensor_dims);
- Tensor<DataType, 4, DataLayout,IndexType> no_stride(stride_dims);
- Tensor<DataType, 4, DataLayout,IndexType> stride(stride_dims);
-
-
- std::size_t tensor_bytes = tensor.size() * sizeof(DataType);
- std::size_t no_stride_bytes = no_stride.size() * sizeof(DataType);
- std::size_t stride_bytes = stride.size() * sizeof(DataType);
-
- DataType * d_tensor = static_cast<DataType*>(sycl_device.allocate(tensor_bytes));
- DataType * d_no_stride = static_cast<DataType*>(sycl_device.allocate(no_stride_bytes));
- DataType * d_stride = static_cast<DataType*>(sycl_device.allocate(stride_bytes));
-
- Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, IndexType> > gpu_tensor(d_tensor, tensor_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, IndexType> > gpu_no_stride(d_no_stride, stride_dims);
- Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, IndexType> > gpu_stride(d_stride, stride_dims);
-
- //Tensor<float, 4, DataLayout> tensor(2,3,5,7);
- tensor.setRandom();
- array<IndexType, 4> strides;
- strides[0] = 2;
- strides[1] = 4;
- strides[2] = 2;
- strides[3] = 3;
-
-// Tensor<float, 4, DataLayout> result(3, 12, 10, 21);
-// result.stride(strides) = tensor;
- sycl_device.memcpyHostToDevice(d_tensor, tensor.data(), tensor_bytes);
- gpu_stride.stride(strides).device(sycl_device)=gpu_tensor;
- sycl_device.memcpyDeviceToHost(stride.data(), d_stride, stride_bytes);
-
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 3; ++j) {
- for (IndexType k = 0; k < 5; ++k) {
- for (IndexType l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), stride(2*i,4*j,2*k,3*l));
- }
- }
- }
- }
-
- array<IndexType, 4> no_strides;
- no_strides[0] = 1;
- no_strides[1] = 1;
- no_strides[2] = 1;
- no_strides[3] = 1;
-// Tensor<float, 4, DataLayout> result2(3, 12, 10, 21);
-// result2.stride(strides) = tensor.stride(no_strides);
-
- gpu_no_stride.stride(strides).device(sycl_device)=gpu_tensor.stride(no_strides);
- sycl_device.memcpyDeviceToHost(no_stride.data(), d_no_stride, no_stride_bytes);
-
- for (IndexType i = 0; i < 2; ++i) {
- for (IndexType j = 0; j < 3; ++j) {
- for (IndexType k = 0; k < 5; ++k) {
- for (IndexType l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), no_stride(2*i,4*j,2*k,3*l));
- }
- }
- }
- }
- sycl_device.deallocate(d_tensor);
- sycl_device.deallocate(d_no_stride);
- sycl_device.deallocate(d_stride);
-}
-
-
-template <typename Dev_selector> void tensorStridingPerDevice(Dev_selector& s){
- QueueInterface queueInterface(s);
- auto sycl_device=Eigen::SyclDevice(&queueInterface);
- test_simple_striding<float, ColMajor, int64_t>(sycl_device);
- test_simple_striding<float, RowMajor, int64_t>(sycl_device);
- test_striding_as_lvalue<float, ColMajor, int64_t>(sycl_device);
- test_striding_as_lvalue<float, RowMajor, int64_t>(sycl_device);
-}
-
-void test_cxx11_tensor_striding_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(tensorStridingPerDevice(device));
- }
-}
diff --git a/eigen/unsupported/test/cxx11_tensor_sycl.cpp b/eigen/unsupported/test/cxx11_tensor_sycl.cpp
index 5cd0f4c..6a9c334 100644
--- a/eigen/unsupported/test/cxx11_tensor_sycl.cpp
+++ b/eigen/unsupported/test/cxx11_tensor_sycl.cpp
@@ -16,7 +16,7 @@
#define EIGEN_TEST_NO_LONGDOUBLE
#define EIGEN_TEST_NO_COMPLEX
#define EIGEN_TEST_FUNC cxx11_tensor_sycl
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
+#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
#define EIGEN_USE_SYCL
#include "main.h"
@@ -27,105 +27,36 @@ using Eigen::SyclDevice;
using Eigen::Tensor;
using Eigen::TensorMap;
-template <typename DataType, int DataLayout, typename IndexType>
-void test_sycl_mem_transfers(const Eigen::SyclDevice &sycl_device) {
- IndexType sizeDim1 = 100;
- IndexType sizeDim2 = 10;
- IndexType sizeDim3 = 20;
- array<IndexType, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
- Tensor<DataType, 3, DataLayout, IndexType> in1(tensorRange);
- Tensor<DataType, 3, DataLayout, IndexType> out1(tensorRange);
- Tensor<DataType, 3, DataLayout, IndexType> out2(tensorRange);
- Tensor<DataType, 3, DataLayout, IndexType> out3(tensorRange);
+void test_sycl_cpu(const Eigen::SyclDevice &sycl_device) {
- in1 = in1.random();
-
- DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(in1.size()*sizeof(DataType)));
- DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(out1.size()*sizeof(DataType)));
-
- TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu1(gpu_data1, tensorRange);
- TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu2(gpu_data2, tensorRange);
-
- sycl_device.memcpyHostToDevice(gpu_data1, in1.data(),(in1.size())*sizeof(DataType));
- sycl_device.memcpyHostToDevice(gpu_data2, in1.data(),(in1.size())*sizeof(DataType));
- gpu1.device(sycl_device) = gpu1 * 3.14f;
- gpu2.device(sycl_device) = gpu2 * 2.7f;
- sycl_device.memcpyDeviceToHost(out1.data(), gpu_data1,(out1.size())*sizeof(DataType));
- sycl_device.memcpyDeviceToHost(out2.data(), gpu_data1,(out2.size())*sizeof(DataType));
- sycl_device.memcpyDeviceToHost(out3.data(), gpu_data2,(out3.size())*sizeof(DataType));
- sycl_device.synchronize();
-
- for (IndexType i = 0; i < in1.size(); ++i) {
- VERIFY_IS_APPROX(out1(i), in1(i) * 3.14f);
- VERIFY_IS_APPROX(out2(i), in1(i) * 3.14f);
- VERIFY_IS_APPROX(out3(i), in1(i) * 2.7f);
- }
-
- sycl_device.deallocate(gpu_data1);
- sycl_device.deallocate(gpu_data2);
-}
-
-template <typename DataType, int DataLayout, typename IndexType>
-void test_sycl_mem_sync(const Eigen::SyclDevice &sycl_device) {
- IndexType size = 20;
- array<IndexType, 1> tensorRange = {{size}};
- Tensor<DataType, 1, DataLayout, IndexType> in1(tensorRange);
- Tensor<DataType, 1, DataLayout, IndexType> in2(tensorRange);
- Tensor<DataType, 1, DataLayout, IndexType> out(tensorRange);
-
- in1 = in1.random();
- in2 = in1;
-
- DataType* gpu_data = static_cast<DataType*>(sycl_device.allocate(in1.size()*sizeof(DataType)));
-
- TensorMap<Tensor<DataType, 1, DataLayout, IndexType>> gpu1(gpu_data, tensorRange);
- sycl_device.memcpyHostToDevice(gpu_data, in1.data(),(in1.size())*sizeof(DataType));
- sycl_device.synchronize();
- in1.setZero();
-
- sycl_device.memcpyDeviceToHost(out.data(), gpu_data, out.size()*sizeof(DataType));
- sycl_device.synchronize();
-
- for (IndexType i = 0; i < in1.size(); ++i) {
- VERIFY_IS_APPROX(out(i), in2(i));
- }
-
- sycl_device.deallocate(gpu_data);
-}
-
-template <typename DataType, int DataLayout, typename IndexType>
-void test_sycl_computations(const Eigen::SyclDevice &sycl_device) {
-
- IndexType sizeDim1 = 100;
- IndexType sizeDim2 = 10;
- IndexType sizeDim3 = 20;
- array<IndexType, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
- Tensor<DataType, 3,DataLayout, IndexType> in1(tensorRange);
- Tensor<DataType, 3,DataLayout, IndexType> in2(tensorRange);
- Tensor<DataType, 3,DataLayout, IndexType> in3(tensorRange);
- Tensor<DataType, 3,DataLayout, IndexType> out(tensorRange);
+ int sizeDim1 = 100;
+ int sizeDim2 = 100;
+ int sizeDim3 = 100;
+ array<int, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
+ Tensor<float, 3> in1(tensorRange);
+ Tensor<float, 3> in2(tensorRange);
+ Tensor<float, 3> in3(tensorRange);
+ Tensor<float, 3> out(tensorRange);
in2 = in2.random();
in3 = in3.random();
- DataType * gpu_in1_data = static_cast<DataType*>(sycl_device.allocate(in1.size()*sizeof(DataType)));
- DataType * gpu_in2_data = static_cast<DataType*>(sycl_device.allocate(in2.size()*sizeof(DataType)));
- DataType * gpu_in3_data = static_cast<DataType*>(sycl_device.allocate(in3.size()*sizeof(DataType)));
- DataType * gpu_out_data = static_cast<DataType*>(sycl_device.allocate(out.size()*sizeof(DataType)));
+ float * gpu_in1_data = static_cast<float*>(sycl_device.allocate(in1.dimensions().TotalSize()*sizeof(float)));
+ float * gpu_in2_data = static_cast<float*>(sycl_device.allocate(in2.dimensions().TotalSize()*sizeof(float)));
+ float * gpu_in3_data = static_cast<float*>(sycl_device.allocate(in3.dimensions().TotalSize()*sizeof(float)));
+ float * gpu_out_data = static_cast<float*>(sycl_device.allocate(out.dimensions().TotalSize()*sizeof(float)));
- TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_in1(gpu_in1_data, tensorRange);
- TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_in2(gpu_in2_data, tensorRange);
- TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_in3(gpu_in3_data, tensorRange);
- TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_out(gpu_out_data, tensorRange);
+ TensorMap<Tensor<float, 3>> gpu_in1(gpu_in1_data, tensorRange);
+ TensorMap<Tensor<float, 3>> gpu_in2(gpu_in2_data, tensorRange);
+ TensorMap<Tensor<float, 3>> gpu_in3(gpu_in3_data, tensorRange);
+ TensorMap<Tensor<float, 3>> gpu_out(gpu_out_data, tensorRange);
/// a=1.2f
gpu_in1.device(sycl_device) = gpu_in1.constant(1.2f);
- sycl_device.memcpyDeviceToHost(in1.data(), gpu_in1_data ,(in1.size())*sizeof(DataType));
- sycl_device.synchronize();
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
+ sycl_device.memcpyDeviceToHost(in1.data(), gpu_in1_data ,(in1.dimensions().TotalSize())*sizeof(float));
+ for (int i = 0; i < sizeDim1; ++i) {
+ for (int j = 0; j < sizeDim2; ++j) {
+ for (int k = 0; k < sizeDim3; ++k) {
VERIFY_IS_APPROX(in1(i,j,k), 1.2f);
}
}
@@ -134,12 +65,10 @@ void test_sycl_computations(const Eigen::SyclDevice &sycl_device) {
/// a=b*1.2f
gpu_out.device(sycl_device) = gpu_in1 * 1.2f;
- sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data ,(out.size())*sizeof(DataType));
- sycl_device.synchronize();
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
+ sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data ,(out.dimensions().TotalSize())*sizeof(float));
+ for (int i = 0; i < sizeDim1; ++i) {
+ for (int j = 0; j < sizeDim2; ++j) {
+ for (int k = 0; k < sizeDim3; ++k) {
VERIFY_IS_APPROX(out(i,j,k),
in1(i,j,k) * 1.2f);
}
@@ -148,14 +77,12 @@ void test_sycl_computations(const Eigen::SyclDevice &sycl_device) {
printf("a=b*1.2f Test Passed\n");
/// c=a*b
- sycl_device.memcpyHostToDevice(gpu_in2_data, in2.data(),(in2.size())*sizeof(DataType));
+ sycl_device.memcpyHostToDevice(gpu_in2_data, in2.data(),(in2.dimensions().TotalSize())*sizeof(float));
gpu_out.device(sycl_device) = gpu_in1 * gpu_in2;
- sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.size())*sizeof(DataType));
- sycl_device.synchronize();
-
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
+ sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.dimensions().TotalSize())*sizeof(float));
+ for (int i = 0; i < sizeDim1; ++i) {
+ for (int j = 0; j < sizeDim2; ++j) {
+ for (int k = 0; k < sizeDim3; ++k) {
VERIFY_IS_APPROX(out(i,j,k),
in1(i,j,k) *
in2(i,j,k));
@@ -166,11 +93,10 @@ void test_sycl_computations(const Eigen::SyclDevice &sycl_device) {
/// c=a+b
gpu_out.device(sycl_device) = gpu_in1 + gpu_in2;
- sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.size())*sizeof(DataType));
- sycl_device.synchronize();
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
+ sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.dimensions().TotalSize())*sizeof(float));
+ for (int i = 0; i < sizeDim1; ++i) {
+ for (int j = 0; j < sizeDim2; ++j) {
+ for (int k = 0; k < sizeDim3; ++k) {
VERIFY_IS_APPROX(out(i,j,k),
in1(i,j,k) +
in2(i,j,k));
@@ -181,11 +107,10 @@ void test_sycl_computations(const Eigen::SyclDevice &sycl_device) {
/// c=a*a
gpu_out.device(sycl_device) = gpu_in1 * gpu_in1;
- sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.size())*sizeof(DataType));
- sycl_device.synchronize();
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
+ sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.dimensions().TotalSize())*sizeof(float));
+ for (int i = 0; i < sizeDim1; ++i) {
+ for (int j = 0; j < sizeDim2; ++j) {
+ for (int k = 0; k < sizeDim3; ++k) {
VERIFY_IS_APPROX(out(i,j,k),
in1(i,j,k) *
in1(i,j,k));
@@ -196,11 +121,10 @@ void test_sycl_computations(const Eigen::SyclDevice &sycl_device) {
//a*3.14f + b*2.7f
gpu_out.device(sycl_device) = gpu_in1 * gpu_in1.constant(3.14f) + gpu_in2 * gpu_in2.constant(2.7f);
- sycl_device.memcpyDeviceToHost(out.data(),gpu_out_data,(out.size())*sizeof(DataType));
- sycl_device.synchronize();
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
+ sycl_device.memcpyDeviceToHost(out.data(),gpu_out_data,(out.dimensions().TotalSize())*sizeof(float));
+ for (int i = 0; i < sizeDim1; ++i) {
+ for (int j = 0; j < sizeDim2; ++j) {
+ for (int k = 0; k < sizeDim3; ++k) {
VERIFY_IS_APPROX(out(i,j,k),
in1(i,j,k) * 3.14f
+ in2(i,j,k) * 2.7f);
@@ -210,13 +134,12 @@ void test_sycl_computations(const Eigen::SyclDevice &sycl_device) {
printf("a*3.14f + b*2.7f Test Passed\n");
///d= (a>0.5? b:c)
- sycl_device.memcpyHostToDevice(gpu_in3_data, in3.data(),(in3.size())*sizeof(DataType));
+ sycl_device.memcpyHostToDevice(gpu_in3_data, in3.data(),(in3.dimensions().TotalSize())*sizeof(float));
gpu_out.device(sycl_device) =(gpu_in1 > gpu_in1.constant(0.5f)).select(gpu_in2, gpu_in3);
- sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.size())*sizeof(DataType));
- sycl_device.synchronize();
- for (IndexType i = 0; i < sizeDim1; ++i) {
- for (IndexType j = 0; j < sizeDim2; ++j) {
- for (IndexType k = 0; k < sizeDim3; ++k) {
+ sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data,(out.dimensions().TotalSize())*sizeof(float));
+ for (int i = 0; i < sizeDim1; ++i) {
+ for (int j = 0; j < sizeDim2; ++j) {
+ for (int k = 0; k < sizeDim3; ++k) {
VERIFY_IS_APPROX(out(i, j, k), (in1(i, j, k) > 0.5f)
? in2(i, j, k)
: in3(i, j, k));
@@ -229,48 +152,8 @@ void test_sycl_computations(const Eigen::SyclDevice &sycl_device) {
sycl_device.deallocate(gpu_in3_data);
sycl_device.deallocate(gpu_out_data);
}
-template<typename Scalar1, typename Scalar2, int DataLayout, typename IndexType>
-static void test_sycl_cast(const Eigen::SyclDevice& sycl_device){
- IndexType size = 20;
- array<IndexType, 1> tensorRange = {{size}};
- Tensor<Scalar1, 1, DataLayout, IndexType> in(tensorRange);
- Tensor<Scalar2, 1, DataLayout, IndexType> out(tensorRange);
- Tensor<Scalar2, 1, DataLayout, IndexType> out_host(tensorRange);
-
- in = in.random();
-
- Scalar1* gpu_in_data = static_cast<Scalar1*>(sycl_device.allocate(in.size()*sizeof(Scalar1)));
- Scalar2 * gpu_out_data = static_cast<Scalar2*>(sycl_device.allocate(out.size()*sizeof(Scalar2)));
-
- TensorMap<Tensor<Scalar1, 1, DataLayout, IndexType>> gpu_in(gpu_in_data, tensorRange);
- TensorMap<Tensor<Scalar2, 1, DataLayout, IndexType>> gpu_out(gpu_out_data, tensorRange);
- sycl_device.memcpyHostToDevice(gpu_in_data, in.data(),(in.size())*sizeof(Scalar1));
- gpu_out.device(sycl_device) = gpu_in. template cast<Scalar2>();
- sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data, out.size()*sizeof(Scalar2));
- out_host = in. template cast<Scalar2>();
- for(IndexType i=0; i< size; i++)
- {
- VERIFY_IS_APPROX(out(i), out_host(i));
- }
- printf("cast Test Passed\n");
- sycl_device.deallocate(gpu_in_data);
- sycl_device.deallocate(gpu_out_data);
-}
-template<typename DataType, typename dev_Selector> void sycl_computing_test_per_device(dev_Selector s){
- QueueInterface queueInterface(s);
- auto sycl_device = Eigen::SyclDevice(&queueInterface);
- test_sycl_mem_transfers<DataType, RowMajor, int64_t>(sycl_device);
- test_sycl_computations<DataType, RowMajor, int64_t>(sycl_device);
- test_sycl_mem_sync<DataType, RowMajor, int64_t>(sycl_device);
- test_sycl_mem_transfers<DataType, ColMajor, int64_t>(sycl_device);
- test_sycl_computations<DataType, ColMajor, int64_t>(sycl_device);
- test_sycl_mem_sync<DataType, ColMajor, int64_t>(sycl_device);
- test_sycl_cast<DataType, int, RowMajor, int64_t>(sycl_device);
- test_sycl_cast<DataType, int, ColMajor, int64_t>(sycl_device);
-}
-
void test_cxx11_tensor_sycl() {
- for (const auto& device :Eigen::get_sycl_supported_devices()) {
- CALL_SUBTEST(sycl_computing_test_per_device<float>(device));
- }
+ cl::sycl::gpu_selector s;
+ Eigen::SyclDevice sycl_device(s);
+ CALL_SUBTEST(test_sycl_cpu(sycl_device));
}
diff --git a/eigen/unsupported/test/polynomialsolver.cpp b/eigen/unsupported/test/polynomialsolver.cpp
index 7ad4aa6..0c87478 100644
--- a/eigen/unsupported/test/polynomialsolver.cpp
+++ b/eigen/unsupported/test/polynomialsolver.cpp
@@ -32,10 +32,9 @@ bool aux_evalSolver( const POLYNOMIAL& pols, SOLVER& psolve )
{
typedef typename POLYNOMIAL::Index Index;
typedef typename POLYNOMIAL::Scalar Scalar;
- typedef typename POLYNOMIAL::RealScalar RealScalar;
typedef typename SOLVER::RootsType RootsType;
- typedef Matrix<RealScalar,Deg,1> EvalRootsType;
+ typedef Matrix<Scalar,Deg,1> EvalRootsType;
const Index deg = pols.size()-1;
@@ -58,7 +57,7 @@ bool aux_evalSolver( const POLYNOMIAL& pols, SOLVER& psolve )
cerr << endl;
}
- std::vector<RealScalar> rootModuli( roots.size() );
+ std::vector<Scalar> rootModuli( roots.size() );
Map< EvalRootsType > aux( &rootModuli[0], roots.size() );
aux = roots.array().abs();
std::sort( rootModuli.begin(), rootModuli.end() );
@@ -84,7 +83,7 @@ void evalSolver( const POLYNOMIAL& pols )
{
typedef typename POLYNOMIAL::Scalar Scalar;
- typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;
+ typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;
PolynomialSolverType psolve;
aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve );
@@ -98,7 +97,6 @@ void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const
{
using std::sqrt;
typedef typename POLYNOMIAL::Scalar Scalar;
- typedef typename POLYNOMIAL::RealScalar RealScalar;
typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;
@@ -109,12 +107,15 @@ void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const
// 1) the roots found are correct
// 2) the roots have distinct moduli
+ typedef typename POLYNOMIAL::Scalar Scalar;
+ typedef typename REAL_ROOTS::Scalar Real;
+
//Test realRoots
- std::vector< RealScalar > calc_realRoots;
- psolve.realRoots( calc_realRoots, test_precision<RealScalar>());
- VERIFY_IS_EQUAL( calc_realRoots.size() , (size_t)real_roots.size() );
+ std::vector< Real > calc_realRoots;
+ psolve.realRoots( calc_realRoots );
+ VERIFY( calc_realRoots.size() == (size_t)real_roots.size() );
- const RealScalar psPrec = sqrt( test_precision<RealScalar>() );
+ const Scalar psPrec = sqrt( test_precision<Scalar>() );
for( size_t i=0; i<calc_realRoots.size(); ++i )
{
@@ -137,7 +138,7 @@ void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const
bool hasRealRoot;
//Test absGreatestRealRoot
- RealScalar r = psolve.absGreatestRealRoot( hasRealRoot );
+ Real r = psolve.absGreatestRealRoot( hasRealRoot );
VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
if( hasRealRoot ){
VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(), abs(r), psPrec ) ); }
@@ -166,11 +167,9 @@ void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const
template<typename _Scalar, int _Deg>
void polynomialsolver(int deg)
{
- typedef typename NumTraits<_Scalar>::Real RealScalar;
- typedef internal::increment_if_fixed_size<_Deg> Dim;
+ typedef internal::increment_if_fixed_size<_Deg> Dim;
typedef Matrix<_Scalar,Dim::ret,1> PolynomialType;
typedef Matrix<_Scalar,_Deg,1> EvalRootsType;
- typedef Matrix<RealScalar,_Deg,1> RealRootsType;
cout << "Standard cases" << endl;
PolynomialType pols = PolynomialType::Random(deg+1);
@@ -183,11 +182,15 @@ void polynomialsolver(int deg)
evalSolver<_Deg,PolynomialType>( pols );
cout << "Test sugar" << endl;
- RealRootsType realRoots = RealRootsType::Random(deg);
+ EvalRootsType realRoots = EvalRootsType::Random(deg);
roots_to_monicPolynomial( realRoots, pols );
evalSolverSugarFunction<_Deg>(
pols,
- realRoots.template cast <std::complex<RealScalar> >().eval(),
+ realRoots.template cast <
+ std::complex<
+ typename NumTraits<_Scalar>::Real
+ >
+ >(),
realRoots );
}
@@ -211,6 +214,5 @@ void test_polynomialsolver()
internal::random<int>(9,13)
)) );
CALL_SUBTEST_11((polynomialsolver<float,Dynamic>(1)) );
- CALL_SUBTEST_12((polynomialsolver<std::complex<double>,Dynamic>(internal::random<int>(2,13))) );
}
}
diff --git a/eigen/unsupported/test/sparse_extra.cpp b/eigen/unsupported/test/sparse_extra.cpp
index 4f6723d..a010ceb 100644
--- a/eigen/unsupported/test/sparse_extra.cpp
+++ b/eigen/unsupported/test/sparse_extra.cpp
@@ -129,19 +129,6 @@ template<typename SparseMatrixType> void sparse_extra(const SparseMatrixType& re
}
-template<typename SparseMatrixType>
-void check_marketio()
-{
- typedef Matrix<typename SparseMatrixType::Scalar, Dynamic, Dynamic> DenseMatrix;
- Index rows = internal::random<Index>(1,100);
- Index cols = internal::random<Index>(1,100);
- SparseMatrixType m1, m2;
- m1 = DenseMatrix::Random(rows, cols).sparseView();
- saveMarket(m1, "sparse_extra.mtx");
- loadMarket(m2, "sparse_extra.mtx");
- VERIFY_IS_EQUAL(DenseMatrix(m1),DenseMatrix(m2));
-}
-
void test_sparse_extra()
{
for(int i = 0; i < g_repeat; i++) {
@@ -156,15 +143,5 @@ void test_sparse_extra()
CALL_SUBTEST_3( (sparse_product<DynamicSparseMatrix<float, ColMajor> >()) );
CALL_SUBTEST_3( (sparse_product<DynamicSparseMatrix<float, RowMajor> >()) );
-
- CALL_SUBTEST_4( (check_marketio<SparseMatrix<float,ColMajor,int> >()) );
- CALL_SUBTEST_4( (check_marketio<SparseMatrix<double,ColMajor,int> >()) );
- CALL_SUBTEST_4( (check_marketio<SparseMatrix<std::complex<float>,ColMajor,int> >()) );
- CALL_SUBTEST_4( (check_marketio<SparseMatrix<std::complex<double>,ColMajor,int> >()) );
- CALL_SUBTEST_4( (check_marketio<SparseMatrix<float,ColMajor,long int> >()) );
- CALL_SUBTEST_4( (check_marketio<SparseMatrix<double,ColMajor,long int> >()) );
- CALL_SUBTEST_4( (check_marketio<SparseMatrix<std::complex<float>,ColMajor,long int> >()) );
- CALL_SUBTEST_4( (check_marketio<SparseMatrix<std::complex<double>,ColMajor,long int> >()) );
- TEST_SET_BUT_UNUSED_VARIABLE(s);
}
}