summaryrefslogtreecommitdiffhomepage
path: root/eigen/bench
diff options
context:
space:
mode:
Diffstat (limited to 'eigen/bench')
-rw-r--r--eigen/bench/BenchSparseUtil.h149
-rw-r--r--eigen/bench/BenchTimer.h187
-rw-r--r--eigen/bench/BenchUtil.h92
-rw-r--r--eigen/bench/README.txt55
-rw-r--r--eigen/bench/basicbench.cxxlist28
-rw-r--r--eigen/bench/basicbenchmark.cpp35
-rw-r--r--eigen/bench/basicbenchmark.h63
-rw-r--r--eigen/bench/benchBlasGemm.cpp219
-rw-r--r--eigen/bench/benchCholesky.cpp142
-rw-r--r--eigen/bench/benchEigenSolver.cpp212
-rw-r--r--eigen/bench/benchFFT.cpp115
-rw-r--r--eigen/bench/benchGeometry.cpp134
-rw-r--r--eigen/bench/benchVecAdd.cpp135
-rw-r--r--eigen/bench/bench_gemm.cpp271
-rw-r--r--eigen/bench/bench_multi_compilers.sh28
-rw-r--r--eigen/bench/bench_norm.cpp345
-rw-r--r--eigen/bench/bench_reverse.cpp84
-rw-r--r--eigen/bench/bench_sum.cpp18
-rw-r--r--eigen/bench/bench_unrolling12
-rw-r--r--eigen/bench/benchmark.cpp39
-rw-r--r--eigen/bench/benchmarkSlice.cpp38
-rw-r--r--eigen/bench/benchmarkX.cpp36
-rw-r--r--eigen/bench/benchmarkXcwise.cpp35
-rw-r--r--eigen/bench/benchmark_suite18
-rw-r--r--eigen/bench/btl/CMakeLists.txt104
-rw-r--r--eigen/bench/btl/COPYING340
-rw-r--r--eigen/bench/btl/README154
-rw-r--r--eigen/bench/btl/actions/action_aat_product.hh145
-rw-r--r--eigen/bench/btl/actions/action_ata_product.hh145
-rw-r--r--eigen/bench/btl/actions/action_atv_product.hh134
-rw-r--r--eigen/bench/btl/actions/action_axpby.hh127
-rw-r--r--eigen/bench/btl/actions/action_axpy.hh139
-rw-r--r--eigen/bench/btl/actions/action_cholesky.hh128
-rw-r--r--eigen/bench/btl/actions/action_ger.hh128
-rw-r--r--eigen/bench/btl/actions/action_hessenberg.hh233
-rw-r--r--eigen/bench/btl/actions/action_lu_decomp.hh124
-rw-r--r--eigen/bench/btl/actions/action_lu_solve.hh136
-rw-r--r--eigen/bench/btl/actions/action_matrix_matrix_product.hh150
-rw-r--r--eigen/bench/btl/actions/action_matrix_matrix_product_bis.hh152
-rw-r--r--eigen/bench/btl/actions/action_matrix_vector_product.hh153
-rw-r--r--eigen/bench/btl/actions/action_partial_lu.hh125
-rw-r--r--eigen/bench/btl/actions/action_rot.hh116
-rw-r--r--eigen/bench/btl/actions/action_symv.hh139
-rw-r--r--eigen/bench/btl/actions/action_syr2.hh133
-rw-r--r--eigen/bench/btl/actions/action_trisolve.hh137
-rw-r--r--eigen/bench/btl/actions/action_trisolve_matrix.hh165
-rw-r--r--eigen/bench/btl/actions/action_trmm.hh165
-rw-r--r--eigen/bench/btl/actions/basic_actions.hh21
-rw-r--r--eigen/bench/btl/cmake/FindACML.cmake49
-rw-r--r--eigen/bench/btl/cmake/FindATLAS.cmake39
-rw-r--r--eigen/bench/btl/cmake/FindBlitz.cmake40
-rw-r--r--eigen/bench/btl/cmake/FindCBLAS.cmake34
-rw-r--r--eigen/bench/btl/cmake/FindGMM.cmake17
-rw-r--r--eigen/bench/btl/cmake/FindGOTO.cmake15
-rw-r--r--eigen/bench/btl/cmake/FindGOTO2.cmake25
-rw-r--r--eigen/bench/btl/cmake/FindMKL.cmake65
-rw-r--r--eigen/bench/btl/cmake/FindMTL4.cmake31
-rw-r--r--eigen/bench/btl/cmake/FindPackageHandleStandardArgs.cmake60
-rw-r--r--eigen/bench/btl/cmake/FindTvmet.cmake32
-rw-r--r--eigen/bench/btl/cmake/MacroOptionalAddSubdirectory.cmake31
-rw-r--r--eigen/bench/btl/data/CMakeLists.txt32
-rw-r--r--eigen/bench/btl/data/action_settings.txt19
-rw-r--r--eigen/bench/btl/data/gnuplot_common_settings.hh87
-rw-r--r--eigen/bench/btl/data/go_mean58
-rw-r--r--eigen/bench/btl/data/mean.cxx182
-rw-r--r--eigen/bench/btl/data/mk_gnuplot_script.sh68
-rw-r--r--eigen/bench/btl/data/mk_mean_script.sh52
-rw-r--r--eigen/bench/btl/data/mk_new_gnuplot.sh54
-rw-r--r--eigen/bench/btl/data/perlib_plot_settings.txt16
-rw-r--r--eigen/bench/btl/data/regularize.cxx131
-rw-r--r--eigen/bench/btl/data/smooth.cxx198
-rw-r--r--eigen/bench/btl/data/smooth_all.sh68
-rw-r--r--eigen/bench/btl/generic_bench/bench.hh168
-rw-r--r--eigen/bench/btl/generic_bench/bench_parameter.hh53
-rw-r--r--eigen/bench/btl/generic_bench/btl.hh242
-rw-r--r--eigen/bench/btl/generic_bench/init/init_function.hh54
-rw-r--r--eigen/bench/btl/generic_bench/init/init_matrix.hh64
-rw-r--r--eigen/bench/btl/generic_bench/init/init_vector.hh37
-rw-r--r--eigen/bench/btl/generic_bench/static/bench_static.hh80
-rw-r--r--eigen/bench/btl/generic_bench/static/intel_bench_fixed_size.hh66
-rw-r--r--eigen/bench/btl/generic_bench/static/static_size_generator.hh57
-rw-r--r--eigen/bench/btl/generic_bench/timers/STL_perf_analyzer.hh82
-rw-r--r--eigen/bench/btl/generic_bench/timers/STL_timer.hh78
-rw-r--r--eigen/bench/btl/generic_bench/timers/mixed_perf_analyzer.hh73
-rw-r--r--eigen/bench/btl/generic_bench/timers/portable_perf_analyzer.hh103
-rw-r--r--eigen/bench/btl/generic_bench/timers/portable_perf_analyzer_old.hh134
-rw-r--r--eigen/bench/btl/generic_bench/timers/portable_timer.hh145
-rw-r--r--eigen/bench/btl/generic_bench/timers/x86_perf_analyzer.hh108
-rw-r--r--eigen/bench/btl/generic_bench/timers/x86_timer.hh246
-rw-r--r--eigen/bench/btl/generic_bench/utils/size_lin_log.hh70
-rw-r--r--eigen/bench/btl/generic_bench/utils/size_log.hh54
-rw-r--r--eigen/bench/btl/generic_bench/utils/utilities.h90
-rw-r--r--eigen/bench/btl/generic_bench/utils/xy_file.hh75
-rw-r--r--eigen/bench/btl/libs/BLAS/CMakeLists.txt60
-rw-r--r--eigen/bench/btl/libs/BLAS/blas.h675
-rw-r--r--eigen/bench/btl/libs/BLAS/blas_interface.hh83
-rw-r--r--eigen/bench/btl/libs/BLAS/blas_interface_impl.hh151
-rw-r--r--eigen/bench/btl/libs/BLAS/c_interface_base.h73
-rw-r--r--eigen/bench/btl/libs/BLAS/main.cpp73
-rw-r--r--eigen/bench/btl/libs/STL/CMakeLists.txt2
-rw-r--r--eigen/bench/btl/libs/STL/STL_interface.hh244
-rw-r--r--eigen/bench/btl/libs/STL/main.cpp42
-rw-r--r--eigen/bench/btl/libs/blitz/CMakeLists.txt17
-rw-r--r--eigen/bench/btl/libs/blitz/blitz_LU_solve_interface.hh192
-rw-r--r--eigen/bench/btl/libs/blitz/blitz_interface.hh147
-rw-r--r--eigen/bench/btl/libs/blitz/btl_blitz.cpp51
-rw-r--r--eigen/bench/btl/libs/blitz/btl_tiny_blitz.cpp38
-rw-r--r--eigen/bench/btl/libs/blitz/tiny_blitz_interface.hh106
-rw-r--r--eigen/bench/btl/libs/eigen2/CMakeLists.txt19
-rw-r--r--eigen/bench/btl/libs/eigen2/btl_tiny_eigen2.cpp46
-rw-r--r--eigen/bench/btl/libs/eigen2/eigen2_interface.hh168
-rw-r--r--eigen/bench/btl/libs/eigen2/main_adv.cpp44
-rw-r--r--eigen/bench/btl/libs/eigen2/main_linear.cpp34
-rw-r--r--eigen/bench/btl/libs/eigen2/main_matmat.cpp35
-rw-r--r--eigen/bench/btl/libs/eigen2/main_vecmat.cpp36
-rw-r--r--eigen/bench/btl/libs/eigen3/CMakeLists.txt65
-rw-r--r--eigen/bench/btl/libs/eigen3/btl_tiny_eigen3.cpp46
-rw-r--r--eigen/bench/btl/libs/eigen3/eigen3_interface.hh240
-rw-r--r--eigen/bench/btl/libs/eigen3/main_adv.cpp44
-rw-r--r--eigen/bench/btl/libs/eigen3/main_linear.cpp35
-rw-r--r--eigen/bench/btl/libs/eigen3/main_matmat.cpp35
-rw-r--r--eigen/bench/btl/libs/eigen3/main_vecmat.cpp36
-rw-r--r--eigen/bench/btl/libs/gmm/CMakeLists.txt6
-rw-r--r--eigen/bench/btl/libs/gmm/gmm_LU_solve_interface.hh192
-rw-r--r--eigen/bench/btl/libs/gmm/gmm_interface.hh144
-rw-r--r--eigen/bench/btl/libs/gmm/main.cpp51
-rw-r--r--eigen/bench/btl/libs/mtl4/.kdbgrc.main12
-rw-r--r--eigen/bench/btl/libs/mtl4/CMakeLists.txt6
-rw-r--r--eigen/bench/btl/libs/mtl4/main.cpp46
-rw-r--r--eigen/bench/btl/libs/mtl4/mtl4_LU_solve_interface.hh192
-rw-r--r--eigen/bench/btl/libs/mtl4/mtl4_interface.hh144
-rw-r--r--eigen/bench/btl/libs/tvmet/CMakeLists.txt6
-rw-r--r--eigen/bench/btl/libs/tvmet/main.cpp40
-rw-r--r--eigen/bench/btl/libs/tvmet/tvmet_interface.hh104
-rw-r--r--eigen/bench/btl/libs/ublas/CMakeLists.txt7
-rw-r--r--eigen/bench/btl/libs/ublas/main.cpp44
-rw-r--r--eigen/bench/btl/libs/ublas/ublas_interface.hh141
-rw-r--r--eigen/bench/check_cache_queries.cpp101
-rw-r--r--eigen/bench/eig33.cpp196
-rw-r--r--eigen/bench/geometry.cpp126
-rw-r--r--eigen/bench/product_threshold.cpp143
-rw-r--r--eigen/bench/quat_slerp.cpp247
-rw-r--r--eigen/bench/quatmul.cpp47
-rw-r--r--eigen/bench/sparse_cholesky.cpp216
-rw-r--r--eigen/bench/sparse_dense_product.cpp187
-rw-r--r--eigen/bench/sparse_lu.cpp132
-rw-r--r--eigen/bench/sparse_product.cpp323
-rw-r--r--eigen/bench/sparse_randomsetter.cpp125
-rw-r--r--eigen/bench/sparse_setter.cpp485
-rw-r--r--eigen/bench/sparse_transpose.cpp104
-rw-r--r--eigen/bench/sparse_trisolver.cpp220
-rw-r--r--eigen/bench/spbench/CMakeLists.txt78
-rw-r--r--eigen/bench/spbench/sp_solver.cpp125
-rw-r--r--eigen/bench/spbench/spbench.dtd31
-rw-r--r--eigen/bench/spbench/spbenchsolver.cpp87
-rw-r--r--eigen/bench/spbench/spbenchsolver.h554
-rw-r--r--eigen/bench/spbench/spbenchstyle.h94
-rw-r--r--eigen/bench/spbench/test_sparseLU.cpp93
-rw-r--r--eigen/bench/spmv.cpp233
-rw-r--r--eigen/bench/vdw_new.cpp56
160 files changed, 17440 insertions, 0 deletions
diff --git a/eigen/bench/BenchSparseUtil.h b/eigen/bench/BenchSparseUtil.h
new file mode 100644
index 0000000..13981f6
--- /dev/null
+++ b/eigen/bench/BenchSparseUtil.h
@@ -0,0 +1,149 @@
+
+#include <Eigen/Sparse>
+#include <bench/BenchTimer.h>
+#include <set>
+
+using namespace std;
+using namespace Eigen;
+using namespace Eigen;
+
+#ifndef SIZE
+#define SIZE 1024
+#endif
+
+#ifndef DENSITY
+#define DENSITY 0.01
+#endif
+
+#ifndef SCALAR
+#define SCALAR double
+#endif
+
+typedef SCALAR Scalar;
+typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
+typedef Matrix<Scalar,Dynamic,1> DenseVector;
+typedef SparseMatrix<Scalar> EigenSparseMatrix;
+
+void fillMatrix(float density, int rows, int cols, EigenSparseMatrix& dst)
+{
+ dst.reserve(double(rows)*cols*density);
+ for(int j = 0; j < cols; j++)
+ {
+ for(int i = 0; i < rows; i++)
+ {
+ Scalar v = (internal::random<float>(0,1) < density) ? internal::random<Scalar>() : 0;
+ if (v!=0)
+ dst.insert(i,j) = v;
+ }
+ }
+ dst.finalize();
+}
+
+void fillMatrix2(int nnzPerCol, int rows, int cols, EigenSparseMatrix& dst)
+{
+// std::cout << "alloc " << nnzPerCol*cols << "\n";
+ dst.reserve(nnzPerCol*cols);
+ for(int j = 0; j < cols; j++)
+ {
+ std::set<int> aux;
+ for(int i = 0; i < nnzPerCol; i++)
+ {
+ int k = internal::random<int>(0,rows-1);
+ while (aux.find(k)!=aux.end())
+ k = internal::random<int>(0,rows-1);
+ aux.insert(k);
+
+ dst.insert(k,j) = internal::random<Scalar>();
+ }
+ }
+ dst.finalize();
+}
+
+void eiToDense(const EigenSparseMatrix& src, DenseMatrix& dst)
+{
+ dst.setZero();
+ for (int j=0; j<src.cols(); ++j)
+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)
+ dst(it.index(),j) = it.value();
+}
+
+#ifndef NOGMM
+#include "gmm/gmm.h"
+typedef gmm::csc_matrix<Scalar> GmmSparse;
+typedef gmm::col_matrix< gmm::wsvector<Scalar> > GmmDynSparse;
+void eiToGmm(const EigenSparseMatrix& src, GmmSparse& dst)
+{
+ GmmDynSparse tmp(src.rows(), src.cols());
+ for (int j=0; j<src.cols(); ++j)
+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)
+ tmp(it.index(),j) = it.value();
+ gmm::copy(tmp, dst);
+}
+#endif
+
+#ifndef NOMTL
+#include <boost/numeric/mtl/mtl.hpp>
+typedef mtl::compressed2D<Scalar, mtl::matrix::parameters<mtl::tag::col_major> > MtlSparse;
+typedef mtl::compressed2D<Scalar, mtl::matrix::parameters<mtl::tag::row_major> > MtlSparseRowMajor;
+void eiToMtl(const EigenSparseMatrix& src, MtlSparse& dst)
+{
+ mtl::matrix::inserter<MtlSparse> ins(dst);
+ for (int j=0; j<src.cols(); ++j)
+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)
+ ins[it.index()][j] = it.value();
+}
+#endif
+
+#ifdef CSPARSE
+extern "C" {
+#include "cs.h"
+}
+void eiToCSparse(const EigenSparseMatrix& src, cs* &dst)
+{
+ cs* aux = cs_spalloc (0, 0, 1, 1, 1);
+ for (int j=0; j<src.cols(); ++j)
+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)
+ if (!cs_entry(aux, it.index(), j, it.value()))
+ {
+ std::cout << "cs_entry error\n";
+ exit(2);
+ }
+ dst = cs_compress(aux);
+// cs_spfree(aux);
+}
+#endif // CSPARSE
+
+#ifndef NOUBLAS
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/vector_of_vector.hpp>
+#include <boost/numeric/ublas/operation.hpp>
+
+typedef boost::numeric::ublas::compressed_matrix<Scalar,boost::numeric::ublas::column_major> UBlasSparse;
+
+void eiToUblas(const EigenSparseMatrix& src, UBlasSparse& dst)
+{
+ dst.resize(src.rows(), src.cols(), false);
+ for (int j=0; j<src.cols(); ++j)
+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)
+ dst(it.index(),j) = it.value();
+}
+
+template <typename EigenType, typename UblasType>
+void eiToUblasVec(const EigenType& src, UblasType& dst)
+{
+ dst.resize(src.size());
+ for (int j=0; j<src.size(); ++j)
+ dst[j] = src.coeff(j);
+}
+#endif
+
+#ifdef OSKI
+extern "C" {
+#include <oski/oski.h>
+}
+#endif
diff --git a/eigen/bench/BenchTimer.h b/eigen/bench/BenchTimer.h
new file mode 100644
index 0000000..28e2bca
--- /dev/null
+++ b/eigen/bench/BenchTimer.h
@@ -0,0 +1,187 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_BENCH_TIMERR_H
+#define EIGEN_BENCH_TIMERR_H
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# ifndef NOMINMAX
+# define NOMINMAX
+# define EIGEN_BT_UNDEF_NOMINMAX
+# endif
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# define EIGEN_BT_UNDEF_WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+#elif defined(__APPLE__)
+#include <CoreServices/CoreServices.h>
+#include <mach/mach_time.h>
+#else
+# include <unistd.h>
+#endif
+
+#include <Eigen/Core>
+
+namespace Eigen
+{
+
+enum {
+ CPU_TIMER = 0,
+ REAL_TIMER = 1
+};
+
+/** Elapsed time timer keeping the best try.
+ *
+ * On POSIX platforms we use clock_gettime with CLOCK_PROCESS_CPUTIME_ID.
+ * On Windows we use QueryPerformanceCounter
+ *
+ * Important: on linux, you must link with -lrt
+ */
+class BenchTimer
+{
+public:
+
+ BenchTimer()
+ {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ LARGE_INTEGER freq;
+ QueryPerformanceFrequency(&freq);
+ m_frequency = (double)freq.QuadPart;
+#endif
+ reset();
+ }
+
+ ~BenchTimer() {}
+
+ inline void reset()
+ {
+ m_bests.fill(1e9);
+ m_worsts.fill(0);
+ m_totals.setZero();
+ }
+ inline void start()
+ {
+ m_starts[CPU_TIMER] = getCpuTime();
+ m_starts[REAL_TIMER] = getRealTime();
+ }
+ inline void stop()
+ {
+ m_times[CPU_TIMER] = getCpuTime() - m_starts[CPU_TIMER];
+ m_times[REAL_TIMER] = getRealTime() - m_starts[REAL_TIMER];
+ #if EIGEN_VERSION_AT_LEAST(2,90,0)
+ m_bests = m_bests.cwiseMin(m_times);
+ m_worsts = m_worsts.cwiseMax(m_times);
+ #else
+ m_bests(0) = std::min(m_bests(0),m_times(0));
+ m_bests(1) = std::min(m_bests(1),m_times(1));
+ m_worsts(0) = std::max(m_worsts(0),m_times(0));
+ m_worsts(1) = std::max(m_worsts(1),m_times(1));
+ #endif
+ m_totals += m_times;
+ }
+
+ /** Return the elapsed time in seconds between the last start/stop pair
+ */
+ inline double value(int TIMER = CPU_TIMER) const
+ {
+ return m_times[TIMER];
+ }
+
+ /** Return the best elapsed time in seconds
+ */
+ inline double best(int TIMER = CPU_TIMER) const
+ {
+ return m_bests[TIMER];
+ }
+
+ /** Return the worst elapsed time in seconds
+ */
+ inline double worst(int TIMER = CPU_TIMER) const
+ {
+ return m_worsts[TIMER];
+ }
+
+ /** Return the total elapsed time in seconds.
+ */
+ inline double total(int TIMER = CPU_TIMER) const
+ {
+ return m_totals[TIMER];
+ }
+
+ inline double getCpuTime() const
+ {
+#ifdef _WIN32
+ LARGE_INTEGER query_ticks;
+ QueryPerformanceCounter(&query_ticks);
+ return query_ticks.QuadPart/m_frequency;
+#elif __APPLE__
+ return double(mach_absolute_time())*1e-9;
+#else
+ timespec ts;
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
+ return double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);
+#endif
+ }
+
+ inline double getRealTime() const
+ {
+#ifdef _WIN32
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ return (double)st.wSecond + 1.e-3 * (double)st.wMilliseconds;
+#elif __APPLE__
+ return double(mach_absolute_time())*1e-9;
+#else
+ timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ return double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);
+#endif
+ }
+
+protected:
+#if defined(_WIN32) || defined(__CYGWIN__)
+ double m_frequency;
+#endif
+ Vector2d m_starts;
+ Vector2d m_times;
+ Vector2d m_bests;
+ Vector2d m_worsts;
+ Vector2d m_totals;
+
+public:
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+};
+
+#define BENCH(TIMER,TRIES,REP,CODE) { \
+ TIMER.reset(); \
+ for(int uglyvarname1=0; uglyvarname1<TRIES; ++uglyvarname1){ \
+ TIMER.start(); \
+ for(int uglyvarname2=0; uglyvarname2<REP; ++uglyvarname2){ \
+ CODE; \
+ } \
+ TIMER.stop(); \
+ } \
+ }
+
+}
+
+// clean #defined tokens
+#ifdef EIGEN_BT_UNDEF_NOMINMAX
+# undef EIGEN_BT_UNDEF_NOMINMAX
+# undef NOMINMAX
+#endif
+
+#ifdef EIGEN_BT_UNDEF_WIN32_LEAN_AND_MEAN
+# undef EIGEN_BT_UNDEF_WIN32_LEAN_AND_MEAN
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+#endif // EIGEN_BENCH_TIMERR_H
diff --git a/eigen/bench/BenchUtil.h b/eigen/bench/BenchUtil.h
new file mode 100644
index 0000000..8883a13
--- /dev/null
+++ b/eigen/bench/BenchUtil.h
@@ -0,0 +1,92 @@
+
+#ifndef EIGEN_BENCH_UTIL_H
+#define EIGEN_BENCH_UTIL_H
+
+#include <Eigen/Core>
+#include "BenchTimer.h"
+
+using namespace std;
+using namespace Eigen;
+
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/preprocessor/seq.hpp>
+#include <boost/preprocessor/array.hpp>
+#include <boost/preprocessor/arithmetic.hpp>
+#include <boost/preprocessor/comparison.hpp>
+#include <boost/preprocessor/punctuation.hpp>
+#include <boost/preprocessor/punctuation/comma.hpp>
+#include <boost/preprocessor/stringize.hpp>
+
+template<typename MatrixType> void initMatrix_random(MatrixType& mat) __attribute__((noinline));
+template<typename MatrixType> void initMatrix_random(MatrixType& mat)
+{
+ mat.setRandom();// = MatrixType::random(mat.rows(), mat.cols());
+}
+
+template<typename MatrixType> void initMatrix_identity(MatrixType& mat) __attribute__((noinline));
+template<typename MatrixType> void initMatrix_identity(MatrixType& mat)
+{
+ mat.setIdentity();
+}
+
+#ifndef __INTEL_COMPILER
+#define DISABLE_SSE_EXCEPTIONS() { \
+ int aux; \
+ asm( \
+ "stmxcsr %[aux] \n\t" \
+ "orl $32832, %[aux] \n\t" \
+ "ldmxcsr %[aux] \n\t" \
+ : : [aux] "m" (aux)); \
+}
+#else
+#define DISABLE_SSE_EXCEPTIONS()
+#endif
+
+#ifdef BENCH_GMM
+#include <gmm/gmm.h>
+template <typename EigenMatrixType, typename GmmMatrixType>
+void eiToGmm(const EigenMatrixType& src, GmmMatrixType& dst)
+{
+ dst.resize(src.rows(),src.cols());
+ for (int j=0; j<src.cols(); ++j)
+ for (int i=0; i<src.rows(); ++i)
+ dst(i,j) = src.coeff(i,j);
+}
+#endif
+
+
+#ifdef BENCH_GSL
+#include <gsl/gsl_matrix.h>
+#include <gsl/gsl_linalg.h>
+#include <gsl/gsl_eigen.h>
+template <typename EigenMatrixType>
+void eiToGsl(const EigenMatrixType& src, gsl_matrix** dst)
+{
+ for (int j=0; j<src.cols(); ++j)
+ for (int i=0; i<src.rows(); ++i)
+ gsl_matrix_set(*dst, i, j, src.coeff(i,j));
+}
+#endif
+
+#ifdef BENCH_UBLAS
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+template <typename EigenMatrixType, typename UblasMatrixType>
+void eiToUblas(const EigenMatrixType& src, UblasMatrixType& dst)
+{
+ dst.resize(src.rows(),src.cols());
+ for (int j=0; j<src.cols(); ++j)
+ for (int i=0; i<src.rows(); ++i)
+ dst(i,j) = src.coeff(i,j);
+}
+template <typename EigenType, typename UblasType>
+void eiToUblasVec(const EigenType& src, UblasType& dst)
+{
+ dst.resize(src.size());
+ for (int j=0; j<src.size(); ++j)
+ dst[j] = src.coeff(j);
+}
+#endif
+
+#endif // EIGEN_BENCH_UTIL_H
diff --git a/eigen/bench/README.txt b/eigen/bench/README.txt
new file mode 100644
index 0000000..39831ae
--- /dev/null
+++ b/eigen/bench/README.txt
@@ -0,0 +1,55 @@
+
+This folder contains a couple of benchmark utities and Eigen benchmarks.
+
+****************************
+* bench_multi_compilers.sh *
+****************************
+
+This script allows to run a benchmark on a set of different compilers/compiler options.
+It takes two arguments:
+ - a file defining the list of the compilers with their options
+ - the .cpp file of the benchmark
+
+Examples:
+
+$ ./bench_multi_compilers.sh basicbench.cxxlist basicbenchmark.cpp
+
+ g++-4.1 -O3 -DNDEBUG -finline-limit=10000
+ 3d-3x3 / 4d-4x4 / Xd-4x4 / Xd-20x20 /
+ 0.271102 0.131416 0.422322 0.198633
+ 0.201658 0.102436 0.397566 0.207282
+
+ g++-4.2 -O3 -DNDEBUG -finline-limit=10000
+ 3d-3x3 / 4d-4x4 / Xd-4x4 / Xd-20x20 /
+ 0.107805 0.0890579 0.30265 0.161843
+ 0.127157 0.0712581 0.278341 0.191029
+
+ g++-4.3 -O3 -DNDEBUG -finline-limit=10000
+ 3d-3x3 / 4d-4x4 / Xd-4x4 / Xd-20x20 /
+ 0.134318 0.105291 0.3704 0.180966
+ 0.137703 0.0732472 0.31225 0.202204
+
+ icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size
+ 3d-3x3 / 4d-4x4 / Xd-4x4 / Xd-20x20 /
+ 0.226145 0.0941319 0.371873 0.159433
+ 0.109302 0.0837538 0.328102 0.173891
+
+
+$ ./bench_multi_compilers.sh ompbench.cxxlist ompbenchmark.cpp
+
+ g++-4.2 -O3 -DNDEBUG -finline-limit=10000 -fopenmp
+ double, fixed-size 4x4: 0.00165105s 0.0778739s
+ double, 32x32: 0.0654769s 0.075289s => x0.869674 (2)
+ double, 128x128: 0.054148s 0.0419669s => x1.29025 (2)
+ double, 512x512: 0.913799s 0.428533s => x2.13239 (2)
+ double, 1024x1024: 14.5972s 9.3542s => x1.5605 (2)
+
+ icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size -openmp
+ double, fixed-size 4x4: 0.000589848s 0.019949s
+ double, 32x32: 0.0682781s 0.0449722s => x1.51823 (2)
+ double, 128x128: 0.0547509s 0.0435519s => x1.25714 (2)
+ double, 512x512: 0.829436s 0.424438s => x1.9542 (2)
+ double, 1024x1024: 14.5243s 10.7735s => x1.34815 (2)
+
+
+
diff --git a/eigen/bench/basicbench.cxxlist b/eigen/bench/basicbench.cxxlist
new file mode 100644
index 0000000..a8ab34e
--- /dev/null
+++ b/eigen/bench/basicbench.cxxlist
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# CLIST[((g++))]="g++-3.4 -O3 -DNDEBUG"
+# CLIST[((g++))]="g++-3.4 -O3 -DNDEBUG -finline-limit=20000"
+
+# CLIST[((g++))]="g++-4.1 -O3 -DNDEBUG"
+#CLIST[((g++))]="g++-4.1 -O3 -DNDEBUG -finline-limit=20000"
+
+# CLIST[((g++))]="g++-4.2 -O3 -DNDEBUG"
+#CLIST[((g++))]="g++-4.2 -O3 -DNDEBUG -finline-limit=20000"
+# CLIST[((g++))]="g++-4.2 -O3 -DNDEBUG -finline-limit=20000 -fprofile-generate"
+# CLIST[((g++))]="g++-4.2 -O3 -DNDEBUG -finline-limit=20000 -fprofile-use"
+
+# CLIST[((g++))]="g++-4.3 -O3 -DNDEBUG"
+#CLIST[((g++))]="g++-4.3 -O3 -DNDEBUG -finline-limit=20000"
+# CLIST[((g++))]="g++-4.3 -O3 -DNDEBUG -finline-limit=20000 -fprofile-generate"
+# CLIST[((g++))]="g++-4.3 -O3 -DNDEBUG -finline-limit=20000 -fprofile-use"
+
+# CLIST[((g++))]="icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size -prof-genx"
+# CLIST[((g++))]="icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size -prof-use"
+
+#CLIST[((g++))]="/opt/intel/Compiler/11.1/072/bin/intel64/icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size -lrt"
+CLIST[((g++))]="/home/orzel/svn/llvm/Release/bin/clang++ -O3 -DNDEBUG -DEIGEN_DONT_VECTORIZE -lrt"
+CLIST[((g++))]="/home/orzel/svn/llvm/Release/bin/clang++ -O3 -DNDEBUG -lrt"
+CLIST[((g++))]="g++-4.4.4 -O3 -DNDEBUG -DEIGEN_DONT_VECTORIZE -lrt"
+CLIST[((g++))]="g++-4.4.4 -O3 -DNDEBUG -lrt"
+CLIST[((g++))]="g++-4.5.0 -O3 -DNDEBUG -DEIGEN_DONT_VECTORIZE -lrt"
+CLIST[((g++))]="g++-4.5.0 -O3 -DNDEBUG -lrt"
diff --git a/eigen/bench/basicbenchmark.cpp b/eigen/bench/basicbenchmark.cpp
new file mode 100644
index 0000000..a26ea85
--- /dev/null
+++ b/eigen/bench/basicbenchmark.cpp
@@ -0,0 +1,35 @@
+
+#include <iostream>
+#include "BenchUtil.h"
+#include "basicbenchmark.h"
+
+int main(int argc, char *argv[])
+{
+ DISABLE_SSE_EXCEPTIONS();
+
+ // this is the list of matrix type and size we want to bench:
+ // ((suffix) (matrix size) (number of iterations))
+ #define MODES ((3d)(3)(4000000)) ((4d)(4)(1000000)) ((Xd)(4)(1000000)) ((Xd)(20)(10000))
+// #define MODES ((Xd)(20)(10000))
+
+ #define _GENERATE_HEADER(R,ARG,EL) << BOOST_PP_STRINGIZE(BOOST_PP_SEQ_HEAD(EL)) << "-" \
+ << BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(1,EL)) << "x" \
+ << BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(1,EL)) << " / "
+
+ std::cout BOOST_PP_SEQ_FOR_EACH(_GENERATE_HEADER, ~, MODES ) << endl;
+
+ const int tries = 10;
+
+ #define _RUN_BENCH(R,ARG,EL) \
+ std::cout << ARG( \
+ BOOST_PP_CAT(Matrix, BOOST_PP_SEQ_HEAD(EL)) (\
+ BOOST_PP_SEQ_ELEM(1,EL),BOOST_PP_SEQ_ELEM(1,EL)), BOOST_PP_SEQ_ELEM(2,EL), tries) \
+ << " ";
+
+ BOOST_PP_SEQ_FOR_EACH(_RUN_BENCH, benchBasic<LazyEval>, MODES );
+ std::cout << endl;
+ BOOST_PP_SEQ_FOR_EACH(_RUN_BENCH, benchBasic<EarlyEval>, MODES );
+ std::cout << endl;
+
+ return 0;
+}
diff --git a/eigen/bench/basicbenchmark.h b/eigen/bench/basicbenchmark.h
new file mode 100644
index 0000000..3fdc357
--- /dev/null
+++ b/eigen/bench/basicbenchmark.h
@@ -0,0 +1,63 @@
+
+#ifndef EIGEN_BENCH_BASICBENCH_H
+#define EIGEN_BENCH_BASICBENCH_H
+
+enum {LazyEval, EarlyEval, OmpEval};
+
+template<int Mode, typename MatrixType>
+void benchBasic_loop(const MatrixType& I, MatrixType& m, int iterations) __attribute__((noinline));
+
+template<int Mode, typename MatrixType>
+void benchBasic_loop(const MatrixType& I, MatrixType& m, int iterations)
+{
+ for(int a = 0; a < iterations; a++)
+ {
+ if (Mode==LazyEval)
+ {
+ asm("#begin_bench_loop LazyEval");
+ if (MatrixType::SizeAtCompileTime!=Eigen::Dynamic) asm("#fixedsize");
+ m = (I + 0.00005 * (m + m.lazy() * m)).eval();
+ }
+ else if (Mode==OmpEval)
+ {
+ asm("#begin_bench_loop OmpEval");
+ if (MatrixType::SizeAtCompileTime!=Eigen::Dynamic) asm("#fixedsize");
+ m = (I + 0.00005 * (m + m.lazy() * m)).evalOMP();
+ }
+ else
+ {
+ asm("#begin_bench_loop EarlyEval");
+ if (MatrixType::SizeAtCompileTime!=Eigen::Dynamic) asm("#fixedsize");
+ m = I + 0.00005 * (m + m * m);
+ }
+ asm("#end_bench_loop");
+ }
+}
+
+template<int Mode, typename MatrixType>
+double benchBasic(const MatrixType& mat, int size, int tries) __attribute__((noinline));
+
+template<int Mode, typename MatrixType>
+double benchBasic(const MatrixType& mat, int iterations, int tries)
+{
+ const int rows = mat.rows();
+ const int cols = mat.cols();
+
+ MatrixType I(rows,cols);
+ MatrixType m(rows,cols);
+
+ initMatrix_identity(I);
+
+ Eigen::BenchTimer timer;
+ for(uint t=0; t<tries; ++t)
+ {
+ initMatrix_random(m);
+ timer.start();
+ benchBasic_loop<Mode>(I, m, iterations);
+ timer.stop();
+ cerr << m;
+ }
+ return timer.value();
+};
+
+#endif // EIGEN_BENCH_BASICBENCH_H
diff --git a/eigen/bench/benchBlasGemm.cpp b/eigen/bench/benchBlasGemm.cpp
new file mode 100644
index 0000000..cb086a5
--- /dev/null
+++ b/eigen/bench/benchBlasGemm.cpp
@@ -0,0 +1,219 @@
+// g++ -O3 -DNDEBUG -I.. -L /usr/lib64/atlas/ benchBlasGemm.cpp -o benchBlasGemm -lrt -lcblas
+// possible options:
+// -DEIGEN_DONT_VECTORIZE
+// -msse2
+
+// #define EIGEN_DEFAULT_TO_ROW_MAJOR
+#define _FLOAT
+
+#include <iostream>
+
+#include <Eigen/Core>
+#include "BenchTimer.h"
+
+// include the BLAS headers
+extern "C" {
+#include <cblas.h>
+}
+#include <string>
+
+#ifdef _FLOAT
+typedef float Scalar;
+#define CBLAS_GEMM cblas_sgemm
+#else
+typedef double Scalar;
+#define CBLAS_GEMM cblas_dgemm
+#endif
+
+
+typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> MyMatrix;
+void bench_eigengemm(MyMatrix& mc, const MyMatrix& ma, const MyMatrix& mb, int nbloops);
+void check_product(int M, int N, int K);
+void check_product(void);
+
+int main(int argc, char *argv[])
+{
+ // disable SSE exceptions
+ #ifdef __GNUC__
+ {
+ int aux;
+ asm(
+ "stmxcsr %[aux] \n\t"
+ "orl $32832, %[aux] \n\t"
+ "ldmxcsr %[aux] \n\t"
+ : : [aux] "m" (aux));
+ }
+ #endif
+
+ int nbtries=1, nbloops=1, M, N, K;
+
+ if (argc==2)
+ {
+ if (std::string(argv[1])=="check")
+ check_product();
+ else
+ M = N = K = atoi(argv[1]);
+ }
+ else if ((argc==3) && (std::string(argv[1])=="auto"))
+ {
+ M = N = K = atoi(argv[2]);
+ nbloops = 1000000000/(M*M*M);
+ if (nbloops<1)
+ nbloops = 1;
+ nbtries = 6;
+ }
+ else if (argc==4)
+ {
+ M = N = K = atoi(argv[1]);
+ nbloops = atoi(argv[2]);
+ nbtries = atoi(argv[3]);
+ }
+ else if (argc==6)
+ {
+ M = atoi(argv[1]);
+ N = atoi(argv[2]);
+ K = atoi(argv[3]);
+ nbloops = atoi(argv[4]);
+ nbtries = atoi(argv[5]);
+ }
+ else
+ {
+ std::cout << "Usage: " << argv[0] << " size \n";
+ std::cout << "Usage: " << argv[0] << " auto size\n";
+ std::cout << "Usage: " << argv[0] << " size nbloops nbtries\n";
+ std::cout << "Usage: " << argv[0] << " M N K nbloops nbtries\n";
+ std::cout << "Usage: " << argv[0] << " check\n";
+ std::cout << "Options:\n";
+ std::cout << " size unique size of the 2 matrices (integer)\n";
+ std::cout << " auto automatically set the number of repetitions and tries\n";
+ std::cout << " nbloops number of times the GEMM routines is executed\n";
+ std::cout << " nbtries number of times the loop is benched (return the best try)\n";
+ std::cout << " M N K sizes of the matrices: MxN = MxK * KxN (integers)\n";
+ std::cout << " check check eigen product using cblas as a reference\n";
+ exit(1);
+ }
+
+ double nbmad = double(M) * double(N) * double(K) * double(nbloops);
+
+ if (!(std::string(argv[1])=="auto"))
+ std::cout << M << " x " << N << " x " << K << "\n";
+
+ Scalar alpha, beta;
+ MyMatrix ma(M,K), mb(K,N), mc(M,N);
+ ma = MyMatrix::Random(M,K);
+ mb = MyMatrix::Random(K,N);
+ mc = MyMatrix::Random(M,N);
+
+ Eigen::BenchTimer timer;
+
+ // we simply compute c += a*b, so:
+ alpha = 1;
+ beta = 1;
+
+ // bench cblas
+ // ROWS_A, COLS_B, COLS_A, 1.0, A, COLS_A, B, COLS_B, 0.0, C, COLS_B);
+ if (!(std::string(argv[1])=="auto"))
+ {
+ timer.reset();
+ for (uint k=0 ; k<nbtries ; ++k)
+ {
+ timer.start();
+ for (uint j=0 ; j<nbloops ; ++j)
+ #ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
+ CBLAS_GEMM(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, ma.data(), K, mb.data(), N, beta, mc.data(), N);
+ #else
+ CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, ma.data(), M, mb.data(), K, beta, mc.data(), M);
+ #endif
+ timer.stop();
+ }
+ if (!(std::string(argv[1])=="auto"))
+ std::cout << "cblas: " << timer.value() << " (" << 1e-3*floor(1e-6*nbmad/timer.value()) << " GFlops/s)\n";
+ else
+ std::cout << M << " : " << timer.value() << " ; " << 1e-3*floor(1e-6*nbmad/timer.value()) << "\n";
+ }
+
+ // clear
+ ma = MyMatrix::Random(M,K);
+ mb = MyMatrix::Random(K,N);
+ mc = MyMatrix::Random(M,N);
+
+ // eigen
+// if (!(std::string(argv[1])=="auto"))
+ {
+ timer.reset();
+ for (uint k=0 ; k<nbtries ; ++k)
+ {
+ timer.start();
+ bench_eigengemm(mc, ma, mb, nbloops);
+ timer.stop();
+ }
+ if (!(std::string(argv[1])=="auto"))
+ std::cout << "eigen : " << timer.value() << " (" << 1e-3*floor(1e-6*nbmad/timer.value()) << " GFlops/s)\n";
+ else
+ std::cout << M << " : " << timer.value() << " ; " << 1e-3*floor(1e-6*nbmad/timer.value()) << "\n";
+ }
+
+ std::cout << "l1: " << Eigen::l1CacheSize() << std::endl;
+ std::cout << "l2: " << Eigen::l2CacheSize() << std::endl;
+
+
+ return 0;
+}
+
+using namespace Eigen;
+
+void bench_eigengemm(MyMatrix& mc, const MyMatrix& ma, const MyMatrix& mb, int nbloops)
+{
+ for (uint j=0 ; j<nbloops ; ++j)
+ mc.noalias() += ma * mb;
+}
+
+#define MYVERIFY(A,M) if (!(A)) { \
+ std::cout << "FAIL: " << M << "\n"; \
+ }
+void check_product(int M, int N, int K)
+{
+ MyMatrix ma(M,K), mb(K,N), mc(M,N), maT(K,M), mbT(N,K), meigen(M,N), mref(M,N);
+ ma = MyMatrix::Random(M,K);
+ mb = MyMatrix::Random(K,N);
+ maT = ma.transpose();
+ mbT = mb.transpose();
+ mc = MyMatrix::Random(M,N);
+
+ MyMatrix::Scalar eps = 1e-4;
+
+ meigen = mref = mc;
+ CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, 1, ma.data(), M, mb.data(), K, 1, mref.data(), M);
+ meigen += ma * mb;
+ MYVERIFY(meigen.isApprox(mref, eps),". * .");
+
+ meigen = mref = mc;
+ CBLAS_GEMM(CblasColMajor, CblasTrans, CblasNoTrans, M, N, K, 1, maT.data(), K, mb.data(), K, 1, mref.data(), M);
+ meigen += maT.transpose() * mb;
+ MYVERIFY(meigen.isApprox(mref, eps),"T * .");
+
+ meigen = mref = mc;
+ CBLAS_GEMM(CblasColMajor, CblasTrans, CblasTrans, M, N, K, 1, maT.data(), K, mbT.data(), N, 1, mref.data(), M);
+ meigen += (maT.transpose()) * (mbT.transpose());
+ MYVERIFY(meigen.isApprox(mref, eps),"T * T");
+
+ meigen = mref = mc;
+ CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasTrans, M, N, K, 1, ma.data(), M, mbT.data(), N, 1, mref.data(), M);
+ meigen += ma * mbT.transpose();
+ MYVERIFY(meigen.isApprox(mref, eps),". * T");
+}
+
+void check_product(void)
+{
+ int M, N, K;
+ for (uint i=0; i<1000; ++i)
+ {
+ M = internal::random<int>(1,64);
+ N = internal::random<int>(1,768);
+ K = internal::random<int>(1,768);
+ M = (0 + M) * 1;
+ std::cout << M << " x " << N << " x " << K << "\n";
+ check_product(M, N, K);
+ }
+}
+
diff --git a/eigen/bench/benchCholesky.cpp b/eigen/bench/benchCholesky.cpp
new file mode 100644
index 0000000..42b3e12
--- /dev/null
+++ b/eigen/bench/benchCholesky.cpp
@@ -0,0 +1,142 @@
+
+// g++ -DNDEBUG -O3 -I.. benchLLT.cpp -o benchLLT && ./benchLLT
+// options:
+// -DBENCH_GSL -lgsl /usr/lib/libcblas.so.3
+// -DEIGEN_DONT_VECTORIZE
+// -msse2
+// -DREPEAT=100
+// -DTRIES=10
+// -DSCALAR=double
+
+#include <iostream>
+
+#include <Eigen/Core>
+#include <Eigen/Cholesky>
+#include <bench/BenchUtil.h>
+using namespace Eigen;
+
+#ifndef REPEAT
+#define REPEAT 10000
+#endif
+
+#ifndef TRIES
+#define TRIES 10
+#endif
+
+typedef float Scalar;
+
+template <typename MatrixType>
+__attribute__ ((noinline)) void benchLLT(const MatrixType& m)
+{
+ int rows = m.rows();
+ int cols = m.cols();
+
+ int cost = 0;
+ for (int j=0; j<rows; ++j)
+ {
+ int r = std::max(rows - j -1,0);
+ cost += 2*(r*j+r+j);
+ }
+
+ int repeats = (REPEAT*1000)/(rows*rows);
+
+ typedef typename MatrixType::Scalar Scalar;
+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
+
+ MatrixType a = MatrixType::Random(rows,cols);
+ SquareMatrixType covMat = a * a.adjoint();
+
+ BenchTimer timerNoSqrt, timerSqrt;
+
+ Scalar acc = 0;
+ int r = internal::random<int>(0,covMat.rows()-1);
+ int c = internal::random<int>(0,covMat.cols()-1);
+ for (int t=0; t<TRIES; ++t)
+ {
+ timerNoSqrt.start();
+ for (int k=0; k<repeats; ++k)
+ {
+ LDLT<SquareMatrixType> cholnosqrt(covMat);
+ acc += cholnosqrt.matrixL().coeff(r,c);
+ }
+ timerNoSqrt.stop();
+ }
+
+ for (int t=0; t<TRIES; ++t)
+ {
+ timerSqrt.start();
+ for (int k=0; k<repeats; ++k)
+ {
+ LLT<SquareMatrixType> chol(covMat);
+ acc += chol.matrixL().coeff(r,c);
+ }
+ timerSqrt.stop();
+ }
+
+ if (MatrixType::RowsAtCompileTime==Dynamic)
+ std::cout << "dyn ";
+ else
+ std::cout << "fixed ";
+ std::cout << covMat.rows() << " \t"
+ << (timerNoSqrt.value() * REPEAT) / repeats << "s "
+ << "(" << 1e-6 * cost*repeats/timerNoSqrt.value() << " MFLOPS)\t"
+ << (timerSqrt.value() * REPEAT) / repeats << "s "
+ << "(" << 1e-6 * cost*repeats/timerSqrt.value() << " MFLOPS)\n";
+
+
+ #ifdef BENCH_GSL
+ if (MatrixType::RowsAtCompileTime==Dynamic)
+ {
+ timerSqrt.reset();
+
+ gsl_matrix* gslCovMat = gsl_matrix_alloc(covMat.rows(),covMat.cols());
+ gsl_matrix* gslCopy = gsl_matrix_alloc(covMat.rows(),covMat.cols());
+
+ eiToGsl(covMat, &gslCovMat);
+ for (int t=0; t<TRIES; ++t)
+ {
+ timerSqrt.start();
+ for (int k=0; k<repeats; ++k)
+ {
+ gsl_matrix_memcpy(gslCopy,gslCovMat);
+ gsl_linalg_cholesky_decomp(gslCopy);
+ acc += gsl_matrix_get(gslCopy,r,c);
+ }
+ timerSqrt.stop();
+ }
+
+ std::cout << " | \t"
+ << timerSqrt.value() * REPEAT / repeats << "s";
+
+ gsl_matrix_free(gslCovMat);
+ }
+ #endif
+ std::cout << "\n";
+ // make sure the compiler does not optimize too much
+ if (acc==123)
+ std::cout << acc;
+}
+
+int main(int argc, char* argv[])
+{
+ const int dynsizes[] = {4,6,8,16,24,32,49,64,128,256,512,900,0};
+ std::cout << "size no sqrt standard";
+// #ifdef BENCH_GSL
+// std::cout << " GSL (standard + double + ATLAS) ";
+// #endif
+ std::cout << "\n";
+ for (uint i=0; dynsizes[i]>0; ++i)
+ benchLLT(Matrix<Scalar,Dynamic,Dynamic>(dynsizes[i],dynsizes[i]));
+
+ benchLLT(Matrix<Scalar,2,2>());
+ benchLLT(Matrix<Scalar,3,3>());
+ benchLLT(Matrix<Scalar,4,4>());
+ benchLLT(Matrix<Scalar,5,5>());
+ benchLLT(Matrix<Scalar,6,6>());
+ benchLLT(Matrix<Scalar,7,7>());
+ benchLLT(Matrix<Scalar,8,8>());
+ benchLLT(Matrix<Scalar,12,12>());
+ benchLLT(Matrix<Scalar,16,16>());
+ return 0;
+}
+
diff --git a/eigen/bench/benchEigenSolver.cpp b/eigen/bench/benchEigenSolver.cpp
new file mode 100644
index 0000000..dd78c7e
--- /dev/null
+++ b/eigen/bench/benchEigenSolver.cpp
@@ -0,0 +1,212 @@
+
+// g++ -DNDEBUG -O3 -I.. benchEigenSolver.cpp -o benchEigenSolver && ./benchEigenSolver
+// options:
+// -DBENCH_GMM
+// -DBENCH_GSL -lgsl /usr/lib/libcblas.so.3
+// -DEIGEN_DONT_VECTORIZE
+// -msse2
+// -DREPEAT=100
+// -DTRIES=10
+// -DSCALAR=double
+
+#include <iostream>
+
+#include <Eigen/Core>
+#include <Eigen/QR>
+#include <bench/BenchUtil.h>
+using namespace Eigen;
+
+#ifndef REPEAT
+#define REPEAT 1000
+#endif
+
+#ifndef TRIES
+#define TRIES 4
+#endif
+
+#ifndef SCALAR
+#define SCALAR float
+#endif
+
+typedef SCALAR Scalar;
+
+template <typename MatrixType>
+__attribute__ ((noinline)) void benchEigenSolver(const MatrixType& m)
+{
+ int rows = m.rows();
+ int cols = m.cols();
+
+ int stdRepeats = std::max(1,int((REPEAT*1000)/(rows*rows*sqrt(rows))));
+ int saRepeats = stdRepeats * 4;
+
+ typedef typename MatrixType::Scalar Scalar;
+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
+
+ MatrixType a = MatrixType::Random(rows,cols);
+ SquareMatrixType covMat = a * a.adjoint();
+
+ BenchTimer timerSa, timerStd;
+
+ Scalar acc = 0;
+ int r = internal::random<int>(0,covMat.rows()-1);
+ int c = internal::random<int>(0,covMat.cols()-1);
+ {
+ SelfAdjointEigenSolver<SquareMatrixType> ei(covMat);
+ for (int t=0; t<TRIES; ++t)
+ {
+ timerSa.start();
+ for (int k=0; k<saRepeats; ++k)
+ {
+ ei.compute(covMat);
+ acc += ei.eigenvectors().coeff(r,c);
+ }
+ timerSa.stop();
+ }
+ }
+
+ {
+ EigenSolver<SquareMatrixType> ei(covMat);
+ for (int t=0; t<TRIES; ++t)
+ {
+ timerStd.start();
+ for (int k=0; k<stdRepeats; ++k)
+ {
+ ei.compute(covMat);
+ acc += ei.eigenvectors().coeff(r,c);
+ }
+ timerStd.stop();
+ }
+ }
+
+ if (MatrixType::RowsAtCompileTime==Dynamic)
+ std::cout << "dyn ";
+ else
+ std::cout << "fixed ";
+ std::cout << covMat.rows() << " \t"
+ << timerSa.value() * REPEAT / saRepeats << "s \t"
+ << timerStd.value() * REPEAT / stdRepeats << "s";
+
+ #ifdef BENCH_GMM
+ if (MatrixType::RowsAtCompileTime==Dynamic)
+ {
+ timerSa.reset();
+ timerStd.reset();
+
+ gmm::dense_matrix<Scalar> gmmCovMat(covMat.rows(),covMat.cols());
+ gmm::dense_matrix<Scalar> eigvect(covMat.rows(),covMat.cols());
+ std::vector<Scalar> eigval(covMat.rows());
+ eiToGmm(covMat, gmmCovMat);
+ for (int t=0; t<TRIES; ++t)
+ {
+ timerSa.start();
+ for (int k=0; k<saRepeats; ++k)
+ {
+ gmm::symmetric_qr_algorithm(gmmCovMat, eigval, eigvect);
+ acc += eigvect(r,c);
+ }
+ timerSa.stop();
+ }
+ // the non-selfadjoint solver does not compute the eigen vectors
+// for (int t=0; t<TRIES; ++t)
+// {
+// timerStd.start();
+// for (int k=0; k<stdRepeats; ++k)
+// {
+// gmm::implicit_qr_algorithm(gmmCovMat, eigval, eigvect);
+// acc += eigvect(r,c);
+// }
+// timerStd.stop();
+// }
+
+ std::cout << " | \t"
+ << timerSa.value() * REPEAT / saRepeats << "s"
+ << /*timerStd.value() * REPEAT / stdRepeats << "s"*/ " na ";
+ }
+ #endif
+
+ #ifdef BENCH_GSL
+ if (MatrixType::RowsAtCompileTime==Dynamic)
+ {
+ timerSa.reset();
+ timerStd.reset();
+
+ gsl_matrix* gslCovMat = gsl_matrix_alloc(covMat.rows(),covMat.cols());
+ gsl_matrix* gslCopy = gsl_matrix_alloc(covMat.rows(),covMat.cols());
+ gsl_matrix* eigvect = gsl_matrix_alloc(covMat.rows(),covMat.cols());
+ gsl_vector* eigval = gsl_vector_alloc(covMat.rows());
+ gsl_eigen_symmv_workspace* eisymm = gsl_eigen_symmv_alloc(covMat.rows());
+
+ gsl_matrix_complex* eigvectz = gsl_matrix_complex_alloc(covMat.rows(),covMat.cols());
+ gsl_vector_complex* eigvalz = gsl_vector_complex_alloc(covMat.rows());
+ gsl_eigen_nonsymmv_workspace* einonsymm = gsl_eigen_nonsymmv_alloc(covMat.rows());
+
+ eiToGsl(covMat, &gslCovMat);
+ for (int t=0; t<TRIES; ++t)
+ {
+ timerSa.start();
+ for (int k=0; k<saRepeats; ++k)
+ {
+ gsl_matrix_memcpy(gslCopy,gslCovMat);
+ gsl_eigen_symmv(gslCopy, eigval, eigvect, eisymm);
+ acc += gsl_matrix_get(eigvect,r,c);
+ }
+ timerSa.stop();
+ }
+ for (int t=0; t<TRIES; ++t)
+ {
+ timerStd.start();
+ for (int k=0; k<stdRepeats; ++k)
+ {
+ gsl_matrix_memcpy(gslCopy,gslCovMat);
+ gsl_eigen_nonsymmv(gslCopy, eigvalz, eigvectz, einonsymm);
+ acc += GSL_REAL(gsl_matrix_complex_get(eigvectz,r,c));
+ }
+ timerStd.stop();
+ }
+
+ std::cout << " | \t"
+ << timerSa.value() * REPEAT / saRepeats << "s \t"
+ << timerStd.value() * REPEAT / stdRepeats << "s";
+
+ gsl_matrix_free(gslCovMat);
+ gsl_vector_free(gslCopy);
+ gsl_matrix_free(eigvect);
+ gsl_vector_free(eigval);
+ gsl_matrix_complex_free(eigvectz);
+ gsl_vector_complex_free(eigvalz);
+ gsl_eigen_symmv_free(eisymm);
+ gsl_eigen_nonsymmv_free(einonsymm);
+ }
+ #endif
+
+ std::cout << "\n";
+
+ // make sure the compiler does not optimize too much
+ if (acc==123)
+ std::cout << acc;
+}
+
+int main(int argc, char* argv[])
+{
+ const int dynsizes[] = {4,6,8,12,16,24,32,64,128,256,512,0};
+ std::cout << "size selfadjoint generic";
+ #ifdef BENCH_GMM
+ std::cout << " GMM++ ";
+ #endif
+ #ifdef BENCH_GSL
+ std::cout << " GSL (double + ATLAS) ";
+ #endif
+ std::cout << "\n";
+ for (uint i=0; dynsizes[i]>0; ++i)
+ benchEigenSolver(Matrix<Scalar,Dynamic,Dynamic>(dynsizes[i],dynsizes[i]));
+
+ benchEigenSolver(Matrix<Scalar,2,2>());
+ benchEigenSolver(Matrix<Scalar,3,3>());
+ benchEigenSolver(Matrix<Scalar,4,4>());
+ benchEigenSolver(Matrix<Scalar,6,6>());
+ benchEigenSolver(Matrix<Scalar,8,8>());
+ benchEigenSolver(Matrix<Scalar,12,12>());
+ benchEigenSolver(Matrix<Scalar,16,16>());
+ return 0;
+}
+
diff --git a/eigen/bench/benchFFT.cpp b/eigen/bench/benchFFT.cpp
new file mode 100644
index 0000000..3eb1a1a
--- /dev/null
+++ b/eigen/bench/benchFFT.cpp
@@ -0,0 +1,115 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 Mark Borgerding mark a borgerding net
+//
+// 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 <iostream>
+
+#include <bench/BenchUtil.h>
+#include <complex>
+#include <vector>
+#include <Eigen/Core>
+
+#include <unsupported/Eigen/FFT>
+
+using namespace Eigen;
+using namespace std;
+
+
+template <typename T>
+string nameof();
+
+template <> string nameof<float>() {return "float";}
+template <> string nameof<double>() {return "double";}
+template <> string nameof<long double>() {return "long double";}
+
+#ifndef TYPE
+#define TYPE float
+#endif
+
+#ifndef NFFT
+#define NFFT 1024
+#endif
+#ifndef NDATA
+#define NDATA 1000000
+#endif
+
+using namespace Eigen;
+
+template <typename T>
+void bench(int nfft,bool fwd,bool unscaled=false, bool halfspec=false)
+{
+ typedef typename NumTraits<T>::Real Scalar;
+ typedef typename std::complex<Scalar> Complex;
+ int nits = NDATA/nfft;
+ vector<T> inbuf(nfft);
+ vector<Complex > outbuf(nfft);
+ FFT< Scalar > fft;
+
+ if (unscaled) {
+ fft.SetFlag(fft.Unscaled);
+ cout << "unscaled ";
+ }
+ if (halfspec) {
+ fft.SetFlag(fft.HalfSpectrum);
+ cout << "halfspec ";
+ }
+
+
+ std::fill(inbuf.begin(),inbuf.end(),0);
+ fft.fwd( outbuf , inbuf);
+
+ BenchTimer timer;
+ timer.reset();
+ for (int k=0;k<8;++k) {
+ timer.start();
+ if (fwd)
+ for(int i = 0; i < nits; i++)
+ fft.fwd( outbuf , inbuf);
+ else
+ for(int i = 0; i < nits; i++)
+ fft.inv(inbuf,outbuf);
+ timer.stop();
+ }
+
+ cout << nameof<Scalar>() << " ";
+ double mflops = 5.*nfft*log2((double)nfft) / (1e6 * timer.value() / (double)nits );
+ if ( NumTraits<T>::IsComplex ) {
+ cout << "complex";
+ }else{
+ cout << "real ";
+ mflops /= 2;
+ }
+
+
+ if (fwd)
+ cout << " fwd";
+ else
+ cout << " inv";
+
+ cout << " NFFT=" << nfft << " " << (double(1e-6*nfft*nits)/timer.value()) << " MS/s " << mflops << "MFLOPS\n";
+}
+
+int main(int argc,char ** argv)
+{
+ bench<complex<float> >(NFFT,true);
+ bench<complex<float> >(NFFT,false);
+ bench<float>(NFFT,true);
+ bench<float>(NFFT,false);
+ bench<float>(NFFT,false,true);
+ bench<float>(NFFT,false,true,true);
+
+ bench<complex<double> >(NFFT,true);
+ bench<complex<double> >(NFFT,false);
+ bench<double>(NFFT,true);
+ bench<double>(NFFT,false);
+ bench<complex<long double> >(NFFT,true);
+ bench<complex<long double> >(NFFT,false);
+ bench<long double>(NFFT,true);
+ bench<long double>(NFFT,false);
+ return 0;
+}
diff --git a/eigen/bench/benchGeometry.cpp b/eigen/bench/benchGeometry.cpp
new file mode 100644
index 0000000..6e16c03
--- /dev/null
+++ b/eigen/bench/benchGeometry.cpp
@@ -0,0 +1,134 @@
+#include <iostream>
+#include <iomanip>
+#include <Eigen/Core>
+#include <Eigen/Geometry>
+#include <bench/BenchTimer.h>
+
+using namespace Eigen;
+using namespace std;
+
+#ifndef REPEAT
+#define REPEAT 1000000
+#endif
+
+enum func_opt
+{
+ TV,
+ TMATV,
+ TMATVMAT,
+};
+
+
+template <class res, class arg1, class arg2, int opt>
+struct func;
+
+template <class res, class arg1, class arg2>
+struct func<res, arg1, arg2, TV>
+{
+ static EIGEN_DONT_INLINE res run( arg1& a1, arg2& a2 )
+ {
+ asm ("");
+ return a1 * a2;
+ }
+};
+
+template <class res, class arg1, class arg2>
+struct func<res, arg1, arg2, TMATV>
+{
+ static EIGEN_DONT_INLINE res run( arg1& a1, arg2& a2 )
+ {
+ asm ("");
+ return a1.matrix() * a2;
+ }
+};
+
+template <class res, class arg1, class arg2>
+struct func<res, arg1, arg2, TMATVMAT>
+{
+ static EIGEN_DONT_INLINE res run( arg1& a1, arg2& a2 )
+ {
+ asm ("");
+ return res(a1.matrix() * a2.matrix());
+ }
+};
+
+template <class func, class arg1, class arg2>
+struct test_transform
+{
+ static void run()
+ {
+ arg1 a1;
+ a1.setIdentity();
+ arg2 a2;
+ a2.setIdentity();
+
+ BenchTimer timer;
+ timer.reset();
+ for (int k=0; k<10; ++k)
+ {
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ a2 = func::run( a1, a2 );
+ timer.stop();
+ }
+ cout << setprecision(4) << fixed << timer.value() << "s " << endl;;
+ }
+};
+
+
+#define run_vec( op, scalar, mode, option, vsize ) \
+ std::cout << #scalar << "\t " << #mode << "\t " << #option << " " << #vsize " "; \
+ {\
+ typedef Transform<scalar, 3, mode, option> Trans;\
+ typedef Matrix<scalar, vsize, 1, option> Vec;\
+ typedef func<Vec,Trans,Vec,op> Func;\
+ test_transform< Func, Trans, Vec >::run();\
+ }
+
+#define run_trans( op, scalar, mode, option ) \
+ std::cout << #scalar << "\t " << #mode << "\t " << #option << " "; \
+ {\
+ typedef Transform<scalar, 3, mode, option> Trans;\
+ typedef func<Trans,Trans,Trans,op> Func;\
+ test_transform< Func, Trans, Trans >::run();\
+ }
+
+int main(int argc, char* argv[])
+{
+ cout << "vec = trans * vec" << endl;
+ run_vec(TV, float, Isometry, AutoAlign, 3);
+ run_vec(TV, float, Isometry, DontAlign, 3);
+ run_vec(TV, float, Isometry, AutoAlign, 4);
+ run_vec(TV, float, Isometry, DontAlign, 4);
+ run_vec(TV, float, Projective, AutoAlign, 4);
+ run_vec(TV, float, Projective, DontAlign, 4);
+ run_vec(TV, double, Isometry, AutoAlign, 3);
+ run_vec(TV, double, Isometry, DontAlign, 3);
+ run_vec(TV, double, Isometry, AutoAlign, 4);
+ run_vec(TV, double, Isometry, DontAlign, 4);
+ run_vec(TV, double, Projective, AutoAlign, 4);
+ run_vec(TV, double, Projective, DontAlign, 4);
+
+ cout << "vec = trans.matrix() * vec" << endl;
+ run_vec(TMATV, float, Isometry, AutoAlign, 4);
+ run_vec(TMATV, float, Isometry, DontAlign, 4);
+ run_vec(TMATV, double, Isometry, AutoAlign, 4);
+ run_vec(TMATV, double, Isometry, DontAlign, 4);
+
+ cout << "trans = trans1 * trans" << endl;
+ run_trans(TV, float, Isometry, AutoAlign);
+ run_trans(TV, float, Isometry, DontAlign);
+ run_trans(TV, double, Isometry, AutoAlign);
+ run_trans(TV, double, Isometry, DontAlign);
+ run_trans(TV, float, Projective, AutoAlign);
+ run_trans(TV, float, Projective, DontAlign);
+ run_trans(TV, double, Projective, AutoAlign);
+ run_trans(TV, double, Projective, DontAlign);
+
+ cout << "trans = trans1.matrix() * trans.matrix()" << endl;
+ run_trans(TMATVMAT, float, Isometry, AutoAlign);
+ run_trans(TMATVMAT, float, Isometry, DontAlign);
+ run_trans(TMATVMAT, double, Isometry, AutoAlign);
+ run_trans(TMATVMAT, double, Isometry, DontAlign);
+}
+
diff --git a/eigen/bench/benchVecAdd.cpp b/eigen/bench/benchVecAdd.cpp
new file mode 100644
index 0000000..ce8e1e9
--- /dev/null
+++ b/eigen/bench/benchVecAdd.cpp
@@ -0,0 +1,135 @@
+
+#include <iostream>
+#include <Eigen/Core>
+#include <bench/BenchTimer.h>
+using namespace Eigen;
+
+#ifndef SIZE
+#define SIZE 50
+#endif
+
+#ifndef REPEAT
+#define REPEAT 10000
+#endif
+
+typedef float Scalar;
+
+__attribute__ ((noinline)) void benchVec(Scalar* a, Scalar* b, Scalar* c, int size);
+__attribute__ ((noinline)) void benchVec(MatrixXf& a, MatrixXf& b, MatrixXf& c);
+__attribute__ ((noinline)) void benchVec(VectorXf& a, VectorXf& b, VectorXf& c);
+
+int main(int argc, char* argv[])
+{
+ int size = SIZE * 8;
+ int size2 = size * size;
+ Scalar* a = internal::aligned_new<Scalar>(size2);
+ Scalar* b = internal::aligned_new<Scalar>(size2+4)+1;
+ Scalar* c = internal::aligned_new<Scalar>(size2);
+
+ for (int i=0; i<size; ++i)
+ {
+ a[i] = b[i] = c[i] = 0;
+ }
+
+ BenchTimer timer;
+
+ timer.reset();
+ for (int k=0; k<10; ++k)
+ {
+ timer.start();
+ benchVec(a, b, c, size2);
+ timer.stop();
+ }
+ std::cout << timer.value() << "s " << (double(size2*REPEAT)/timer.value())/(1024.*1024.*1024.) << " GFlops\n";
+ return 0;
+ for (int innersize = size; innersize>2 ; --innersize)
+ {
+ if (size2%innersize==0)
+ {
+ int outersize = size2/innersize;
+ MatrixXf ma = Map<MatrixXf>(a, innersize, outersize );
+ MatrixXf mb = Map<MatrixXf>(b, innersize, outersize );
+ MatrixXf mc = Map<MatrixXf>(c, innersize, outersize );
+ timer.reset();
+ for (int k=0; k<3; ++k)
+ {
+ timer.start();
+ benchVec(ma, mb, mc);
+ timer.stop();
+ }
+ std::cout << innersize << " x " << outersize << " " << timer.value() << "s " << (double(size2*REPEAT)/timer.value())/(1024.*1024.*1024.) << " GFlops\n";
+ }
+ }
+
+ VectorXf va = Map<VectorXf>(a, size2);
+ VectorXf vb = Map<VectorXf>(b, size2);
+ VectorXf vc = Map<VectorXf>(c, size2);
+ timer.reset();
+ for (int k=0; k<3; ++k)
+ {
+ timer.start();
+ benchVec(va, vb, vc);
+ timer.stop();
+ }
+ std::cout << timer.value() << "s " << (double(size2*REPEAT)/timer.value())/(1024.*1024.*1024.) << " GFlops\n";
+
+ return 0;
+}
+
+void benchVec(MatrixXf& a, MatrixXf& b, MatrixXf& c)
+{
+ for (int k=0; k<REPEAT; ++k)
+ a = a + b;
+}
+
+void benchVec(VectorXf& a, VectorXf& b, VectorXf& c)
+{
+ for (int k=0; k<REPEAT; ++k)
+ a = a + b;
+}
+
+void benchVec(Scalar* a, Scalar* b, Scalar* c, int size)
+{
+ typedef internal::packet_traits<Scalar>::type PacketScalar;
+ const int PacketSize = internal::packet_traits<Scalar>::size;
+ PacketScalar a0, a1, a2, a3, b0, b1, b2, b3;
+ for (int k=0; k<REPEAT; ++k)
+ for (int i=0; i<size; i+=PacketSize*8)
+ {
+// a0 = internal::pload(&a[i]);
+// b0 = internal::pload(&b[i]);
+// a1 = internal::pload(&a[i+1*PacketSize]);
+// b1 = internal::pload(&b[i+1*PacketSize]);
+// a2 = internal::pload(&a[i+2*PacketSize]);
+// b2 = internal::pload(&b[i+2*PacketSize]);
+// a3 = internal::pload(&a[i+3*PacketSize]);
+// b3 = internal::pload(&b[i+3*PacketSize]);
+// internal::pstore(&a[i], internal::padd(a0, b0));
+// a0 = internal::pload(&a[i+4*PacketSize]);
+// b0 = internal::pload(&b[i+4*PacketSize]);
+//
+// internal::pstore(&a[i+1*PacketSize], internal::padd(a1, b1));
+// a1 = internal::pload(&a[i+5*PacketSize]);
+// b1 = internal::pload(&b[i+5*PacketSize]);
+//
+// internal::pstore(&a[i+2*PacketSize], internal::padd(a2, b2));
+// a2 = internal::pload(&a[i+6*PacketSize]);
+// b2 = internal::pload(&b[i+6*PacketSize]);
+//
+// internal::pstore(&a[i+3*PacketSize], internal::padd(a3, b3));
+// a3 = internal::pload(&a[i+7*PacketSize]);
+// b3 = internal::pload(&b[i+7*PacketSize]);
+//
+// internal::pstore(&a[i+4*PacketSize], internal::padd(a0, b0));
+// internal::pstore(&a[i+5*PacketSize], internal::padd(a1, b1));
+// internal::pstore(&a[i+6*PacketSize], internal::padd(a2, b2));
+// internal::pstore(&a[i+7*PacketSize], internal::padd(a3, b3));
+
+ internal::pstore(&a[i+2*PacketSize], internal::padd(internal::ploadu(&a[i+2*PacketSize]), internal::ploadu(&b[i+2*PacketSize])));
+ internal::pstore(&a[i+3*PacketSize], internal::padd(internal::ploadu(&a[i+3*PacketSize]), internal::ploadu(&b[i+3*PacketSize])));
+ internal::pstore(&a[i+4*PacketSize], internal::padd(internal::ploadu(&a[i+4*PacketSize]), internal::ploadu(&b[i+4*PacketSize])));
+ internal::pstore(&a[i+5*PacketSize], internal::padd(internal::ploadu(&a[i+5*PacketSize]), internal::ploadu(&b[i+5*PacketSize])));
+ internal::pstore(&a[i+6*PacketSize], internal::padd(internal::ploadu(&a[i+6*PacketSize]), internal::ploadu(&b[i+6*PacketSize])));
+ internal::pstore(&a[i+7*PacketSize], internal::padd(internal::ploadu(&a[i+7*PacketSize]), internal::ploadu(&b[i+7*PacketSize])));
+ }
+}
diff --git a/eigen/bench/bench_gemm.cpp b/eigen/bench/bench_gemm.cpp
new file mode 100644
index 0000000..41ca8b3
--- /dev/null
+++ b/eigen/bench/bench_gemm.cpp
@@ -0,0 +1,271 @@
+
+// g++-4.4 bench_gemm.cpp -I .. -O2 -DNDEBUG -lrt -fopenmp && OMP_NUM_THREADS=2 ./a.out
+// icpc bench_gemm.cpp -I .. -O3 -DNDEBUG -lrt -openmp && OMP_NUM_THREADS=2 ./a.out
+
+#include <iostream>
+#include <Eigen/Core>
+#include <bench/BenchTimer.h>
+
+using namespace std;
+using namespace Eigen;
+
+#ifndef SCALAR
+// #define SCALAR std::complex<float>
+#define SCALAR float
+#endif
+
+typedef SCALAR Scalar;
+typedef NumTraits<Scalar>::Real RealScalar;
+typedef Matrix<RealScalar,Dynamic,Dynamic> A;
+typedef Matrix</*Real*/Scalar,Dynamic,Dynamic> B;
+typedef Matrix<Scalar,Dynamic,Dynamic> C;
+typedef Matrix<RealScalar,Dynamic,Dynamic> M;
+
+#ifdef HAVE_BLAS
+
+extern "C" {
+ #include <Eigen/src/misc/blas.h>
+}
+
+static float fone = 1;
+static float fzero = 0;
+static double done = 1;
+static double szero = 0;
+static std::complex<float> cfone = 1;
+static std::complex<float> cfzero = 0;
+static std::complex<double> cdone = 1;
+static std::complex<double> cdzero = 0;
+static char notrans = 'N';
+static char trans = 'T';
+static char nonunit = 'N';
+static char lower = 'L';
+static char right = 'R';
+static int intone = 1;
+
+void blas_gemm(const MatrixXf& a, const MatrixXf& b, MatrixXf& c)
+{
+ int M = c.rows(); int N = c.cols(); int K = a.cols();
+ int lda = a.rows(); int ldb = b.rows(); int ldc = c.rows();
+
+ sgemm_(&notrans,&notrans,&M,&N,&K,&fone,
+ const_cast<float*>(a.data()),&lda,
+ const_cast<float*>(b.data()),&ldb,&fone,
+ c.data(),&ldc);
+}
+
+EIGEN_DONT_INLINE void blas_gemm(const MatrixXd& a, const MatrixXd& b, MatrixXd& c)
+{
+ int M = c.rows(); int N = c.cols(); int K = a.cols();
+ int lda = a.rows(); int ldb = b.rows(); int ldc = c.rows();
+
+ dgemm_(&notrans,&notrans,&M,&N,&K,&done,
+ const_cast<double*>(a.data()),&lda,
+ const_cast<double*>(b.data()),&ldb,&done,
+ c.data(),&ldc);
+}
+
+void blas_gemm(const MatrixXcf& a, const MatrixXcf& b, MatrixXcf& c)
+{
+ int M = c.rows(); int N = c.cols(); int K = a.cols();
+ int lda = a.rows(); int ldb = b.rows(); int ldc = c.rows();
+
+ cgemm_(&notrans,&notrans,&M,&N,&K,(float*)&cfone,
+ const_cast<float*>((const float*)a.data()),&lda,
+ const_cast<float*>((const float*)b.data()),&ldb,(float*)&cfone,
+ (float*)c.data(),&ldc);
+}
+
+void blas_gemm(const MatrixXcd& a, const MatrixXcd& b, MatrixXcd& c)
+{
+ int M = c.rows(); int N = c.cols(); int K = a.cols();
+ int lda = a.rows(); int ldb = b.rows(); int ldc = c.rows();
+
+ zgemm_(&notrans,&notrans,&M,&N,&K,(double*)&cdone,
+ const_cast<double*>((const double*)a.data()),&lda,
+ const_cast<double*>((const double*)b.data()),&ldb,(double*)&cdone,
+ (double*)c.data(),&ldc);
+}
+
+
+
+#endif
+
+void matlab_cplx_cplx(const M& ar, const M& ai, const M& br, const M& bi, M& cr, M& ci)
+{
+ cr.noalias() += ar * br;
+ cr.noalias() -= ai * bi;
+ ci.noalias() += ar * bi;
+ ci.noalias() += ai * br;
+}
+
+void matlab_real_cplx(const M& a, const M& br, const M& bi, M& cr, M& ci)
+{
+ cr.noalias() += a * br;
+ ci.noalias() += a * bi;
+}
+
+void matlab_cplx_real(const M& ar, const M& ai, const M& b, M& cr, M& ci)
+{
+ cr.noalias() += ar * b;
+ ci.noalias() += ai * b;
+}
+
+template<typename A, typename B, typename C>
+EIGEN_DONT_INLINE void gemm(const A& a, const B& b, C& c)
+{
+ c.noalias() += a * b;
+}
+
+int main(int argc, char ** argv)
+{
+ std::ptrdiff_t l1 = internal::queryL1CacheSize();
+ std::ptrdiff_t l2 = internal::queryTopLevelCacheSize();
+ std::cout << "L1 cache size = " << (l1>0 ? l1/1024 : -1) << " KB\n";
+ std::cout << "L2/L3 cache size = " << (l2>0 ? l2/1024 : -1) << " KB\n";
+ typedef internal::gebp_traits<Scalar,Scalar> Traits;
+ std::cout << "Register blocking = " << Traits::mr << " x " << Traits::nr << "\n";
+
+ int rep = 1; // number of repetitions per try
+ int tries = 2; // number of tries, we keep the best
+
+ int s = 2048;
+ int cache_size = -1;
+
+ bool need_help = false;
+ for (int i=1; i<argc; ++i)
+ {
+ if(argv[i][0]=='s')
+ s = atoi(argv[i]+1);
+ else if(argv[i][0]=='c')
+ cache_size = atoi(argv[i]+1);
+ else if(argv[i][0]=='t')
+ tries = atoi(argv[i]+1);
+ else if(argv[i][0]=='p')
+ rep = atoi(argv[i]+1);
+ else
+ need_help = true;
+ }
+
+ if(need_help)
+ {
+ std::cout << argv[0] << " s<matrix size> c<cache size> t<nb tries> p<nb repeats>\n";
+ return 1;
+ }
+
+ if(cache_size>0)
+ setCpuCacheSizes(cache_size,96*cache_size);
+
+ int m = s;
+ int n = s;
+ int p = s;
+ A a(m,p); a.setRandom();
+ B b(p,n); b.setRandom();
+ C c(m,n); c.setOnes();
+ C rc = c;
+
+ std::cout << "Matrix sizes = " << m << "x" << p << " * " << p << "x" << n << "\n";
+ std::ptrdiff_t mc(m), nc(n), kc(p);
+ internal::computeProductBlockingSizes<Scalar,Scalar>(kc, mc, nc);
+ std::cout << "blocking size (mc x kc) = " << mc << " x " << kc << "\n";
+
+ C r = c;
+
+ // check the parallel product is correct
+ #if defined EIGEN_HAS_OPENMP
+ int procs = omp_get_max_threads();
+ if(procs>1)
+ {
+ #ifdef HAVE_BLAS
+ blas_gemm(a,b,r);
+ #else
+ omp_set_num_threads(1);
+ r.noalias() += a * b;
+ omp_set_num_threads(procs);
+ #endif
+ c.noalias() += a * b;
+ if(!r.isApprox(c)) std::cerr << "Warning, your parallel product is crap!\n\n";
+ }
+ #elif defined HAVE_BLAS
+ blas_gemm(a,b,r);
+ c.noalias() += a * b;
+ if(!r.isApprox(c)) std::cerr << "Warning, your product is crap!\n\n";
+ #else
+ gemm(a,b,c);
+ r.noalias() += a.cast<Scalar>() * b.cast<Scalar>();
+ if(!r.isApprox(c)) std::cerr << "Warning, your product is crap!\n\n";
+ #endif
+
+ #ifdef HAVE_BLAS
+ BenchTimer tblas;
+ c = rc;
+ BENCH(tblas, tries, rep, blas_gemm(a,b,c));
+ std::cout << "blas cpu " << tblas.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tblas.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << tblas.total(CPU_TIMER) << "s)\n";
+ std::cout << "blas real " << tblas.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tblas.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << tblas.total(REAL_TIMER) << "s)\n";
+ #endif
+
+ BenchTimer tmt;
+ c = rc;
+ BENCH(tmt, tries, rep, gemm(a,b,c));
+ std::cout << "eigen cpu " << tmt.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tmt.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << tmt.total(CPU_TIMER) << "s)\n";
+ std::cout << "eigen real " << tmt.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tmt.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << tmt.total(REAL_TIMER) << "s)\n";
+
+ #ifdef EIGEN_HAS_OPENMP
+ if(procs>1)
+ {
+ BenchTimer tmono;
+ omp_set_num_threads(1);
+ Eigen::internal::setNbThreads(1);
+ c = rc;
+ BENCH(tmono, tries, rep, gemm(a,b,c));
+ std::cout << "eigen mono cpu " << tmono.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tmono.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << tmono.total(CPU_TIMER) << "s)\n";
+ std::cout << "eigen mono real " << tmono.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tmono.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << tmono.total(REAL_TIMER) << "s)\n";
+ std::cout << "mt speed up x" << tmono.best(CPU_TIMER) / tmt.best(REAL_TIMER) << " => " << (100.0*tmono.best(CPU_TIMER) / tmt.best(REAL_TIMER))/procs << "%\n";
+ }
+ #endif
+
+ #ifdef DECOUPLED
+ if((NumTraits<A::Scalar>::IsComplex) && (NumTraits<B::Scalar>::IsComplex))
+ {
+ M ar(m,p); ar.setRandom();
+ M ai(m,p); ai.setRandom();
+ M br(p,n); br.setRandom();
+ M bi(p,n); bi.setRandom();
+ M cr(m,n); cr.setRandom();
+ M ci(m,n); ci.setRandom();
+
+ BenchTimer t;
+ BENCH(t, tries, rep, matlab_cplx_cplx(ar,ai,br,bi,cr,ci));
+ std::cout << "\"matlab\" cpu " << t.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << t.total(CPU_TIMER) << "s)\n";
+ std::cout << "\"matlab\" real " << t.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << t.total(REAL_TIMER) << "s)\n";
+ }
+ if((!NumTraits<A::Scalar>::IsComplex) && (NumTraits<B::Scalar>::IsComplex))
+ {
+ M a(m,p); a.setRandom();
+ M br(p,n); br.setRandom();
+ M bi(p,n); bi.setRandom();
+ M cr(m,n); cr.setRandom();
+ M ci(m,n); ci.setRandom();
+
+ BenchTimer t;
+ BENCH(t, tries, rep, matlab_real_cplx(a,br,bi,cr,ci));
+ std::cout << "\"matlab\" cpu " << t.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << t.total(CPU_TIMER) << "s)\n";
+ std::cout << "\"matlab\" real " << t.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << t.total(REAL_TIMER) << "s)\n";
+ }
+ if((NumTraits<A::Scalar>::IsComplex) && (!NumTraits<B::Scalar>::IsComplex))
+ {
+ M ar(m,p); ar.setRandom();
+ M ai(m,p); ai.setRandom();
+ M b(p,n); b.setRandom();
+ M cr(m,n); cr.setRandom();
+ M ci(m,n); ci.setRandom();
+
+ BenchTimer t;
+ BENCH(t, tries, rep, matlab_cplx_real(ar,ai,b,cr,ci));
+ std::cout << "\"matlab\" cpu " << t.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << t.total(CPU_TIMER) << "s)\n";
+ std::cout << "\"matlab\" real " << t.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << t.total(REAL_TIMER) << "s)\n";
+ }
+ #endif
+
+ return 0;
+}
+
diff --git a/eigen/bench/bench_multi_compilers.sh b/eigen/bench/bench_multi_compilers.sh
new file mode 100644
index 0000000..27e91f1
--- /dev/null
+++ b/eigen/bench/bench_multi_compilers.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+if (($# < 2)); then
+ echo "Usage: $0 compilerlist.txt benchfile.cpp"
+else
+
+compilerlist=$1
+benchfile=$2
+
+g=0
+source $compilerlist
+
+# for each compiler, compile benchfile and run the benchmark
+for (( i=0 ; i<g ; ++i )) ; do
+ # check the compiler exists
+ compiler=`echo ${CLIST[$i]} | cut -d " " -f 1`
+ if [ -e `which $compiler` ]; then
+ echo "${CLIST[$i]}"
+# echo "${CLIST[$i]} $benchfile -I.. -o bench~"
+# if [ -e ./.bench ] ; then rm .bench; fi
+ ${CLIST[$i]} $benchfile -I.. -o .bench && ./.bench 2> /dev/null
+ echo ""
+ else
+ echo "compiler not found: $compiler"
+ fi
+done
+
+fi
diff --git a/eigen/bench/bench_norm.cpp b/eigen/bench/bench_norm.cpp
new file mode 100644
index 0000000..806db29
--- /dev/null
+++ b/eigen/bench/bench_norm.cpp
@@ -0,0 +1,345 @@
+#include <typeinfo>
+#include <iostream>
+#include <Eigen/Core>
+#include "BenchTimer.h"
+using namespace Eigen;
+using namespace std;
+
+template<typename T>
+EIGEN_DONT_INLINE typename T::Scalar sqsumNorm(const T& v)
+{
+ return v.norm();
+}
+
+template<typename T>
+EIGEN_DONT_INLINE typename T::Scalar hypotNorm(const T& v)
+{
+ return v.hypotNorm();
+}
+
+template<typename T>
+EIGEN_DONT_INLINE typename T::Scalar blueNorm(const T& v)
+{
+ return v.blueNorm();
+}
+
+template<typename T>
+EIGEN_DONT_INLINE typename T::Scalar lapackNorm(T& v)
+{
+ typedef typename T::Scalar Scalar;
+ int n = v.size();
+ Scalar scale = 0;
+ Scalar ssq = 1;
+ for (int i=0;i<n;++i)
+ {
+ Scalar ax = internal::abs(v.coeff(i));
+ if (scale >= ax)
+ {
+ ssq += internal::abs2(ax/scale);
+ }
+ else
+ {
+ ssq = Scalar(1) + ssq * internal::abs2(scale/ax);
+ scale = ax;
+ }
+ }
+ return scale * internal::sqrt(ssq);
+}
+
+template<typename T>
+EIGEN_DONT_INLINE typename T::Scalar twopassNorm(T& v)
+{
+ typedef typename T::Scalar Scalar;
+ Scalar s = v.cwise().abs().maxCoeff();
+ return s*(v/s).norm();
+}
+
+template<typename T>
+EIGEN_DONT_INLINE typename T::Scalar bl2passNorm(T& v)
+{
+ return v.stableNorm();
+}
+
+template<typename T>
+EIGEN_DONT_INLINE typename T::Scalar divacNorm(T& v)
+{
+ int n =v.size() / 2;
+ for (int i=0;i<n;++i)
+ v(i) = v(2*i)*v(2*i) + v(2*i+1)*v(2*i+1);
+ n = n/2;
+ while (n>0)
+ {
+ for (int i=0;i<n;++i)
+ v(i) = v(2*i) + v(2*i+1);
+ n = n/2;
+ }
+ return internal::sqrt(v(0));
+}
+
+#ifdef EIGEN_VECTORIZE
+Packet4f internal::plt(const Packet4f& a, Packet4f& b) { return _mm_cmplt_ps(a,b); }
+Packet2d internal::plt(const Packet2d& a, Packet2d& b) { return _mm_cmplt_pd(a,b); }
+
+Packet4f internal::pandnot(const Packet4f& a, Packet4f& b) { return _mm_andnot_ps(a,b); }
+Packet2d internal::pandnot(const Packet2d& a, Packet2d& b) { return _mm_andnot_pd(a,b); }
+#endif
+
+template<typename T>
+EIGEN_DONT_INLINE typename T::Scalar pblueNorm(const T& v)
+{
+ #ifndef EIGEN_VECTORIZE
+ return v.blueNorm();
+ #else
+ typedef typename T::Scalar Scalar;
+
+ static int nmax = 0;
+ static Scalar b1, b2, s1m, s2m, overfl, rbig, relerr;
+ int n;
+
+ if(nmax <= 0)
+ {
+ int nbig, ibeta, it, iemin, iemax, iexp;
+ Scalar abig, eps;
+
+ nbig = std::numeric_limits<int>::max(); // largest integer
+ ibeta = std::numeric_limits<Scalar>::radix; //NumTraits<Scalar>::Base; // base for floating-point numbers
+ it = std::numeric_limits<Scalar>::digits; //NumTraits<Scalar>::Mantissa; // number of base-beta digits in mantissa
+ iemin = std::numeric_limits<Scalar>::min_exponent; // minimum exponent
+ iemax = std::numeric_limits<Scalar>::max_exponent; // maximum exponent
+ rbig = std::numeric_limits<Scalar>::max(); // largest floating-point number
+
+ // Check the basic machine-dependent constants.
+ if(iemin > 1 - 2*it || 1+it>iemax || (it==2 && ibeta<5)
+ || (it<=4 && ibeta <= 3 ) || it<2)
+ {
+ eigen_assert(false && "the algorithm cannot be guaranteed on this computer");
+ }
+ iexp = -((1-iemin)/2);
+ b1 = std::pow(ibeta, iexp); // lower boundary of midrange
+ iexp = (iemax + 1 - it)/2;
+ b2 = std::pow(ibeta,iexp); // upper boundary of midrange
+
+ iexp = (2-iemin)/2;
+ s1m = std::pow(ibeta,iexp); // scaling factor for lower range
+ iexp = - ((iemax+it)/2);
+ s2m = std::pow(ibeta,iexp); // scaling factor for upper range
+
+ overfl = rbig*s2m; // overfow boundary for abig
+ eps = std::pow(ibeta, 1-it);
+ relerr = internal::sqrt(eps); // tolerance for neglecting asml
+ abig = 1.0/eps - 1.0;
+ if (Scalar(nbig)>abig) nmax = abig; // largest safe n
+ else nmax = nbig;
+ }
+
+ typedef typename internal::packet_traits<Scalar>::type Packet;
+ const int ps = internal::packet_traits<Scalar>::size;
+ Packet pasml = internal::pset1(Scalar(0));
+ Packet pamed = internal::pset1(Scalar(0));
+ Packet pabig = internal::pset1(Scalar(0));
+ Packet ps2m = internal::pset1(s2m);
+ Packet ps1m = internal::pset1(s1m);
+ Packet pb2 = internal::pset1(b2);
+ Packet pb1 = internal::pset1(b1);
+ for(int j=0; j<v.size(); j+=ps)
+ {
+ Packet ax = internal::pabs(v.template packet<Aligned>(j));
+ Packet ax_s2m = internal::pmul(ax,ps2m);
+ Packet ax_s1m = internal::pmul(ax,ps1m);
+ Packet maskBig = internal::plt(pb2,ax);
+ Packet maskSml = internal::plt(ax,pb1);
+
+// Packet maskMed = internal::pand(maskSml,maskBig);
+// Packet scale = internal::pset1(Scalar(0));
+// scale = internal::por(scale, internal::pand(maskBig,ps2m));
+// scale = internal::por(scale, internal::pand(maskSml,ps1m));
+// scale = internal::por(scale, internal::pandnot(internal::pset1(Scalar(1)),maskMed));
+// ax = internal::pmul(ax,scale);
+// ax = internal::pmul(ax,ax);
+// pabig = internal::padd(pabig, internal::pand(maskBig, ax));
+// pasml = internal::padd(pasml, internal::pand(maskSml, ax));
+// pamed = internal::padd(pamed, internal::pandnot(ax,maskMed));
+
+
+ pabig = internal::padd(pabig, internal::pand(maskBig, internal::pmul(ax_s2m,ax_s2m)));
+ pasml = internal::padd(pasml, internal::pand(maskSml, internal::pmul(ax_s1m,ax_s1m)));
+ pamed = internal::padd(pamed, internal::pandnot(internal::pmul(ax,ax),internal::pand(maskSml,maskBig)));
+ }
+ Scalar abig = internal::predux(pabig);
+ Scalar asml = internal::predux(pasml);
+ Scalar amed = internal::predux(pamed);
+ if(abig > Scalar(0))
+ {
+ abig = internal::sqrt(abig);
+ if(abig > overfl)
+ {
+ eigen_assert(false && "overflow");
+ return rbig;
+ }
+ if(amed > Scalar(0))
+ {
+ abig = abig/s2m;
+ amed = internal::sqrt(amed);
+ }
+ else
+ {
+ return abig/s2m;
+ }
+
+ }
+ else if(asml > Scalar(0))
+ {
+ if (amed > Scalar(0))
+ {
+ abig = internal::sqrt(amed);
+ amed = internal::sqrt(asml) / s1m;
+ }
+ else
+ {
+ return internal::sqrt(asml)/s1m;
+ }
+ }
+ else
+ {
+ return internal::sqrt(amed);
+ }
+ asml = std::min(abig, amed);
+ abig = std::max(abig, amed);
+ if(asml <= abig*relerr)
+ return abig;
+ else
+ return abig * internal::sqrt(Scalar(1) + internal::abs2(asml/abig));
+ #endif
+}
+
+#define BENCH_PERF(NRM) { \
+ Eigen::BenchTimer tf, td, tcf; tf.reset(); td.reset(); tcf.reset();\
+ for (int k=0; k<tries; ++k) { \
+ tf.start(); \
+ for (int i=0; i<iters; ++i) NRM(vf); \
+ tf.stop(); \
+ } \
+ for (int k=0; k<tries; ++k) { \
+ td.start(); \
+ for (int i=0; i<iters; ++i) NRM(vd); \
+ td.stop(); \
+ } \
+ for (int k=0; k<std::max(1,tries/3); ++k) { \
+ tcf.start(); \
+ for (int i=0; i<iters; ++i) NRM(vcf); \
+ tcf.stop(); \
+ } \
+ std::cout << #NRM << "\t" << tf.value() << " " << td.value() << " " << tcf.value() << "\n"; \
+}
+
+void check_accuracy(double basef, double based, int s)
+{
+ double yf = basef * internal::abs(internal::random<double>());
+ double yd = based * internal::abs(internal::random<double>());
+ VectorXf vf = VectorXf::Ones(s) * yf;
+ VectorXd vd = VectorXd::Ones(s) * yd;
+
+ std::cout << "reference\t" << internal::sqrt(double(s))*yf << "\t" << internal::sqrt(double(s))*yd << "\n";
+ std::cout << "sqsumNorm\t" << sqsumNorm(vf) << "\t" << sqsumNorm(vd) << "\n";
+ std::cout << "hypotNorm\t" << hypotNorm(vf) << "\t" << hypotNorm(vd) << "\n";
+ std::cout << "blueNorm\t" << blueNorm(vf) << "\t" << blueNorm(vd) << "\n";
+ std::cout << "pblueNorm\t" << pblueNorm(vf) << "\t" << pblueNorm(vd) << "\n";
+ std::cout << "lapackNorm\t" << lapackNorm(vf) << "\t" << lapackNorm(vd) << "\n";
+ std::cout << "twopassNorm\t" << twopassNorm(vf) << "\t" << twopassNorm(vd) << "\n";
+ std::cout << "bl2passNorm\t" << bl2passNorm(vf) << "\t" << bl2passNorm(vd) << "\n";
+}
+
+void check_accuracy_var(int ef0, int ef1, int ed0, int ed1, int s)
+{
+ VectorXf vf(s);
+ VectorXd vd(s);
+ for (int i=0; i<s; ++i)
+ {
+ vf[i] = internal::abs(internal::random<double>()) * std::pow(double(10), internal::random<int>(ef0,ef1));
+ vd[i] = internal::abs(internal::random<double>()) * std::pow(double(10), internal::random<int>(ed0,ed1));
+ }
+
+ //std::cout << "reference\t" << internal::sqrt(double(s))*yf << "\t" << internal::sqrt(double(s))*yd << "\n";
+ std::cout << "sqsumNorm\t" << sqsumNorm(vf) << "\t" << sqsumNorm(vd) << "\t" << sqsumNorm(vf.cast<long double>()) << "\t" << sqsumNorm(vd.cast<long double>()) << "\n";
+ std::cout << "hypotNorm\t" << hypotNorm(vf) << "\t" << hypotNorm(vd) << "\t" << hypotNorm(vf.cast<long double>()) << "\t" << hypotNorm(vd.cast<long double>()) << "\n";
+ std::cout << "blueNorm\t" << blueNorm(vf) << "\t" << blueNorm(vd) << "\t" << blueNorm(vf.cast<long double>()) << "\t" << blueNorm(vd.cast<long double>()) << "\n";
+ std::cout << "pblueNorm\t" << pblueNorm(vf) << "\t" << pblueNorm(vd) << "\t" << blueNorm(vf.cast<long double>()) << "\t" << blueNorm(vd.cast<long double>()) << "\n";
+ std::cout << "lapackNorm\t" << lapackNorm(vf) << "\t" << lapackNorm(vd) << "\t" << lapackNorm(vf.cast<long double>()) << "\t" << lapackNorm(vd.cast<long double>()) << "\n";
+ std::cout << "twopassNorm\t" << twopassNorm(vf) << "\t" << twopassNorm(vd) << "\t" << twopassNorm(vf.cast<long double>()) << "\t" << twopassNorm(vd.cast<long double>()) << "\n";
+// std::cout << "bl2passNorm\t" << bl2passNorm(vf) << "\t" << bl2passNorm(vd) << "\t" << bl2passNorm(vf.cast<long double>()) << "\t" << bl2passNorm(vd.cast<long double>()) << "\n";
+}
+
+int main(int argc, char** argv)
+{
+ int tries = 10;
+ int iters = 100000;
+ double y = 1.1345743233455785456788e12 * internal::random<double>();
+ VectorXf v = VectorXf::Ones(1024) * y;
+
+// return 0;
+ int s = 10000;
+ double basef_ok = 1.1345743233455785456788e15;
+ double based_ok = 1.1345743233455785456788e95;
+
+ double basef_under = 1.1345743233455785456788e-27;
+ double based_under = 1.1345743233455785456788e-303;
+
+ double basef_over = 1.1345743233455785456788e+27;
+ double based_over = 1.1345743233455785456788e+302;
+
+ std::cout.precision(20);
+
+ std::cerr << "\nNo under/overflow:\n";
+ check_accuracy(basef_ok, based_ok, s);
+
+ std::cerr << "\nUnderflow:\n";
+ check_accuracy(basef_under, based_under, s);
+
+ std::cerr << "\nOverflow:\n";
+ check_accuracy(basef_over, based_over, s);
+
+ std::cerr << "\nVarying (over):\n";
+ for (int k=0; k<1; ++k)
+ {
+ check_accuracy_var(20,27,190,302,s);
+ std::cout << "\n";
+ }
+
+ std::cerr << "\nVarying (under):\n";
+ for (int k=0; k<1; ++k)
+ {
+ check_accuracy_var(-27,20,-302,-190,s);
+ std::cout << "\n";
+ }
+
+ std::cout.precision(4);
+ std::cerr << "Performance (out of cache):\n";
+ {
+ int iters = 1;
+ VectorXf vf = VectorXf::Random(1024*1024*32) * y;
+ VectorXd vd = VectorXd::Random(1024*1024*32) * y;
+ VectorXcf vcf = VectorXcf::Random(1024*1024*32) * y;
+ BENCH_PERF(sqsumNorm);
+ BENCH_PERF(blueNorm);
+// BENCH_PERF(pblueNorm);
+// BENCH_PERF(lapackNorm);
+// BENCH_PERF(hypotNorm);
+// BENCH_PERF(twopassNorm);
+ BENCH_PERF(bl2passNorm);
+ }
+
+ std::cerr << "\nPerformance (in cache):\n";
+ {
+ int iters = 100000;
+ VectorXf vf = VectorXf::Random(512) * y;
+ VectorXd vd = VectorXd::Random(512) * y;
+ VectorXcf vcf = VectorXcf::Random(512) * y;
+ BENCH_PERF(sqsumNorm);
+ BENCH_PERF(blueNorm);
+// BENCH_PERF(pblueNorm);
+// BENCH_PERF(lapackNorm);
+// BENCH_PERF(hypotNorm);
+// BENCH_PERF(twopassNorm);
+ BENCH_PERF(bl2passNorm);
+ }
+}
diff --git a/eigen/bench/bench_reverse.cpp b/eigen/bench/bench_reverse.cpp
new file mode 100644
index 0000000..1e69ca1
--- /dev/null
+++ b/eigen/bench/bench_reverse.cpp
@@ -0,0 +1,84 @@
+
+#include <iostream>
+#include <Eigen/Core>
+#include <bench/BenchUtil.h>
+using namespace Eigen;
+
+#ifndef REPEAT
+#define REPEAT 100000
+#endif
+
+#ifndef TRIES
+#define TRIES 20
+#endif
+
+typedef double Scalar;
+
+template <typename MatrixType>
+__attribute__ ((noinline)) void bench_reverse(const MatrixType& m)
+{
+ int rows = m.rows();
+ int cols = m.cols();
+ int size = m.size();
+
+ int repeats = (REPEAT*1000)/size;
+ MatrixType a = MatrixType::Random(rows,cols);
+ MatrixType b = MatrixType::Random(rows,cols);
+
+ BenchTimer timerB, timerH, timerV;
+
+ Scalar acc = 0;
+ int r = internal::random<int>(0,rows-1);
+ int c = internal::random<int>(0,cols-1);
+ for (int t=0; t<TRIES; ++t)
+ {
+ timerB.start();
+ for (int k=0; k<repeats; ++k)
+ {
+ asm("#begin foo");
+ b = a.reverse();
+ asm("#end foo");
+ acc += b.coeff(r,c);
+ }
+ timerB.stop();
+ }
+
+ if (MatrixType::RowsAtCompileTime==Dynamic)
+ std::cout << "dyn ";
+ else
+ std::cout << "fixed ";
+ std::cout << rows << " x " << cols << " \t"
+ << (timerB.value() * REPEAT) / repeats << "s "
+ << "(" << 1e-6 * size*repeats/timerB.value() << " MFLOPS)\t";
+
+ std::cout << "\n";
+ // make sure the compiler does not optimize too much
+ if (acc==123)
+ std::cout << acc;
+}
+
+int main(int argc, char* argv[])
+{
+ const int dynsizes[] = {4,6,8,16,24,32,49,64,128,256,512,900,0};
+ std::cout << "size no sqrt standard";
+// #ifdef BENCH_GSL
+// std::cout << " GSL (standard + double + ATLAS) ";
+// #endif
+ std::cout << "\n";
+ for (uint i=0; dynsizes[i]>0; ++i)
+ {
+ bench_reverse(Matrix<Scalar,Dynamic,Dynamic>(dynsizes[i],dynsizes[i]));
+ bench_reverse(Matrix<Scalar,Dynamic,1>(dynsizes[i]*dynsizes[i]));
+ }
+// bench_reverse(Matrix<Scalar,2,2>());
+// bench_reverse(Matrix<Scalar,3,3>());
+// bench_reverse(Matrix<Scalar,4,4>());
+// bench_reverse(Matrix<Scalar,5,5>());
+// bench_reverse(Matrix<Scalar,6,6>());
+// bench_reverse(Matrix<Scalar,7,7>());
+// bench_reverse(Matrix<Scalar,8,8>());
+// bench_reverse(Matrix<Scalar,12,12>());
+// bench_reverse(Matrix<Scalar,16,16>());
+ return 0;
+}
+
diff --git a/eigen/bench/bench_sum.cpp b/eigen/bench/bench_sum.cpp
new file mode 100644
index 0000000..a3d925e
--- /dev/null
+++ b/eigen/bench/bench_sum.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <Eigen/Core>
+using namespace Eigen;
+using namespace std;
+
+int main()
+{
+ typedef Matrix<SCALAR,Eigen::Dynamic,1> Vec;
+ Vec v(SIZE);
+ v.setZero();
+ v[0] = 1;
+ v[1] = 2;
+ for(int i = 0; i < 1000000; i++)
+ {
+ v.coeffRef(0) += v.sum() * SCALAR(1e-20);
+ }
+ cout << v.sum() << endl;
+}
diff --git a/eigen/bench/bench_unrolling b/eigen/bench/bench_unrolling
new file mode 100644
index 0000000..8264438
--- /dev/null
+++ b/eigen/bench/bench_unrolling
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# gcc : CXX="g++ -finline-limit=10000 -ftemplate-depth-2000 --param max-inline-recursive-depth=2000"
+# icc : CXX="icpc -fast -no-inline-max-size -fno-exceptions"
+CXX=${CXX-g++ -finline-limit=10000 -ftemplate-depth-2000 --param max-inline-recursive-depth=2000} # default value
+
+for ((i=1; i<16; ++i)); do
+ echo "Matrix size: $i x $i :"
+ $CXX -O3 -I.. -DNDEBUG benchmark.cpp -DMATSIZE=$i -DEIGEN_UNROLLING_LIMIT=400 -o benchmark && time ./benchmark >/dev/null
+ $CXX -O3 -I.. -DNDEBUG -finline-limit=10000 benchmark.cpp -DMATSIZE=$i -DEIGEN_DONT_USE_UNROLLED_LOOPS=1 -o benchmark && time ./benchmark >/dev/null
+ echo " "
+done
diff --git a/eigen/bench/benchmark.cpp b/eigen/bench/benchmark.cpp
new file mode 100644
index 0000000..c721b90
--- /dev/null
+++ b/eigen/bench/benchmark.cpp
@@ -0,0 +1,39 @@
+// g++ -O3 -DNDEBUG -DMATSIZE=<x> benchmark.cpp -o benchmark && time ./benchmark
+
+#include <iostream>
+
+#include <Eigen/Core>
+
+#ifndef MATSIZE
+#define MATSIZE 3
+#endif
+
+using namespace std;
+using namespace Eigen;
+
+#ifndef REPEAT
+#define REPEAT 40000000
+#endif
+
+#ifndef SCALAR
+#define SCALAR double
+#endif
+
+int main(int argc, char *argv[])
+{
+ Matrix<SCALAR,MATSIZE,MATSIZE> I = Matrix<SCALAR,MATSIZE,MATSIZE>::Ones();
+ Matrix<SCALAR,MATSIZE,MATSIZE> m;
+ for(int i = 0; i < MATSIZE; i++)
+ for(int j = 0; j < MATSIZE; j++)
+ {
+ m(i,j) = (i+MATSIZE*j);
+ }
+ asm("#begin");
+ for(int a = 0; a < REPEAT; a++)
+ {
+ m = Matrix<SCALAR,MATSIZE,MATSIZE>::Ones() + 0.00005 * (m + (m*m));
+ }
+ asm("#end");
+ cout << m << endl;
+ return 0;
+}
diff --git a/eigen/bench/benchmarkSlice.cpp b/eigen/bench/benchmarkSlice.cpp
new file mode 100644
index 0000000..c5b89c5
--- /dev/null
+++ b/eigen/bench/benchmarkSlice.cpp
@@ -0,0 +1,38 @@
+// g++ -O3 -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX
+
+#include <iostream>
+
+#include <Eigen/Core>
+
+using namespace std;
+using namespace Eigen;
+
+#ifndef REPEAT
+#define REPEAT 10000
+#endif
+
+#ifndef SCALAR
+#define SCALAR float
+#endif
+
+int main(int argc, char *argv[])
+{
+ typedef Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> Mat;
+ Mat m(100, 100);
+ m.setRandom();
+
+ for(int a = 0; a < REPEAT; a++)
+ {
+ int r, c, nr, nc;
+ r = Eigen::internal::random<int>(0,10);
+ c = Eigen::internal::random<int>(0,10);
+ nr = Eigen::internal::random<int>(50,80);
+ nc = Eigen::internal::random<int>(50,80);
+ m.block(r,c,nr,nc) += Mat::Ones(nr,nc);
+ m.block(r,c,nr,nc) *= SCALAR(10);
+ m.block(r,c,nr,nc) -= Mat::constant(nr,nc,10);
+ m.block(r,c,nr,nc) /= SCALAR(10);
+ }
+ cout << m[0] << endl;
+ return 0;
+}
diff --git a/eigen/bench/benchmarkX.cpp b/eigen/bench/benchmarkX.cpp
new file mode 100644
index 0000000..8e4b60c
--- /dev/null
+++ b/eigen/bench/benchmarkX.cpp
@@ -0,0 +1,36 @@
+// g++ -fopenmp -I .. -O3 -DNDEBUG -finline-limit=1000 benchmarkX.cpp -o b && time ./b
+
+#include <iostream>
+
+#include <Eigen/Core>
+
+using namespace std;
+using namespace Eigen;
+
+#ifndef MATTYPE
+#define MATTYPE MatrixXLd
+#endif
+
+#ifndef MATSIZE
+#define MATSIZE 400
+#endif
+
+#ifndef REPEAT
+#define REPEAT 100
+#endif
+
+int main(int argc, char *argv[])
+{
+ MATTYPE I = MATTYPE::Ones(MATSIZE,MATSIZE);
+ MATTYPE m(MATSIZE,MATSIZE);
+ for(int i = 0; i < MATSIZE; i++) for(int j = 0; j < MATSIZE; j++)
+ {
+ m(i,j) = (i+j+1)/(MATSIZE*MATSIZE);
+ }
+ for(int a = 0; a < REPEAT; a++)
+ {
+ m = I + 0.0001 * (m + m*m);
+ }
+ cout << m(0,0) << endl;
+ return 0;
+}
diff --git a/eigen/bench/benchmarkXcwise.cpp b/eigen/bench/benchmarkXcwise.cpp
new file mode 100644
index 0000000..6243743
--- /dev/null
+++ b/eigen/bench/benchmarkXcwise.cpp
@@ -0,0 +1,35 @@
+// g++ -O3 -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX
+
+#include <iostream>
+#include <Eigen/Core>
+
+using namespace std;
+using namespace Eigen;
+
+#ifndef VECTYPE
+#define VECTYPE VectorXLd
+#endif
+
+#ifndef VECSIZE
+#define VECSIZE 1000000
+#endif
+
+#ifndef REPEAT
+#define REPEAT 1000
+#endif
+
+int main(int argc, char *argv[])
+{
+ VECTYPE I = VECTYPE::Ones(VECSIZE);
+ VECTYPE m(VECSIZE,1);
+ for(int i = 0; i < VECSIZE; i++)
+ {
+ m[i] = 0.1 * i/VECSIZE;
+ }
+ for(int a = 0; a < REPEAT; a++)
+ {
+ m = VECTYPE::Ones(VECSIZE) + 0.00005 * (m.cwise().square() + m/4);
+ }
+ cout << m[0] << endl;
+ return 0;
+}
diff --git a/eigen/bench/benchmark_suite b/eigen/bench/benchmark_suite
new file mode 100644
index 0000000..3f21d36
--- /dev/null
+++ b/eigen/bench/benchmark_suite
@@ -0,0 +1,18 @@
+#!/bin/bash
+CXX=${CXX-g++} # default value unless caller has defined CXX
+echo "Fixed size 3x3, column-major, -DNDEBUG"
+$CXX -O3 -I .. -DNDEBUG benchmark.cpp -o benchmark && time ./benchmark >/dev/null
+echo "Fixed size 3x3, column-major, with asserts"
+$CXX -O3 -I .. benchmark.cpp -o benchmark && time ./benchmark >/dev/null
+echo "Fixed size 3x3, row-major, -DNDEBUG"
+$CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR -DNDEBUG benchmark.cpp -o benchmark && time ./benchmark >/dev/null
+echo "Fixed size 3x3, row-major, with asserts"
+$CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR benchmark.cpp -o benchmark && time ./benchmark >/dev/null
+echo "Dynamic size 20x20, column-major, -DNDEBUG"
+$CXX -O3 -I .. -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null
+echo "Dynamic size 20x20, column-major, with asserts"
+$CXX -O3 -I .. benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null
+echo "Dynamic size 20x20, row-major, -DNDEBUG"
+$CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null
+echo "Dynamic size 20x20, row-major, with asserts"
+$CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null
diff --git a/eigen/bench/btl/CMakeLists.txt b/eigen/bench/btl/CMakeLists.txt
new file mode 100644
index 0000000..119b470
--- /dev/null
+++ b/eigen/bench/btl/CMakeLists.txt
@@ -0,0 +1,104 @@
+PROJECT(BTL)
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6.2)
+
+set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${Eigen_SOURCE_DIR}/cmake)
+include(MacroOptionalAddSubdirectory)
+
+OPTION(BTL_NOVEC "Disable SSE/Altivec optimizations when possible" OFF)
+
+SET(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+string(REGEX MATCH icpc IS_ICPC ${CMAKE_CXX_COMPILER})
+IF(CMAKE_COMPILER_IS_GNUCXX OR IS_ICPC)
+ SET(CMAKE_CXX_FLAGS "-g0 -O3 -DNDEBUG")
+ SET(CMAKE_Fortran_FLAGS "-g0 -O3 -DNDEBUG")
+ IF(NOT BTL_NOVEC)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
+ SET(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -msse2")
+ ELSE(NOT BTL_NOVEC)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEIGEN_DONT_VECTORIZE")
+ ENDIF(NOT BTL_NOVEC)
+ENDIF(CMAKE_COMPILER_IS_GNUCXX OR IS_ICPC)
+
+IF(MSVC)
+ SET(CMAKE_CXX_FLAGS " /O2 /Ot /GL /fp:fast -DNDEBUG")
+# SET(CMAKE_Fortran_FLAGS "-g0 -O3 -DNDEBUG")
+ IF(NOT BTL_NOVEC)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")
+ ELSE(NOT BTL_NOVEC)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEIGEN_DONT_VECTORIZE")
+ ENDIF(NOT BTL_NOVEC)
+ENDIF(MSVC)
+
+if(IS_ICPC)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fast")
+ set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fast")
+endif(IS_ICPC)
+
+include_directories(
+ ${PROJECT_SOURCE_DIR}/actions
+ ${PROJECT_SOURCE_DIR}/generic_bench
+ ${PROJECT_SOURCE_DIR}/generic_bench/utils
+ ${PROJECT_SOURCE_DIR}/libs/STL)
+
+# find_package(MKL)
+# if (MKL_FOUND)
+# add_definitions(-DHAVE_MKL)
+# set(DEFAULT_LIBRARIES ${MKL_LIBRARIES})
+# endif (MKL_FOUND)
+
+MACRO(BTL_ADD_BENCH targetname)
+
+ foreach(_current_var ${ARGN})
+ set(_last_var ${_current_var})
+ endforeach(_current_var)
+
+ set(_sources ${ARGN})
+ list(LENGTH _sources _argn_length)
+
+ list(REMOVE_ITEM _sources ON OFF TRUE FALSE)
+
+ list(LENGTH _sources _src_length)
+
+ if (${_argn_length} EQUAL ${_src_length})
+ set(_last_var ON)
+ endif (${_argn_length} EQUAL ${_src_length})
+
+ OPTION(BUILD_${targetname} "Build benchmark ${targetname}" ${_last_var})
+
+ IF(BUILD_${targetname})
+ ADD_EXECUTABLE(${targetname} ${_sources})
+ ADD_TEST(${targetname} "${targetname}")
+ target_link_libraries(${targetname} ${DEFAULT_LIBRARIES} rt)
+ ENDIF(BUILD_${targetname})
+
+ENDMACRO(BTL_ADD_BENCH)
+
+macro(btl_add_target_property target prop value)
+
+ if(BUILD_${target})
+ get_target_property(previous ${target} ${prop})
+ if(NOT previous)
+ set(previous "")
+ endif()
+ set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")
+ endif()
+
+endmacro(btl_add_target_property)
+
+ENABLE_TESTING()
+
+add_subdirectory(libs/eigen3)
+add_subdirectory(libs/eigen2)
+add_subdirectory(libs/BLAS)
+add_subdirectory(libs/ublas)
+add_subdirectory(libs/gmm)
+add_subdirectory(libs/mtl4)
+add_subdirectory(libs/blitz)
+add_subdirectory(libs/tvmet)
+add_subdirectory(libs/STL)
+
+add_subdirectory(data)
+
+
diff --git a/eigen/bench/btl/COPYING b/eigen/bench/btl/COPYING
new file mode 100644
index 0000000..486449c
--- /dev/null
+++ b/eigen/bench/btl/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/eigen/bench/btl/README b/eigen/bench/btl/README
new file mode 100644
index 0000000..f3f5fb3
--- /dev/null
+++ b/eigen/bench/btl/README
@@ -0,0 +1,154 @@
+Bench Template Library
+
+****************************************
+Introduction :
+
+The aim of this project is to compare the performance
+of available numerical libraries. The code is designed
+as generic and modular as possible. Thus, adding new
+numerical libraries or new numerical tests should
+require minimal effort.
+
+
+*****************************************
+
+Installation :
+
+BTL uses cmake / ctest:
+
+1 - create a build directory:
+
+ $ mkdir build
+ $ cd build
+
+2 - configure:
+
+ $ ccmake ..
+
+3 - run the bench using ctest:
+
+ $ ctest -V
+
+You can run the benchmarks only on libraries matching a given regular expression:
+ ctest -V -R <regexp>
+For instance:
+ ctest -V -R eigen2
+
+You can also select a given set of actions defining the environment variable BTL_CONFIG this way:
+ BTL_CONFIG="-a action1{:action2}*" ctest -V
+An exemple:
+ BTL_CONFIG="-a axpy:vector_matrix:trisolve:ata" ctest -V -R eigen2
+
+Finally, if bench results already exist (the bench*.dat files) then they merges by keeping the best for each matrix size. If you want to overwrite the previous ones you can simply add the "--overwrite" option:
+ BTL_CONFIG="-a axpy:vector_matrix:trisolve:ata --overwrite" ctest -V -R eigen2
+
+4 : Analyze the result. different data files (.dat) are produced in each libs directories.
+ If gnuplot is available, choose a directory name in the data directory to store the results and type:
+ $ cd data
+ $ mkdir my_directory
+ $ cp ../libs/*/*.dat my_directory
+ Build the data utilities in this (data) directory
+ make
+ Then you can look the raw data,
+ go_mean my_directory
+ or smooth the data first :
+ smooth_all.sh my_directory
+ go_mean my_directory_smooth
+
+
+*************************************************
+
+Files and directories :
+
+ generic_bench : all the bench sources common to all libraries
+
+ actions : sources for different action wrappers (axpy, matrix-matrix product) to be tested.
+
+ libs/* : bench sources specific to each tested libraries.
+
+ machine_dep : directory used to store machine specific Makefile.in
+
+ data : directory used to store gnuplot scripts and data analysis utilities
+
+**************************************************
+
+Principles : the code modularity is achieved by defining two concepts :
+
+ ****** Action concept : This is a class defining which kind
+ of test must be performed (e.g. a matrix_vector_product).
+ An Action should define the following methods :
+
+ *** Ctor using the size of the problem (matrix or vector size) as an argument
+ Action action(size);
+ *** initialize : this method initialize the calculation (e.g. initialize the matrices and vectors arguments)
+ action.initialize();
+ *** calculate : this method actually launch the calculation to be benchmarked
+ action.calculate;
+ *** nb_op_base() : this method returns the complexity of the calculate method (allowing the mflops evaluation)
+ *** name() : this method returns the name of the action (std::string)
+
+ ****** Interface concept : This is a class or namespace defining how to use a given library and
+ its specific containers (matrix and vector). Up to now an interface should following types
+
+ *** real_type : kind of float to be used (float or double)
+ *** stl_vector : must correspond to std::vector<real_type>
+ *** stl_matrix : must correspond to std::vector<stl_vector>
+ *** gene_vector : the vector type for this interface --> e.g. (real_type *) for the C_interface
+ *** gene_matrix : the matrix type for this interface --> e.g. (gene_vector *) for the C_interface
+
+ + the following common methods
+
+ *** free_matrix(gene_matrix & A, int N) dealocation of a N sized gene_matrix A
+ *** free_vector(gene_vector & B) dealocation of a N sized gene_vector B
+ *** matrix_from_stl(gene_matrix & A, stl_matrix & A_stl) copy the content of an stl_matrix A_stl into a gene_matrix A.
+ The allocation of A is done in this function.
+ *** vector_to_stl(gene_vector & B, stl_vector & B_stl) copy the content of an stl_vector B_stl into a gene_vector B.
+ The allocation of B is done in this function.
+ *** matrix_to_stl(gene_matrix & A, stl_matrix & A_stl) copy the content of an gene_matrix A into an stl_matrix A_stl.
+ The size of A_STL must corresponds to the size of A.
+ *** vector_to_stl(gene_vector & A, stl_vector & A_stl) copy the content of an gene_vector A into an stl_vector A_stl.
+ The size of B_STL must corresponds to the size of B.
+ *** copy_matrix(gene_matrix & source, gene_matrix & cible, int N) : copy the content of source in cible. Both source
+ and cible must be sized NxN.
+ *** copy_vector(gene_vector & source, gene_vector & cible, int N) : copy the content of source in cible. Both source
+ and cible must be sized N.
+
+ and the following method corresponding to the action one wants to be benchmarked :
+
+ *** matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)
+ *** matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N)
+ *** ata_product(const gene_matrix & A, gene_matrix & X, int N)
+ *** aat_product(const gene_matrix & A, gene_matrix & X, int N)
+ *** axpy(real coef, const gene_vector & X, gene_vector & Y, int N)
+
+ The bench algorithm (generic_bench/bench.hh) is templated with an action itself templated with
+ an interface. A typical main.cpp source stored in a given library directory libs/A_LIB
+ looks like :
+
+ bench< AN_ACTION < AN_INTERFACE > >( 10 , 1000 , 50 ) ;
+
+ this function will produce XY data file containing measured mflops as a function of the size for 50
+ sizes between 10 and 10000.
+
+ This algorithm can be adapted by providing a given Perf_Analyzer object which determines how the time
+ measurements must be done. For example, the X86_Perf_Analyzer use the asm rdtsc function and provides
+ a very fast and accurate (but less portable) timing method. The default is the Portable_Perf_Analyzer
+ so
+
+ bench< AN_ACTION < AN_INTERFACE > >( 10 , 1000 , 50 ) ;
+
+ is equivalent to
+
+ bench< Portable_Perf_Analyzer,AN_ACTION < AN_INTERFACE > >( 10 , 1000 , 50 ) ;
+
+ If your system supports it we suggest to use a mixed implementation (X86_perf_Analyzer+Portable_Perf_Analyzer).
+ replace
+ bench<Portable_Perf_Analyzer,Action>(size_min,size_max,nb_point);
+ with
+ bench<Mixed_Perf_Analyzer,Action>(size_min,size_max,nb_point);
+ in generic/bench.hh
+
+.
+
+
+
diff --git a/eigen/bench/btl/actions/action_aat_product.hh b/eigen/bench/btl/actions/action_aat_product.hh
new file mode 100644
index 0000000..aa5b35c
--- /dev/null
+++ b/eigen/bench/btl/actions/action_aat_product.hh
@@ -0,0 +1,145 @@
+//=====================================================
+// File : action_aat_product.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_AAT_PRODUCT
+#define ACTION_AAT_PRODUCT
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_aat_product {
+
+public :
+
+ // Ctor
+
+ Action_aat_product( int size ):_size(size)
+ {
+ MESSAGE("Action_aat_product Ctor");
+
+ // STL matrix and vector initialization
+
+ init_matrix<pseudo_random>(A_stl,_size);
+ init_matrix<null_function>(X_stl,_size);
+ init_matrix<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(X_ref,X_stl);
+
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::matrix_from_stl(X,X_stl);
+
+ }
+
+ // invalidate copy ctor
+
+ Action_aat_product( const Action_aat_product & )
+ {
+ INFOS("illegal call to Action_aat_product Copy Ctor");
+ exit(0);
+ }
+
+ // Dtor
+
+ ~Action_aat_product( void ){
+
+ MESSAGE("Action_aat_product Dtor");
+
+ // deallocation
+
+ Interface::free_matrix(A,_size);
+ Interface::free_matrix(X,_size);
+
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_matrix(X_ref,_size);
+
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "aat_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return double(_size)*double(_size)*double(_size);
+ }
+
+ inline void initialize( void ){
+
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_matrix(X_ref,X,_size);
+
+ }
+
+ inline void calculate( void ) {
+
+ Interface::aat_product(A,X,_size);
+
+ }
+
+ void check_result( void ){
+ if (_size>128) return;
+ // calculation check
+
+ Interface::matrix_to_stl(X,resu_stl);
+
+ STL_interface<typename Interface::real_type>::aat_product(A_stl,X_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+ if (error>1.e-6){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(1);
+ }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_matrix X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_matrix X;
+
+
+ int _size;
+
+};
+
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/actions/action_ata_product.hh b/eigen/bench/btl/actions/action_ata_product.hh
new file mode 100644
index 0000000..04364fe
--- /dev/null
+++ b/eigen/bench/btl/actions/action_ata_product.hh
@@ -0,0 +1,145 @@
+//=====================================================
+// File : action_ata_product.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_ATA_PRODUCT
+#define ACTION_ATA_PRODUCT
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_ata_product {
+
+public :
+
+ // Ctor
+
+ Action_ata_product( int size ):_size(size)
+ {
+ MESSAGE("Action_ata_product Ctor");
+
+ // STL matrix and vector initialization
+
+ init_matrix<pseudo_random>(A_stl,_size);
+ init_matrix<null_function>(X_stl,_size);
+ init_matrix<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(X_ref,X_stl);
+
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::matrix_from_stl(X,X_stl);
+
+ }
+
+ // invalidate copy ctor
+
+ Action_ata_product( const Action_ata_product & )
+ {
+ INFOS("illegal call to Action_ata_product Copy Ctor");
+ exit(0);
+ }
+
+ // Dtor
+
+ ~Action_ata_product( void ){
+
+ MESSAGE("Action_ata_product Dtor");
+
+ // deallocation
+
+ Interface::free_matrix(A,_size);
+ Interface::free_matrix(X,_size);
+
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_matrix(X_ref,_size);
+
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "ata_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return 2.0*_size*_size*_size;
+ }
+
+ inline void initialize( void ){
+
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_matrix(X_ref,X,_size);
+
+ }
+
+ inline void calculate( void ) {
+
+ Interface::ata_product(A,X,_size);
+
+ }
+
+ void check_result( void ){
+ if (_size>128) return;
+ // calculation check
+
+ Interface::matrix_to_stl(X,resu_stl);
+
+ STL_interface<typename Interface::real_type>::ata_product(A_stl,X_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+ if (error>1.e-6){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(1);
+ }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_matrix X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_matrix X;
+
+
+ int _size;
+
+};
+
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/actions/action_atv_product.hh b/eigen/bench/btl/actions/action_atv_product.hh
new file mode 100644
index 0000000..a823451
--- /dev/null
+++ b/eigen/bench/btl/actions/action_atv_product.hh
@@ -0,0 +1,134 @@
+//=====================================================
+// File : action_atv_product.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_ATV_PRODUCT
+#define ACTION_ATV_PRODUCT
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_atv_product {
+
+public :
+
+ Action_atv_product( int size ) : _size(size)
+ {
+ MESSAGE("Action_atv_product Ctor");
+
+ // STL matrix and vector initialization
+
+ init_matrix<pseudo_random>(A_stl,_size);
+ init_vector<pseudo_random>(B_stl,_size);
+ init_vector<null_function>(X_stl,_size);
+ init_vector<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::vector_from_stl(B_ref,B_stl);
+ Interface::vector_from_stl(X_ref,X_stl);
+
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::vector_from_stl(B,B_stl);
+ Interface::vector_from_stl(X,X_stl);
+ }
+
+ // invalidate copy ctor
+ Action_atv_product( const Action_atv_product & )
+ {
+ INFOS("illegal call to Action_atv_product Copy Ctor");
+ exit(1);
+ }
+
+ ~Action_atv_product( void )
+ {
+ MESSAGE("Action_atv_product Dtor");
+
+ Interface::free_matrix(A,_size);
+ Interface::free_vector(B);
+ Interface::free_vector(X);
+
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_vector(B_ref);
+ Interface::free_vector(X_ref);
+ }
+
+ static inline std::string name() { return "atv_" + Interface::name(); }
+
+ double nb_op_base( void ) { return 2.0*_size*_size; }
+
+ inline void initialize( void ){
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_vector(B_ref,B,_size);
+ Interface::copy_vector(X_ref,X,_size);
+ }
+
+ BTL_DONT_INLINE void calculate( void ) {
+ BTL_ASM_COMMENT("begin atv");
+ Interface::atv_product(A,B,X,_size);
+ BTL_ASM_COMMENT("end atv");
+ }
+
+ void check_result( void )
+ {
+ if (_size>128) return;
+ Interface::vector_to_stl(X,resu_stl);
+
+ STL_interface<typename Interface::real_type>::atv_product(A_stl,B_stl,X_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+ if (error>1.e-6){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(1);
+ }
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_vector B_stl;
+ typename Interface::stl_vector X_stl;
+ typename Interface::stl_vector resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_vector B_ref;
+ typename Interface::gene_vector X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_vector B;
+ typename Interface::gene_vector X;
+
+
+ int _size;
+
+};
+
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/actions/action_axpby.hh b/eigen/bench/btl/actions/action_axpby.hh
new file mode 100644
index 0000000..98511ab
--- /dev/null
+++ b/eigen/bench/btl/actions/action_axpby.hh
@@ -0,0 +1,127 @@
+//=====================================================
+// File : action_axpby.hh
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_AXPBY
+#define ACTION_AXPBY
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_axpby {
+
+public :
+
+ // Ctor
+ Action_axpby( int size ):_size(size),_alpha(0.5),_beta(0.95)
+ {
+ MESSAGE("Action_axpby Ctor");
+
+ // STL vector initialization
+ init_vector<pseudo_random>(X_stl,_size);
+ init_vector<pseudo_random>(Y_stl,_size);
+ init_vector<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+ Interface::vector_from_stl(X_ref,X_stl);
+ Interface::vector_from_stl(Y_ref,Y_stl);
+
+ Interface::vector_from_stl(X,X_stl);
+ Interface::vector_from_stl(Y,Y_stl);
+ }
+
+ // invalidate copy ctor
+ Action_axpby( const Action_axpby & )
+ {
+ INFOS("illegal call to Action_axpby Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+ ~Action_axpby( void ){
+ MESSAGE("Action_axpby Dtor");
+
+ // deallocation
+ Interface::free_vector(X_ref);
+ Interface::free_vector(Y_ref);
+
+ Interface::free_vector(X);
+ Interface::free_vector(Y);
+ }
+
+ // action name
+ static inline std::string name( void )
+ {
+ return "axpby_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return 3.0*_size;
+ }
+
+ inline void initialize( void ){
+ Interface::copy_vector(X_ref,X,_size);
+ Interface::copy_vector(Y_ref,Y,_size);
+ }
+
+ inline void calculate( void ) {
+ BTL_ASM_COMMENT("mybegin axpby");
+ Interface::axpby(_alpha,X,_beta,Y,_size);
+ BTL_ASM_COMMENT("myend axpby");
+ }
+
+ void check_result( void ){
+ if (_size>128) return;
+ // calculation check
+ Interface::vector_to_stl(Y,resu_stl);
+
+ STL_interface<typename Interface::real_type>::axpby(_alpha,X_stl,_beta,Y_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(Y_stl,resu_stl);
+
+ if (error>1.e-6){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(2);
+ }
+ }
+
+private :
+
+ typename Interface::stl_vector X_stl;
+ typename Interface::stl_vector Y_stl;
+ typename Interface::stl_vector resu_stl;
+
+ typename Interface::gene_vector X_ref;
+ typename Interface::gene_vector Y_ref;
+
+ typename Interface::gene_vector X;
+ typename Interface::gene_vector Y;
+
+ typename Interface::real_type _alpha;
+ typename Interface::real_type _beta;
+
+ int _size;
+};
+
+#endif
diff --git a/eigen/bench/btl/actions/action_axpy.hh b/eigen/bench/btl/actions/action_axpy.hh
new file mode 100644
index 0000000..e4cb3a5
--- /dev/null
+++ b/eigen/bench/btl/actions/action_axpy.hh
@@ -0,0 +1,139 @@
+//=====================================================
+// File : action_axpy.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_AXPY
+#define ACTION_AXPY
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_axpy {
+
+public :
+
+ // Ctor
+
+ Action_axpy( int size ):_size(size),_coef(1.0)
+ {
+ MESSAGE("Action_axpy Ctor");
+
+ // STL vector initialization
+
+ init_vector<pseudo_random>(X_stl,_size);
+ init_vector<pseudo_random>(Y_stl,_size);
+ init_vector<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+
+ Interface::vector_from_stl(X_ref,X_stl);
+ Interface::vector_from_stl(Y_ref,Y_stl);
+
+ Interface::vector_from_stl(X,X_stl);
+ Interface::vector_from_stl(Y,Y_stl);
+
+
+ }
+
+ // invalidate copy ctor
+
+ Action_axpy( const Action_axpy & )
+ {
+ INFOS("illegal call to Action_axpy Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+
+ ~Action_axpy( void ){
+
+ MESSAGE("Action_axpy Dtor");
+
+ // deallocation
+
+ Interface::free_vector(X_ref);
+ Interface::free_vector(Y_ref);
+
+ Interface::free_vector(X);
+ Interface::free_vector(Y);
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "axpy_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return 2.0*_size;
+ }
+
+ inline void initialize( void ){
+ Interface::copy_vector(X_ref,X,_size);
+ Interface::copy_vector(Y_ref,Y,_size);
+ }
+
+ inline void calculate( void ) {
+ BTL_ASM_COMMENT("mybegin axpy");
+ Interface::axpy(_coef,X,Y,_size);
+ BTL_ASM_COMMENT("myend axpy");
+ }
+
+ void check_result( void ){
+ if (_size>128) return;
+ // calculation check
+
+ Interface::vector_to_stl(Y,resu_stl);
+
+ STL_interface<typename Interface::real_type>::axpy(_coef,X_stl,Y_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(Y_stl,resu_stl);
+
+ if (error>1.e-6){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(0);
+ }
+
+ }
+
+private :
+
+ typename Interface::stl_vector X_stl;
+ typename Interface::stl_vector Y_stl;
+ typename Interface::stl_vector resu_stl;
+
+ typename Interface::gene_vector X_ref;
+ typename Interface::gene_vector Y_ref;
+
+ typename Interface::gene_vector X;
+ typename Interface::gene_vector Y;
+
+ typename Interface::real_type _coef;
+
+ int _size;
+};
+
+#endif
diff --git a/eigen/bench/btl/actions/action_cholesky.hh b/eigen/bench/btl/actions/action_cholesky.hh
new file mode 100644
index 0000000..5f66d11
--- /dev/null
+++ b/eigen/bench/btl/actions/action_cholesky.hh
@@ -0,0 +1,128 @@
+//=====================================================
+// File : action_cholesky.hh
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_CHOLESKY
+#define ACTION_CHOLESKY
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_cholesky {
+
+public :
+
+ // Ctor
+
+ Action_cholesky( int size ):_size(size)
+ {
+ MESSAGE("Action_cholesky Ctor");
+
+ // STL mat/vec initialization
+ init_matrix_symm<pseudo_random>(X_stl,_size);
+ init_matrix<null_function>(C_stl,_size);
+
+ // make sure X is invertible
+ for (int i=0; i<_size; ++i)
+ X_stl[i][i] = std::abs(X_stl[i][i]) * 1e2 + 100;
+
+ // generic matrix and vector initialization
+ Interface::matrix_from_stl(X_ref,X_stl);
+ Interface::matrix_from_stl(X,X_stl);
+ Interface::matrix_from_stl(C,C_stl);
+
+ _cost = 0;
+ for (int j=0; j<_size; ++j)
+ {
+ double r = std::max(_size - j -1,0);
+ _cost += 2*(r*j+r+j);
+ }
+ }
+
+ // invalidate copy ctor
+
+ Action_cholesky( const Action_cholesky & )
+ {
+ INFOS("illegal call to Action_cholesky Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+
+ ~Action_cholesky( void ){
+
+ MESSAGE("Action_cholesky Dtor");
+
+ // deallocation
+ Interface::free_matrix(X_ref,_size);
+ Interface::free_matrix(X,_size);
+ Interface::free_matrix(C,_size);
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "cholesky_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return _cost;
+ }
+
+ inline void initialize( void ){
+ Interface::copy_matrix(X_ref,X,_size);
+ }
+
+ inline void calculate( void ) {
+ Interface::cholesky(X,C,_size);
+ }
+
+ void check_result( void ){
+ // calculation check
+// STL_interface<typename Interface::real_type>::cholesky(X_stl,C_stl,_size);
+//
+// typename Interface::real_type error=
+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);
+//
+// if (error>1.e-6){
+// INFOS("WRONG CALCULATION...residual=" << error);
+// exit(0);
+// }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix C_stl;
+
+ typename Interface::gene_matrix X_ref;
+ typename Interface::gene_matrix X;
+ typename Interface::gene_matrix C;
+
+ int _size;
+ double _cost;
+};
+
+#endif
diff --git a/eigen/bench/btl/actions/action_ger.hh b/eigen/bench/btl/actions/action_ger.hh
new file mode 100644
index 0000000..dc766ef
--- /dev/null
+++ b/eigen/bench/btl/actions/action_ger.hh
@@ -0,0 +1,128 @@
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_GER
+#define ACTION_GER
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_ger {
+
+public :
+
+ // Ctor
+ BTL_DONT_INLINE Action_ger( int size ):_size(size)
+ {
+ MESSAGE("Action_ger Ctor");
+
+ // STL matrix and vector initialization
+ typename Interface::stl_matrix tmp;
+ init_matrix<pseudo_random>(A_stl,_size);
+ init_vector<pseudo_random>(B_stl,_size);
+ init_vector<pseudo_random>(X_stl,_size);
+ init_vector<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::vector_from_stl(B_ref,B_stl);
+ Interface::vector_from_stl(B,B_stl);
+ Interface::vector_from_stl(X_ref,X_stl);
+ Interface::vector_from_stl(X,X_stl);
+ }
+
+ // invalidate copy ctor
+ Action_ger( const Action_ger & )
+ {
+ INFOS("illegal call to Action_ger Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+ BTL_DONT_INLINE ~Action_ger( void ){
+ MESSAGE("Action_ger Dtor");
+ Interface::free_matrix(A,_size);
+ Interface::free_vector(B);
+ Interface::free_vector(X);
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_vector(B_ref);
+ Interface::free_vector(X_ref);
+
+ }
+
+ // action name
+ static inline std::string name( void )
+ {
+ return "ger_" + Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return 2.0*_size*_size;
+ }
+
+ BTL_DONT_INLINE void initialize( void ){
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_vector(B_ref,B,_size);
+ Interface::copy_vector(X_ref,X,_size);
+ }
+
+ BTL_DONT_INLINE void calculate( void ) {
+ BTL_ASM_COMMENT("#begin ger");
+ Interface::ger(A,B,X,_size);
+ BTL_ASM_COMMENT("end ger");
+ }
+
+ BTL_DONT_INLINE void check_result( void ){
+ // calculation check
+ Interface::vector_to_stl(X,resu_stl);
+
+ STL_interface<typename Interface::real_type>::ger(A_stl,B_stl,X_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+ if (error>1.e-3){
+ INFOS("WRONG CALCULATION...residual=" << error);
+// exit(0);
+ }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_vector B_stl;
+ typename Interface::stl_vector X_stl;
+ typename Interface::stl_vector resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_vector B_ref;
+ typename Interface::gene_vector X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_vector B;
+ typename Interface::gene_vector X;
+
+ int _size;
+};
+
+
+#endif
diff --git a/eigen/bench/btl/actions/action_hessenberg.hh b/eigen/bench/btl/actions/action_hessenberg.hh
new file mode 100644
index 0000000..2100ebd
--- /dev/null
+++ b/eigen/bench/btl/actions/action_hessenberg.hh
@@ -0,0 +1,233 @@
+//=====================================================
+// File : action_hessenberg.hh
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_HESSENBERG
+#define ACTION_HESSENBERG
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_hessenberg {
+
+public :
+
+ // Ctor
+
+ Action_hessenberg( int size ):_size(size)
+ {
+ MESSAGE("Action_hessenberg Ctor");
+
+ // STL vector initialization
+ init_matrix<pseudo_random>(X_stl,_size);
+
+ init_matrix<null_function>(C_stl,_size);
+ init_matrix<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+ Interface::matrix_from_stl(X_ref,X_stl);
+ Interface::matrix_from_stl(X,X_stl);
+ Interface::matrix_from_stl(C,C_stl);
+
+ _cost = 0;
+ for (int j=0; j<_size-2; ++j)
+ {
+ double r = std::max(0,_size-j-1);
+ double b = std::max(0,_size-j-2);
+ _cost += 6 + 3*b + r*r*4 + r*_size*4;
+ }
+ }
+
+ // invalidate copy ctor
+
+ Action_hessenberg( const Action_hessenberg & )
+ {
+ INFOS("illegal call to Action_hessenberg Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+
+ ~Action_hessenberg( void ){
+
+ MESSAGE("Action_hessenberg Dtor");
+
+ // deallocation
+ Interface::free_matrix(X_ref,_size);
+ Interface::free_matrix(X,_size);
+ Interface::free_matrix(C,_size);
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "hessenberg_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return _cost;
+ }
+
+ inline void initialize( void ){
+ Interface::copy_matrix(X_ref,X,_size);
+ }
+
+ inline void calculate( void ) {
+ Interface::hessenberg(X,C,_size);
+ }
+
+ void check_result( void ){
+ // calculation check
+ Interface::matrix_to_stl(C,resu_stl);
+
+// STL_interface<typename Interface::real_type>::hessenberg(X_stl,C_stl,_size);
+//
+// typename Interface::real_type error=
+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);
+//
+// if (error>1.e-6){
+// INFOS("WRONG CALCULATION...residual=" << error);
+// exit(0);
+// }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix C_stl;
+ typename Interface::stl_matrix resu_stl;
+
+ typename Interface::gene_matrix X_ref;
+ typename Interface::gene_matrix X;
+ typename Interface::gene_matrix C;
+
+ int _size;
+ double _cost;
+};
+
+template<class Interface>
+class Action_tridiagonalization {
+
+public :
+
+ // Ctor
+
+ Action_tridiagonalization( int size ):_size(size)
+ {
+ MESSAGE("Action_tridiagonalization Ctor");
+
+ // STL vector initialization
+ init_matrix<pseudo_random>(X_stl,_size);
+
+ for(int i=0; i<_size; ++i)
+ {
+ for(int j=0; j<i; ++j)
+ X_stl[i][j] = X_stl[j][i];
+ }
+
+ init_matrix<null_function>(C_stl,_size);
+ init_matrix<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+ Interface::matrix_from_stl(X_ref,X_stl);
+ Interface::matrix_from_stl(X,X_stl);
+ Interface::matrix_from_stl(C,C_stl);
+
+ _cost = 0;
+ for (int j=0; j<_size-2; ++j)
+ {
+ double r = std::max(0,_size-j-1);
+ double b = std::max(0,_size-j-2);
+ _cost += 6. + 3.*b + r*r*8.;
+ }
+ }
+
+ // invalidate copy ctor
+
+ Action_tridiagonalization( const Action_tridiagonalization & )
+ {
+ INFOS("illegal call to Action_tridiagonalization Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+
+ ~Action_tridiagonalization( void ){
+
+ MESSAGE("Action_tridiagonalization Dtor");
+
+ // deallocation
+ Interface::free_matrix(X_ref,_size);
+ Interface::free_matrix(X,_size);
+ Interface::free_matrix(C,_size);
+ }
+
+ // action name
+
+ static inline std::string name( void ) { return "tridiagonalization_"+Interface::name(); }
+
+ double nb_op_base( void ){
+ return _cost;
+ }
+
+ inline void initialize( void ){
+ Interface::copy_matrix(X_ref,X,_size);
+ }
+
+ inline void calculate( void ) {
+ Interface::tridiagonalization(X,C,_size);
+ }
+
+ void check_result( void ){
+ // calculation check
+ Interface::matrix_to_stl(C,resu_stl);
+
+// STL_interface<typename Interface::real_type>::tridiagonalization(X_stl,C_stl,_size);
+//
+// typename Interface::real_type error=
+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);
+//
+// if (error>1.e-6){
+// INFOS("WRONG CALCULATION...residual=" << error);
+// exit(0);
+// }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix C_stl;
+ typename Interface::stl_matrix resu_stl;
+
+ typename Interface::gene_matrix X_ref;
+ typename Interface::gene_matrix X;
+ typename Interface::gene_matrix C;
+
+ int _size;
+ double _cost;
+};
+
+#endif
diff --git a/eigen/bench/btl/actions/action_lu_decomp.hh b/eigen/bench/btl/actions/action_lu_decomp.hh
new file mode 100644
index 0000000..2448e82
--- /dev/null
+++ b/eigen/bench/btl/actions/action_lu_decomp.hh
@@ -0,0 +1,124 @@
+//=====================================================
+// File : action_lu_decomp.hh
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_LU_DECOMP
+#define ACTION_LU_DECOMP
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_lu_decomp {
+
+public :
+
+ // Ctor
+
+ Action_lu_decomp( int size ):_size(size)
+ {
+ MESSAGE("Action_lu_decomp Ctor");
+
+ // STL vector initialization
+ init_matrix<pseudo_random>(X_stl,_size);
+
+ init_matrix<null_function>(C_stl,_size);
+ init_matrix<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+ Interface::matrix_from_stl(X_ref,X_stl);
+ Interface::matrix_from_stl(X,X_stl);
+ Interface::matrix_from_stl(C,C_stl);
+
+ _cost = 2.0*size*size*size/3.0 + size*size;
+ }
+
+ // invalidate copy ctor
+
+ Action_lu_decomp( const Action_lu_decomp & )
+ {
+ INFOS("illegal call to Action_lu_decomp Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+
+ ~Action_lu_decomp( void ){
+
+ MESSAGE("Action_lu_decomp Dtor");
+
+ // deallocation
+ Interface::free_matrix(X_ref,_size);
+ Interface::free_matrix(X,_size);
+ Interface::free_matrix(C,_size);
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "complete_lu_decomp_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return _cost;
+ }
+
+ inline void initialize( void ){
+ Interface::copy_matrix(X_ref,X,_size);
+ }
+
+ inline void calculate( void ) {
+ Interface::lu_decomp(X,C,_size);
+ }
+
+ void check_result( void ){
+ // calculation check
+ Interface::matrix_to_stl(C,resu_stl);
+
+// STL_interface<typename Interface::real_type>::lu_decomp(X_stl,C_stl,_size);
+//
+// typename Interface::real_type error=
+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);
+//
+// if (error>1.e-6){
+// INFOS("WRONG CALCULATION...residual=" << error);
+// exit(0);
+// }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix C_stl;
+ typename Interface::stl_matrix resu_stl;
+
+ typename Interface::gene_matrix X_ref;
+ typename Interface::gene_matrix X;
+ typename Interface::gene_matrix C;
+
+ int _size;
+ double _cost;
+};
+
+#endif
diff --git a/eigen/bench/btl/actions/action_lu_solve.hh b/eigen/bench/btl/actions/action_lu_solve.hh
new file mode 100644
index 0000000..5a81e63
--- /dev/null
+++ b/eigen/bench/btl/actions/action_lu_solve.hh
@@ -0,0 +1,136 @@
+//=====================================================
+// File : action_lu_solve.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_LU_SOLVE
+#define ACTION_LU_SOLVE
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_lu_solve
+{
+
+public :
+
+ static inline std::string name( void )
+ {
+ return "lu_solve_"+Interface::name();
+ }
+
+ static double nb_op_base(int size){
+ return 2.0*size*size*size/3.0; // questionable but not really important
+ }
+
+
+ static double calculate( int nb_calc, int size ) {
+
+ // STL matrix and vector initialization
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_vector B_stl;
+ typename Interface::stl_vector X_stl;
+
+ init_matrix<pseudo_random>(A_stl,size);
+ init_vector<pseudo_random>(B_stl,size);
+ init_vector<null_function>(X_stl,size);
+
+ // generic matrix and vector initialization
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_vector B;
+ typename Interface::gene_vector X;
+
+ typename Interface::gene_matrix LU;
+
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::vector_from_stl(B,B_stl);
+ Interface::vector_from_stl(X,X_stl);
+ Interface::matrix_from_stl(LU,A_stl);
+
+ // local variable :
+
+ typename Interface::Pivot_Vector pivot; // pivot vector
+ Interface::new_Pivot_Vector(pivot,size);
+
+ // timer utilities
+
+ Portable_Timer chronos;
+
+ // time measurement
+
+ chronos.start();
+
+ for (int ii=0;ii<nb_calc;ii++){
+
+ // LU factorization
+ Interface::copy_matrix(A,LU,size);
+ Interface::LU_factor(LU,pivot,size);
+
+ // LU solve
+
+ Interface::LU_solve(LU,pivot,B,X,size);
+
+ }
+
+ // Time stop
+
+ chronos.stop();
+
+ double time=chronos.user_time();
+
+ // check result :
+
+ typename Interface::stl_vector B_new_stl(size);
+ Interface::vector_to_stl(X,X_stl);
+
+ STL_interface<typename Interface::real_type>::matrix_vector_product(A_stl,X_stl,B_new_stl,size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(B_stl,B_new_stl);
+
+ if (error>1.e-5){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ STL_interface<typename Interface::real_type>::display_vector(B_stl);
+ STL_interface<typename Interface::real_type>::display_vector(B_new_stl);
+ exit(0);
+ }
+
+ // deallocation and return time
+
+ Interface::free_matrix(A,size);
+ Interface::free_vector(B);
+ Interface::free_vector(X);
+ Interface::free_Pivot_Vector(pivot);
+
+ return time;
+ }
+
+};
+
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/actions/action_matrix_matrix_product.hh b/eigen/bench/btl/actions/action_matrix_matrix_product.hh
new file mode 100644
index 0000000..f65ee05
--- /dev/null
+++ b/eigen/bench/btl/actions/action_matrix_matrix_product.hh
@@ -0,0 +1,150 @@
+//=====================================================
+// File : action_matrix_matrix_product.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_MATRIX_MATRIX_PRODUCT
+#define ACTION_MATRIX_MATRIX_PRODUCT
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_matrix_matrix_product {
+
+public :
+
+ // Ctor
+
+ Action_matrix_matrix_product( int size ):_size(size)
+ {
+ MESSAGE("Action_matrix_matrix_product Ctor");
+
+ // STL matrix and vector initialization
+
+ init_matrix<pseudo_random>(A_stl,_size);
+ init_matrix<pseudo_random>(B_stl,_size);
+ init_matrix<null_function>(X_stl,_size);
+ init_matrix<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(B_ref,B_stl);
+ Interface::matrix_from_stl(X_ref,X_stl);
+
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::matrix_from_stl(B,B_stl);
+ Interface::matrix_from_stl(X,X_stl);
+
+ }
+
+ // invalidate copy ctor
+
+ Action_matrix_matrix_product( const Action_matrix_matrix_product & )
+ {
+ INFOS("illegal call to Action_matrix_matrix_product Copy Ctor");
+ exit(0);
+ }
+
+ // Dtor
+
+ ~Action_matrix_matrix_product( void ){
+
+ MESSAGE("Action_matrix_matrix_product Dtor");
+
+ // deallocation
+
+ Interface::free_matrix(A,_size);
+ Interface::free_matrix(B,_size);
+ Interface::free_matrix(X,_size);
+
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_matrix(B_ref,_size);
+ Interface::free_matrix(X_ref,_size);
+
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "matrix_matrix_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return 2.0*_size*_size*_size;
+ }
+
+ inline void initialize( void ){
+
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_matrix(B_ref,B,_size);
+ Interface::copy_matrix(X_ref,X,_size);
+
+ }
+
+ inline void calculate( void ) {
+ Interface::matrix_matrix_product(A,B,X,_size);
+ }
+
+ void check_result( void ){
+
+ // calculation check
+ if (_size<200)
+ {
+ Interface::matrix_to_stl(X,resu_stl);
+ STL_interface<typename Interface::real_type>::matrix_matrix_product(A_stl,B_stl,X_stl,_size);
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+ if (error>1.e-6){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(1);
+ }
+ }
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_matrix B_stl;
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_matrix B_ref;
+ typename Interface::gene_matrix X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_matrix B;
+ typename Interface::gene_matrix X;
+
+
+ int _size;
+
+};
+
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/actions/action_matrix_matrix_product_bis.hh b/eigen/bench/btl/actions/action_matrix_matrix_product_bis.hh
new file mode 100644
index 0000000..29c10a6
--- /dev/null
+++ b/eigen/bench/btl/actions/action_matrix_matrix_product_bis.hh
@@ -0,0 +1,152 @@
+//=====================================================
+// File : action_matrix_matrix_product_bis.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_MATRIX_MATRIX_PRODUCT_BIS
+#define ACTION_MATRIX_MATRIX_PRODUCT_BIS
+#include "utilities.h"
+#include "STL_interface.hh"
+#include "STL_timer.hh"
+#include <string>
+#include "init_function.hh"
+#include "init_vector.hh"
+#include "init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_matrix_matrix_product_bis {
+
+public :
+
+ static inline std::string name( void )
+ {
+ return "matrix_matrix_"+Interface::name();
+ }
+
+ static double nb_op_base(int size){
+ return 2.0*size*size*size;
+ }
+
+ static double calculate( int nb_calc, int size ) {
+
+ // STL matrix and vector initialization
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_matrix B_stl;
+ typename Interface::stl_matrix X_stl;
+
+ init_matrix<pseudo_random>(A_stl,size);
+ init_matrix<pseudo_random>(B_stl,size);
+ init_matrix<null_function>(X_stl,size);
+
+ // generic matrix and vector initialization
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_matrix B_ref;
+ typename Interface::gene_matrix X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_matrix B;
+ typename Interface::gene_matrix X;
+
+
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(B_ref,B_stl);
+ Interface::matrix_from_stl(X_ref,X_stl);
+
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::matrix_from_stl(B,B_stl);
+ Interface::matrix_from_stl(X,X_stl);
+
+
+ // STL_timer utilities
+
+ STL_timer chronos;
+
+ // Baseline evaluation
+
+ chronos.start_baseline(nb_calc);
+
+ do {
+
+ Interface::copy_matrix(A_ref,A,size);
+ Interface::copy_matrix(B_ref,B,size);
+ Interface::copy_matrix(X_ref,X,size);
+
+
+ // Interface::matrix_matrix_product(A,B,X,size); This line must be commented !!!!
+ }
+ while(chronos.check());
+
+ chronos.report(true);
+
+ // Time measurement
+
+ chronos.start(nb_calc);
+
+ do {
+
+ Interface::copy_matrix(A_ref,A,size);
+ Interface::copy_matrix(B_ref,B,size);
+ Interface::copy_matrix(X_ref,X,size);
+
+ Interface::matrix_matrix_product(A,B,X,size); // here it is not commented !!!!
+ }
+ while(chronos.check());
+
+ chronos.report(true);
+
+ double time=chronos.calculated_time/2000.0;
+
+ // calculation check
+
+ typename Interface::stl_matrix resu_stl(size);
+
+ Interface::matrix_to_stl(X,resu_stl);
+
+ STL_interface<typename Interface::real_type>::matrix_matrix_product(A_stl,B_stl,X_stl,size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+ if (error>1.e-6){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(1);
+ }
+
+ // deallocation and return time
+
+ Interface::free_matrix(A,size);
+ Interface::free_matrix(B,size);
+ Interface::free_matrix(X,size);
+
+ Interface::free_matrix(A_ref,size);
+ Interface::free_matrix(B_ref,size);
+ Interface::free_matrix(X_ref,size);
+
+ return time;
+ }
+
+};
+
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/actions/action_matrix_vector_product.hh b/eigen/bench/btl/actions/action_matrix_vector_product.hh
new file mode 100644
index 0000000..8bab79d
--- /dev/null
+++ b/eigen/bench/btl/actions/action_matrix_vector_product.hh
@@ -0,0 +1,153 @@
+//=====================================================
+// File : action_matrix_vector_product.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_MATRIX_VECTOR_PRODUCT
+#define ACTION_MATRIX_VECTOR_PRODUCT
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_matrix_vector_product {
+
+public :
+
+ // Ctor
+
+ BTL_DONT_INLINE Action_matrix_vector_product( int size ):_size(size)
+ {
+ MESSAGE("Action_matrix_vector_product Ctor");
+
+ // STL matrix and vector initialization
+
+ init_matrix<pseudo_random>(A_stl,_size);
+ init_vector<pseudo_random>(B_stl,_size);
+ init_vector<null_function>(X_stl,_size);
+ init_vector<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::vector_from_stl(B_ref,B_stl);
+ Interface::vector_from_stl(B,B_stl);
+ Interface::vector_from_stl(X_ref,X_stl);
+ Interface::vector_from_stl(X,X_stl);
+
+ }
+
+ // invalidate copy ctor
+
+ Action_matrix_vector_product( const Action_matrix_vector_product & )
+ {
+ INFOS("illegal call to Action_matrix_vector_product Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+
+ BTL_DONT_INLINE ~Action_matrix_vector_product( void ){
+
+ MESSAGE("Action_matrix_vector_product Dtor");
+
+ // deallocation
+
+ Interface::free_matrix(A,_size);
+ Interface::free_vector(B);
+ Interface::free_vector(X);
+
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_vector(B_ref);
+ Interface::free_vector(X_ref);
+
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "matrix_vector_" + Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return 2.0*_size*_size;
+ }
+
+ BTL_DONT_INLINE void initialize( void ){
+
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_vector(B_ref,B,_size);
+ Interface::copy_vector(X_ref,X,_size);
+
+ }
+
+ BTL_DONT_INLINE void calculate( void ) {
+ BTL_ASM_COMMENT("#begin matrix_vector_product");
+ Interface::matrix_vector_product(A,B,X,_size);
+ BTL_ASM_COMMENT("end matrix_vector_product");
+ }
+
+ BTL_DONT_INLINE void check_result( void ){
+
+ // calculation check
+
+ Interface::vector_to_stl(X,resu_stl);
+
+ STL_interface<typename Interface::real_type>::matrix_vector_product(A_stl,B_stl,X_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+ if (error>1.e-5){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(0);
+ }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_vector B_stl;
+ typename Interface::stl_vector X_stl;
+ typename Interface::stl_vector resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_vector B_ref;
+ typename Interface::gene_vector X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_vector B;
+ typename Interface::gene_vector X;
+
+
+ int _size;
+
+};
+
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/actions/action_partial_lu.hh b/eigen/bench/btl/actions/action_partial_lu.hh
new file mode 100644
index 0000000..770ea1d
--- /dev/null
+++ b/eigen/bench/btl/actions/action_partial_lu.hh
@@ -0,0 +1,125 @@
+//=====================================================
+// File : action_lu_decomp.hh
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_PARTIAL_LU
+#define ACTION_PARTIAL_LU
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_partial_lu {
+
+public :
+
+ // Ctor
+
+ Action_partial_lu( int size ):_size(size)
+ {
+ MESSAGE("Action_partial_lu Ctor");
+
+ // STL vector initialization
+ init_matrix<pseudo_random>(X_stl,_size);
+ init_matrix<null_function>(C_stl,_size);
+
+ // make sure X is invertible
+ for (int i=0; i<_size; ++i)
+ X_stl[i][i] = X_stl[i][i] * 1e2 + 1;
+
+ // generic matrix and vector initialization
+ Interface::matrix_from_stl(X_ref,X_stl);
+ Interface::matrix_from_stl(X,X_stl);
+ Interface::matrix_from_stl(C,C_stl);
+
+ _cost = 2.0*size*size*size/3.0 + size*size;
+ }
+
+ // invalidate copy ctor
+
+ Action_partial_lu( const Action_partial_lu & )
+ {
+ INFOS("illegal call to Action_partial_lu Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+
+ ~Action_partial_lu( void ){
+
+ MESSAGE("Action_partial_lu Dtor");
+
+ // deallocation
+ Interface::free_matrix(X_ref,_size);
+ Interface::free_matrix(X,_size);
+ Interface::free_matrix(C,_size);
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "partial_lu_decomp_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return _cost;
+ }
+
+ inline void initialize( void ){
+ Interface::copy_matrix(X_ref,X,_size);
+ }
+
+ inline void calculate( void ) {
+ Interface::partial_lu_decomp(X,C,_size);
+ }
+
+ void check_result( void ){
+ // calculation check
+// Interface::matrix_to_stl(C,resu_stl);
+
+// STL_interface<typename Interface::real_type>::lu_decomp(X_stl,C_stl,_size);
+//
+// typename Interface::real_type error=
+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);
+//
+// if (error>1.e-6){
+// INFOS("WRONG CALCULATION...residual=" << error);
+// exit(0);
+// }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix C_stl;
+
+ typename Interface::gene_matrix X_ref;
+ typename Interface::gene_matrix X;
+ typename Interface::gene_matrix C;
+
+ int _size;
+ double _cost;
+};
+
+#endif
diff --git a/eigen/bench/btl/actions/action_rot.hh b/eigen/bench/btl/actions/action_rot.hh
new file mode 100644
index 0000000..df822a6
--- /dev/null
+++ b/eigen/bench/btl/actions/action_rot.hh
@@ -0,0 +1,116 @@
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_ROT
+#define ACTION_ROT
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_rot {
+
+public :
+
+ // Ctor
+ BTL_DONT_INLINE Action_rot( int size ):_size(size)
+ {
+ MESSAGE("Action_rot Ctor");
+
+ // STL matrix and vector initialization
+ typename Interface::stl_matrix tmp;
+ init_vector<pseudo_random>(A_stl,_size);
+ init_vector<pseudo_random>(B_stl,_size);
+
+ // generic matrix and vector initialization
+ Interface::vector_from_stl(A_ref,A_stl);
+ Interface::vector_from_stl(A,A_stl);
+ Interface::vector_from_stl(B_ref,B_stl);
+ Interface::vector_from_stl(B,B_stl);
+ }
+
+ // invalidate copy ctor
+ Action_rot( const Action_rot & )
+ {
+ INFOS("illegal call to Action_rot Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+ BTL_DONT_INLINE ~Action_rot( void ){
+ MESSAGE("Action_rot Dtor");
+ Interface::free_vector(A);
+ Interface::free_vector(B);
+ Interface::free_vector(A_ref);
+ Interface::free_vector(B_ref);
+ }
+
+ // action name
+ static inline std::string name( void )
+ {
+ return "rot_" + Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return 6.0*_size;
+ }
+
+ BTL_DONT_INLINE void initialize( void ){
+ Interface::copy_vector(A_ref,A,_size);
+ Interface::copy_vector(B_ref,B,_size);
+ }
+
+ BTL_DONT_INLINE void calculate( void ) {
+ BTL_ASM_COMMENT("#begin rot");
+ Interface::rot(A,B,0.5,0.6,_size);
+ BTL_ASM_COMMENT("end rot");
+ }
+
+ BTL_DONT_INLINE void check_result( void ){
+ // calculation check
+// Interface::vector_to_stl(X,resu_stl);
+
+// STL_interface<typename Interface::real_type>::rot(A_stl,B_stl,X_stl,_size);
+
+// typename Interface::real_type error=
+// STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+// if (error>1.e-3){
+// INFOS("WRONG CALCULATION...residual=" << error);
+// exit(0);
+// }
+
+ }
+
+private :
+
+ typename Interface::stl_vector A_stl;
+ typename Interface::stl_vector B_stl;
+
+ typename Interface::gene_vector A_ref;
+ typename Interface::gene_vector B_ref;
+
+ typename Interface::gene_vector A;
+ typename Interface::gene_vector B;
+
+ int _size;
+};
+
+
+#endif
diff --git a/eigen/bench/btl/actions/action_symv.hh b/eigen/bench/btl/actions/action_symv.hh
new file mode 100644
index 0000000..a32b9df
--- /dev/null
+++ b/eigen/bench/btl/actions/action_symv.hh
@@ -0,0 +1,139 @@
+//=====================================================
+// File : action_symv.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_SYMV
+#define ACTION_SYMV
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_symv {
+
+public :
+
+ // Ctor
+
+ BTL_DONT_INLINE Action_symv( int size ):_size(size)
+ {
+ MESSAGE("Action_symv Ctor");
+
+ // STL matrix and vector initialization
+ init_matrix_symm<pseudo_random>(A_stl,_size);
+ init_vector<pseudo_random>(B_stl,_size);
+ init_vector<null_function>(X_stl,_size);
+ init_vector<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::vector_from_stl(B_ref,B_stl);
+ Interface::vector_from_stl(B,B_stl);
+ Interface::vector_from_stl(X_ref,X_stl);
+ Interface::vector_from_stl(X,X_stl);
+
+ }
+
+ // invalidate copy ctor
+
+ Action_symv( const Action_symv & )
+ {
+ INFOS("illegal call to Action_symv Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+ BTL_DONT_INLINE ~Action_symv( void ){
+ Interface::free_matrix(A,_size);
+ Interface::free_vector(B);
+ Interface::free_vector(X);
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_vector(B_ref);
+ Interface::free_vector(X_ref);
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "symv_" + Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return 2.0*_size*_size;
+ }
+
+ BTL_DONT_INLINE void initialize( void ){
+
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_vector(B_ref,B,_size);
+ Interface::copy_vector(X_ref,X,_size);
+
+ }
+
+ BTL_DONT_INLINE void calculate( void ) {
+ BTL_ASM_COMMENT("#begin symv");
+ Interface::symv(A,B,X,_size);
+ BTL_ASM_COMMENT("end symv");
+ }
+
+ BTL_DONT_INLINE void check_result( void ){
+ if (_size>128) return;
+ // calculation check
+ Interface::vector_to_stl(X,resu_stl);
+
+ STL_interface<typename Interface::real_type>::symv(A_stl,B_stl,X_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+ if (error>1.e-5){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(0);
+ }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_vector B_stl;
+ typename Interface::stl_vector X_stl;
+ typename Interface::stl_vector resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_vector B_ref;
+ typename Interface::gene_vector X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_vector B;
+ typename Interface::gene_vector X;
+
+
+ int _size;
+
+};
+
+
+#endif
diff --git a/eigen/bench/btl/actions/action_syr2.hh b/eigen/bench/btl/actions/action_syr2.hh
new file mode 100644
index 0000000..7c6712b
--- /dev/null
+++ b/eigen/bench/btl/actions/action_syr2.hh
@@ -0,0 +1,133 @@
+//=====================================================
+// File : action_syr2.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_SYR2
+#define ACTION_SYR2
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_syr2 {
+
+public :
+
+ // Ctor
+
+ BTL_DONT_INLINE Action_syr2( int size ):_size(size)
+ {
+ // STL matrix and vector initialization
+ typename Interface::stl_matrix tmp;
+ init_matrix<pseudo_random>(A_stl,_size);
+ init_vector<pseudo_random>(B_stl,_size);
+ init_vector<pseudo_random>(X_stl,_size);
+ init_vector<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::vector_from_stl(B_ref,B_stl);
+ Interface::vector_from_stl(B,B_stl);
+ Interface::vector_from_stl(X_ref,X_stl);
+ Interface::vector_from_stl(X,X_stl);
+ }
+
+ // invalidate copy ctor
+ Action_syr2( const Action_syr2 & )
+ {
+ INFOS("illegal call to Action_syr2 Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+ BTL_DONT_INLINE ~Action_syr2( void ){
+ Interface::free_matrix(A,_size);
+ Interface::free_vector(B);
+ Interface::free_vector(X);
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_vector(B_ref);
+ Interface::free_vector(X_ref);
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "syr2_" + Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return 2.0*_size*_size;
+ }
+
+ BTL_DONT_INLINE void initialize( void ){
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_vector(B_ref,B,_size);
+ Interface::copy_vector(X_ref,X,_size);
+ }
+
+ BTL_DONT_INLINE void calculate( void ) {
+ BTL_ASM_COMMENT("#begin syr2");
+ Interface::syr2(A,B,X,_size);
+ BTL_ASM_COMMENT("end syr2");
+ }
+
+ BTL_DONT_INLINE void check_result( void ){
+ // calculation check
+ Interface::vector_to_stl(X,resu_stl);
+
+ STL_interface<typename Interface::real_type>::syr2(A_stl,B_stl,X_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+ if (error>1.e-3){
+ INFOS("WRONG CALCULATION...residual=" << error);
+// exit(0);
+ }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_vector B_stl;
+ typename Interface::stl_vector X_stl;
+ typename Interface::stl_vector resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_vector B_ref;
+ typename Interface::gene_vector X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_vector B;
+ typename Interface::gene_vector X;
+
+
+ int _size;
+
+};
+
+
+#endif
diff --git a/eigen/bench/btl/actions/action_trisolve.hh b/eigen/bench/btl/actions/action_trisolve.hh
new file mode 100644
index 0000000..d6f0b47
--- /dev/null
+++ b/eigen/bench/btl/actions/action_trisolve.hh
@@ -0,0 +1,137 @@
+//=====================================================
+// File : action_trisolve.hh
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_TRISOLVE
+#define ACTION_TRISOLVE
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_trisolve {
+
+public :
+
+ // Ctor
+
+ Action_trisolve( int size ):_size(size)
+ {
+ MESSAGE("Action_trisolve Ctor");
+
+ // STL vector initialization
+ init_matrix<pseudo_random>(L_stl,_size);
+ init_vector<pseudo_random>(B_stl,_size);
+ init_vector<null_function>(X_stl,_size);
+ for (int j=0; j<_size; ++j)
+ {
+ for (int i=0; i<j; ++i)
+ L_stl[j][i] = 0;
+ L_stl[j][j] += 3;
+ }
+
+ init_vector<null_function>(resu_stl,_size);
+
+ // generic matrix and vector initialization
+ Interface::matrix_from_stl(L,L_stl);
+ Interface::vector_from_stl(X,X_stl);
+ Interface::vector_from_stl(B,B_stl);
+
+ _cost = 0;
+ for (int j=0; j<_size; ++j)
+ {
+ _cost += 2*j + 1;
+ }
+ }
+
+ // invalidate copy ctor
+
+ Action_trisolve( const Action_trisolve & )
+ {
+ INFOS("illegal call to Action_trisolve Copy Ctor");
+ exit(1);
+ }
+
+ // Dtor
+
+ ~Action_trisolve( void ){
+
+ MESSAGE("Action_trisolve Dtor");
+
+ // deallocation
+ Interface::free_matrix(L,_size);
+ Interface::free_vector(B);
+ Interface::free_vector(X);
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "trisolve_vector_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return _cost;
+ }
+
+ inline void initialize( void ){
+ //Interface::copy_vector(X_ref,X,_size);
+ }
+
+ inline void calculate( void ) {
+ Interface::trisolve_lower(L,B,X,_size);
+ }
+
+ void check_result(){
+ if (_size>128) return;
+ // calculation check
+ Interface::vector_to_stl(X,resu_stl);
+
+ STL_interface<typename Interface::real_type>::trisolve_lower(L_stl,B_stl,X_stl,_size);
+
+ typename Interface::real_type error=
+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+
+ if (error>1.e-4){
+ INFOS("WRONG CALCULATION...residual=" << error);
+ exit(2);
+ } //else INFOS("CALCULATION OK...residual=" << error);
+
+ }
+
+private :
+
+ typename Interface::stl_matrix L_stl;
+ typename Interface::stl_vector X_stl;
+ typename Interface::stl_vector B_stl;
+ typename Interface::stl_vector resu_stl;
+
+ typename Interface::gene_matrix L;
+ typename Interface::gene_vector X;
+ typename Interface::gene_vector B;
+
+ int _size;
+ double _cost;
+};
+
+#endif
diff --git a/eigen/bench/btl/actions/action_trisolve_matrix.hh b/eigen/bench/btl/actions/action_trisolve_matrix.hh
new file mode 100644
index 0000000..0fc2bb9
--- /dev/null
+++ b/eigen/bench/btl/actions/action_trisolve_matrix.hh
@@ -0,0 +1,165 @@
+//=====================================================
+// File : action_matrix_matrix_product.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_TRISOLVE_MATRIX_PRODUCT
+#define ACTION_TRISOLVE_MATRIX_PRODUCT
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_trisolve_matrix {
+
+public :
+
+ // Ctor
+
+ Action_trisolve_matrix( int size ):_size(size)
+ {
+ MESSAGE("Action_trisolve_matrix Ctor");
+
+ // STL matrix and vector initialization
+
+ init_matrix<pseudo_random>(A_stl,_size);
+ init_matrix<pseudo_random>(B_stl,_size);
+ init_matrix<null_function>(X_stl,_size);
+ init_matrix<null_function>(resu_stl,_size);
+
+ for (int j=0; j<_size; ++j)
+ {
+ for (int i=0; i<j; ++i)
+ A_stl[j][i] = 0;
+ A_stl[j][j] += 3;
+ }
+
+ // generic matrix and vector initialization
+
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(B_ref,B_stl);
+ Interface::matrix_from_stl(X_ref,X_stl);
+
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::matrix_from_stl(B,B_stl);
+ Interface::matrix_from_stl(X,X_stl);
+
+ _cost = 0;
+ for (int j=0; j<_size; ++j)
+ {
+ _cost += 2*j + 1;
+ }
+ _cost *= _size;
+ }
+
+ // invalidate copy ctor
+
+ Action_trisolve_matrix( const Action_trisolve_matrix & )
+ {
+ INFOS("illegal call to Action_trisolve_matrix Copy Ctor");
+ exit(0);
+ }
+
+ // Dtor
+
+ ~Action_trisolve_matrix( void ){
+
+ MESSAGE("Action_trisolve_matrix Dtor");
+
+ // deallocation
+
+ Interface::free_matrix(A,_size);
+ Interface::free_matrix(B,_size);
+ Interface::free_matrix(X,_size);
+
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_matrix(B_ref,_size);
+ Interface::free_matrix(X_ref,_size);
+
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "trisolve_matrix_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return _cost;
+ }
+
+ inline void initialize( void ){
+
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_matrix(B_ref,B,_size);
+ Interface::copy_matrix(X_ref,X,_size);
+
+ }
+
+ inline void calculate( void ) {
+ Interface::trisolve_lower_matrix(A,B,X,_size);
+ }
+
+ void check_result( void ){
+
+ // calculation check
+
+// Interface::matrix_to_stl(X,resu_stl);
+//
+// STL_interface<typename Interface::real_type>::matrix_matrix_product(A_stl,B_stl,X_stl,_size);
+//
+// typename Interface::real_type error=
+// STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+//
+// if (error>1.e-6){
+// INFOS("WRONG CALCULATION...residual=" << error);
+// // exit(1);
+// }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_matrix B_stl;
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_matrix B_ref;
+ typename Interface::gene_matrix X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_matrix B;
+ typename Interface::gene_matrix X;
+
+ int _size;
+ double _cost;
+
+};
+
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/actions/action_trmm.hh b/eigen/bench/btl/actions/action_trmm.hh
new file mode 100644
index 0000000..8f78138
--- /dev/null
+++ b/eigen/bench/btl/actions/action_trmm.hh
@@ -0,0 +1,165 @@
+//=====================================================
+// File : action_matrix_matrix_product.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef ACTION_TRMM
+#define ACTION_TRMM
+#include "utilities.h"
+#include "STL_interface.hh"
+#include <string>
+#include "init/init_function.hh"
+#include "init/init_vector.hh"
+#include "init/init_matrix.hh"
+
+using namespace std;
+
+template<class Interface>
+class Action_trmm {
+
+public :
+
+ // Ctor
+
+ Action_trmm( int size ):_size(size)
+ {
+ MESSAGE("Action_trmm Ctor");
+
+ // STL matrix and vector initialization
+
+ init_matrix<pseudo_random>(A_stl,_size);
+ init_matrix<pseudo_random>(B_stl,_size);
+ init_matrix<null_function>(X_stl,_size);
+ init_matrix<null_function>(resu_stl,_size);
+
+ for (int j=0; j<_size; ++j)
+ {
+ for (int i=0; i<j; ++i)
+ A_stl[j][i] = 0;
+ A_stl[j][j] += 3;
+ }
+
+ // generic matrix and vector initialization
+
+ Interface::matrix_from_stl(A_ref,A_stl);
+ Interface::matrix_from_stl(B_ref,B_stl);
+ Interface::matrix_from_stl(X_ref,X_stl);
+
+ Interface::matrix_from_stl(A,A_stl);
+ Interface::matrix_from_stl(B,B_stl);
+ Interface::matrix_from_stl(X,X_stl);
+
+ _cost = 0;
+ for (int j=0; j<_size; ++j)
+ {
+ _cost += 2*j + 1;
+ }
+ _cost *= _size;
+ }
+
+ // invalidate copy ctor
+
+ Action_trmm( const Action_trmm & )
+ {
+ INFOS("illegal call to Action_trmm Copy Ctor");
+ exit(0);
+ }
+
+ // Dtor
+
+ ~Action_trmm( void ){
+
+ MESSAGE("Action_trmm Dtor");
+
+ // deallocation
+
+ Interface::free_matrix(A,_size);
+ Interface::free_matrix(B,_size);
+ Interface::free_matrix(X,_size);
+
+ Interface::free_matrix(A_ref,_size);
+ Interface::free_matrix(B_ref,_size);
+ Interface::free_matrix(X_ref,_size);
+
+ }
+
+ // action name
+
+ static inline std::string name( void )
+ {
+ return "trmm_"+Interface::name();
+ }
+
+ double nb_op_base( void ){
+ return _cost;
+ }
+
+ inline void initialize( void ){
+
+ Interface::copy_matrix(A_ref,A,_size);
+ Interface::copy_matrix(B_ref,B,_size);
+ Interface::copy_matrix(X_ref,X,_size);
+
+ }
+
+ inline void calculate( void ) {
+ Interface::trmm(A,B,X,_size);
+ }
+
+ void check_result( void ){
+
+ // calculation check
+
+// Interface::matrix_to_stl(X,resu_stl);
+//
+// STL_interface<typename Interface::real_type>::matrix_matrix_product(A_stl,B_stl,X_stl,_size);
+//
+// typename Interface::real_type error=
+// STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
+//
+// if (error>1.e-6){
+// INFOS("WRONG CALCULATION...residual=" << error);
+// // exit(1);
+// }
+
+ }
+
+private :
+
+ typename Interface::stl_matrix A_stl;
+ typename Interface::stl_matrix B_stl;
+ typename Interface::stl_matrix X_stl;
+ typename Interface::stl_matrix resu_stl;
+
+ typename Interface::gene_matrix A_ref;
+ typename Interface::gene_matrix B_ref;
+ typename Interface::gene_matrix X_ref;
+
+ typename Interface::gene_matrix A;
+ typename Interface::gene_matrix B;
+ typename Interface::gene_matrix X;
+
+ int _size;
+ double _cost;
+
+};
+
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/actions/basic_actions.hh b/eigen/bench/btl/actions/basic_actions.hh
new file mode 100644
index 0000000..a3333ea
--- /dev/null
+++ b/eigen/bench/btl/actions/basic_actions.hh
@@ -0,0 +1,21 @@
+
+#include "action_axpy.hh"
+#include "action_axpby.hh"
+
+#include "action_matrix_vector_product.hh"
+#include "action_atv_product.hh"
+
+#include "action_matrix_matrix_product.hh"
+// #include "action_ata_product.hh"
+#include "action_aat_product.hh"
+
+#include "action_trisolve.hh"
+#include "action_trmm.hh"
+#include "action_symv.hh"
+// #include "action_symm.hh"
+#include "action_syr2.hh"
+#include "action_ger.hh"
+#include "action_rot.hh"
+
+// #include "action_lu_solve.hh"
+
diff --git a/eigen/bench/btl/cmake/FindACML.cmake b/eigen/bench/btl/cmake/FindACML.cmake
new file mode 100644
index 0000000..f45ae1b
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindACML.cmake
@@ -0,0 +1,49 @@
+
+if (ACML_LIBRARIES)
+ set(ACML_FIND_QUIETLY TRUE)
+endif (ACML_LIBRARIES)
+
+find_library(ACML_LIBRARIES
+ NAMES
+ acml_mp acml_mv
+ PATHS
+ $ENV{ACMLDIR}/lib
+ $ENV{ACML_DIR}/lib
+ ${LIB_INSTALL_DIR}
+)
+
+find_file(ACML_LIBRARIES
+ NAMES
+ libacml_mp.so
+ PATHS
+ /usr/lib
+ $ENV{ACMLDIR}/lib
+ ${LIB_INSTALL_DIR}
+)
+
+if(NOT ACML_LIBRARIES)
+ message(STATUS "Multi-threaded library not found, looking for single-threaded")
+ find_library(ACML_LIBRARIES
+ NAMES
+ acml acml_mv
+ PATHS
+ $ENV{ACMLDIR}/lib
+ $ENV{ACML_DIR}/lib
+ ${LIB_INSTALL_DIR}
+ )
+ find_file(ACML_LIBRARIES
+ libacml.so libacml_mv.so
+ PATHS
+ /usr/lib
+ $ENV{ACMLDIR}/lib
+ ${LIB_INSTALL_DIR}
+ )
+endif()
+
+
+
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ACML DEFAULT_MSG ACML_LIBRARIES)
+
+mark_as_advanced(ACML_LIBRARIES)
diff --git a/eigen/bench/btl/cmake/FindATLAS.cmake b/eigen/bench/btl/cmake/FindATLAS.cmake
new file mode 100644
index 0000000..6b90652
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindATLAS.cmake
@@ -0,0 +1,39 @@
+
+if (ATLAS_LIBRARIES)
+ set(ATLAS_FIND_QUIETLY TRUE)
+endif (ATLAS_LIBRARIES)
+
+find_file(ATLAS_LIB libatlas.so.3 PATHS /usr/lib $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+find_library(ATLAS_LIB atlas PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+
+find_file(ATLAS_CBLAS libcblas.so.3 PATHS /usr/lib $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+find_library(ATLAS_CBLAS cblas PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+
+find_file(ATLAS_LAPACK liblapack_atlas.so.3 PATHS /usr/lib $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+find_library(ATLAS_LAPACK lapack_atlas PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+
+if(NOT ATLAS_LAPACK)
+ find_file(ATLAS_LAPACK liblapack.so.3 PATHS /usr/lib/atlas $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+ find_library(ATLAS_LAPACK lapack PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+endif(NOT ATLAS_LAPACK)
+
+find_file(ATLAS_F77BLAS libf77blas.so.3 PATHS /usr/lib $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+find_library(ATLAS_F77BLAS f77blas PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})
+
+if(ATLAS_LIB AND ATLAS_CBLAS AND ATLAS_LAPACK AND ATLAS_F77BLAS)
+
+ set(ATLAS_LIBRARIES ${ATLAS_LAPACK} ${ATLAS_CBLAS} ${ATLAS_F77BLAS} ${ATLAS_LIB})
+
+ # search the default lapack lib link to it
+ find_file(ATLAS_REFERENCE_LAPACK liblapack.so.3 PATHS /usr/lib /usr/lib64)
+ find_library(ATLAS_REFERENCE_LAPACK NAMES lapack)
+ if(ATLAS_REFERENCE_LAPACK)
+ set(ATLAS_LIBRARIES ${ATLAS_LIBRARIES} ${ATLAS_REFERENCE_LAPACK})
+ endif()
+
+endif(ATLAS_LIB AND ATLAS_CBLAS AND ATLAS_LAPACK AND ATLAS_F77BLAS)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ATLAS DEFAULT_MSG ATLAS_LIBRARIES)
+
+mark_as_advanced(ATLAS_LIBRARIES)
diff --git a/eigen/bench/btl/cmake/FindBlitz.cmake b/eigen/bench/btl/cmake/FindBlitz.cmake
new file mode 100644
index 0000000..92880bb
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindBlitz.cmake
@@ -0,0 +1,40 @@
+# - Try to find blitz lib
+# Once done this will define
+#
+# BLITZ_FOUND - system has blitz lib
+# BLITZ_INCLUDES - the blitz include directory
+# BLITZ_LIBRARIES - The libraries needed to use blitz
+
+# Copyright (c) 2006, Montel Laurent, <montel@kde.org>
+# Copyright (c) 2007, Allen Winter, <winter@kde.org>
+# Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+# include(FindLibraryWithDebug)
+
+if (BLITZ_INCLUDES AND BLITZ_LIBRARIES)
+ set(Blitz_FIND_QUIETLY TRUE)
+endif (BLITZ_INCLUDES AND BLITZ_LIBRARIES)
+
+find_path(BLITZ_INCLUDES
+ NAMES
+ blitz/array.h
+ PATH_SUFFIXES blitz*
+ PATHS
+ $ENV{BLITZDIR}/include
+ ${INCLUDE_INSTALL_DIR}
+)
+
+find_library(BLITZ_LIBRARIES
+ blitz
+ PATHS
+ $ENV{BLITZDIR}/lib
+ ${LIB_INSTALL_DIR}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Blitz DEFAULT_MSG
+ BLITZ_INCLUDES BLITZ_LIBRARIES)
+
+mark_as_advanced(BLITZ_INCLUDES BLITZ_LIBRARIES)
diff --git a/eigen/bench/btl/cmake/FindCBLAS.cmake b/eigen/bench/btl/cmake/FindCBLAS.cmake
new file mode 100644
index 0000000..554f029
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindCBLAS.cmake
@@ -0,0 +1,34 @@
+# include(FindLibraryWithDebug)
+
+if (CBLAS_INCLUDES AND CBLAS_LIBRARIES)
+ set(CBLAS_FIND_QUIETLY TRUE)
+endif (CBLAS_INCLUDES AND CBLAS_LIBRARIES)
+
+find_path(CBLAS_INCLUDES
+ NAMES
+ cblas.h
+ PATHS
+ $ENV{CBLASDIR}/include
+ ${INCLUDE_INSTALL_DIR}
+)
+
+find_library(CBLAS_LIBRARIES
+ cblas
+ PATHS
+ $ENV{CBLASDIR}/lib
+ ${LIB_INSTALL_DIR}
+)
+
+find_file(CBLAS_LIBRARIES
+ libcblas.so.3
+ PATHS
+ /usr/lib
+ $ENV{CBLASDIR}/lib
+ ${LIB_INSTALL_DIR}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(CBLAS DEFAULT_MSG
+ CBLAS_INCLUDES CBLAS_LIBRARIES)
+
+mark_as_advanced(CBLAS_INCLUDES CBLAS_LIBRARIES)
diff --git a/eigen/bench/btl/cmake/FindGMM.cmake b/eigen/bench/btl/cmake/FindGMM.cmake
new file mode 100644
index 0000000..5049c64
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindGMM.cmake
@@ -0,0 +1,17 @@
+if (GMM_INCLUDE_DIR)
+ # in cache already
+ set(GMM_FOUND TRUE)
+else (GMM_INCLUDE_DIR)
+
+find_path(GMM_INCLUDE_DIR NAMES gmm/gmm.h
+ PATHS
+ ${INCLUDE_INSTALL_DIR}
+ ${GMM_INCLUDE_PATH}
+ )
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMM DEFAULT_MSG GMM_INCLUDE_DIR )
+
+mark_as_advanced(GMM_INCLUDE_DIR)
+
+endif(GMM_INCLUDE_DIR)
diff --git a/eigen/bench/btl/cmake/FindGOTO.cmake b/eigen/bench/btl/cmake/FindGOTO.cmake
new file mode 100644
index 0000000..67ea093
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindGOTO.cmake
@@ -0,0 +1,15 @@
+
+if (GOTO_LIBRARIES)
+ set(GOTO_FIND_QUIETLY TRUE)
+endif (GOTO_LIBRARIES)
+
+find_library(GOTO_LIBRARIES goto PATHS $ENV{GOTODIR} ${LIB_INSTALL_DIR})
+
+if(GOTO_LIBRARIES AND CMAKE_COMPILER_IS_GNUCXX)
+ set(GOTO_LIBRARIES ${GOTO_LIBRARIES} "-lpthread -lgfortran")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(GOTO DEFAULT_MSG GOTO_LIBRARIES)
+
+mark_as_advanced(GOTO_LIBRARIES)
diff --git a/eigen/bench/btl/cmake/FindGOTO2.cmake b/eigen/bench/btl/cmake/FindGOTO2.cmake
new file mode 100644
index 0000000..baa68d2
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindGOTO2.cmake
@@ -0,0 +1,25 @@
+
+if (GOTO2_LIBRARIES)
+ set(GOTO2_FIND_QUIETLY TRUE)
+endif (GOTO2_LIBRARIES)
+#
+# find_path(GOTO_INCLUDES
+# NAMES
+# cblas.h
+# PATHS
+# $ENV{GOTODIR}/include
+# ${INCLUDE_INSTALL_DIR}
+# )
+
+find_file(GOTO2_LIBRARIES libgoto2.so PATHS /usr/lib $ENV{GOTO2DIR} ${LIB_INSTALL_DIR})
+find_library(GOTO2_LIBRARIES goto2 PATHS $ENV{GOTO2DIR} ${LIB_INSTALL_DIR})
+
+if(GOTO2_LIBRARIES AND CMAKE_COMPILER_IS_GNUCXX)
+ set(GOTO2_LIBRARIES ${GOTO2_LIBRARIES} "-lpthread -lgfortran")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(GOTO2 DEFAULT_MSG
+ GOTO2_LIBRARIES)
+
+mark_as_advanced(GOTO2_LIBRARIES)
diff --git a/eigen/bench/btl/cmake/FindMKL.cmake b/eigen/bench/btl/cmake/FindMKL.cmake
new file mode 100644
index 0000000..f4d7c6e
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindMKL.cmake
@@ -0,0 +1,65 @@
+
+if (MKL_LIBRARIES)
+ set(MKL_FIND_QUIETLY TRUE)
+endif (MKL_LIBRARIES)
+
+if(CMAKE_MINOR_VERSION GREATER 4)
+
+if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
+
+find_library(MKL_LIBRARIES
+ mkl_core
+ PATHS
+ $ENV{MKLLIB}
+ /opt/intel/mkl/*/lib/em64t
+ /opt/intel/Compiler/*/*/mkl/lib/em64t
+ ${LIB_INSTALL_DIR}
+)
+
+find_library(MKL_GUIDE
+ guide
+ PATHS
+ $ENV{MKLLIB}
+ /opt/intel/mkl/*/lib/em64t
+ /opt/intel/Compiler/*/*/mkl/lib/em64t
+ /opt/intel/Compiler/*/*/lib/intel64
+ ${LIB_INSTALL_DIR}
+)
+
+if(MKL_LIBRARIES AND MKL_GUIDE)
+ set(MKL_LIBRARIES ${MKL_LIBRARIES} mkl_intel_lp64 mkl_sequential ${MKL_GUIDE} pthread)
+endif()
+
+else(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
+
+find_library(MKL_LIBRARIES
+ mkl_core
+ PATHS
+ $ENV{MKLLIB}
+ /opt/intel/mkl/*/lib/32
+ /opt/intel/Compiler/*/*/mkl/lib/32
+ ${LIB_INSTALL_DIR}
+)
+
+find_library(MKL_GUIDE
+ guide
+ PATHS
+ $ENV{MKLLIB}
+ /opt/intel/mkl/*/lib/32
+ /opt/intel/Compiler/*/*/mkl/lib/32
+ /opt/intel/Compiler/*/*/lib/intel32
+ ${LIB_INSTALL_DIR}
+)
+
+if(MKL_LIBRARIES AND MKL_GUIDE)
+ set(MKL_LIBRARIES ${MKL_LIBRARIES} mkl_intel mkl_sequential ${MKL_GUIDE} pthread)
+endif()
+
+endif(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
+
+endif(CMAKE_MINOR_VERSION GREATER 4)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MKL DEFAULT_MSG MKL_LIBRARIES)
+
+mark_as_advanced(MKL_LIBRARIES)
diff --git a/eigen/bench/btl/cmake/FindMTL4.cmake b/eigen/bench/btl/cmake/FindMTL4.cmake
new file mode 100644
index 0000000..3de4909
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindMTL4.cmake
@@ -0,0 +1,31 @@
+# - Try to find eigen2 headers
+# Once done this will define
+#
+# MTL4_FOUND - system has eigen2 lib
+# MTL4_INCLUDE_DIR - the eigen2 include directory
+#
+# Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+# Adapted from FindEigen.cmake:
+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+if (MTL4_INCLUDE_DIR)
+
+ # in cache already
+ set(MTL4_FOUND TRUE)
+
+else (MTL4_INCLUDE_DIR)
+
+find_path(MTL4_INCLUDE_DIR NAMES boost/numeric/mtl/mtl.hpp
+ PATHS
+ ${INCLUDE_INSTALL_DIR}
+ )
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MTL4 DEFAULT_MSG MTL4_INCLUDE_DIR)
+
+mark_as_advanced(MTL4_INCLUDE_DIR)
+
+endif(MTL4_INCLUDE_DIR)
+
diff --git a/eigen/bench/btl/cmake/FindPackageHandleStandardArgs.cmake b/eigen/bench/btl/cmake/FindPackageHandleStandardArgs.cmake
new file mode 100644
index 0000000..7f122ed
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindPackageHandleStandardArgs.cmake
@@ -0,0 +1,60 @@
+# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME (DEFAULT_MSG|"Custom failure message") VAR1 ... )
+#
+# This macro is intended to be used in FindXXX.cmake modules files.
+# It handles the REQUIRED and QUIET argument to FIND_PACKAGE() and
+# it also sets the <UPPERCASED_NAME>_FOUND variable.
+# The package is found if all variables listed are TRUE.
+# Example:
+#
+# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR)
+#
+# LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and
+# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE.
+# If it is not found and REQUIRED was used, it fails with FATAL_ERROR,
+# independent whether QUIET was used or not.
+#
+# If it is found, the location is reported using the VAR1 argument, so
+# here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out.
+# If the second argument is DEFAULT_MSG, the message in the failure case will
+# be "Could NOT find LibXml2", if you don't like this message you can specify
+# your own custom failure message there.
+
+MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 )
+
+ IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")
+ IF (${_NAME}_FIND_REQUIRED)
+ SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}")
+ ELSE (${_NAME}_FIND_REQUIRED)
+ SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}")
+ ENDIF (${_NAME}_FIND_REQUIRED)
+ ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")
+ SET(_FAIL_MESSAGE "${_FAIL_MSG}")
+ ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")
+
+ STRING(TOUPPER ${_NAME} _NAME_UPPER)
+
+ SET(${_NAME_UPPER}_FOUND TRUE)
+ IF(NOT ${_VAR1})
+ SET(${_NAME_UPPER}_FOUND FALSE)
+ ENDIF(NOT ${_VAR1})
+
+ FOREACH(_CURRENT_VAR ${ARGN})
+ IF(NOT ${_CURRENT_VAR})
+ SET(${_NAME_UPPER}_FOUND FALSE)
+ ENDIF(NOT ${_CURRENT_VAR})
+ ENDFOREACH(_CURRENT_VAR)
+
+ IF (${_NAME_UPPER}_FOUND)
+ IF (NOT ${_NAME}_FIND_QUIETLY)
+ MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}")
+ ENDIF (NOT ${_NAME}_FIND_QUIETLY)
+ ELSE (${_NAME_UPPER}_FOUND)
+ IF (${_NAME}_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}")
+ ELSE (${_NAME}_FIND_REQUIRED)
+ IF (NOT ${_NAME}_FIND_QUIETLY)
+ MESSAGE(STATUS "${_FAIL_MESSAGE}")
+ ENDIF (NOT ${_NAME}_FIND_QUIETLY)
+ ENDIF (${_NAME}_FIND_REQUIRED)
+ ENDIF (${_NAME_UPPER}_FOUND)
+ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS)
diff --git a/eigen/bench/btl/cmake/FindTvmet.cmake b/eigen/bench/btl/cmake/FindTvmet.cmake
new file mode 100644
index 0000000..26a29d9
--- /dev/null
+++ b/eigen/bench/btl/cmake/FindTvmet.cmake
@@ -0,0 +1,32 @@
+# - Try to find tvmet headers
+# Once done this will define
+#
+# TVMET_FOUND - system has tvmet lib
+# TVMET_INCLUDE_DIR - the tvmet include directory
+#
+# Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+# Adapted from FindEigen.cmake:
+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+if (TVMET_INCLUDE_DIR)
+
+ # in cache already
+ set(TVMET_FOUND TRUE)
+
+else (TVMET_INCLUDE_DIR)
+
+find_path(TVMET_INCLUDE_DIR NAMES tvmet/tvmet.h
+ PATHS
+ ${TVMETDIR}/
+ ${INCLUDE_INSTALL_DIR}
+ )
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Tvmet DEFAULT_MSG TVMET_INCLUDE_DIR)
+
+mark_as_advanced(TVMET_INCLUDE_DIR)
+
+endif(TVMET_INCLUDE_DIR)
+
diff --git a/eigen/bench/btl/cmake/MacroOptionalAddSubdirectory.cmake b/eigen/bench/btl/cmake/MacroOptionalAddSubdirectory.cmake
new file mode 100644
index 0000000..545048b
--- /dev/null
+++ b/eigen/bench/btl/cmake/MacroOptionalAddSubdirectory.cmake
@@ -0,0 +1,31 @@
+# - MACRO_OPTIONAL_ADD_SUBDIRECTORY() combines ADD_SUBDIRECTORY() with an OPTION()
+# MACRO_OPTIONAL_ADD_SUBDIRECTORY( <dir> )
+# If you use MACRO_OPTIONAL_ADD_SUBDIRECTORY() instead of ADD_SUBDIRECTORY(),
+# this will have two effects
+# 1 - CMake will not complain if the directory doesn't exist
+# This makes sense if you want to distribute just one of the subdirs
+# in a source package, e.g. just one of the subdirs in kdeextragear.
+# 2 - If the directory exists, it will offer an option to skip the
+# subdirectory.
+# This is useful if you want to compile only a subset of all
+# directories.
+
+# Copyright (c) 2007, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+MACRO (MACRO_OPTIONAL_ADD_SUBDIRECTORY _dir )
+ GET_FILENAME_COMPONENT(_fullPath ${_dir} ABSOLUTE)
+ IF(EXISTS ${_fullPath})
+ IF(${ARGC} EQUAL 2)
+ OPTION(BUILD_${_dir} "Build directory ${_dir}" ${ARGV1})
+ ELSE(${ARGC} EQUAL 2)
+ OPTION(BUILD_${_dir} "Build directory ${_dir}" TRUE)
+ ENDIF(${ARGC} EQUAL 2)
+ IF(BUILD_${_dir})
+ ADD_SUBDIRECTORY(${_dir})
+ ENDIF(BUILD_${_dir})
+ ENDIF(EXISTS ${_fullPath})
+ENDMACRO (MACRO_OPTIONAL_ADD_SUBDIRECTORY)
diff --git a/eigen/bench/btl/data/CMakeLists.txt b/eigen/bench/btl/data/CMakeLists.txt
new file mode 100644
index 0000000..6af2a36
--- /dev/null
+++ b/eigen/bench/btl/data/CMakeLists.txt
@@ -0,0 +1,32 @@
+
+ADD_CUSTOM_TARGET(copy_scripts)
+
+SET(script_files go_mean mk_mean_script.sh mk_new_gnuplot.sh
+ perlib_plot_settings.txt action_settings.txt gnuplot_common_settings.hh )
+
+FOREACH(script_file ${script_files})
+ADD_CUSTOM_COMMAND(
+ TARGET copy_scripts
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${script_file} ${CMAKE_CURRENT_BINARY_DIR}/
+ ARGS
+)
+ENDFOREACH(script_file)
+
+ADD_CUSTOM_COMMAND(
+ TARGET copy_scripts
+ POST_BUILD
+ COMMAND ${CMAKE_CXX_COMPILER} --version | head -n 1 > ${CMAKE_CURRENT_BINARY_DIR}/compiler_version.txt
+ ARGS
+)
+ADD_CUSTOM_COMMAND(
+ TARGET copy_scripts
+ POST_BUILD
+ COMMAND echo "${Eigen_SOURCE_DIR}" > ${CMAKE_CURRENT_BINARY_DIR}/eigen_root_dir.txt
+ ARGS
+)
+
+add_executable(smooth smooth.cxx)
+add_executable(regularize regularize.cxx)
+add_executable(main mean.cxx)
+add_dependencies(main copy_scripts)
diff --git a/eigen/bench/btl/data/action_settings.txt b/eigen/bench/btl/data/action_settings.txt
new file mode 100644
index 0000000..e32213e
--- /dev/null
+++ b/eigen/bench/btl/data/action_settings.txt
@@ -0,0 +1,19 @@
+aat ; "{/*1.5 A x A^T}" ; "matrix size" ; 4:3000
+ata ; "{/*1.5 A^T x A}" ; "matrix size" ; 4:3000
+atv ; "{/*1.5 matrix^T x vector}" ; "matrix size" ; 4:3000
+axpby ; "{/*1.5 Y = alpha X + beta Y}" ; "vector size" ; 5:1000000
+axpy ; "{/*1.5 Y += alpha X}" ; "vector size" ; 5:1000000
+matrix_matrix ; "{/*1.5 matrix matrix product}" ; "matrix size" ; 4:3000
+matrix_vector ; "{/*1.5 matrix vector product}" ; "matrix size" ; 4:3000
+trmm ; "{/*1.5 triangular matrix matrix product}" ; "matrix size" ; 4:3000
+trisolve_vector ; "{/*1.5 triangular solver - vector (X = inv(L) X)}" ; "size" ; 4:3000
+trisolve_matrix ; "{/*1.5 triangular solver - matrix (M = inv(L) M)}" ; "size" ; 4:3000
+cholesky ; "{/*1.5 Cholesky decomposition}" ; "matrix size" ; 4:3000
+complete_lu_decomp ; "{/*1.5 Complete LU decomposition}" ; "matrix size" ; 4:3000
+partial_lu_decomp ; "{/*1.5 Partial LU decomposition}" ; "matrix size" ; 4:3000
+tridiagonalization ; "{/*1.5 Tridiagonalization}" ; "matrix size" ; 4:3000
+hessenberg ; "{/*1.5 Hessenberg decomposition}" ; "matrix size" ; 4:3000
+symv ; "{/*1.5 symmetric matrix vector product}" ; "matrix size" ; 4:3000
+syr2 ; "{/*1.5 symmretric rank-2 update (A += u^T v + u v^T)}" ; "matrix size" ; 4:3000
+ger ; "{/*1.5 general rank-1 update (A += u v^T)}" ; "matrix size" ; 4:3000
+rot ; "{/*1.5 apply rotation in the plane}" ; "vector size" ; 4:1000000 \ No newline at end of file
diff --git a/eigen/bench/btl/data/gnuplot_common_settings.hh b/eigen/bench/btl/data/gnuplot_common_settings.hh
new file mode 100644
index 0000000..6f677df
--- /dev/null
+++ b/eigen/bench/btl/data/gnuplot_common_settings.hh
@@ -0,0 +1,87 @@
+set noclip points
+set clip one
+set noclip two
+set bar 1.000000
+set border 31 lt -1 lw 1.000
+set xdata
+set ydata
+set zdata
+set x2data
+set y2data
+set boxwidth
+set dummy x,y
+set format x "%g"
+set format y "%g"
+set format x2 "%g"
+set format y2 "%g"
+set format z "%g"
+set angles radians
+set nogrid
+set key title ""
+set key left top Right noreverse box linetype -2 linewidth 1.000 samplen 4 spacing 1 width 0
+set nolabel
+set noarrow
+# set nolinestyle # deprecated
+set nologscale
+set logscale x 10
+set offsets 0, 0, 0, 0
+set pointsize 1
+set encoding default
+set nopolar
+set noparametric
+set view 60, 30, 1, 1
+set samples 100, 100
+set isosamples 10, 10
+set surface
+set nocontour
+set clabel '%8.3g'
+set mapping cartesian
+set nohidden3d
+set cntrparam order 4
+set cntrparam linear
+set cntrparam levels auto 5
+set cntrparam points 5
+set size ratio 0 1,1
+set origin 0,0
+# set data style lines
+# set function style lines
+set xzeroaxis lt -2 lw 1.000
+set x2zeroaxis lt -2 lw 1.000
+set yzeroaxis lt -2 lw 1.000
+set y2zeroaxis lt -2 lw 1.000
+set tics in
+set ticslevel 0.5
+set tics scale 1, 0.5
+set mxtics default
+set mytics default
+set mx2tics default
+set my2tics default
+set xtics border mirror norotate autofreq
+set ytics border mirror norotate autofreq
+set ztics border nomirror norotate autofreq
+set nox2tics
+set noy2tics
+set timestamp "" bottom norotate offset 0,0
+set rrange [ * : * ] noreverse nowriteback # (currently [-0:10] )
+set trange [ * : * ] noreverse nowriteback # (currently [-5:5] )
+set urange [ * : * ] noreverse nowriteback # (currently [-5:5] )
+set vrange [ * : * ] noreverse nowriteback # (currently [-5:5] )
+set xlabel "matrix size" offset 0,0
+set x2label "" offset 0,0
+set timefmt "%d/%m/%y\n%H:%M"
+set xrange [ 10 : 1000 ] noreverse nowriteback
+set x2range [ * : * ] noreverse nowriteback # (currently [-10:10] )
+set ylabel "MFLOPS" offset 0,0
+set y2label "" offset 0,0
+set yrange [ * : * ] noreverse nowriteback # (currently [-10:10] )
+set y2range [ * : * ] noreverse nowriteback # (currently [-10:10] )
+set zlabel "" offset 0,0
+set zrange [ * : * ] noreverse nowriteback # (currently [-10:10] )
+set zero 1e-08
+set lmargin -1
+set bmargin -1
+set rmargin -1
+set tmargin -1
+set locale "C"
+set xrange [4:1024]
+
diff --git a/eigen/bench/btl/data/go_mean b/eigen/bench/btl/data/go_mean
new file mode 100644
index 0000000..42338ca
--- /dev/null
+++ b/eigen/bench/btl/data/go_mean
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+if [ $# < 1 ]; then
+ echo "Usage: $0 working_directory [tiny|large [prefix]]"
+else
+
+mkdir -p $1
+##cp ../libs/*/*.dat $1
+
+mode=large
+if [ $# > 2 ]; then
+ mode=$2
+fi
+if [ $# > 3 ]; then
+ prefix=$3
+fi
+
+EIGENDIR=`cat eigen_root_dir.txt`
+
+webpagefilename=$1/index.html
+meanstatsfilename=$1/mean.html
+
+echo '' > $meanstatsfilename
+echo '' > $webpagefilename
+echo '<p><strong>Configuration</strong>' >> $webpagefilename
+echo '<ul>'\
+ '<li>' `cat /proc/cpuinfo | grep "model name" | head -n 1`\
+ ' (' `uname -m` ')</li>'\
+ '<li> compiler: ' `cat compiler_version.txt` '</li>'\
+ '<li> eigen3: ' `hg identify -i $EIGENDIR` '</li>'\
+ '</ul>' \
+ '</p>' >> $webpagefilename
+
+source mk_mean_script.sh axpy $1 11 2500 100000 250000 $mode $prefix
+source mk_mean_script.sh axpby $1 11 2500 100000 250000 $mode $prefix
+source mk_mean_script.sh matrix_vector $1 11 50 300 1000 $mode $prefix
+source mk_mean_script.sh atv $1 11 50 300 1000 $mode $prefix
+source mk_mean_script.sh matrix_matrix $1 11 100 300 1000 $mode $prefix
+source mk_mean_script.sh aat $1 11 100 300 1000 $mode $prefix
+# source mk_mean_script.sh ata $1 11 100 300 1000 $mode $prefix
+source mk_mean_script.sh trmm $1 11 100 300 1000 $mode $prefix
+source mk_mean_script.sh trisolve_vector $1 11 100 300 1000 $mode $prefix
+source mk_mean_script.sh trisolve_matrix $1 11 100 300 1000 $mode $prefix
+source mk_mean_script.sh cholesky $1 11 100 300 1000 $mode $prefix
+source mk_mean_script.sh partial_lu_decomp $1 11 100 300 1000 $mode $prefix
+source mk_mean_script.sh tridiagonalization $1 11 100 300 1000 $mode $prefix
+source mk_mean_script.sh hessenberg $1 11 100 300 1000 $mode $prefix
+source mk_mean_script.sh symv $1 11 50 300 1000 $mode $prefix
+source mk_mean_script.sh syr2 $1 11 50 300 1000 $mode $prefix
+source mk_mean_script.sh ger $1 11 50 300 1000 $mode $prefix
+source mk_mean_script.sh rot $1 11 2500 100000 250000 $mode $prefix
+source mk_mean_script.sh complete_lu_decomp $1 11 100 300 1000 $mode $prefix
+
+fi
+
+## compile the web page ##
+
+#echo `cat footer.html` >> $webpagefilename \ No newline at end of file
diff --git a/eigen/bench/btl/data/mean.cxx b/eigen/bench/btl/data/mean.cxx
new file mode 100644
index 0000000..c567ef3
--- /dev/null
+++ b/eigen/bench/btl/data/mean.cxx
@@ -0,0 +1,182 @@
+//=====================================================
+// File : mean.cxx
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:15 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include <vector>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include "bench_parameter.hh"
+#include "utils/xy_file.hh"
+#include <set>
+
+using namespace std;
+
+double mean_calc(const vector<int> & tab_sizes, const vector<double> & tab_mflops, const int size_min, const int size_max);
+
+class Lib_Mean{
+
+public:
+ Lib_Mean( void ):_lib_name(),_mean_in_cache(),_mean_out_of_cache(){
+ MESSAGE("Lib_mean Default Ctor");
+ MESSAGE("!!! should not be used");
+ exit(0);
+ }
+ Lib_Mean(const string & name, const double & mic, const double & moc):_lib_name(name),_mean_in_cache(mic),_mean_out_of_cache(moc){
+ MESSAGE("Lib_mean Ctor");
+ }
+ Lib_Mean(const Lib_Mean & lm):_lib_name(lm._lib_name),_mean_in_cache(lm._mean_in_cache),_mean_out_of_cache(lm._mean_out_of_cache){
+ MESSAGE("Lib_mean Copy Ctor");
+ }
+ ~Lib_Mean( void ){
+ MESSAGE("Lib_mean Dtor");
+ }
+
+ double _mean_in_cache;
+ double _mean_out_of_cache;
+ string _lib_name;
+
+ bool operator < ( const Lib_Mean &right) const
+ {
+ //return ( this->_mean_out_of_cache > right._mean_out_of_cache) ;
+ return ( this->_mean_in_cache > right._mean_in_cache) ;
+ }
+
+};
+
+
+int main( int argc , char *argv[] )
+{
+
+ if (argc<6){
+ INFOS("!!! Error ... usage : main what mic Mic moc Moc filename1 finename2...");
+ exit(0);
+ }
+ INFOS(argc);
+
+ int min_in_cache=atoi(argv[2]);
+ int max_in_cache=atoi(argv[3]);
+ int min_out_of_cache=atoi(argv[4]);
+ int max_out_of_cache=atoi(argv[5]);
+
+
+ multiset<Lib_Mean> s_lib_mean ;
+
+ for (int i=6;i<argc;i++){
+
+ string filename=argv[i];
+
+ INFOS(filename);
+
+ double mic=0;
+ double moc=0;
+
+ {
+
+ vector<int> tab_sizes;
+ vector<double> tab_mflops;
+
+ read_xy_file(filename,tab_sizes,tab_mflops);
+
+ mic=mean_calc(tab_sizes,tab_mflops,min_in_cache,max_in_cache);
+ moc=mean_calc(tab_sizes,tab_mflops,min_out_of_cache,max_out_of_cache);
+
+ Lib_Mean cur_lib_mean(filename,mic,moc);
+
+ s_lib_mean.insert(cur_lib_mean);
+
+ }
+
+ }
+
+
+ cout << "<TABLE BORDER CELLPADDING=2>" << endl ;
+ cout << " <TR>" << endl ;
+ cout << " <TH ALIGN=CENTER> " << argv[1] << " </TH>" << endl ;
+ cout << " <TH ALIGN=CENTER> <a href=""#mean_marker""> in cache <BR> mean perf <BR> Mflops </a></TH>" << endl ;
+ cout << " <TH ALIGN=CENTER> in cache <BR> % best </TH>" << endl ;
+ cout << " <TH ALIGN=CENTER> <a href=""#mean_marker""> out of cache <BR> mean perf <BR> Mflops </a></TH>" << endl ;
+ cout << " <TH ALIGN=CENTER> out of cache <BR> % best </TH>" << endl ;
+ cout << " <TH ALIGN=CENTER> details </TH>" << endl ;
+ cout << " <TH ALIGN=CENTER> comments </TH>" << endl ;
+ cout << " </TR>" << endl ;
+
+ multiset<Lib_Mean>::iterator is = s_lib_mean.begin();
+ Lib_Mean best(*is);
+
+
+ for (is=s_lib_mean.begin(); is!=s_lib_mean.end() ; is++){
+
+ cout << " <TR>" << endl ;
+ cout << " <TD> " << is->_lib_name << " </TD>" << endl ;
+ cout << " <TD> " << is->_mean_in_cache << " </TD>" << endl ;
+ cout << " <TD> " << 100*(is->_mean_in_cache/best._mean_in_cache) << " </TD>" << endl ;
+ cout << " <TD> " << is->_mean_out_of_cache << " </TD>" << endl ;
+ cout << " <TD> " << 100*(is->_mean_out_of_cache/best._mean_out_of_cache) << " </TD>" << endl ;
+ cout << " <TD> " <<
+ "<a href=\"#"<<is->_lib_name<<"_"<<argv[1]<<"\">snippet</a>/"
+ "<a href=\"#"<<is->_lib_name<<"_flags\">flags</a> </TD>" << endl ;
+ cout << " <TD> " <<
+ "<a href=\"#"<<is->_lib_name<<"_comments\">click here</a> </TD>" << endl ;
+ cout << " </TR>" << endl ;
+
+ }
+
+ cout << "</TABLE>" << endl ;
+
+ ofstream output_file ("../order_lib",ios::out) ;
+
+ for (is=s_lib_mean.begin(); is!=s_lib_mean.end() ; is++){
+ output_file << is->_lib_name << endl ;
+ }
+
+ output_file.close();
+
+}
+
+double mean_calc(const vector<int> & tab_sizes, const vector<double> & tab_mflops, const int size_min, const int size_max){
+
+ int size=tab_sizes.size();
+ int nb_sample=0;
+ double mean=0.0;
+
+ for (int i=0;i<size;i++){
+
+
+ if ((tab_sizes[i]>=size_min)&&(tab_sizes[i]<=size_max)){
+
+ nb_sample++;
+ mean+=tab_mflops[i];
+
+ }
+
+
+ }
+
+ if (nb_sample==0){
+ INFOS("no data for mean calculation");
+ return 0.0;
+ }
+
+ return mean/nb_sample;
+}
+
+
+
+
diff --git a/eigen/bench/btl/data/mk_gnuplot_script.sh b/eigen/bench/btl/data/mk_gnuplot_script.sh
new file mode 100644
index 0000000..2ca7b5c
--- /dev/null
+++ b/eigen/bench/btl/data/mk_gnuplot_script.sh
@@ -0,0 +1,68 @@
+#! /bin/bash
+WHAT=$1
+DIR=$2
+echo $WHAT script generation
+cat $WHAT.hh > $WHAT.gnuplot
+
+DATA_FILE=`find $DIR -name "*.dat" | grep $WHAT`
+
+echo plot \\ >> $WHAT.gnuplot
+
+for FILE in $DATA_FILE
+do
+ LAST=$FILE
+done
+
+echo LAST=$LAST
+
+for FILE in $DATA_FILE
+do
+ if [ $FILE != $LAST ]
+ then
+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}
+ echo "'"$FILE"'" title "'"$TITLE"'" ",\\" >> $WHAT.gnuplot
+ fi
+done
+BASE=${LAST##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}
+echo "'"$LAST"'" title "'"$TITLE"'" >> $WHAT.gnuplot
+
+#echo set term postscript color >> $WHAT.gnuplot
+#echo set output "'"$WHAT.ps"'" >> $WHAT.gnuplot
+echo set term pbm small color >> $WHAT.gnuplot
+echo set output "'"$WHAT.ppm"'" >> $WHAT.gnuplot
+echo plot \\ >> $WHAT.gnuplot
+
+for FILE in $DATA_FILE
+do
+ if [ $FILE != $LAST ]
+ then
+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}
+ echo "'"$FILE"'" title "'"$TITLE"'" ",\\" >> $WHAT.gnuplot
+ fi
+done
+BASE=${LAST##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}
+echo "'"$LAST"'" title "'"$TITLE"'" >> $WHAT.gnuplot
+
+echo set term jpeg large >> $WHAT.gnuplot
+echo set output "'"$WHAT.jpg"'" >> $WHAT.gnuplot
+echo plot \\ >> $WHAT.gnuplot
+
+for FILE in $DATA_FILE
+do
+ if [ $FILE != $LAST ]
+ then
+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}
+ echo "'"$FILE"'" title "'"$TITLE"'" ",\\" >> $WHAT.gnuplot
+ fi
+done
+BASE=${LAST##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}
+echo "'"$LAST"'" title "'"$TITLE"'" >> $WHAT.gnuplot
+
+
+gnuplot -persist < $WHAT.gnuplot
+
+rm $WHAT.gnuplot
+
+
+
+
diff --git a/eigen/bench/btl/data/mk_mean_script.sh b/eigen/bench/btl/data/mk_mean_script.sh
new file mode 100644
index 0000000..b10df02
--- /dev/null
+++ b/eigen/bench/btl/data/mk_mean_script.sh
@@ -0,0 +1,52 @@
+#! /bin/bash
+WHAT=$1
+DIR=$2
+MINIC=$3
+MAXIC=$4
+MINOC=$5
+MAXOC=$6
+prefix=$8
+
+meanstatsfilename=$2/mean.html
+
+WORK_DIR=tmp
+mkdir $WORK_DIR
+
+DATA_FILE=`find $DIR -name "*.dat" | grep _${WHAT}`
+
+if [ -n "$DATA_FILE" ]; then
+
+ echo ""
+ echo "$1..."
+ for FILE in $DATA_FILE
+ do
+ ##echo hello world
+ ##echo "mk_mean_script1" ${FILE}
+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}
+
+ ##echo "mk_mean_script1" ${TITLE}
+ cp $FILE ${WORK_DIR}/${TITLE}
+
+ done
+
+ cd $WORK_DIR
+ ../main $1 $3 $4 $5 $6 * >> ../$meanstatsfilename
+ ../mk_new_gnuplot.sh $1 $2 $7
+ rm -f *.gnuplot
+ cd ..
+
+ echo '<br/>' >> $meanstatsfilename
+
+ webpagefilename=$2/index.html
+ # echo '<h3>'${WHAT}'</h3>' >> $webpagefilename
+ echo '<hr/><a href="'$prefix$1'.pdf"><img src="'$prefix$1'.png" alt="'${WHAT}'" /></a><br/>' >> $webpagefilename
+
+fi
+
+rm -R $WORK_DIR
+
+
+
+
+
+
diff --git a/eigen/bench/btl/data/mk_new_gnuplot.sh b/eigen/bench/btl/data/mk_new_gnuplot.sh
new file mode 100644
index 0000000..fad3b23
--- /dev/null
+++ b/eigen/bench/btl/data/mk_new_gnuplot.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+WHAT=$1
+DIR=$2
+
+cat ../gnuplot_common_settings.hh > ${WHAT}.gnuplot
+
+echo "set title " `grep ${WHAT} ../action_settings.txt | head -n 1 | cut -d ";" -f 2` >> $WHAT.gnuplot
+echo "set xlabel " `grep ${WHAT} ../action_settings.txt | head -n 1 | cut -d ";" -f 3` " offset 0,0" >> $WHAT.gnuplot
+echo "set xrange [" `grep ${WHAT} ../action_settings.txt | head -n 1 | cut -d ";" -f 4` "]" >> $WHAT.gnuplot
+
+if [ $# > 3 ]; then
+ if [ "$3" == "tiny" ]; then
+ echo "set xrange [2:16]" >> $WHAT.gnuplot
+ echo "set nologscale" >> $WHAT.gnuplot
+ fi
+fi
+
+
+
+DATA_FILE=`cat ../order_lib`
+echo set term postscript color rounded enhanced >> $WHAT.gnuplot
+echo set output "'"../${DIR}/$WHAT.ps"'" >> $WHAT.gnuplot
+
+# echo set term svg color rounded enhanced >> $WHAT.gnuplot
+# echo "set terminal svg enhanced size 1000 1000 fname \"Times\" fsize 36" >> $WHAT.gnuplot
+# echo set output "'"../${DIR}/$WHAT.svg"'" >> $WHAT.gnuplot
+
+echo plot \\ >> $WHAT.gnuplot
+
+for FILE in $DATA_FILE
+do
+ LAST=$FILE
+done
+
+for FILE in $DATA_FILE
+do
+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}
+
+ echo "'"$FILE"'" `grep $TITLE ../perlib_plot_settings.txt | head -n 1 | cut -d ";" -f 2` "\\" >> $WHAT.gnuplot
+ if [ $FILE != $LAST ]
+ then
+ echo ", \\" >> $WHAT.gnuplot
+ fi
+done
+echo " " >> $WHAT.gnuplot
+
+gnuplot -persist < $WHAT.gnuplot
+
+rm $WHAT.gnuplot
+
+ps2pdf ../${DIR}/$WHAT.ps ../${DIR}/$WHAT.pdf
+convert -background white -density 120 -rotate 90 -resize 800 +dither -colors 256 -quality 0 ../${DIR}/$WHAT.ps -background white -flatten ../${DIR}/$WHAT.png
+
+# pstoedit -rotate -90 -xscale 0.8 -yscale 0.8 -centered -yshift -50 -xshift -100 -f plot-svg aat.ps aat2.svg
diff --git a/eigen/bench/btl/data/perlib_plot_settings.txt b/eigen/bench/btl/data/perlib_plot_settings.txt
new file mode 100644
index 0000000..6844bab
--- /dev/null
+++ b/eigen/bench/btl/data/perlib_plot_settings.txt
@@ -0,0 +1,16 @@
+eigen3 ; with lines lw 4 lt 1 lc rgbcolor "black"
+eigen2 ; with lines lw 3 lt 1 lc rgbcolor "#999999"
+EigenBLAS ; with lines lw 3 lt 3 lc rgbcolor "#999999"
+eigen3_novec ; with lines lw 2 lt 1 lc rgbcolor "#999999"
+eigen3_nogccvec ; with lines lw 2 lt 2 lc rgbcolor "#991010"
+INTEL_MKL ; with lines lw 3 lt 1 lc rgbcolor "#ff0000"
+ATLAS ; with lines lw 3 lt 1 lc rgbcolor "#008000"
+gmm ; with lines lw 3 lt 1 lc rgbcolor "#0000ff"
+ublas ; with lines lw 3 lt 1 lc rgbcolor "#00b7ff"
+mtl4 ; with lines lw 3 lt 1 lc rgbcolor "#d18847"
+blitz ; with lines lw 3 lt 1 lc rgbcolor "#ff00ff"
+F77 ; with lines lw 3 lt 3 lc rgbcolor "#e6e64c"
+GOTO ; with lines lw 3 lt 3 lc rgbcolor "#C05600"
+GOTO2 ; with lines lw 3 lt 1 lc rgbcolor "#C05600"
+C ; with lines lw 3 lt 3 lc rgbcolor "#e6bd96"
+ACML ; with lines lw 2 lt 3 lc rgbcolor "#e6e64c"
diff --git a/eigen/bench/btl/data/regularize.cxx b/eigen/bench/btl/data/regularize.cxx
new file mode 100644
index 0000000..eea2b8b
--- /dev/null
+++ b/eigen/bench/btl/data/regularize.cxx
@@ -0,0 +1,131 @@
+//=====================================================
+// File : regularize.cxx
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:15 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include <vector>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include "bench_parameter.hh"
+#include <set>
+
+using namespace std;
+
+void read_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops);
+void regularize_curve(const string & filename,
+ const vector<double> & tab_mflops,
+ const vector<int> & tab_sizes,
+ int start_cut_size, int stop_cut_size);
+/////////////////////////////////////////////////////////////////////////////////////////////////
+
+int main( int argc , char *argv[] )
+{
+
+ // input data
+
+ if (argc<4){
+ INFOS("!!! Error ... usage : main filename start_cut_size stop_cut_size regularize_filename");
+ exit(0);
+ }
+ INFOS(argc);
+
+ int start_cut_size=atoi(argv[2]);
+ int stop_cut_size=atoi(argv[3]);
+
+ string filename=argv[1];
+ string regularize_filename=argv[4];
+
+ INFOS(filename);
+ INFOS("start_cut_size="<<start_cut_size);
+
+ vector<int> tab_sizes;
+ vector<double> tab_mflops;
+
+ read_xy_file(filename,tab_sizes,tab_mflops);
+
+ // regularizeing
+
+ regularize_curve(regularize_filename,tab_mflops,tab_sizes,start_cut_size,stop_cut_size);
+
+
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+void regularize_curve(const string & filename,
+ const vector<double> & tab_mflops,
+ const vector<int> & tab_sizes,
+ int start_cut_size, int stop_cut_size)
+{
+ int size=tab_mflops.size();
+ ofstream output_file (filename.c_str(),ios::out) ;
+
+ int i=0;
+
+ while(tab_sizes[i]<start_cut_size){
+
+ output_file << tab_sizes[i] << " " << tab_mflops[i] << endl ;
+ i++;
+
+ }
+
+ output_file << endl ;
+
+ while(tab_sizes[i]<stop_cut_size){
+
+ i++;
+
+ }
+
+ while(i<size){
+
+ output_file << tab_sizes[i] << " " << tab_mflops[i] << endl ;
+ i++;
+
+ }
+
+ output_file.close();
+
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void read_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops){
+
+ ifstream input_file (filename.c_str(),ios::in) ;
+
+ if (!input_file){
+ INFOS("!!! Error opening "<<filename);
+ exit(0);
+ }
+
+ int nb_point=0;
+ int size=0;
+ double mflops=0;
+
+ while (input_file >> size >> mflops ){
+ nb_point++;
+ tab_sizes.push_back(size);
+ tab_mflops.push_back(mflops);
+ }
+ SCRUTE(nb_point);
+
+ input_file.close();
+}
+
diff --git a/eigen/bench/btl/data/smooth.cxx b/eigen/bench/btl/data/smooth.cxx
new file mode 100644
index 0000000..e5270cc
--- /dev/null
+++ b/eigen/bench/btl/data/smooth.cxx
@@ -0,0 +1,198 @@
+//=====================================================
+// File : smooth.cxx
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:15 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include <vector>
+#include <deque>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include "bench_parameter.hh"
+#include <set>
+
+using namespace std;
+
+void read_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops);
+void write_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops);
+void smooth_curve(const vector<double> & tab_mflops, vector<double> & smooth_tab_mflops,int window_half_width);
+void centered_smooth_curve(const vector<double> & tab_mflops, vector<double> & smooth_tab_mflops,int window_half_width);
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+
+int main( int argc , char *argv[] )
+{
+
+ // input data
+
+ if (argc<3){
+ INFOS("!!! Error ... usage : main filename window_half_width smooth_filename");
+ exit(0);
+ }
+ INFOS(argc);
+
+ int window_half_width=atoi(argv[2]);
+
+ string filename=argv[1];
+ string smooth_filename=argv[3];
+
+ INFOS(filename);
+ INFOS("window_half_width="<<window_half_width);
+
+ vector<int> tab_sizes;
+ vector<double> tab_mflops;
+
+ read_xy_file(filename,tab_sizes,tab_mflops);
+
+ // smoothing
+
+ vector<double> smooth_tab_mflops;
+
+ //smooth_curve(tab_mflops,smooth_tab_mflops,window_half_width);
+ centered_smooth_curve(tab_mflops,smooth_tab_mflops,window_half_width);
+
+ // output result
+
+ write_xy_file(smooth_filename,tab_sizes,smooth_tab_mflops);
+
+
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+template<class VECTOR>
+double weighted_mean(const VECTOR & data)
+{
+
+ double mean=0.0;
+
+ for (int i=0 ; i<data.size() ; i++){
+
+ mean+=data[i];
+
+ }
+
+ return mean/double(data.size()) ;
+
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void smooth_curve(const vector<double> & tab_mflops, vector<double> & smooth_tab_mflops,int window_half_width){
+
+ int window_width=2*window_half_width+1;
+
+ int size=tab_mflops.size();
+
+ vector<double> sample(window_width);
+
+ for (int i=0 ; i < size ; i++){
+
+ for ( int j=0 ; j < window_width ; j++ ){
+
+ int shifted_index=i+j-window_half_width;
+ if (shifted_index<0) shifted_index=0;
+ if (shifted_index>size-1) shifted_index=size-1;
+ sample[j]=tab_mflops[shifted_index];
+
+ }
+
+ smooth_tab_mflops.push_back(weighted_mean(sample));
+
+ }
+
+}
+
+void centered_smooth_curve(const vector<double> & tab_mflops, vector<double> & smooth_tab_mflops,int window_half_width){
+
+ int max_window_width=2*window_half_width+1;
+
+ int size=tab_mflops.size();
+
+
+ for (int i=0 ; i < size ; i++){
+
+ deque<double> sample;
+
+
+ sample.push_back(tab_mflops[i]);
+
+ for ( int j=1 ; j <= window_half_width ; j++ ){
+
+ int before=i-j;
+ int after=i+j;
+
+ if ((before>=0)&&(after<size)) // inside of the vector
+ {
+ sample.push_front(tab_mflops[before]);
+ sample.push_back(tab_mflops[after]);
+ }
+ }
+
+ smooth_tab_mflops.push_back(weighted_mean(sample));
+
+ }
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void write_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops){
+
+ ofstream output_file (filename.c_str(),ios::out) ;
+
+ for (int i=0 ; i < tab_sizes.size() ; i++)
+ {
+ output_file << tab_sizes[i] << " " << tab_mflops[i] << endl ;
+ }
+
+ output_file.close();
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void read_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops){
+
+ ifstream input_file (filename.c_str(),ios::in) ;
+
+ if (!input_file){
+ INFOS("!!! Error opening "<<filename);
+ exit(0);
+ }
+
+ int nb_point=0;
+ int size=0;
+ double mflops=0;
+
+ while (input_file >> size >> mflops ){
+ nb_point++;
+ tab_sizes.push_back(size);
+ tab_mflops.push_back(mflops);
+ }
+ SCRUTE(nb_point);
+
+ input_file.close();
+}
+
diff --git a/eigen/bench/btl/data/smooth_all.sh b/eigen/bench/btl/data/smooth_all.sh
new file mode 100644
index 0000000..3e5bfdf
--- /dev/null
+++ b/eigen/bench/btl/data/smooth_all.sh
@@ -0,0 +1,68 @@
+#! /bin/bash
+ORIG_DIR=$1
+SMOOTH_DIR=${ORIG_DIR}_smooth
+mkdir ${SMOOTH_DIR}
+
+AXPY_FILE=`find ${ORIG_DIR} -name "*.dat" | grep axpy`
+for FILE in ${AXPY_FILE}
+do
+ echo $FILE
+ BASE=${FILE##*/}
+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}_tmp
+ ./regularize ${SMOOTH_DIR}/${BASE}_tmp 2500 15000 ${SMOOTH_DIR}/${BASE}
+ rm -f ${SMOOTH_DIR}/${BASE}_tmp
+done
+
+
+MATRIX_VECTOR_FILE=`find ${ORIG_DIR} -name "*.dat" | grep matrix_vector`
+for FILE in ${MATRIX_VECTOR_FILE}
+do
+ echo $FILE
+ BASE=${FILE##*/}
+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}_tmp
+ ./regularize ${SMOOTH_DIR}/${BASE}_tmp 50 180 ${SMOOTH_DIR}/${BASE}
+ rm -f ${SMOOTH_DIR}/${BASE}_tmp
+done
+
+MATRIX_MATRIX_FILE=`find ${ORIG_DIR} -name "*.dat" | grep matrix_matrix`
+for FILE in ${MATRIX_MATRIX_FILE}
+do
+ echo $FILE
+ BASE=${FILE##*/}
+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}
+done
+
+AAT_FILE=`find ${ORIG_DIR} -name "*.dat" | grep _aat`
+for FILE in ${AAT_FILE}
+do
+ echo $FILE
+ BASE=${FILE##*/}
+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}
+done
+
+
+ATA_FILE=`find ${ORIG_DIR} -name "*.dat" | grep _ata`
+for FILE in ${ATA_FILE}
+do
+ echo $FILE
+ BASE=${FILE##*/}
+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}
+done
+
+### no smoothing for tinyvector and matrices libs
+
+TINY_BLITZ_FILE=`find ${ORIG_DIR} -name "*.dat" | grep tiny_blitz`
+for FILE in ${TINY_BLITZ_FILE}
+do
+ echo $FILE
+ BASE=${FILE##*/}
+ cp ${ORIG_DIR}/${BASE} ${SMOOTH_DIR}/${BASE}
+done
+
+TVMET_FILE=`find ${ORIG_DIR} -name "*.dat" | grep tvmet`
+for FILE in ${TVMET_FILE}
+do
+ echo $FILE
+ BASE=${FILE##*/}
+ cp ${ORIG_DIR}/${BASE} ${SMOOTH_DIR}/${BASE}
+done
diff --git a/eigen/bench/btl/generic_bench/bench.hh b/eigen/bench/btl/generic_bench/bench.hh
new file mode 100644
index 0000000..005c363
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/bench.hh
@@ -0,0 +1,168 @@
+//=====================================================
+// File : bench.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:16 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef BENCH_HH
+#define BENCH_HH
+
+#include "btl.hh"
+#include "bench_parameter.hh"
+#include <iostream>
+#include "utilities.h"
+#include "size_lin_log.hh"
+#include "xy_file.hh"
+#include <vector>
+#include <string>
+#include "timers/portable_perf_analyzer.hh"
+// #include "timers/mixed_perf_analyzer.hh"
+// #include "timers/x86_perf_analyzer.hh"
+// #include "timers/STL_perf_analyzer.hh"
+#ifdef HAVE_MKL
+extern "C" void cblas_saxpy(const int, const float, const float*, const int, float *, const int);
+#endif
+using namespace std;
+
+template <template<class> class Perf_Analyzer, class Action>
+BTL_DONT_INLINE void bench( int size_min, int size_max, int nb_point )
+{
+ if (BtlConfig::skipAction(Action::name()))
+ return;
+
+ string filename="bench_"+Action::name()+".dat";
+
+ INFOS("starting " <<filename);
+
+ // utilities
+
+ std::vector<double> tab_mflops(nb_point);
+ std::vector<int> tab_sizes(nb_point);
+
+ // matrices and vector size calculations
+ size_lin_log(nb_point,size_min,size_max,tab_sizes);
+
+ std::vector<int> oldSizes;
+ std::vector<double> oldFlops;
+ bool hasOldResults = read_xy_file(filename, oldSizes, oldFlops, true);
+ int oldi = oldSizes.size() - 1;
+
+ // loop on matrix size
+ Perf_Analyzer<Action> perf_action;
+ for (int i=nb_point-1;i>=0;i--)
+ {
+ //INFOS("size=" <<tab_sizes[i]<<" ("<<nb_point-i<<"/"<<nb_point<<")");
+ std::cout << " " << "size = " << tab_sizes[i] << " " << std::flush;
+
+ BTL_DISABLE_SSE_EXCEPTIONS();
+ #ifdef HAVE_MKL
+ {
+ float dummy;
+ cblas_saxpy(1,0,&dummy,1,&dummy,1);
+ }
+ #endif
+
+ tab_mflops[i] = perf_action.eval_mflops(tab_sizes[i]);
+ std::cout << tab_mflops[i];
+
+ if (hasOldResults)
+ {
+ while (oldi>=0 && oldSizes[oldi]>tab_sizes[i])
+ --oldi;
+ if (oldi>=0 && oldSizes[oldi]==tab_sizes[i])
+ {
+ if (oldFlops[oldi]<tab_mflops[i])
+ std::cout << "\t > ";
+ else
+ std::cout << "\t < ";
+ std::cout << oldFlops[oldi];
+ }
+ --oldi;
+ }
+ std::cout << " MFlops (" << nb_point-i << "/" << nb_point << ")" << std::endl;
+ }
+
+ if (!BtlConfig::Instance.overwriteResults)
+ {
+ if (hasOldResults)
+ {
+ // merge the two data
+ std::vector<int> newSizes;
+ std::vector<double> newFlops;
+ int i=0;
+ int j=0;
+ while (i<tab_sizes.size() && j<oldSizes.size())
+ {
+ if (tab_sizes[i] == oldSizes[j])
+ {
+ newSizes.push_back(tab_sizes[i]);
+ newFlops.push_back(std::max(tab_mflops[i], oldFlops[j]));
+ ++i;
+ ++j;
+ }
+ else if (tab_sizes[i] < oldSizes[j])
+ {
+ newSizes.push_back(tab_sizes[i]);
+ newFlops.push_back(tab_mflops[i]);
+ ++i;
+ }
+ else
+ {
+ newSizes.push_back(oldSizes[j]);
+ newFlops.push_back(oldFlops[j]);
+ ++j;
+ }
+ }
+ while (i<tab_sizes.size())
+ {
+ newSizes.push_back(tab_sizes[i]);
+ newFlops.push_back(tab_mflops[i]);
+ ++i;
+ }
+ while (j<oldSizes.size())
+ {
+ newSizes.push_back(oldSizes[j]);
+ newFlops.push_back(oldFlops[j]);
+ ++j;
+ }
+ tab_mflops = newFlops;
+ tab_sizes = newSizes;
+ }
+ }
+
+ // dump the result in a file :
+ dump_xy_file(tab_sizes,tab_mflops,filename);
+
+}
+
+// default Perf Analyzer
+
+template <class Action>
+BTL_DONT_INLINE void bench( int size_min, int size_max, int nb_point ){
+
+ // if the rdtsc is not available :
+ bench<Portable_Perf_Analyzer,Action>(size_min,size_max,nb_point);
+ // if the rdtsc is available :
+// bench<Mixed_Perf_Analyzer,Action>(size_min,size_max,nb_point);
+
+
+ // Only for small problem size. Otherwize it will be too long
+// bench<X86_Perf_Analyzer,Action>(size_min,size_max,nb_point);
+// bench<STL_Perf_Analyzer,Action>(size_min,size_max,nb_point);
+
+}
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/bench_parameter.hh b/eigen/bench/btl/generic_bench/bench_parameter.hh
new file mode 100644
index 0000000..4c355cd
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/bench_parameter.hh
@@ -0,0 +1,53 @@
+//=====================================================
+// File : bench_parameter.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:16 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef BENCH_PARAMETER_HH
+#define BENCH_PARAMETER_HH
+
+// minimal time for each measurement
+#define REAL_TYPE float
+// minimal time for each measurement
+#define MIN_TIME 0.2
+// nb of point on bench curves
+#define NB_POINT 100
+// min vector size for axpy bench
+#define MIN_AXPY 5
+// max vector size for axpy bench
+#define MAX_AXPY 1000000
+// min matrix size for matrix vector product bench
+#define MIN_MV 5
+// max matrix size for matrix vector product bench
+#define MAX_MV 3000
+// min matrix size for matrix matrix product bench
+#define MIN_MM 5
+// max matrix size for matrix matrix product bench
+#define MAX_MM MAX_MV
+// min matrix size for LU bench
+#define MIN_LU 5
+// max matrix size for LU bench
+#define MAX_LU 3000
+// max size for tiny vector and matrix
+#define TINY_MV_MAX_SIZE 16
+// default nb_sample for x86 timer
+#define DEFAULT_NB_SAMPLE 1000
+
+// how many times we run a single bench (keep the best perf)
+#define DEFAULT_NB_TRIES 3
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/btl.hh b/eigen/bench/btl/generic_bench/btl.hh
new file mode 100644
index 0000000..86a8438
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/btl.hh
@@ -0,0 +1,242 @@
+//=====================================================
+// File : btl.hh
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef BTL_HH
+#define BTL_HH
+
+#include "bench_parameter.hh"
+#include <iostream>
+#include <algorithm>
+#include <vector>
+#include <string>
+#include "utilities.h"
+
+#if (defined __GNUC__)
+#define BTL_ALWAYS_INLINE __attribute__((always_inline)) inline
+#else
+#define BTL_ALWAYS_INLINE inline
+#endif
+
+#if (defined __GNUC__)
+#define BTL_DONT_INLINE __attribute__((noinline))
+#else
+#define BTL_DONT_INLINE
+#endif
+
+#if (defined __GNUC__)
+#define BTL_ASM_COMMENT(X) asm("#" X)
+#else
+#define BTL_ASM_COMMENT(X)
+#endif
+
+#ifdef __SSE__
+#include "xmmintrin.h"
+// This enables flush to zero (FTZ) and denormals are zero (DAZ) modes:
+#define BTL_DISABLE_SSE_EXCEPTIONS() { _mm_setcsr(_mm_getcsr() | 0x8040); }
+#else
+#define BTL_DISABLE_SSE_EXCEPTIONS()
+#endif
+
+/** Enhanced std::string
+*/
+class BtlString : public std::string
+{
+public:
+ BtlString() : std::string() {}
+ BtlString(const BtlString& str) : std::string(static_cast<const std::string&>(str)) {}
+ BtlString(const std::string& str) : std::string(str) {}
+ BtlString(const char* str) : std::string(str) {}
+
+ operator const char* () const { return c_str(); }
+
+ void trim( bool left = true, bool right = true )
+ {
+ int lspaces, rspaces, len = length(), i;
+ lspaces = rspaces = 0;
+
+ if ( left )
+ for (i=0; i<len && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); ++lspaces,++i);
+
+ if ( right && lspaces < len )
+ for(i=len-1; i>=0 && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); rspaces++,i--);
+
+ *this = substr(lspaces, len-lspaces-rspaces);
+ }
+
+ std::vector<BtlString> split( const BtlString& delims = "\t\n ") const
+ {
+ std::vector<BtlString> ret;
+ unsigned int numSplits = 0;
+ size_t start, pos;
+ start = 0;
+ do
+ {
+ pos = find_first_of(delims, start);
+ if (pos == start)
+ {
+ ret.push_back("");
+ start = pos + 1;
+ }
+ else if (pos == npos)
+ ret.push_back( substr(start) );
+ else
+ {
+ ret.push_back( substr(start, pos - start) );
+ start = pos + 1;
+ }
+ //start = find_first_not_of(delims, start);
+ ++numSplits;
+ } while (pos != npos);
+ return ret;
+ }
+
+ bool endsWith(const BtlString& str) const
+ {
+ if(str.size()>this->size())
+ return false;
+ return this->substr(this->size()-str.size(),str.size()) == str;
+ }
+ bool contains(const BtlString& str) const
+ {
+ return this->find(str)<this->size();
+ }
+ bool beginsWith(const BtlString& str) const
+ {
+ if(str.size()>this->size())
+ return false;
+ return this->substr(0,str.size()) == str;
+ }
+
+ BtlString toLowerCase( void )
+ {
+ std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::tolower) );
+ return *this;
+ }
+ BtlString toUpperCase( void )
+ {
+ std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::toupper) );
+ return *this;
+ }
+
+ /** Case insensitive comparison.
+ */
+ bool isEquiv(const BtlString& str) const
+ {
+ BtlString str0 = *this;
+ str0.toLowerCase();
+ BtlString str1 = str;
+ str1.toLowerCase();
+ return str0 == str1;
+ }
+
+ /** Decompose the current string as a path and a file.
+ For instance: "dir1/dir2/file.ext" leads to path="dir1/dir2/" and filename="file.ext"
+ */
+ void decomposePathAndFile(BtlString& path, BtlString& filename) const
+ {
+ std::vector<BtlString> elements = this->split("/\\");
+ path = "";
+ filename = elements.back();
+ elements.pop_back();
+ if (this->at(0)=='/')
+ path = "/";
+ for (unsigned int i=0 ; i<elements.size() ; ++i)
+ path += elements[i] + "/";
+ }
+};
+
+class BtlConfig
+{
+public:
+ BtlConfig()
+ : overwriteResults(false), checkResults(true), realclock(false), tries(DEFAULT_NB_TRIES)
+ {
+ char * _config;
+ _config = getenv ("BTL_CONFIG");
+ if (_config!=NULL)
+ {
+ std::vector<BtlString> config = BtlString(_config).split(" \t\n");
+ for (int i = 0; i<config.size(); i++)
+ {
+ if (config[i].beginsWith("-a"))
+ {
+ if (i+1==config.size())
+ {
+ std::cerr << "error processing option: " << config[i] << "\n";
+ exit(2);
+ }
+ Instance.m_selectedActionNames = config[i+1].split(":");
+
+ i += 1;
+ }
+ else if (config[i].beginsWith("-t"))
+ {
+ if (i+1==config.size())
+ {
+ std::cerr << "error processing option: " << config[i] << "\n";
+ exit(2);
+ }
+ Instance.tries = atoi(config[i+1].c_str());
+
+ i += 1;
+ }
+ else if (config[i].beginsWith("--overwrite"))
+ {
+ Instance.overwriteResults = true;
+ }
+ else if (config[i].beginsWith("--nocheck"))
+ {
+ Instance.checkResults = false;
+ }
+ else if (config[i].beginsWith("--real"))
+ {
+ Instance.realclock = true;
+ }
+ }
+ }
+
+ BTL_DISABLE_SSE_EXCEPTIONS();
+ }
+
+ BTL_DONT_INLINE static bool skipAction(const std::string& _name)
+ {
+ if (Instance.m_selectedActionNames.empty())
+ return false;
+
+ BtlString name(_name);
+ for (int i=0; i<Instance.m_selectedActionNames.size(); ++i)
+ if (name.contains(Instance.m_selectedActionNames[i]))
+ return false;
+
+ return true;
+ }
+
+ static BtlConfig Instance;
+ bool overwriteResults;
+ bool checkResults;
+ bool realclock;
+ int tries;
+
+protected:
+ std::vector<BtlString> m_selectedActionNames;
+};
+
+#define BTL_MAIN \
+ BtlConfig BtlConfig::Instance
+
+#endif // BTL_HH
diff --git a/eigen/bench/btl/generic_bench/init/init_function.hh b/eigen/bench/btl/generic_bench/init/init_function.hh
new file mode 100644
index 0000000..7b3bdba
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/init/init_function.hh
@@ -0,0 +1,54 @@
+//=====================================================
+// File : init_function.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:18 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef INIT_FUNCTION_HH
+#define INIT_FUNCTION_HH
+
+double simple_function(int index)
+{
+ return index;
+}
+
+double simple_function(int index_i, int index_j)
+{
+ return index_i+index_j;
+}
+
+double pseudo_random(int index)
+{
+ return std::rand()/double(RAND_MAX);
+}
+
+double pseudo_random(int index_i, int index_j)
+{
+ return std::rand()/double(RAND_MAX);
+}
+
+
+double null_function(int index)
+{
+ return 0.0;
+}
+
+double null_function(int index_i, int index_j)
+{
+ return 0.0;
+}
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/init/init_matrix.hh b/eigen/bench/btl/generic_bench/init/init_matrix.hh
new file mode 100644
index 0000000..67cbd20
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/init/init_matrix.hh
@@ -0,0 +1,64 @@
+//=====================================================
+// File : init_matrix.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef INIT_MATRIX_HH
+#define INIT_MATRIX_HH
+
+// The Vector class must satisfy the following part of STL vector concept :
+// resize() method
+// [] operator for setting element
+// value_type defined
+template<double init_function(int,int), class Vector>
+BTL_DONT_INLINE void init_row(Vector & X, int size, int row){
+
+ X.resize(size);
+
+ for (int j=0;j<X.size();j++){
+ X[j]=typename Vector::value_type(init_function(row,j));
+ }
+}
+
+
+// Matrix is a Vector of Vector
+// The Matrix class must satisfy the following part of STL vector concept :
+// resize() method
+// [] operator for setting rows
+template<double init_function(int,int),class Vector>
+BTL_DONT_INLINE void init_matrix(Vector & A, int size){
+ A.resize(size);
+ for (int row=0; row<A.size() ; row++){
+ init_row<init_function>(A[row],size,row);
+ }
+}
+
+template<double init_function(int,int),class Matrix>
+BTL_DONT_INLINE void init_matrix_symm(Matrix& A, int size){
+ A.resize(size);
+ for (int row=0; row<A.size() ; row++)
+ A[row].resize(size);
+ for (int row=0; row<A.size() ; row++){
+ A[row][row] = init_function(row,row);
+ for (int col=0; col<row ; col++){
+ double x = init_function(row,col);
+ A[row][col] = A[col][row] = x;
+ }
+ }
+}
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/init/init_vector.hh b/eigen/bench/btl/generic_bench/init/init_vector.hh
new file mode 100644
index 0000000..efaf0c9
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/init/init_vector.hh
@@ -0,0 +1,37 @@
+//=====================================================
+// File : init_vector.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:18 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef INIT_VECTOR_HH
+#define INIT_VECTOR_HH
+
+// The Vector class must satisfy the following part of STL vector concept :
+// resize() method
+// [] operator for setting element
+// value_type defined
+template<double init_function(int), class Vector>
+void init_vector(Vector & X, int size){
+
+ X.resize(size);
+
+ for (int i=0;i<X.size();i++){
+ X[i]=typename Vector::value_type(init_function(i));
+ }
+}
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/static/bench_static.hh b/eigen/bench/btl/generic_bench/static/bench_static.hh
new file mode 100644
index 0000000..23b55ec
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/static/bench_static.hh
@@ -0,0 +1,80 @@
+//=====================================================
+// File : bench_static.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:16 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef BENCH_STATIC_HH
+#define BENCH_STATIC_HH
+
+#include "btl.hh"
+#include "bench_parameter.hh"
+#include <iostream>
+#include "utilities.h"
+#include "xy_file.hh"
+#include "static/static_size_generator.hh"
+#include "timers/portable_perf_analyzer.hh"
+// #include "timers/mixed_perf_analyzer.hh"
+// #include "timers/x86_perf_analyzer.hh"
+
+using namespace std;
+
+
+template <template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface>
+BTL_DONT_INLINE void bench_static(void)
+{
+ if (BtlConfig::skipAction(Action<Interface<REAL_TYPE,10> >::name()))
+ return;
+
+ string filename = "bench_" + Action<Interface<REAL_TYPE,10> >::name() + ".dat";
+
+ INFOS("starting " << filename);
+
+ const int max_size = TINY_MV_MAX_SIZE;
+
+ std::vector<double> tab_mflops;
+ std::vector<double> tab_sizes;
+
+ static_size_generator<max_size,Perf_Analyzer,Action,Interface>::go(tab_sizes,tab_mflops);
+
+ dump_xy_file(tab_sizes,tab_mflops,filename);
+}
+
+// default Perf Analyzer
+template <template<class> class Action, template<class,int> class Interface>
+BTL_DONT_INLINE void bench_static(void)
+{
+ bench_static<Portable_Perf_Analyzer,Action,Interface>();
+ //bench_static<Mixed_Perf_Analyzer,Action,Interface>();
+ //bench_static<X86_Perf_Analyzer,Action,Interface>();
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eigen/bench/btl/generic_bench/static/intel_bench_fixed_size.hh b/eigen/bench/btl/generic_bench/static/intel_bench_fixed_size.hh
new file mode 100644
index 0000000..b4edcbc
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/static/intel_bench_fixed_size.hh
@@ -0,0 +1,66 @@
+//=====================================================
+// File : intel_bench_fixed_size.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar déc 3 18:59:37 CET 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef _BENCH_FIXED_SIZE_HH_
+#define _BENCH_FIXED_SIZE_HH_
+
+#include "utilities.h"
+#include "function_time.hh"
+
+template <class Action>
+double bench_fixed_size(int size, unsigned long long & nb_calc,unsigned long long & nb_init)
+{
+
+ Action action(size);
+
+ double time_baseline=time_init(nb_init,action);
+
+ while (time_baseline < MIN_TIME) {
+
+ //INFOS("nb_init="<<nb_init);
+ //INFOS("time_baseline="<<time_baseline);
+ nb_init*=2;
+ time_baseline=time_init(nb_init,action);
+ }
+
+ time_baseline=time_baseline/(double(nb_init));
+
+ double time_action=time_calculate(nb_calc,action);
+
+ while (time_action < MIN_TIME) {
+
+ nb_calc*=2;
+ time_action=time_calculate(nb_calc,action);
+ }
+
+ INFOS("nb_init="<<nb_init);
+ INFOS("nb_calc="<<nb_calc);
+
+
+ time_action=time_action/(double(nb_calc));
+
+ action.check_result();
+
+ time_action=time_action-time_baseline;
+
+ return action.nb_op_base()/(time_action*1000000.0);
+
+}
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/static/static_size_generator.hh b/eigen/bench/btl/generic_bench/static/static_size_generator.hh
new file mode 100644
index 0000000..dd02df3
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/static/static_size_generator.hh
@@ -0,0 +1,57 @@
+//=====================================================
+// File : static_size_generator.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar déc 3 18:59:36 CET 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef _STATIC_SIZE_GENERATOR_HH
+#define _STATIC_SIZE_GENERATOR_HH
+#include <vector>
+
+using namespace std;
+
+//recursive generation of statically defined matrix and vector sizes
+
+template <int SIZE,template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface>
+struct static_size_generator{
+ static void go(vector<double> & tab_sizes, vector<double> & tab_mflops)
+ {
+ tab_sizes.push_back(SIZE);
+ std::cout << tab_sizes.back() << " \t" << std::flush;
+ Perf_Analyzer<Action<Interface<REAL_TYPE,SIZE> > > perf_action;
+ tab_mflops.push_back(perf_action.eval_mflops(SIZE));
+ std::cout << tab_mflops.back() << " MFlops" << std::endl;
+ static_size_generator<SIZE-1,Perf_Analyzer,Action,Interface>::go(tab_sizes,tab_mflops);
+ };
+};
+
+//recursion end
+
+template <template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface>
+struct static_size_generator<1,Perf_Analyzer,Action,Interface>{
+ static void go(vector<double> & tab_sizes, vector<double> & tab_mflops)
+ {
+ tab_sizes.push_back(1);
+ Perf_Analyzer<Action<Interface<REAL_TYPE,1> > > perf_action;
+ tab_mflops.push_back(perf_action.eval_mflops(1));
+ };
+};
+
+#endif
+
+
+
+
diff --git a/eigen/bench/btl/generic_bench/timers/STL_perf_analyzer.hh b/eigen/bench/btl/generic_bench/timers/STL_perf_analyzer.hh
new file mode 100644
index 0000000..c9f894b
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/timers/STL_perf_analyzer.hh
@@ -0,0 +1,82 @@
+//=====================================================
+// File : STL_perf_analyzer.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar déc 3 18:59:35 CET 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef _STL_PERF_ANALYSER_HH
+#define _STL_PERF_ANALYSER_HH
+
+#include "STL_timer.hh"
+#include "bench_parameter.hh"
+
+template<class ACTION>
+class STL_Perf_Analyzer{
+public:
+ STL_Perf_Analyzer(unsigned long long nb_sample=DEFAULT_NB_SAMPLE):_nb_sample(nb_sample),_chronos()
+ {
+ MESSAGE("STL_Perf_Analyzer Ctor");
+ };
+ STL_Perf_Analyzer( const STL_Perf_Analyzer & ){
+ INFOS("Copy Ctor not implemented");
+ exit(0);
+ };
+ ~STL_Perf_Analyzer( void ){
+ MESSAGE("STL_Perf_Analyzer Dtor");
+ };
+
+
+ inline double eval_mflops(int size)
+ {
+
+ ACTION action(size);
+
+ _chronos.start_baseline(_nb_sample);
+
+ do {
+
+ action.initialize();
+ } while (_chronos.check());
+
+ double baseline_time=_chronos.get_time();
+
+ _chronos.start(_nb_sample);
+ do {
+ action.initialize();
+ action.calculate();
+ } while (_chronos.check());
+
+ double calculate_time=_chronos.get_time();
+
+ double corrected_time=calculate_time-baseline_time;
+
+ // cout << size <<" "<<baseline_time<<" "<<calculate_time<<" "<<corrected_time<<" "<<action.nb_op_base() << endl;
+
+ return action.nb_op_base()/(corrected_time*1000000.0);
+ //return action.nb_op_base()/(calculate_time*1000000.0);
+
+ }
+private:
+
+ STL_Timer _chronos;
+ unsigned long long _nb_sample;
+
+
+};
+
+
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/timers/STL_timer.hh b/eigen/bench/btl/generic_bench/timers/STL_timer.hh
new file mode 100644
index 0000000..19c54e9
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/timers/STL_timer.hh
@@ -0,0 +1,78 @@
+//=====================================================
+// File : STL_Timer.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar déc 3 18:59:35 CET 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// STL Timer Class. Adapted (L.P.) from the timer class by Musser et Al
+// described int the Book : STL Tutorial and reference guide.
+// Define a timer class for analyzing algorithm performance.
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <map>
+#include <algorithm>
+using namespace std;
+
+class STL_Timer {
+public:
+ STL_Timer(){ baseline = false; }; // Default constructor
+ // Start a series of r trials:
+ void start(unsigned int r){
+ reps = r;
+ count = 0;
+ iterations.clear();
+ iterations.reserve(reps);
+ initial = time(0);
+ };
+ // Start a series of r trials to determine baseline time:
+ void start_baseline(unsigned int r)
+ {
+ baseline = true;
+ start(r);
+ }
+ // Returns true if the trials have been completed, else false
+ bool check()
+ {
+ ++count;
+ final = time(0);
+ if (initial < final) {
+ iterations.push_back(count);
+ initial = final;
+ count = 0;
+ }
+ return (iterations.size() < reps);
+ };
+ // Returns the results for external use
+ double get_time( void )
+ {
+ sort(iterations.begin(), iterations.end());
+ return 1.0/iterations[reps/2];
+ };
+private:
+ unsigned int reps; // Number of trials
+ // For storing loop iterations of a trial
+ vector<long> iterations;
+ // For saving initial and final times of a trial
+ time_t initial, final;
+ // For counting loop iterations of a trial
+ unsigned long count;
+ // true if this is a baseline computation, false otherwise
+ bool baseline;
+ // For recording the baseline time
+ double baseline_time;
+};
+
diff --git a/eigen/bench/btl/generic_bench/timers/mixed_perf_analyzer.hh b/eigen/bench/btl/generic_bench/timers/mixed_perf_analyzer.hh
new file mode 100644
index 0000000..e190236
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/timers/mixed_perf_analyzer.hh
@@ -0,0 +1,73 @@
+//=====================================================
+// File : mixed_perf_analyzer.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar déc 3 18:59:36 CET 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef _MIXED_PERF_ANALYSER_HH
+#define _MIXED_PERF_ANALYSER_HH
+
+#include "x86_perf_analyzer.hh"
+#include "portable_perf_analyzer.hh"
+
+// choose portable perf analyzer for long calculations and x86 analyser for short ones
+
+
+template<class Action>
+class Mixed_Perf_Analyzer{
+
+public:
+ Mixed_Perf_Analyzer( void ):_x86pa(),_ppa(),_use_ppa(true)
+ {
+ MESSAGE("Mixed_Perf_Analyzer Ctor");
+ };
+ Mixed_Perf_Analyzer( const Mixed_Perf_Analyzer & ){
+ INFOS("Copy Ctor not implemented");
+ exit(0);
+ };
+ ~Mixed_Perf_Analyzer( void ){
+ MESSAGE("Mixed_Perf_Analyzer Dtor");
+ };
+
+
+ inline double eval_mflops(int size)
+ {
+
+ double result=0.0;
+ if (_use_ppa){
+ result=_ppa.eval_mflops(size);
+ if (_ppa.get_nb_calc()>DEFAULT_NB_SAMPLE){_use_ppa=false;}
+ }
+ else{
+ result=_x86pa.eval_mflops(size);
+ }
+
+ return result;
+ }
+
+private:
+
+ Portable_Perf_Analyzer<Action> _ppa;
+ X86_Perf_Analyzer<Action> _x86pa;
+ bool _use_ppa;
+
+};
+
+#endif
+
+
+
+
diff --git a/eigen/bench/btl/generic_bench/timers/portable_perf_analyzer.hh b/eigen/bench/btl/generic_bench/timers/portable_perf_analyzer.hh
new file mode 100644
index 0000000..fc0f316
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/timers/portable_perf_analyzer.hh
@@ -0,0 +1,103 @@
+//=====================================================
+// File : portable_perf_analyzer.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef _PORTABLE_PERF_ANALYZER_HH
+#define _PORTABLE_PERF_ANALYZER_HH
+
+#include "utilities.h"
+#include "timers/portable_timer.hh"
+
+template <class Action>
+class Portable_Perf_Analyzer{
+public:
+ Portable_Perf_Analyzer( ):_nb_calc(0), m_time_action(0), _chronos(){
+ MESSAGE("Portable_Perf_Analyzer Ctor");
+ };
+ Portable_Perf_Analyzer( const Portable_Perf_Analyzer & ){
+ INFOS("Copy Ctor not implemented");
+ exit(0);
+ };
+ ~Portable_Perf_Analyzer(){
+ MESSAGE("Portable_Perf_Analyzer Dtor");
+ };
+
+ BTL_DONT_INLINE double eval_mflops(int size)
+ {
+ Action action(size);
+
+// action.initialize();
+// time_action = time_calculate(action);
+ while (m_time_action < MIN_TIME)
+ {
+ if(_nb_calc==0) _nb_calc = 1;
+ else _nb_calc *= 2;
+ action.initialize();
+ m_time_action = time_calculate(action);
+ }
+
+ // optimize
+ for (int i=1; i<BtlConfig::Instance.tries; ++i)
+ {
+ Action _action(size);
+ std::cout << " " << _action.nb_op_base()*_nb_calc/(m_time_action*1e6) << " ";
+ _action.initialize();
+ m_time_action = std::min(m_time_action, time_calculate(_action));
+ }
+
+ double time_action = m_time_action / (double(_nb_calc));
+
+ // check
+ if (BtlConfig::Instance.checkResults && size<128)
+ {
+ action.initialize();
+ action.calculate();
+ action.check_result();
+ }
+ return action.nb_op_base()/(time_action*1e6);
+ }
+
+ BTL_DONT_INLINE double time_calculate(Action & action)
+ {
+ // time measurement
+ action.calculate();
+ _chronos.start();
+ for (int ii=0;ii<_nb_calc;ii++)
+ {
+ action.calculate();
+ }
+ _chronos.stop();
+ return _chronos.user_time();
+ }
+
+ unsigned long long get_nb_calc()
+ {
+ return _nb_calc;
+ }
+
+
+private:
+ unsigned long long _nb_calc;
+ double m_time_action;
+ Portable_Timer _chronos;
+
+};
+
+#endif //_PORTABLE_PERF_ANALYZER_HH
+
diff --git a/eigen/bench/btl/generic_bench/timers/portable_perf_analyzer_old.hh b/eigen/bench/btl/generic_bench/timers/portable_perf_analyzer_old.hh
new file mode 100644
index 0000000..fce3781
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/timers/portable_perf_analyzer_old.hh
@@ -0,0 +1,134 @@
+//=====================================================
+// File : portable_perf_analyzer.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef _PORTABLE_PERF_ANALYZER_HH
+#define _PORTABLE_PERF_ANALYZER_HH
+
+#include "utilities.h"
+#include "timers/portable_timer.hh"
+
+template <class Action>
+class Portable_Perf_Analyzer{
+public:
+ Portable_Perf_Analyzer( void ):_nb_calc(1),_nb_init(1),_chronos(){
+ MESSAGE("Portable_Perf_Analyzer Ctor");
+ };
+ Portable_Perf_Analyzer( const Portable_Perf_Analyzer & ){
+ INFOS("Copy Ctor not implemented");
+ exit(0);
+ };
+ ~Portable_Perf_Analyzer( void ){
+ MESSAGE("Portable_Perf_Analyzer Dtor");
+ };
+
+
+
+ inline double eval_mflops(int size)
+ {
+
+ Action action(size);
+
+// double time_baseline = time_init(action);
+// while (time_baseline < MIN_TIME_INIT)
+// {
+// _nb_init *= 2;
+// time_baseline = time_init(action);
+// }
+//
+// // optimize
+// for (int i=1; i<NB_TRIES; ++i)
+// time_baseline = std::min(time_baseline, time_init(action));
+//
+// time_baseline = time_baseline/(double(_nb_init));
+
+ double time_action = time_calculate(action);
+ while (time_action < MIN_TIME)
+ {
+ _nb_calc *= 2;
+ time_action = time_calculate(action);
+ }
+
+ // optimize
+ for (int i=1; i<NB_TRIES; ++i)
+ time_action = std::min(time_action, time_calculate(action));
+
+// INFOS("size="<<size);
+// INFOS("_nb_init="<<_nb_init);
+// INFOS("_nb_calc="<<_nb_calc);
+
+ time_action = time_action / (double(_nb_calc));
+
+ action.check_result();
+
+
+ double time_baseline = time_init(action);
+ for (int i=1; i<NB_TRIES; ++i)
+ time_baseline = std::min(time_baseline, time_init(action));
+ time_baseline = time_baseline/(double(_nb_init));
+
+
+
+// INFOS("time_baseline="<<time_baseline);
+// INFOS("time_action="<<time_action);
+
+ time_action = time_action - time_baseline;
+
+// INFOS("time_corrected="<<time_action);
+
+ return action.nb_op_base()/(time_action*1000000.0);
+ }
+
+ inline double time_init(Action & action)
+ {
+ // time measurement
+ _chronos.start();
+ for (int ii=0; ii<_nb_init; ii++)
+ action.initialize();
+ _chronos.stop();
+ return _chronos.user_time();
+ }
+
+
+ inline double time_calculate(Action & action)
+ {
+ // time measurement
+ _chronos.start();
+ for (int ii=0;ii<_nb_calc;ii++)
+ {
+ action.initialize();
+ action.calculate();
+ }
+ _chronos.stop();
+ return _chronos.user_time();
+ }
+
+ unsigned long long get_nb_calc( void )
+ {
+ return _nb_calc;
+ }
+
+
+private:
+ unsigned long long _nb_calc;
+ unsigned long long _nb_init;
+ Portable_Timer _chronos;
+
+};
+
+#endif //_PORTABLE_PERF_ANALYZER_HH
diff --git a/eigen/bench/btl/generic_bench/timers/portable_timer.hh b/eigen/bench/btl/generic_bench/timers/portable_timer.hh
new file mode 100644
index 0000000..e6ad309
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/timers/portable_timer.hh
@@ -0,0 +1,145 @@
+//=====================================================
+// File : portable_timer.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)> from boost lib
+// Copyright (C) EDF R&D, lun sep 30 14:23:17 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// simple_time extracted from the boost library
+//
+#ifndef _PORTABLE_TIMER_HH
+#define _PORTABLE_TIMER_HH
+
+#include <ctime>
+#include <cstdlib>
+
+#include <time.h>
+
+
+#define USEC_IN_SEC 1000000
+
+
+// timer -------------------------------------------------------------------//
+
+// A timer object measures CPU time.
+#ifdef _MSC_VER
+
+#define NOMINMAX
+#include <windows.h>
+
+/*#ifndef hr_timer
+#include "hr_time.h"
+#define hr_timer
+#endif*/
+
+ class Portable_Timer
+ {
+ public:
+
+ typedef struct {
+ LARGE_INTEGER start;
+ LARGE_INTEGER stop;
+ } stopWatch;
+
+
+ Portable_Timer()
+ {
+ startVal.QuadPart = 0;
+ stopVal.QuadPart = 0;
+ QueryPerformanceFrequency(&frequency);
+ }
+
+ void start() { QueryPerformanceCounter(&startVal); }
+
+ void stop() { QueryPerformanceCounter(&stopVal); }
+
+ double elapsed() {
+ LARGE_INTEGER time;
+ time.QuadPart = stopVal.QuadPart - startVal.QuadPart;
+ return LIToSecs(time);
+ }
+
+ double user_time() { return elapsed(); }
+
+
+ private:
+
+ double LIToSecs(LARGE_INTEGER& L) {
+ return ((double)L.QuadPart /(double)frequency.QuadPart) ;
+ }
+
+ LARGE_INTEGER startVal;
+ LARGE_INTEGER stopVal;
+ LARGE_INTEGER frequency;
+
+
+ }; // Portable_Timer
+
+#else
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <sys/times.h>
+
+class Portable_Timer
+{
+ public:
+
+ Portable_Timer()
+ {
+ m_clkid = BtlConfig::Instance.realclock ? CLOCK_REALTIME : CLOCK_PROCESS_CPUTIME_ID;
+ }
+
+ Portable_Timer(int clkid) : m_clkid(clkid)
+ {}
+
+ void start()
+ {
+ timespec ts;
+ clock_gettime(m_clkid, &ts);
+ m_start_time = double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);
+
+ }
+
+ void stop()
+ {
+ timespec ts;
+ clock_gettime(m_clkid, &ts);
+ m_stop_time = double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);
+
+ }
+
+ double elapsed()
+ {
+ return user_time();
+ }
+
+ double user_time()
+ {
+ return m_stop_time - m_start_time;
+ }
+
+
+private:
+
+ int m_clkid;
+ double m_stop_time, m_start_time;
+
+}; // Portable_Timer
+
+#endif
+
+#endif // PORTABLE_TIMER_HPP
diff --git a/eigen/bench/btl/generic_bench/timers/x86_perf_analyzer.hh b/eigen/bench/btl/generic_bench/timers/x86_perf_analyzer.hh
new file mode 100644
index 0000000..37ea21d
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/timers/x86_perf_analyzer.hh
@@ -0,0 +1,108 @@
+//=====================================================
+// File : x86_perf_analyzer.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef _X86_PERF_ANALYSER_HH
+#define _X86_PERF_ANALYSER_HH
+
+#include "x86_timer.hh"
+#include "bench_parameter.hh"
+
+template<class ACTION>
+class X86_Perf_Analyzer{
+public:
+ X86_Perf_Analyzer( unsigned long long nb_sample=DEFAULT_NB_SAMPLE):_nb_sample(nb_sample),_chronos()
+ {
+ MESSAGE("X86_Perf_Analyzer Ctor");
+ _chronos.find_frequency();
+ };
+ X86_Perf_Analyzer( const X86_Perf_Analyzer & ){
+ INFOS("Copy Ctor not implemented");
+ exit(0);
+ };
+ ~X86_Perf_Analyzer( void ){
+ MESSAGE("X86_Perf_Analyzer Dtor");
+ };
+
+
+ inline double eval_mflops(int size)
+ {
+
+ ACTION action(size);
+
+ int nb_loop=5;
+ double calculate_time=0.0;
+ double baseline_time=0.0;
+
+ for (int j=0 ; j < nb_loop ; j++){
+
+ _chronos.clear();
+
+ for(int i=0 ; i < _nb_sample ; i++)
+ {
+ _chronos.start();
+ action.initialize();
+ action.calculate();
+ _chronos.stop();
+ _chronos.add_get_click();
+ }
+
+ calculate_time += double(_chronos.get_shortest_clicks())/_chronos.frequency();
+
+ if (j==0) action.check_result();
+
+ _chronos.clear();
+
+ for(int i=0 ; i < _nb_sample ; i++)
+ {
+ _chronos.start();
+ action.initialize();
+ _chronos.stop();
+ _chronos.add_get_click();
+
+ }
+
+ baseline_time+=double(_chronos.get_shortest_clicks())/_chronos.frequency();
+
+ }
+
+ double corrected_time = (calculate_time-baseline_time)/double(nb_loop);
+
+
+// INFOS("_nb_sample="<<_nb_sample);
+// INFOS("baseline_time="<<baseline_time);
+// INFOS("calculate_time="<<calculate_time);
+// INFOS("corrected_time="<<corrected_time);
+
+// cout << size <<" "<<baseline_time<<" "<<calculate_time<<" "<<corrected_time<<" "<<action.nb_op_base() << endl;
+
+ return action.nb_op_base()/(corrected_time*1000000.0);
+ //return action.nb_op_base()/(calculate_time*1000000.0);
+ }
+
+private:
+
+ X86_Timer _chronos;
+ unsigned long long _nb_sample;
+
+
+};
+
+
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/timers/x86_timer.hh b/eigen/bench/btl/generic_bench/timers/x86_timer.hh
new file mode 100644
index 0000000..cfb5ee8
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/timers/x86_timer.hh
@@ -0,0 +1,246 @@
+//=====================================================
+// File : x86_timer.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef _X86_TIMER_HH
+#define _X86_TIMER_HH
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <sys/times.h>
+//#include "system_time.h"
+#define u32 unsigned int
+#include <asm/msr.h>
+#include "utilities.h"
+#include <map>
+#include <fstream>
+#include <string>
+#include <iostream>
+
+// frequence de la becanne en Hz
+//#define FREQUENCY 648000000
+//#define FREQUENCY 1400000000
+#define FREQUENCY 1695000000
+
+using namespace std;
+
+
+class X86_Timer {
+
+public :
+
+ X86_Timer( void ):_frequency(FREQUENCY),_nb_sample(0)
+ {
+ MESSAGE("X86_Timer Default Ctor");
+ }
+
+ inline void start( void ){
+
+ rdtsc(_click_start.n32[0],_click_start.n32[1]);
+
+ }
+
+
+ inline void stop( void ){
+
+ rdtsc(_click_stop.n32[0],_click_stop.n32[1]);
+
+ }
+
+
+ inline double frequency( void ){
+ return _frequency;
+ }
+
+ double get_elapsed_time_in_second( void ){
+
+ return (_click_stop.n64-_click_start.n64)/double(FREQUENCY);
+
+
+ }
+
+ unsigned long long get_click( void ){
+
+ return (_click_stop.n64-_click_start.n64);
+
+ }
+
+ inline void find_frequency( void ){
+
+ time_t initial, final;
+ int dummy=2;
+
+ initial = time(0);
+ start();
+ do {
+ dummy+=2;
+ }
+ while(time(0)==initial);
+ // On est au debut d'un cycle d'une seconde !!!
+ initial = time(0);
+ start();
+ do {
+ dummy+=2;
+ }
+ while(time(0)==initial);
+ final=time(0);
+ stop();
+ // INFOS("fine grained time : "<< get_elapsed_time_in_second());
+ // INFOS("coarse grained time : "<< final-initial);
+ _frequency=_frequency*get_elapsed_time_in_second()/double(final-initial);
+ /// INFOS("CPU frequency : "<< _frequency);
+
+ }
+
+ void add_get_click( void ){
+
+ _nb_sample++;
+ _counted_clicks[get_click()]++;
+ fill_history_clicks();
+
+ }
+
+ void dump_statistics(string filemane){
+
+ ofstream outfile (filemane.c_str(),ios::out) ;
+
+ std::map<unsigned long long , unsigned long long>::iterator itr;
+ for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++)
+ {
+ outfile << (*itr).first << " " << (*itr).second << endl ;
+ }
+
+ outfile.close();
+
+ }
+
+ void dump_history(string filemane){
+
+ ofstream outfile (filemane.c_str(),ios::out) ;
+
+
+
+ for(int i=0 ; i<_history_mean_clicks.size() ; i++)
+ {
+ outfile << i << " "
+ << _history_mean_clicks[i] << " "
+ << _history_shortest_clicks[i] << " "
+ << _history_most_occured_clicks[i] << endl ;
+ }
+
+ outfile.close();
+
+ }
+
+
+
+ double get_mean_clicks( void ){
+
+ std::map<unsigned long long,unsigned long long>::iterator itr;
+
+ unsigned long long mean_clicks=0;
+
+ for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++)
+ {
+
+ mean_clicks+=(*itr).second*(*itr).first;
+ }
+
+ return mean_clicks/double(_nb_sample);
+
+ }
+
+ double get_shortest_clicks( void ){
+
+ return double((*_counted_clicks.begin()).first);
+
+ }
+
+ void fill_history_clicks( void ){
+
+ _history_mean_clicks.push_back(get_mean_clicks());
+ _history_shortest_clicks.push_back(get_shortest_clicks());
+ _history_most_occured_clicks.push_back(get_most_occured_clicks());
+
+ }
+
+
+ double get_most_occured_clicks( void ){
+
+ unsigned long long moc=0;
+ unsigned long long max_occurence=0;
+
+ std::map<unsigned long long,unsigned long long>::iterator itr;
+
+ for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++)
+ {
+
+ if (max_occurence<=(*itr).second){
+ max_occurence=(*itr).second;
+ moc=(*itr).first;
+ }
+ }
+
+ return double(moc);
+
+ }
+
+ void clear( void )
+ {
+ _counted_clicks.clear();
+
+ _history_mean_clicks.clear();
+ _history_shortest_clicks.clear();
+ _history_most_occured_clicks.clear();
+
+ _nb_sample=0;
+ }
+
+
+
+private :
+
+ union
+ {
+ unsigned long int n32[2] ;
+ unsigned long long n64 ;
+ } _click_start;
+
+ union
+ {
+ unsigned long int n32[2] ;
+ unsigned long long n64 ;
+ } _click_stop;
+
+ double _frequency ;
+
+ map<unsigned long long,unsigned long long> _counted_clicks;
+
+ vector<double> _history_mean_clicks;
+ vector<double> _history_shortest_clicks;
+ vector<double> _history_most_occured_clicks;
+
+ unsigned long long _nb_sample;
+
+
+
+};
+
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/utils/size_lin_log.hh b/eigen/bench/btl/generic_bench/utils/size_lin_log.hh
new file mode 100644
index 0000000..bca3932
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/utils/size_lin_log.hh
@@ -0,0 +1,70 @@
+//=====================================================
+// File : size_lin_log.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, mar déc 3 18:59:37 CET 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef SIZE_LIN_LOG
+#define SIZE_LIN_LOG
+
+#include "size_log.hh"
+
+template<class Vector>
+void size_lin_log(const int nb_point, const int size_min, const int size_max, Vector & X)
+{
+ int ten=10;
+ int nine=9;
+
+ X.resize(nb_point);
+
+ if (nb_point>ten){
+
+ for (int i=0;i<nine;i++){
+
+ X[i]=i+1;
+
+ }
+
+ Vector log_size;
+ size_log(nb_point-nine,ten,size_max,log_size);
+
+ for (int i=0;i<nb_point-nine;i++){
+
+ X[i+nine]=log_size[i];
+
+ }
+ }
+ else{
+
+ for (int i=0;i<nb_point;i++){
+
+ X[i]=i+1;
+
+ }
+ }
+
+ // for (int i=0;i<nb_point;i++){
+
+// INFOS("computed sizes : X["<<i<<"]="<<X[i]);
+
+// }
+
+}
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/generic_bench/utils/size_log.hh b/eigen/bench/btl/generic_bench/utils/size_log.hh
new file mode 100644
index 0000000..13a3da7
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/utils/size_log.hh
@@ -0,0 +1,54 @@
+//=====================================================
+// File : size_log.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:17 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef SIZE_LOG
+#define SIZE_LOG
+
+#include "math.h"
+// The Vector class must satisfy the following part of STL vector concept :
+// resize() method
+// [] operator for seting element
+// the vector element are int compatible.
+template<class Vector>
+void size_log(const int nb_point, const int size_min, const int size_max, Vector & X)
+{
+ X.resize(nb_point);
+
+ float ls_min=log(float(size_min));
+ float ls_max=log(float(size_max));
+
+ float ls=0.0;
+
+ float delta_ls=(ls_max-ls_min)/(float(nb_point-1));
+
+ int size=0;
+
+ for (int i=0;i<nb_point;i++){
+
+ ls = ls_min + float(i)*delta_ls ;
+
+ size=int(exp(ls));
+
+ X[i]=size;
+ }
+
+}
+
+
+#endif
diff --git a/eigen/bench/btl/generic_bench/utils/utilities.h b/eigen/bench/btl/generic_bench/utils/utilities.h
new file mode 100644
index 0000000..d2330d0
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/utils/utilities.h
@@ -0,0 +1,90 @@
+//=============================================================================
+// File : utilities.h
+// Created : mar jun 19 13:18:14 CEST 2001
+// Author : Antoine YESSAYAN, Paul RASCLE, EDF
+// Project : SALOME
+// Copyright : EDF 2001
+// $Header$
+//=============================================================================
+
+/* --- Definition macros file to print information if _DEBUG_ is defined --- */
+
+# ifndef UTILITIES_H
+# define UTILITIES_H
+
+# include <stdlib.h>
+//# include <iostream> ok for gcc3.01
+# include <iostream>
+
+/* --- INFOS is always defined (without _DEBUG_): to be used for warnings, with release version --- */
+
+# define HEREWEARE cout<<flush ; cerr << __FILE__ << " [" << __LINE__ << "] : " << flush ;
+# define INFOS(chain) {HEREWEARE ; cerr << chain << endl ;}
+# define PYSCRIPT(chain) {cout<<flush ; cerr << "---PYSCRIPT--- " << chain << endl ;}
+
+/* --- To print date and time of compilation of current source on stdout --- */
+
+# if defined ( __GNUC__ )
+# define COMPILER "g++" ;
+# elif defined ( __sun )
+# define COMPILER "CC" ;
+# elif defined ( __KCC )
+# define COMPILER "KCC" ;
+# elif defined ( __PGI )
+# define COMPILER "pgCC" ;
+# else
+# define COMPILER "undefined" ;
+# endif
+
+# ifdef INFOS_COMPILATION
+# error INFOS_COMPILATION already defined
+# endif
+# define INFOS_COMPILATION {\
+ cerr << flush;\
+ cout << __FILE__ ;\
+ cout << " [" << __LINE__ << "] : " ;\
+ cout << "COMPILED with " << COMPILER ;\
+ cout << ", " << __DATE__ ; \
+ cout << " at " << __TIME__ << endl ;\
+ cout << "\n\n" ;\
+ cout << flush ;\
+ }
+
+# ifdef _DEBUG_
+
+/* --- the following MACROS are useful at debug time --- */
+
+# define HERE cout<<flush ; cerr << "- Trace " << __FILE__ << " [" << __LINE__ << "] : " << flush ;
+# define SCRUTE(var) HERE ; cerr << #var << "=" << var << endl ;
+# define MESSAGE(chain) {HERE ; cerr << chain << endl ;}
+# define INTERRUPTION(code) HERE ; cerr << "INTERRUPTION return code= " << code << endl ; exit(code) ;
+
+# ifndef ASSERT
+# define ASSERT(condition) if (!(condition)){ HERE ; cerr << "CONDITION " << #condition << " NOT VERIFIED"<< endl ; INTERRUPTION(1) ;}
+# endif /* ASSERT */
+
+#define REPERE cout<<flush ; cerr << " --------------" << endl << flush ;
+#define BEGIN_OF(chain) {REPERE ; HERE ; cerr << "Begin of: " << chain << endl ; REPERE ; }
+#define END_OF(chain) {REPERE ; HERE ; cerr << "Normal end of: " << chain << endl ; REPERE ; }
+
+
+
+# else /* ifdef _DEBUG_*/
+
+# define HERE
+# define SCRUTE(var)
+# define MESSAGE(chain)
+# define INTERRUPTION(code)
+
+# ifndef ASSERT
+# define ASSERT(condition)
+# endif /* ASSERT */
+
+#define REPERE
+#define BEGIN_OF(chain)
+#define END_OF(chain)
+
+
+# endif /* ifdef _DEBUG_*/
+
+# endif /* ifndef UTILITIES_H */
diff --git a/eigen/bench/btl/generic_bench/utils/xy_file.hh b/eigen/bench/btl/generic_bench/utils/xy_file.hh
new file mode 100644
index 0000000..4571bed
--- /dev/null
+++ b/eigen/bench/btl/generic_bench/utils/xy_file.hh
@@ -0,0 +1,75 @@
+//=====================================================
+// File : dump_file_x_y.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:20 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef XY_FILE_HH
+#define XY_FILE_HH
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+using namespace std;
+
+bool read_xy_file(const std::string & filename, std::vector<int> & tab_sizes,
+ std::vector<double> & tab_mflops, bool quiet = false)
+{
+
+ std::ifstream input_file (filename.c_str(),std::ios::in);
+
+ if (!input_file){
+ if (!quiet) {
+ INFOS("!!! Error opening "<<filename);
+ }
+ return false;
+ }
+
+ int nb_point=0;
+ int size=0;
+ double mflops=0;
+
+ while (input_file >> size >> mflops ){
+ nb_point++;
+ tab_sizes.push_back(size);
+ tab_mflops.push_back(mflops);
+ }
+ SCRUTE(nb_point);
+
+ input_file.close();
+ return true;
+}
+
+// The Vector class must satisfy the following part of STL vector concept :
+// resize() method
+// [] operator for seting element
+// the vector element must have the << operator define
+
+using namespace std;
+
+template<class Vector_A, class Vector_B>
+void dump_xy_file(const Vector_A & X, const Vector_B & Y, const std::string & filename){
+
+ ofstream outfile (filename.c_str(),ios::out) ;
+ int size=X.size();
+
+ for (int i=0;i<size;i++)
+ outfile << X[i] << " " << Y[i] << endl;
+
+ outfile.close();
+}
+
+#endif
diff --git a/eigen/bench/btl/libs/BLAS/CMakeLists.txt b/eigen/bench/btl/libs/BLAS/CMakeLists.txt
new file mode 100644
index 0000000..de42fe0
--- /dev/null
+++ b/eigen/bench/btl/libs/BLAS/CMakeLists.txt
@@ -0,0 +1,60 @@
+
+find_package(ATLAS)
+if (ATLAS_FOUND)
+ btl_add_bench(btl_atlas main.cpp)
+ if(BUILD_btl_atlas)
+ target_link_libraries(btl_atlas ${ATLAS_LIBRARIES})
+ set_target_properties(btl_atlas PROPERTIES COMPILE_FLAGS "-DCBLASNAME=ATLAS -DHAS_LAPACK=1")
+ endif(BUILD_btl_atlas)
+endif (ATLAS_FOUND)
+
+find_package(MKL)
+if (MKL_FOUND)
+ btl_add_bench(btl_mkl main.cpp)
+ if(BUILD_btl_mkl)
+ target_link_libraries(btl_mkl ${MKL_LIBRARIES})
+ set_target_properties(btl_mkl PROPERTIES COMPILE_FLAGS "-DCBLASNAME=INTEL_MKL -DHAS_LAPACK=1")
+ endif(BUILD_btl_mkl)
+endif (MKL_FOUND)
+
+
+find_package(GOTO2)
+if (GOTO2_FOUND)
+ btl_add_bench(btl_goto2 main.cpp)
+ if(BUILD_btl_goto2)
+ target_link_libraries(btl_goto2 ${GOTO_LIBRARIES} )
+ set_target_properties(btl_goto2 PROPERTIES COMPILE_FLAGS "-DCBLASNAME=GOTO2")
+ endif(BUILD_btl_goto2)
+endif (GOTO2_FOUND)
+
+find_package(GOTO)
+if (GOTO_FOUND)
+ if(GOTO2_FOUND)
+ btl_add_bench(btl_goto main.cpp OFF)
+ else()
+ btl_add_bench(btl_goto main.cpp)
+ endif()
+ if(BUILD_btl_goto)
+ target_link_libraries(btl_goto ${GOTO_LIBRARIES} )
+ set_target_properties(btl_goto PROPERTIES COMPILE_FLAGS "-DCBLASNAME=GOTO")
+ endif(BUILD_btl_goto)
+endif (GOTO_FOUND)
+
+find_package(ACML)
+if (ACML_FOUND)
+ btl_add_bench(btl_acml main.cpp)
+ if(BUILD_btl_acml)
+ target_link_libraries(btl_acml ${ACML_LIBRARIES} )
+ set_target_properties(btl_acml PROPERTIES COMPILE_FLAGS "-DCBLASNAME=ACML -DHAS_LAPACK=1")
+ endif(BUILD_btl_acml)
+endif (ACML_FOUND)
+
+if(Eigen_SOURCE_DIR AND CMAKE_Fortran_COMPILER_WORKS)
+ # we are inside Eigen and blas/lapack interface is compilable
+ include_directories(${Eigen_SOURCE_DIR})
+ btl_add_bench(btl_eigenblas main.cpp)
+ if(BUILD_btl_eigenblas)
+ target_link_libraries(btl_eigenblas eigen_blas eigen_lapack )
+ set_target_properties(btl_eigenblas PROPERTIES COMPILE_FLAGS "-DCBLASNAME=EigenBLAS")
+ endif()
+endif()
diff --git a/eigen/bench/btl/libs/BLAS/blas.h b/eigen/bench/btl/libs/BLAS/blas.h
new file mode 100644
index 0000000..28f3a4e
--- /dev/null
+++ b/eigen/bench/btl/libs/BLAS/blas.h
@@ -0,0 +1,675 @@
+#ifndef BLAS_H
+#define BLAS_H
+
+#define BLASFUNC(FUNC) FUNC##_
+
+#ifdef __WIN64__
+typedef long long BLASLONG;
+typedef unsigned long long BLASULONG;
+#else
+typedef long BLASLONG;
+typedef unsigned long BLASULONG;
+#endif
+
+int BLASFUNC(xerbla)(const char *, int *info, int);
+
+float BLASFUNC(sdot) (int *, float *, int *, float *, int *);
+float BLASFUNC(sdsdot)(int *, float *, float *, int *, float *, int *);
+
+double BLASFUNC(dsdot) (int *, float *, int *, float *, int *);
+double BLASFUNC(ddot) (int *, double *, int *, double *, int *);
+double BLASFUNC(qdot) (int *, double *, int *, double *, int *);
+
+#if defined(F_INTERFACE_GFORT) && !defined(__64BIT__)
+int BLASFUNC(cdotu) (int *, float * , int *, float *, int *);
+int BLASFUNC(cdotc) (int *, float *, int *, float *, int *);
+void BLASFUNC(zdotu) (double *, int *, double *, int *, double *, int *);
+void BLASFUNC(zdotc) (double *, int *, double *, int *, double *, int *);
+void BLASFUNC(xdotu) (double *, int *, double *, int *, double *, int *);
+void BLASFUNC(xdotc) (double *, int *, double *, int *, double *, int *);
+#elif defined(F_INTERFACE_F2C) || \
+ defined(F_INTERFACE_PGI) || \
+ defined(F_INTERFACE_GFORT) || \
+ (defined(F_INTERFACE_PATHSCALE) && defined(__64BIT__))
+void BLASFUNC(cdotu) (float *, int *, float * , int *, float *, int *);
+void BLASFUNC(cdotc) (float *, int *, float *, int *, float *, int *);
+void BLASFUNC(zdotu) (double *, int *, double *, int *, double *, int *);
+void BLASFUNC(zdotc) (double *, int *, double *, int *, double *, int *);
+void BLASFUNC(xdotu) (double *, int *, double *, int *, double *, int *);
+void BLASFUNC(xdotc) (double *, int *, double *, int *, double *, int *);
+#else
+std::complex<float> BLASFUNC(cdotu) (int *, float *, int *, float *, int *);
+std::complex<float> BLASFUNC(cdotc) (int *, float *, int *, float *, int *);
+std::complex<double> BLASFUNC(zdotu) (int *, double *, int *, double *, int *);
+std::complex<double> BLASFUNC(zdotc) (int *, double *, int *, double *, int *);
+double BLASFUNC(xdotu) (int *, double *, int *, double *, int *);
+double BLASFUNC(xdotc) (int *, double *, int *, double *, int *);
+#endif
+
+int BLASFUNC(cdotuw) (int *, float *, int *, float *, int *, float*);
+int BLASFUNC(cdotcw) (int *, float *, int *, float *, int *, float*);
+int BLASFUNC(zdotuw) (int *, double *, int *, double *, int *, double*);
+int BLASFUNC(zdotcw) (int *, double *, int *, double *, int *, double*);
+
+int BLASFUNC(saxpy) (int *, float *, float *, int *, float *, int *);
+int BLASFUNC(daxpy) (int *, double *, double *, int *, double *, int *);
+int BLASFUNC(qaxpy) (int *, double *, double *, int *, double *, int *);
+int BLASFUNC(caxpy) (int *, float *, float *, int *, float *, int *);
+int BLASFUNC(zaxpy) (int *, double *, double *, int *, double *, int *);
+int BLASFUNC(xaxpy) (int *, double *, double *, int *, double *, int *);
+int BLASFUNC(caxpyc)(int *, float *, float *, int *, float *, int *);
+int BLASFUNC(zaxpyc)(int *, double *, double *, int *, double *, int *);
+int BLASFUNC(xaxpyc)(int *, double *, double *, int *, double *, int *);
+
+int BLASFUNC(scopy) (int *, float *, int *, float *, int *);
+int BLASFUNC(dcopy) (int *, double *, int *, double *, int *);
+int BLASFUNC(qcopy) (int *, double *, int *, double *, int *);
+int BLASFUNC(ccopy) (int *, float *, int *, float *, int *);
+int BLASFUNC(zcopy) (int *, double *, int *, double *, int *);
+int BLASFUNC(xcopy) (int *, double *, int *, double *, int *);
+
+int BLASFUNC(sswap) (int *, float *, int *, float *, int *);
+int BLASFUNC(dswap) (int *, double *, int *, double *, int *);
+int BLASFUNC(qswap) (int *, double *, int *, double *, int *);
+int BLASFUNC(cswap) (int *, float *, int *, float *, int *);
+int BLASFUNC(zswap) (int *, double *, int *, double *, int *);
+int BLASFUNC(xswap) (int *, double *, int *, double *, int *);
+
+float BLASFUNC(sasum) (int *, float *, int *);
+float BLASFUNC(scasum)(int *, float *, int *);
+double BLASFUNC(dasum) (int *, double *, int *);
+double BLASFUNC(qasum) (int *, double *, int *);
+double BLASFUNC(dzasum)(int *, double *, int *);
+double BLASFUNC(qxasum)(int *, double *, int *);
+
+int BLASFUNC(isamax)(int *, float *, int *);
+int BLASFUNC(idamax)(int *, double *, int *);
+int BLASFUNC(iqamax)(int *, double *, int *);
+int BLASFUNC(icamax)(int *, float *, int *);
+int BLASFUNC(izamax)(int *, double *, int *);
+int BLASFUNC(ixamax)(int *, double *, int *);
+
+int BLASFUNC(ismax) (int *, float *, int *);
+int BLASFUNC(idmax) (int *, double *, int *);
+int BLASFUNC(iqmax) (int *, double *, int *);
+int BLASFUNC(icmax) (int *, float *, int *);
+int BLASFUNC(izmax) (int *, double *, int *);
+int BLASFUNC(ixmax) (int *, double *, int *);
+
+int BLASFUNC(isamin)(int *, float *, int *);
+int BLASFUNC(idamin)(int *, double *, int *);
+int BLASFUNC(iqamin)(int *, double *, int *);
+int BLASFUNC(icamin)(int *, float *, int *);
+int BLASFUNC(izamin)(int *, double *, int *);
+int BLASFUNC(ixamin)(int *, double *, int *);
+
+int BLASFUNC(ismin)(int *, float *, int *);
+int BLASFUNC(idmin)(int *, double *, int *);
+int BLASFUNC(iqmin)(int *, double *, int *);
+int BLASFUNC(icmin)(int *, float *, int *);
+int BLASFUNC(izmin)(int *, double *, int *);
+int BLASFUNC(ixmin)(int *, double *, int *);
+
+float BLASFUNC(samax) (int *, float *, int *);
+double BLASFUNC(damax) (int *, double *, int *);
+double BLASFUNC(qamax) (int *, double *, int *);
+float BLASFUNC(scamax)(int *, float *, int *);
+double BLASFUNC(dzamax)(int *, double *, int *);
+double BLASFUNC(qxamax)(int *, double *, int *);
+
+float BLASFUNC(samin) (int *, float *, int *);
+double BLASFUNC(damin) (int *, double *, int *);
+double BLASFUNC(qamin) (int *, double *, int *);
+float BLASFUNC(scamin)(int *, float *, int *);
+double BLASFUNC(dzamin)(int *, double *, int *);
+double BLASFUNC(qxamin)(int *, double *, int *);
+
+float BLASFUNC(smax) (int *, float *, int *);
+double BLASFUNC(dmax) (int *, double *, int *);
+double BLASFUNC(qmax) (int *, double *, int *);
+float BLASFUNC(scmax) (int *, float *, int *);
+double BLASFUNC(dzmax) (int *, double *, int *);
+double BLASFUNC(qxmax) (int *, double *, int *);
+
+float BLASFUNC(smin) (int *, float *, int *);
+double BLASFUNC(dmin) (int *, double *, int *);
+double BLASFUNC(qmin) (int *, double *, int *);
+float BLASFUNC(scmin) (int *, float *, int *);
+double BLASFUNC(dzmin) (int *, double *, int *);
+double BLASFUNC(qxmin) (int *, double *, int *);
+
+int BLASFUNC(sscal) (int *, float *, float *, int *);
+int BLASFUNC(dscal) (int *, double *, double *, int *);
+int BLASFUNC(qscal) (int *, double *, double *, int *);
+int BLASFUNC(cscal) (int *, float *, float *, int *);
+int BLASFUNC(zscal) (int *, double *, double *, int *);
+int BLASFUNC(xscal) (int *, double *, double *, int *);
+int BLASFUNC(csscal)(int *, float *, float *, int *);
+int BLASFUNC(zdscal)(int *, double *, double *, int *);
+int BLASFUNC(xqscal)(int *, double *, double *, int *);
+
+float BLASFUNC(snrm2) (int *, float *, int *);
+float BLASFUNC(scnrm2)(int *, float *, int *);
+
+double BLASFUNC(dnrm2) (int *, double *, int *);
+double BLASFUNC(qnrm2) (int *, double *, int *);
+double BLASFUNC(dznrm2)(int *, double *, int *);
+double BLASFUNC(qxnrm2)(int *, double *, int *);
+
+int BLASFUNC(srot) (int *, float *, int *, float *, int *, float *, float *);
+int BLASFUNC(drot) (int *, double *, int *, double *, int *, double *, double *);
+int BLASFUNC(qrot) (int *, double *, int *, double *, int *, double *, double *);
+int BLASFUNC(csrot) (int *, float *, int *, float *, int *, float *, float *);
+int BLASFUNC(zdrot) (int *, double *, int *, double *, int *, double *, double *);
+int BLASFUNC(xqrot) (int *, double *, int *, double *, int *, double *, double *);
+
+int BLASFUNC(srotg) (float *, float *, float *, float *);
+int BLASFUNC(drotg) (double *, double *, double *, double *);
+int BLASFUNC(qrotg) (double *, double *, double *, double *);
+int BLASFUNC(crotg) (float *, float *, float *, float *);
+int BLASFUNC(zrotg) (double *, double *, double *, double *);
+int BLASFUNC(xrotg) (double *, double *, double *, double *);
+
+int BLASFUNC(srotmg)(float *, float *, float *, float *, float *);
+int BLASFUNC(drotmg)(double *, double *, double *, double *, double *);
+
+int BLASFUNC(srotm) (int *, float *, int *, float *, int *, float *);
+int BLASFUNC(drotm) (int *, double *, int *, double *, int *, double *);
+int BLASFUNC(qrotm) (int *, double *, int *, double *, int *, double *);
+
+/* Level 2 routines */
+
+int BLASFUNC(sger)(int *, int *, float *, float *, int *,
+ float *, int *, float *, int *);
+int BLASFUNC(dger)(int *, int *, double *, double *, int *,
+ double *, int *, double *, int *);
+int BLASFUNC(qger)(int *, int *, double *, double *, int *,
+ double *, int *, double *, int *);
+int BLASFUNC(cgeru)(int *, int *, float *, float *, int *,
+ float *, int *, float *, int *);
+int BLASFUNC(cgerc)(int *, int *, float *, float *, int *,
+ float *, int *, float *, int *);
+int BLASFUNC(zgeru)(int *, int *, double *, double *, int *,
+ double *, int *, double *, int *);
+int BLASFUNC(zgerc)(int *, int *, double *, double *, int *,
+ double *, int *, double *, int *);
+int BLASFUNC(xgeru)(int *, int *, double *, double *, int *,
+ double *, int *, double *, int *);
+int BLASFUNC(xgerc)(int *, int *, double *, double *, int *,
+ double *, int *, double *, int *);
+
+int BLASFUNC(sgemv)(char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(dgemv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(qgemv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(cgemv)(char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zgemv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xgemv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(strsv) (char *, char *, char *, int *, float *, int *,
+ float *, int *);
+int BLASFUNC(dtrsv) (char *, char *, char *, int *, double *, int *,
+ double *, int *);
+int BLASFUNC(qtrsv) (char *, char *, char *, int *, double *, int *,
+ double *, int *);
+int BLASFUNC(ctrsv) (char *, char *, char *, int *, float *, int *,
+ float *, int *);
+int BLASFUNC(ztrsv) (char *, char *, char *, int *, double *, int *,
+ double *, int *);
+int BLASFUNC(xtrsv) (char *, char *, char *, int *, double *, int *,
+ double *, int *);
+
+int BLASFUNC(stpsv) (char *, char *, char *, int *, float *, float *, int *);
+int BLASFUNC(dtpsv) (char *, char *, char *, int *, double *, double *, int *);
+int BLASFUNC(qtpsv) (char *, char *, char *, int *, double *, double *, int *);
+int BLASFUNC(ctpsv) (char *, char *, char *, int *, float *, float *, int *);
+int BLASFUNC(ztpsv) (char *, char *, char *, int *, double *, double *, int *);
+int BLASFUNC(xtpsv) (char *, char *, char *, int *, double *, double *, int *);
+
+int BLASFUNC(strmv) (char *, char *, char *, int *, float *, int *,
+ float *, int *);
+int BLASFUNC(dtrmv) (char *, char *, char *, int *, double *, int *,
+ double *, int *);
+int BLASFUNC(qtrmv) (char *, char *, char *, int *, double *, int *,
+ double *, int *);
+int BLASFUNC(ctrmv) (char *, char *, char *, int *, float *, int *,
+ float *, int *);
+int BLASFUNC(ztrmv) (char *, char *, char *, int *, double *, int *,
+ double *, int *);
+int BLASFUNC(xtrmv) (char *, char *, char *, int *, double *, int *,
+ double *, int *);
+
+int BLASFUNC(stpmv) (char *, char *, char *, int *, float *, float *, int *);
+int BLASFUNC(dtpmv) (char *, char *, char *, int *, double *, double *, int *);
+int BLASFUNC(qtpmv) (char *, char *, char *, int *, double *, double *, int *);
+int BLASFUNC(ctpmv) (char *, char *, char *, int *, float *, float *, int *);
+int BLASFUNC(ztpmv) (char *, char *, char *, int *, double *, double *, int *);
+int BLASFUNC(xtpmv) (char *, char *, char *, int *, double *, double *, int *);
+
+int BLASFUNC(stbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *);
+int BLASFUNC(dtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);
+int BLASFUNC(qtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);
+int BLASFUNC(ctbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *);
+int BLASFUNC(ztbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);
+int BLASFUNC(xtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);
+
+int BLASFUNC(stbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *);
+int BLASFUNC(dtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);
+int BLASFUNC(qtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);
+int BLASFUNC(ctbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *);
+int BLASFUNC(ztbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);
+int BLASFUNC(xtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);
+
+int BLASFUNC(ssymv) (char *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(dsymv) (char *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(qsymv) (char *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(csymv) (char *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zsymv) (char *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xsymv) (char *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(sspmv) (char *, int *, float *, float *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(dspmv) (char *, int *, double *, double *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(qspmv) (char *, int *, double *, double *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(cspmv) (char *, int *, float *, float *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zspmv) (char *, int *, double *, double *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xspmv) (char *, int *, double *, double *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(ssyr) (char *, int *, float *, float *, int *,
+ float *, int *);
+int BLASFUNC(dsyr) (char *, int *, double *, double *, int *,
+ double *, int *);
+int BLASFUNC(qsyr) (char *, int *, double *, double *, int *,
+ double *, int *);
+int BLASFUNC(csyr) (char *, int *, float *, float *, int *,
+ float *, int *);
+int BLASFUNC(zsyr) (char *, int *, double *, double *, int *,
+ double *, int *);
+int BLASFUNC(xsyr) (char *, int *, double *, double *, int *,
+ double *, int *);
+
+int BLASFUNC(ssyr2) (char *, int *, float *,
+ float *, int *, float *, int *, float *, int *);
+int BLASFUNC(dsyr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *, int *);
+int BLASFUNC(qsyr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *, int *);
+int BLASFUNC(csyr2) (char *, int *, float *,
+ float *, int *, float *, int *, float *, int *);
+int BLASFUNC(zsyr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *, int *);
+int BLASFUNC(xsyr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *, int *);
+
+int BLASFUNC(sspr) (char *, int *, float *, float *, int *,
+ float *);
+int BLASFUNC(dspr) (char *, int *, double *, double *, int *,
+ double *);
+int BLASFUNC(qspr) (char *, int *, double *, double *, int *,
+ double *);
+int BLASFUNC(cspr) (char *, int *, float *, float *, int *,
+ float *);
+int BLASFUNC(zspr) (char *, int *, double *, double *, int *,
+ double *);
+int BLASFUNC(xspr) (char *, int *, double *, double *, int *,
+ double *);
+
+int BLASFUNC(sspr2) (char *, int *, float *,
+ float *, int *, float *, int *, float *);
+int BLASFUNC(dspr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *);
+int BLASFUNC(qspr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *);
+int BLASFUNC(cspr2) (char *, int *, float *,
+ float *, int *, float *, int *, float *);
+int BLASFUNC(zspr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *);
+int BLASFUNC(xspr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *);
+
+int BLASFUNC(cher) (char *, int *, float *, float *, int *,
+ float *, int *);
+int BLASFUNC(zher) (char *, int *, double *, double *, int *,
+ double *, int *);
+int BLASFUNC(xher) (char *, int *, double *, double *, int *,
+ double *, int *);
+
+int BLASFUNC(chpr) (char *, int *, float *, float *, int *, float *);
+int BLASFUNC(zhpr) (char *, int *, double *, double *, int *, double *);
+int BLASFUNC(xhpr) (char *, int *, double *, double *, int *, double *);
+
+int BLASFUNC(cher2) (char *, int *, float *,
+ float *, int *, float *, int *, float *, int *);
+int BLASFUNC(zher2) (char *, int *, double *,
+ double *, int *, double *, int *, double *, int *);
+int BLASFUNC(xher2) (char *, int *, double *,
+ double *, int *, double *, int *, double *, int *);
+
+int BLASFUNC(chpr2) (char *, int *, float *,
+ float *, int *, float *, int *, float *);
+int BLASFUNC(zhpr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *);
+int BLASFUNC(xhpr2) (char *, int *, double *,
+ double *, int *, double *, int *, double *);
+
+int BLASFUNC(chemv) (char *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zhemv) (char *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xhemv) (char *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(chpmv) (char *, int *, float *, float *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zhpmv) (char *, int *, double *, double *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xhpmv) (char *, int *, double *, double *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(snorm)(char *, int *, int *, float *, int *);
+int BLASFUNC(dnorm)(char *, int *, int *, double *, int *);
+int BLASFUNC(cnorm)(char *, int *, int *, float *, int *);
+int BLASFUNC(znorm)(char *, int *, int *, double *, int *);
+
+int BLASFUNC(sgbmv)(char *, int *, int *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(dgbmv)(char *, int *, int *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(qgbmv)(char *, int *, int *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(cgbmv)(char *, int *, int *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zgbmv)(char *, int *, int *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xgbmv)(char *, int *, int *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(ssbmv)(char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(dsbmv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(qsbmv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(csbmv)(char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zsbmv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xsbmv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(chbmv)(char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zhbmv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xhbmv)(char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+/* Level 3 routines */
+
+int BLASFUNC(sgemm)(char *, char *, int *, int *, int *, float *,
+ float *, int *, float *, int *, float *, float *, int *);
+int BLASFUNC(dgemm)(char *, char *, int *, int *, int *, double *,
+ double *, int *, double *, int *, double *, double *, int *);
+int BLASFUNC(qgemm)(char *, char *, int *, int *, int *, double *,
+ double *, int *, double *, int *, double *, double *, int *);
+int BLASFUNC(cgemm)(char *, char *, int *, int *, int *, float *,
+ float *, int *, float *, int *, float *, float *, int *);
+int BLASFUNC(zgemm)(char *, char *, int *, int *, int *, double *,
+ double *, int *, double *, int *, double *, double *, int *);
+int BLASFUNC(xgemm)(char *, char *, int *, int *, int *, double *,
+ double *, int *, double *, int *, double *, double *, int *);
+
+int BLASFUNC(cgemm3m)(char *, char *, int *, int *, int *, float *,
+ float *, int *, float *, int *, float *, float *, int *);
+int BLASFUNC(zgemm3m)(char *, char *, int *, int *, int *, double *,
+ double *, int *, double *, int *, double *, double *, int *);
+int BLASFUNC(xgemm3m)(char *, char *, int *, int *, int *, double *,
+ double *, int *, double *, int *, double *, double *, int *);
+
+int BLASFUNC(sge2mm)(char *, char *, char *, int *, int *,
+ float *, float *, int *, float *, int *,
+ float *, float *, int *);
+int BLASFUNC(dge2mm)(char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *,
+ double *, double *, int *);
+int BLASFUNC(cge2mm)(char *, char *, char *, int *, int *,
+ float *, float *, int *, float *, int *,
+ float *, float *, int *);
+int BLASFUNC(zge2mm)(char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *,
+ double *, double *, int *);
+
+int BLASFUNC(strsm)(char *, char *, char *, char *, int *, int *,
+ float *, float *, int *, float *, int *);
+int BLASFUNC(dtrsm)(char *, char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *);
+int BLASFUNC(qtrsm)(char *, char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *);
+int BLASFUNC(ctrsm)(char *, char *, char *, char *, int *, int *,
+ float *, float *, int *, float *, int *);
+int BLASFUNC(ztrsm)(char *, char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *);
+int BLASFUNC(xtrsm)(char *, char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *);
+
+int BLASFUNC(strmm)(char *, char *, char *, char *, int *, int *,
+ float *, float *, int *, float *, int *);
+int BLASFUNC(dtrmm)(char *, char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *);
+int BLASFUNC(qtrmm)(char *, char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *);
+int BLASFUNC(ctrmm)(char *, char *, char *, char *, int *, int *,
+ float *, float *, int *, float *, int *);
+int BLASFUNC(ztrmm)(char *, char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *);
+int BLASFUNC(xtrmm)(char *, char *, char *, char *, int *, int *,
+ double *, double *, int *, double *, int *);
+
+int BLASFUNC(ssymm)(char *, char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(dsymm)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(qsymm)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(csymm)(char *, char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zsymm)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xsymm)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(csymm3m)(char *, char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zsymm3m)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xsymm3m)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(ssyrk)(char *, char *, int *, int *, float *, float *, int *,
+ float *, float *, int *);
+int BLASFUNC(dsyrk)(char *, char *, int *, int *, double *, double *, int *,
+ double *, double *, int *);
+int BLASFUNC(qsyrk)(char *, char *, int *, int *, double *, double *, int *,
+ double *, double *, int *);
+int BLASFUNC(csyrk)(char *, char *, int *, int *, float *, float *, int *,
+ float *, float *, int *);
+int BLASFUNC(zsyrk)(char *, char *, int *, int *, double *, double *, int *,
+ double *, double *, int *);
+int BLASFUNC(xsyrk)(char *, char *, int *, int *, double *, double *, int *,
+ double *, double *, int *);
+
+int BLASFUNC(ssyr2k)(char *, char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(dsyr2k)(char *, char *, int *, int *, double *, double *, int *,
+ double*, int *, double *, double *, int *);
+int BLASFUNC(qsyr2k)(char *, char *, int *, int *, double *, double *, int *,
+ double*, int *, double *, double *, int *);
+int BLASFUNC(csyr2k)(char *, char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zsyr2k)(char *, char *, int *, int *, double *, double *, int *,
+ double*, int *, double *, double *, int *);
+int BLASFUNC(xsyr2k)(char *, char *, int *, int *, double *, double *, int *,
+ double*, int *, double *, double *, int *);
+
+int BLASFUNC(chemm)(char *, char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zhemm)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xhemm)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(chemm3m)(char *, char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zhemm3m)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+int BLASFUNC(xhemm3m)(char *, char *, int *, int *, double *, double *, int *,
+ double *, int *, double *, double *, int *);
+
+int BLASFUNC(cherk)(char *, char *, int *, int *, float *, float *, int *,
+ float *, float *, int *);
+int BLASFUNC(zherk)(char *, char *, int *, int *, double *, double *, int *,
+ double *, double *, int *);
+int BLASFUNC(xherk)(char *, char *, int *, int *, double *, double *, int *,
+ double *, double *, int *);
+
+int BLASFUNC(cher2k)(char *, char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zher2k)(char *, char *, int *, int *, double *, double *, int *,
+ double*, int *, double *, double *, int *);
+int BLASFUNC(xher2k)(char *, char *, int *, int *, double *, double *, int *,
+ double*, int *, double *, double *, int *);
+int BLASFUNC(cher2m)(char *, char *, char *, int *, int *, float *, float *, int *,
+ float *, int *, float *, float *, int *);
+int BLASFUNC(zher2m)(char *, char *, char *, int *, int *, double *, double *, int *,
+ double*, int *, double *, double *, int *);
+int BLASFUNC(xher2m)(char *, char *, char *, int *, int *, double *, double *, int *,
+ double*, int *, double *, double *, int *);
+
+int BLASFUNC(sgemt)(char *, int *, int *, float *, float *, int *,
+ float *, int *);
+int BLASFUNC(dgemt)(char *, int *, int *, double *, double *, int *,
+ double *, int *);
+int BLASFUNC(cgemt)(char *, int *, int *, float *, float *, int *,
+ float *, int *);
+int BLASFUNC(zgemt)(char *, int *, int *, double *, double *, int *,
+ double *, int *);
+
+int BLASFUNC(sgema)(char *, char *, int *, int *, float *,
+ float *, int *, float *, float *, int *, float *, int *);
+int BLASFUNC(dgema)(char *, char *, int *, int *, double *,
+ double *, int *, double*, double *, int *, double*, int *);
+int BLASFUNC(cgema)(char *, char *, int *, int *, float *,
+ float *, int *, float *, float *, int *, float *, int *);
+int BLASFUNC(zgema)(char *, char *, int *, int *, double *,
+ double *, int *, double*, double *, int *, double*, int *);
+
+int BLASFUNC(sgems)(char *, char *, int *, int *, float *,
+ float *, int *, float *, float *, int *, float *, int *);
+int BLASFUNC(dgems)(char *, char *, int *, int *, double *,
+ double *, int *, double*, double *, int *, double*, int *);
+int BLASFUNC(cgems)(char *, char *, int *, int *, float *,
+ float *, int *, float *, float *, int *, float *, int *);
+int BLASFUNC(zgems)(char *, char *, int *, int *, double *,
+ double *, int *, double*, double *, int *, double*, int *);
+
+int BLASFUNC(sgetf2)(int *, int *, float *, int *, int *, int *);
+int BLASFUNC(dgetf2)(int *, int *, double *, int *, int *, int *);
+int BLASFUNC(qgetf2)(int *, int *, double *, int *, int *, int *);
+int BLASFUNC(cgetf2)(int *, int *, float *, int *, int *, int *);
+int BLASFUNC(zgetf2)(int *, int *, double *, int *, int *, int *);
+int BLASFUNC(xgetf2)(int *, int *, double *, int *, int *, int *);
+
+int BLASFUNC(sgetrf)(int *, int *, float *, int *, int *, int *);
+int BLASFUNC(dgetrf)(int *, int *, double *, int *, int *, int *);
+int BLASFUNC(qgetrf)(int *, int *, double *, int *, int *, int *);
+int BLASFUNC(cgetrf)(int *, int *, float *, int *, int *, int *);
+int BLASFUNC(zgetrf)(int *, int *, double *, int *, int *, int *);
+int BLASFUNC(xgetrf)(int *, int *, double *, int *, int *, int *);
+
+int BLASFUNC(slaswp)(int *, float *, int *, int *, int *, int *, int *);
+int BLASFUNC(dlaswp)(int *, double *, int *, int *, int *, int *, int *);
+int BLASFUNC(qlaswp)(int *, double *, int *, int *, int *, int *, int *);
+int BLASFUNC(claswp)(int *, float *, int *, int *, int *, int *, int *);
+int BLASFUNC(zlaswp)(int *, double *, int *, int *, int *, int *, int *);
+int BLASFUNC(xlaswp)(int *, double *, int *, int *, int *, int *, int *);
+
+int BLASFUNC(sgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *);
+int BLASFUNC(dgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
+int BLASFUNC(qgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
+int BLASFUNC(cgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *);
+int BLASFUNC(zgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
+int BLASFUNC(xgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);
+
+int BLASFUNC(sgesv)(int *, int *, float *, int *, int *, float *, int *, int *);
+int BLASFUNC(dgesv)(int *, int *, double *, int *, int *, double*, int *, int *);
+int BLASFUNC(qgesv)(int *, int *, double *, int *, int *, double*, int *, int *);
+int BLASFUNC(cgesv)(int *, int *, float *, int *, int *, float *, int *, int *);
+int BLASFUNC(zgesv)(int *, int *, double *, int *, int *, double*, int *, int *);
+int BLASFUNC(xgesv)(int *, int *, double *, int *, int *, double*, int *, int *);
+
+int BLASFUNC(spotf2)(char *, int *, float *, int *, int *);
+int BLASFUNC(dpotf2)(char *, int *, double *, int *, int *);
+int BLASFUNC(qpotf2)(char *, int *, double *, int *, int *);
+int BLASFUNC(cpotf2)(char *, int *, float *, int *, int *);
+int BLASFUNC(zpotf2)(char *, int *, double *, int *, int *);
+int BLASFUNC(xpotf2)(char *, int *, double *, int *, int *);
+
+int BLASFUNC(spotrf)(char *, int *, float *, int *, int *);
+int BLASFUNC(dpotrf)(char *, int *, double *, int *, int *);
+int BLASFUNC(qpotrf)(char *, int *, double *, int *, int *);
+int BLASFUNC(cpotrf)(char *, int *, float *, int *, int *);
+int BLASFUNC(zpotrf)(char *, int *, double *, int *, int *);
+int BLASFUNC(xpotrf)(char *, int *, double *, int *, int *);
+
+int BLASFUNC(slauu2)(char *, int *, float *, int *, int *);
+int BLASFUNC(dlauu2)(char *, int *, double *, int *, int *);
+int BLASFUNC(qlauu2)(char *, int *, double *, int *, int *);
+int BLASFUNC(clauu2)(char *, int *, float *, int *, int *);
+int BLASFUNC(zlauu2)(char *, int *, double *, int *, int *);
+int BLASFUNC(xlauu2)(char *, int *, double *, int *, int *);
+
+int BLASFUNC(slauum)(char *, int *, float *, int *, int *);
+int BLASFUNC(dlauum)(char *, int *, double *, int *, int *);
+int BLASFUNC(qlauum)(char *, int *, double *, int *, int *);
+int BLASFUNC(clauum)(char *, int *, float *, int *, int *);
+int BLASFUNC(zlauum)(char *, int *, double *, int *, int *);
+int BLASFUNC(xlauum)(char *, int *, double *, int *, int *);
+
+int BLASFUNC(strti2)(char *, char *, int *, float *, int *, int *);
+int BLASFUNC(dtrti2)(char *, char *, int *, double *, int *, int *);
+int BLASFUNC(qtrti2)(char *, char *, int *, double *, int *, int *);
+int BLASFUNC(ctrti2)(char *, char *, int *, float *, int *, int *);
+int BLASFUNC(ztrti2)(char *, char *, int *, double *, int *, int *);
+int BLASFUNC(xtrti2)(char *, char *, int *, double *, int *, int *);
+
+int BLASFUNC(strtri)(char *, char *, int *, float *, int *, int *);
+int BLASFUNC(dtrtri)(char *, char *, int *, double *, int *, int *);
+int BLASFUNC(qtrtri)(char *, char *, int *, double *, int *, int *);
+int BLASFUNC(ctrtri)(char *, char *, int *, float *, int *, int *);
+int BLASFUNC(ztrtri)(char *, char *, int *, double *, int *, int *);
+int BLASFUNC(xtrtri)(char *, char *, int *, double *, int *, int *);
+
+int BLASFUNC(spotri)(char *, int *, float *, int *, int *);
+int BLASFUNC(dpotri)(char *, int *, double *, int *, int *);
+int BLASFUNC(qpotri)(char *, int *, double *, int *, int *);
+int BLASFUNC(cpotri)(char *, int *, float *, int *, int *);
+int BLASFUNC(zpotri)(char *, int *, double *, int *, int *);
+int BLASFUNC(xpotri)(char *, int *, double *, int *, int *);
+
+#endif
diff --git a/eigen/bench/btl/libs/BLAS/blas_interface.hh b/eigen/bench/btl/libs/BLAS/blas_interface.hh
new file mode 100644
index 0000000..6510546
--- /dev/null
+++ b/eigen/bench/btl/libs/BLAS/blas_interface.hh
@@ -0,0 +1,83 @@
+//=====================================================
+// File : blas_interface.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:28 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef blas_PRODUIT_MATRICE_VECTEUR_HH
+#define blas_PRODUIT_MATRICE_VECTEUR_HH
+
+#include <c_interface_base.h>
+#include <complex>
+extern "C"
+{
+#include "blas.h"
+
+ // Cholesky Factorization
+// void spotrf_(const char* uplo, const int* n, float *a, const int* ld, int* info);
+// void dpotrf_(const char* uplo, const int* n, double *a, const int* ld, int* info);
+ void ssytrd_(char *uplo, const int *n, float *a, const int *lda, float *d, float *e, float *tau, float *work, int *lwork, int *info );
+ void dsytrd_(char *uplo, const int *n, double *a, const int *lda, double *d, double *e, double *tau, double *work, int *lwork, int *info );
+ void sgehrd_( const int *n, int *ilo, int *ihi, float *a, const int *lda, float *tau, float *work, int *lwork, int *info );
+ void dgehrd_( const int *n, int *ilo, int *ihi, double *a, const int *lda, double *tau, double *work, int *lwork, int *info );
+
+ // LU row pivoting
+// void dgetrf_( int *m, int *n, double *a, int *lda, int *ipiv, int *info );
+// void sgetrf_(const int* m, const int* n, float *a, const int* ld, int* ipivot, int* info);
+ // LU full pivoting
+ void sgetc2_(const int* n, float *a, const int *lda, int *ipiv, int *jpiv, int*info );
+ void dgetc2_(const int* n, double *a, const int *lda, int *ipiv, int *jpiv, int*info );
+#ifdef HAS_LAPACK
+#endif
+}
+
+#define MAKE_STRING2(S) #S
+#define MAKE_STRING(S) MAKE_STRING2(S)
+
+#define CAT2(A,B) A##B
+#define CAT(A,B) CAT2(A,B)
+
+
+template<class real> class blas_interface;
+
+
+static char notrans = 'N';
+static char trans = 'T';
+static char nonunit = 'N';
+static char lower = 'L';
+static char right = 'R';
+static char left = 'L';
+static int intone = 1;
+
+
+
+#define SCALAR float
+#define SCALAR_PREFIX s
+#include "blas_interface_impl.hh"
+#undef SCALAR
+#undef SCALAR_PREFIX
+
+
+#define SCALAR double
+#define SCALAR_PREFIX d
+#include "blas_interface_impl.hh"
+#undef SCALAR
+#undef SCALAR_PREFIX
+
+#endif
+
+
+
diff --git a/eigen/bench/btl/libs/BLAS/blas_interface_impl.hh b/eigen/bench/btl/libs/BLAS/blas_interface_impl.hh
new file mode 100644
index 0000000..0e84df0
--- /dev/null
+++ b/eigen/bench/btl/libs/BLAS/blas_interface_impl.hh
@@ -0,0 +1,151 @@
+
+#define BLAS_FUNC(NAME) CAT(CAT(SCALAR_PREFIX,NAME),_)
+
+template<> class blas_interface<SCALAR> : public c_interface_base<SCALAR>
+{
+
+public :
+
+ static SCALAR fone;
+ static SCALAR fzero;
+
+ static inline std::string name()
+ {
+ return MAKE_STRING(CBLASNAME);
+ }
+
+ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ BLAS_FUNC(gemv)(&notrans,&N,&N,&fone,A,&N,B,&intone,&fzero,X,&intone);
+ }
+
+ static inline void symv(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ BLAS_FUNC(symv)(&lower, &N,&fone,A,&N,B,&intone,&fzero,X,&intone);
+ }
+
+ static inline void syr2(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ BLAS_FUNC(syr2)(&lower,&N,&fone,B,&intone,X,&intone,A,&N);
+ }
+
+ static inline void ger(gene_matrix & A, gene_vector & X, gene_vector & Y, int N){
+ BLAS_FUNC(ger)(&N,&N,&fone,X,&intone,Y,&intone,A,&N);
+ }
+
+ static inline void rot(gene_vector & A, gene_vector & B, SCALAR c, SCALAR s, int N){
+ BLAS_FUNC(rot)(&N,A,&intone,B,&intone,&c,&s);
+ }
+
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ BLAS_FUNC(gemv)(&trans,&N,&N,&fone,A,&N,B,&intone,&fzero,X,&intone);
+ }
+
+ static inline void matrix_matrix_product(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){
+ BLAS_FUNC(gemm)(&notrans,&notrans,&N,&N,&N,&fone,A,&N,B,&N,&fzero,X,&N);
+ }
+
+ static inline void transposed_matrix_matrix_product(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){
+ 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){
+// 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);
+ }
+
+ static inline void axpy(SCALAR coef, const gene_vector & X, gene_vector & Y, int N){
+ BLAS_FUNC(axpy)(&N,&coef,X,&intone,Y,&intone);
+ }
+
+ static inline void axpby(SCALAR a, const gene_vector & X, SCALAR b, gene_vector & Y, int N){
+ BLAS_FUNC(scal)(&N,&b,Y,&intone);
+ BLAS_FUNC(axpy)(&N,&a,X,&intone,Y,&intone);
+ }
+
+ static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){
+ int N2 = N*N;
+ BLAS_FUNC(copy)(&N2, X, &intone, C, &intone);
+ char uplo = 'L';
+ int info = 0;
+ BLAS_FUNC(potrf)(&uplo, &N, C, &N, &info);
+ if(info!=0) std::cerr << "potrf_ error " << info << "\n";
+ }
+
+ static inline void partial_lu_decomp(const gene_matrix & X, gene_matrix & C, int N){
+ int N2 = N*N;
+ BLAS_FUNC(copy)(&N2, X, &intone, C, &intone);
+ char uplo = 'L';
+ int info = 0;
+ int * ipiv = (int*)alloca(sizeof(int)*N);
+ BLAS_FUNC(getrf)(&N, &N, C, &N, ipiv, &info);
+ if(info!=0) std::cerr << "getrf_ error " << info << "\n";
+ }
+
+ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector & X, int N){
+ BLAS_FUNC(copy)(&N, B, &intone, X, &intone);
+ BLAS_FUNC(trsv)(&lower, &notrans, &nonunit, &N, L, &N, X, &intone);
+ }
+
+ static inline void trisolve_lower_matrix(const gene_matrix & L, const gene_matrix& B, gene_matrix & X, int N){
+ BLAS_FUNC(copy)(&N, B, &intone, X, &intone);
+ BLAS_FUNC(trsm)(&right, &lower, &notrans, &nonunit, &N, &N, &fone, L, &N, X, &N);
+ }
+
+ static inline void trmm(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){
+ BLAS_FUNC(trmm)(&left, &lower, &notrans,&nonunit, &N,&N,&fone,A,&N,B,&N);
+ }
+
+ #ifdef HAS_LAPACK
+
+ static inline void lu_decomp(const gene_matrix & X, gene_matrix & C, int N){
+ int N2 = N*N;
+ BLAS_FUNC(copy)(&N2, X, &intone, C, &intone);
+ char uplo = 'L';
+ int info = 0;
+ int * ipiv = (int*)alloca(sizeof(int)*N);
+ int * jpiv = (int*)alloca(sizeof(int)*N);
+ BLAS_FUNC(getc2)(&N, C, &N, ipiv, jpiv, &info);
+ }
+
+
+
+ static inline void hessenberg(const gene_matrix & X, gene_matrix & C, int N){
+ {
+ int N2 = N*N;
+ int inc = 1;
+ BLAS_FUNC(copy)(&N2, X, &inc, C, &inc);
+ }
+ int info = 0;
+ int ilo = 1;
+ int ihi = N;
+ int bsize = 64;
+ int worksize = N*bsize;
+ SCALAR* d = new SCALAR[N+worksize];
+ BLAS_FUNC(gehrd)(&N, &ilo, &ihi, C, &N, d, d+N, &worksize, &info);
+ delete[] d;
+ }
+
+ static inline void tridiagonalization(const gene_matrix & X, gene_matrix & C, int N){
+ {
+ int N2 = N*N;
+ int inc = 1;
+ BLAS_FUNC(copy)(&N2, X, &inc, C, &inc);
+ }
+ char uplo = 'U';
+ int info = 0;
+ int ilo = 1;
+ int ihi = N;
+ int bsize = 64;
+ int worksize = N*bsize;
+ SCALAR* d = new SCALAR[3*N+worksize];
+ BLAS_FUNC(sytrd)(&uplo, &N, C, &N, d, d+N, d+2*N, d+3*N, &worksize, &info);
+ delete[] d;
+ }
+
+ #endif // HAS_LAPACK
+
+};
+
+SCALAR blas_interface<SCALAR>::fone = SCALAR(1);
+SCALAR blas_interface<SCALAR>::fzero = SCALAR(0);
diff --git a/eigen/bench/btl/libs/BLAS/c_interface_base.h b/eigen/bench/btl/libs/BLAS/c_interface_base.h
new file mode 100644
index 0000000..515d8dc
--- /dev/null
+++ b/eigen/bench/btl/libs/BLAS/c_interface_base.h
@@ -0,0 +1,73 @@
+
+#ifndef BTL_C_INTERFACE_BASE_H
+#define BTL_C_INTERFACE_BASE_H
+
+#include "utilities.h"
+#include <vector>
+
+template<class real> class c_interface_base
+{
+
+public:
+
+ typedef real real_type;
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector > stl_matrix;
+
+ typedef real* gene_matrix;
+ typedef real* gene_vector;
+
+ static void free_matrix(gene_matrix & A, int N){
+ delete A;
+ }
+
+ static void free_vector(gene_vector & B){
+ delete B;
+ }
+
+ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N = A_stl.size();
+ A = new real[N*N];
+ for (int j=0;j<N;j++)
+ for (int i=0;i<N;i++)
+ A[i+N*j] = A_stl[j][i];
+ }
+
+ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ int N = B_stl.size();
+ B = new real[N];
+ for (int i=0;i<N;i++)
+ B[i] = B_stl[i];
+ }
+
+ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ int N = B_stl.size();
+ for (int i=0;i<N;i++)
+ B_stl[i] = B[i];
+ }
+
+ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N = A_stl.size();
+ for (int j=0;j<N;j++){
+ A_stl[j].resize(N);
+ for (int i=0;i<N;i++)
+ A_stl[j][i] = A[i+N*j];
+ }
+ }
+
+ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ for (int i=0;i<N;i++)
+ cible[i]=source[i];
+ }
+
+ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ for (int j=0;j<N;j++){
+ for (int i=0;i<N;i++){
+ cible[i+N*j] = source[i+N*j];
+ }
+ }
+ }
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/BLAS/main.cpp b/eigen/bench/btl/libs/BLAS/main.cpp
new file mode 100644
index 0000000..8347c9f
--- /dev/null
+++ b/eigen/bench/btl/libs/BLAS/main.cpp
@@ -0,0 +1,73 @@
+//=====================================================
+// File : main.cpp
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:28 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "blas_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+
+#include "action_cholesky.hh"
+#include "action_lu_decomp.hh"
+#include "action_partial_lu.hh"
+#include "action_trisolve_matrix.hh"
+
+#ifdef HAS_LAPACK
+#include "action_hessenberg.hh"
+#endif
+
+BTL_MAIN;
+
+int main()
+{
+
+ bench<Action_axpy<blas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+ bench<Action_axpby<blas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+
+ bench<Action_matrix_vector_product<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_atv_product<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_symv<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_syr2<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+
+ bench<Action_ger<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ 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_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);
+ bench<Action_trisolve_matrix<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ bench<Action_trmm<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ bench<Action_cholesky<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_partial_lu<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ #ifdef HAS_LAPACK
+ bench<Action_lu_decomp<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_hessenberg<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_tridiagonalization<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ #endif
+
+ //bench<Action_lu_solve<blas_LU_solve_interface<REAL_TYPE> > >(MIN_LU,MAX_LU,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/STL/CMakeLists.txt b/eigen/bench/btl/libs/STL/CMakeLists.txt
new file mode 100644
index 0000000..4cfc2dc
--- /dev/null
+++ b/eigen/bench/btl/libs/STL/CMakeLists.txt
@@ -0,0 +1,2 @@
+
+btl_add_bench(btl_STL main.cpp OFF)
diff --git a/eigen/bench/btl/libs/STL/STL_interface.hh b/eigen/bench/btl/libs/STL/STL_interface.hh
new file mode 100644
index 0000000..93e76bd
--- /dev/null
+++ b/eigen/bench/btl/libs/STL/STL_interface.hh
@@ -0,0 +1,244 @@
+//=====================================================
+// File : STL_interface.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:24 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef STL_INTERFACE_HH
+#define STL_INTERFACE_HH
+#include <string>
+#include <vector>
+#include "utilities.h"
+
+using namespace std;
+
+template<class real>
+class STL_interface{
+
+public :
+
+ typedef real real_type ;
+
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector > stl_matrix;
+
+ typedef stl_matrix gene_matrix;
+
+ typedef stl_vector gene_vector;
+
+ static inline std::string name( void )
+ {
+ return "STL";
+ }
+
+ static void free_matrix(gene_matrix & A, int N){}
+
+ static void free_vector(gene_vector & B){}
+
+ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ A = A_stl;
+ }
+
+ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ B = B_stl;
+ }
+
+ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ B_stl = B ;
+ }
+
+
+ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ A_stl = A ;
+ }
+
+ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ for (int i=0;i<N;i++){
+ cible[i]=source[i];
+ }
+ }
+
+
+ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ for (int i=0;i<N;i++)
+ for (int j=0;j<N;j++)
+ 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 aat_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;
+ if(i>=j)
+ {
+ for (int k=0;k<N;k++){
+ somme+=A[k][i]*A[k][j];
+ }
+ X[j][i]=somme;
+ }
+ }
+ }
+ }
+
+
+ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, 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[k][i]*B[j][k];
+ X[j][i]=somme;
+ }
+ }
+ }
+
+ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N)
+ {
+ real somme;
+ for (int i=0;i<N;i++){
+ somme=0.0;
+ for (int j=0;j<N;j++)
+ somme+=A[j][i]*B[j];
+ X[i]=somme;
+ }
+ }
+
+ static inline void symv(gene_matrix & A, gene_vector & B, gene_vector & X, int N)
+ {
+ for (int j=0; j<N; ++j)
+ X[j] = 0;
+ for (int j=0; j<N; ++j)
+ {
+ real t1 = B[j];
+ real t2 = 0;
+ X[j] += t1 * A[j][j];
+ for (int i=j+1; i<N; ++i) {
+ X[i] += t1 * A[j][i];
+ t2 += A[j][i] * B[i];
+ }
+ X[j] += t2;
+ }
+ }
+
+ static inline void syr2(gene_matrix & A, gene_vector & B, gene_vector & X, int N)
+ {
+ for (int j=0; j<N; ++j)
+ {
+ for (int i=j; i<N; ++i)
+ A[j][i] += B[i]*X[j] + B[j]*X[i];
+ }
+ }
+
+ static inline void ger(gene_matrix & A, gene_vector & X, gene_vector & Y, int N)
+ {
+ for (int j=0; j<N; ++j)
+ {
+ for (int i=j; i<N; ++i)
+ A[j][i] += X[i]*Y[j];
+ }
+ }
+
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N)
+ {
+ real somme;
+ for (int i=0;i<N;i++){
+ somme = 0.0;
+ for (int j=0;j<N;j++)
+ somme += A[i][j]*B[j];
+ X[i] = somme;
+ }
+ }
+
+ static inline void axpy(real coef, const gene_vector & X, gene_vector & Y, int N){
+ for (int i=0;i<N;i++)
+ Y[i]+=coef*X[i];
+ }
+
+ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){
+ for (int i=0;i<N;i++)
+ Y[i] = a*X[i] + b*Y[i];
+ }
+
+ static inline void trisolve_lower(const gene_matrix & L, const gene_vector & B, gene_vector & X, int N){
+ copy_vector(B,X,N);
+ for(int i=0; i<N; ++i)
+ {
+ X[i] /= L[i][i];
+ real tmp = X[i];
+ for (int j=i+1; j<N; ++j)
+ X[j] -= tmp * L[i][j];
+ }
+ }
+
+ static inline real norm_diff(const stl_vector & A, const stl_vector & B)
+ {
+ int N=A.size();
+ real somme=0.0;
+ real somme2=0.0;
+
+ for (int i=0;i<N;i++){
+ real diff=A[i]-B[i];
+ somme+=diff*diff;
+ somme2+=A[i]*A[i];
+ }
+ return somme/somme2;
+ }
+
+ static inline real norm_diff(const stl_matrix & A, const stl_matrix & B)
+ {
+ int N=A[0].size();
+ real somme=0.0;
+ real somme2=0.0;
+
+ for (int i=0;i<N;i++){
+ for (int j=0;j<N;j++){
+ real diff=A[i][j] - B[i][j];
+ somme += diff*diff;
+ somme2 += A[i][j]*A[i][j];
+ }
+ }
+
+ return somme/somme2;
+ }
+
+ static inline void display_vector(const stl_vector & A)
+ {
+ int N=A.size();
+ for (int i=0;i<N;i++){
+ INFOS("A["<<i<<"]="<<A[i]<<endl);
+ }
+ }
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/STL/main.cpp b/eigen/bench/btl/libs/STL/main.cpp
new file mode 100644
index 0000000..4e73328
--- /dev/null
+++ b/eigen/bench/btl/libs/STL/main.cpp
@@ -0,0 +1,42 @@
+//=====================================================
+// File : main.cpp
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:23 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "STL_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+
+BTL_MAIN;
+
+int main()
+{
+ bench<Action_axpy<STL_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+ bench<Action_axpby<STL_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+ bench<Action_matrix_vector_product<STL_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_atv_product<STL_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_symv<STL_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_syr2<STL_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_matrix_matrix_product<STL_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_ata_product<STL_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_aat_product<STL_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/blitz/CMakeLists.txt b/eigen/bench/btl/libs/blitz/CMakeLists.txt
new file mode 100644
index 0000000..880ab73
--- /dev/null
+++ b/eigen/bench/btl/libs/blitz/CMakeLists.txt
@@ -0,0 +1,17 @@
+
+find_package(Blitz)
+
+if (BLITZ_FOUND)
+ include_directories(${BLITZ_INCLUDES})
+
+ btl_add_bench(btl_blitz btl_blitz.cpp)
+ if (BUILD_btl_blitz)
+ target_link_libraries(btl_blitz ${BLITZ_LIBRARIES})
+ endif (BUILD_btl_blitz)
+
+ btl_add_bench(btl_tiny_blitz btl_tiny_blitz.cpp OFF)
+ if (BUILD_btl_tiny_blitz)
+ target_link_libraries(btl_tiny_blitz ${BLITZ_LIBRARIES})
+ endif (BUILD_btl_tiny_blitz)
+
+endif (BLITZ_FOUND)
diff --git a/eigen/bench/btl/libs/blitz/blitz_LU_solve_interface.hh b/eigen/bench/btl/libs/blitz/blitz_LU_solve_interface.hh
new file mode 100644
index 0000000..dcb9f56
--- /dev/null
+++ b/eigen/bench/btl/libs/blitz/blitz_LU_solve_interface.hh
@@ -0,0 +1,192 @@
+//=====================================================
+// File : blitz_LU_solve_interface.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:31 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef BLITZ_LU_SOLVE_INTERFACE_HH
+#define BLITZ_LU_SOLVE_INTERFACE_HH
+
+#include "blitz/array.h"
+#include <vector>
+
+BZ_USING_NAMESPACE(blitz)
+
+template<class real>
+class blitz_LU_solve_interface : public blitz_interface<real>
+{
+
+public :
+
+ typedef typename blitz_interface<real>::gene_matrix gene_matrix;
+ typedef typename blitz_interface<real>::gene_vector gene_vector;
+
+ typedef blitz::Array<int,1> Pivot_Vector;
+
+ inline static void new_Pivot_Vector(Pivot_Vector & pivot,int N)
+ {
+
+ pivot.resize(N);
+
+ }
+
+ inline static void free_Pivot_Vector(Pivot_Vector & pivot)
+ {
+
+ return;
+
+ }
+
+
+ static inline real matrix_vector_product_sliced(const gene_matrix & A, gene_vector B, int row, int col_start, int col_end)
+ {
+
+ real somme=0.;
+
+ for (int j=col_start ; j<col_end+1 ; j++){
+
+ somme+=A(row,j)*B(j);
+
+ }
+
+ return somme;
+
+ }
+
+
+
+
+ static inline real matrix_matrix_product_sliced(gene_matrix & A, int row, int col_start, int col_end, gene_matrix & B, int row_shift, int col )
+ {
+
+ real somme=0.;
+
+ for (int j=col_start ; j<col_end+1 ; j++){
+
+ somme+=A(row,j)*B(j+row_shift,col);
+
+ }
+
+ return somme;
+
+ }
+
+ inline static void LU_factor(gene_matrix & LU, Pivot_Vector & pivot, int N)
+ {
+
+ ASSERT( LU.rows()==LU.cols() ) ;
+ int index_max = 0 ;
+ real big = 0. ;
+ real theSum = 0. ;
+ real dum = 0. ;
+ // Get the implicit scaling information :
+ gene_vector ImplicitScaling( N ) ;
+ for( int i=0; i<N; i++ ) {
+ big = 0. ;
+ for( int j=0; j<N; j++ ) {
+ if( abs( LU( i, j ) )>=big ) big = abs( LU( i, j ) ) ;
+ }
+ if( big==0. ) {
+ INFOS( "blitz_LU_factor::Singular matrix" ) ;
+ exit( 0 ) ;
+ }
+ ImplicitScaling( i ) = 1./big ;
+ }
+ // Loop over columns of Crout's method :
+ for( int j=0; j<N; j++ ) {
+ for( int i=0; i<j; i++ ) {
+ theSum = LU( i, j ) ;
+ theSum -= matrix_matrix_product_sliced(LU, i, 0, i-1, LU, 0, j) ;
+ // theSum -= sum( LU( i, Range( fromStart, i-1 ) )*LU( Range( fromStart, i-1 ), j ) ) ;
+ LU( i, j ) = theSum ;
+ }
+
+ // Search for the largest pivot element :
+ big = 0. ;
+ for( int i=j; i<N; i++ ) {
+ theSum = LU( i, j ) ;
+ theSum -= matrix_matrix_product_sliced(LU, i, 0, j-1, LU, 0, j) ;
+ // theSum -= sum( LU( i, Range( fromStart, j-1 ) )*LU( Range( fromStart, j-1 ), j ) ) ;
+ LU( i, j ) = theSum ;
+ if( (ImplicitScaling( i )*abs( theSum ))>=big ) {
+ dum = ImplicitScaling( i )*abs( theSum ) ;
+ big = dum ;
+ index_max = i ;
+ }
+ }
+ // Interchanging rows and the scale factor :
+ if( j!=index_max ) {
+ for( int k=0; k<N; k++ ) {
+ dum = LU( index_max, k ) ;
+ LU( index_max, k ) = LU( j, k ) ;
+ LU( j, k ) = dum ;
+ }
+ ImplicitScaling( index_max ) = ImplicitScaling( j ) ;
+ }
+ pivot( j ) = index_max ;
+ if ( LU( j, j )==0. ) LU( j, j ) = 1.e-20 ;
+ // Divide by the pivot element :
+ if( j<N ) {
+ dum = 1./LU( j, j ) ;
+ for( int i=j+1; i<N; i++ ) LU( i, j ) *= dum ;
+ }
+ }
+
+ }
+
+ inline static void LU_solve(const gene_matrix & LU, const Pivot_Vector pivot, gene_vector &B, gene_vector X, int N)
+ {
+
+ // Pour conserver le meme header, on travaille sur X, copie du second-membre B
+ X = B.copy() ;
+ ASSERT( LU.rows()==LU.cols() ) ;
+ firstIndex indI ;
+ // Forward substitution :
+ int ii = 0 ;
+ real theSum = 0. ;
+ for( int i=0; i<N; i++ ) {
+ int ip = pivot( i ) ;
+ theSum = X( ip ) ;
+ // theSum = B( ip ) ;
+ X( ip ) = X( i ) ;
+ // B( ip ) = B( i ) ;
+ if( ii ) {
+ theSum -= matrix_vector_product_sliced(LU, X, i, ii-1, i-1) ;
+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*X( Range( ii-1, i-1 ) ) ) ;
+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*B( Range( ii-1, i-1 ) ) ) ;
+ } else if( theSum ) {
+ ii = i+1 ;
+ }
+ X( i ) = theSum ;
+ // B( i ) = theSum ;
+ }
+ // Backsubstitution :
+ for( int i=N-1; i>=0; i-- ) {
+ theSum = X( i ) ;
+ // theSum = B( i ) ;
+ theSum -= matrix_vector_product_sliced(LU, X, i, i+1, N) ;
+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*X( Range( i+1, toEnd ) ) ) ;
+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*B( Range( i+1, toEnd ) ) ) ;
+ // Store a component of the solution vector :
+ X( i ) = theSum/LU( i, i ) ;
+ // B( i ) = theSum/LU( i, i ) ;
+ }
+
+ }
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/blitz/blitz_interface.hh b/eigen/bench/btl/libs/blitz/blitz_interface.hh
new file mode 100644
index 0000000..a67c47c
--- /dev/null
+++ b/eigen/bench/btl/libs/blitz/blitz_interface.hh
@@ -0,0 +1,147 @@
+//=====================================================
+// File : blitz_interface.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef BLITZ_INTERFACE_HH
+#define BLITZ_INTERFACE_HH
+
+#include <blitz/blitz.h>
+#include <blitz/array.h>
+#include <blitz/vector-et.h>
+#include <blitz/vecwhere.h>
+#include <blitz/matrix.h>
+#include <vector>
+
+BZ_USING_NAMESPACE(blitz)
+
+template<class real>
+class blitz_interface{
+
+public :
+
+ typedef real real_type ;
+
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector > stl_matrix;
+
+ typedef blitz::Array<real, 2> gene_matrix;
+ typedef blitz::Array<real, 1> gene_vector;
+// typedef blitz::Matrix<real, blitz::ColumnMajor> gene_matrix;
+// typedef blitz::Vector<real> gene_vector;
+
+ static inline std::string name() { return "blitz"; }
+
+ static void free_matrix(gene_matrix & A, int N){}
+
+ static void free_vector(gene_vector & B){}
+
+ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ A.resize(A_stl[0].size(),A_stl.size());
+ for (int j=0; j<A_stl.size() ; j++){
+ for (int i=0; i<A_stl[j].size() ; i++){
+ A(i,j)=A_stl[j][i];
+ }
+ }
+ }
+
+ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ B.resize(B_stl.size());
+ for (int i=0; i<B_stl.size() ; i++){
+ B(i)=B_stl[i];
+ }
+ }
+
+ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ for (int i=0; i<B_stl.size() ; i++){
+ B_stl[i]=B(i);
+ }
+ }
+
+ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N=A_stl.size();
+ for (int j=0;j<N;j++){
+ A_stl[j].resize(N);
+ for (int i=0;i<N;i++)
+ A_stl[j][i] = A(i,j);
+ }
+ }
+
+ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N)
+ {
+ firstIndex i;
+ secondIndex j;
+ thirdIndex k;
+ X = sum(A(i,k) * B(k,j), k);
+ }
+
+ static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N)
+ {
+ firstIndex i;
+ secondIndex j;
+ thirdIndex k;
+ X = sum(A(k,i) * A(k,j), k);
+ }
+
+ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N)
+ {
+ firstIndex i;
+ secondIndex j;
+ thirdIndex k;
+ X = sum(A(i,k) * A(j,k), k);
+ }
+
+ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N)
+ {
+ firstIndex i;
+ secondIndex j;
+ X = sum(A(i,j)*B(j),j);
+ }
+
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N)
+ {
+ firstIndex i;
+ secondIndex j;
+ X = sum(A(j,i) * B(j),j);
+ }
+
+ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N)
+ {
+ firstIndex i;
+ Y = Y(i) + coef * X(i);
+ //Y += coef * X;
+ }
+
+ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ cible = source;
+ //cible.template operator=<gene_matrix>(source);
+// for (int i=0;i<N;i++){
+// for (int j=0;j<N;j++){
+// cible(i,j)=source(i,j);
+// }
+// }
+ }
+
+ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ //cible.template operator=<gene_vector>(source);
+ cible = source;
+ }
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/blitz/btl_blitz.cpp b/eigen/bench/btl/libs/blitz/btl_blitz.cpp
new file mode 100644
index 0000000..16d2b59
--- /dev/null
+++ b/eigen/bench/btl/libs/blitz/btl_blitz.cpp
@@ -0,0 +1,51 @@
+//=====================================================
+// File : main.cpp
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "blitz_interface.hh"
+#include "blitz_LU_solve_interface.hh"
+#include "bench.hh"
+#include "action_matrix_vector_product.hh"
+#include "action_matrix_matrix_product.hh"
+#include "action_axpy.hh"
+#include "action_lu_solve.hh"
+#include "action_ata_product.hh"
+#include "action_aat_product.hh"
+#include "action_atv_product.hh"
+
+BTL_MAIN;
+
+int main()
+{
+
+ bench<Action_matrix_vector_product<blitz_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_atv_product<blitz_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+
+ bench<Action_matrix_matrix_product<blitz_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_ata_product<blitz_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_aat_product<blitz_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ bench<Action_axpy<blitz_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+
+ //bench<Action_lu_solve<blitz_LU_solve_interface<REAL_TYPE> > >(MIN_LU,MAX_LU,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/blitz/btl_tiny_blitz.cpp b/eigen/bench/btl/libs/blitz/btl_tiny_blitz.cpp
new file mode 100644
index 0000000..9fddde7
--- /dev/null
+++ b/eigen/bench/btl/libs/blitz/btl_tiny_blitz.cpp
@@ -0,0 +1,38 @@
+//=====================================================
+// File : main.cpp
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "tiny_blitz_interface.hh"
+#include "static/bench_static.hh"
+#include "action_matrix_vector_product.hh"
+#include "action_matrix_matrix_product.hh"
+#include "action_axpy.hh"
+
+BTL_MAIN;
+
+int main()
+{
+ bench_static<Action_axpy,tiny_blitz_interface>();
+ bench_static<Action_matrix_matrix_product,tiny_blitz_interface>();
+ bench_static<Action_matrix_vector_product,tiny_blitz_interface>();
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/blitz/tiny_blitz_interface.hh b/eigen/bench/btl/libs/blitz/tiny_blitz_interface.hh
new file mode 100644
index 0000000..6b26db7
--- /dev/null
+++ b/eigen/bench/btl/libs/blitz/tiny_blitz_interface.hh
@@ -0,0 +1,106 @@
+//=====================================================
+// File : tiny_blitz_interface.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef TINY_BLITZ_INTERFACE_HH
+#define TINY_BLITZ_INTERFACE_HH
+
+#include "blitz/array.h"
+#include "blitz/tiny.h"
+#include "blitz/tinymat.h"
+#include "blitz/tinyvec.h"
+#include <blitz/tinyvec-et.h>
+
+#include <vector>
+
+BZ_USING_NAMESPACE(blitz)
+
+template<class real, int SIZE>
+class tiny_blitz_interface
+{
+
+public :
+
+ typedef real real_type ;
+
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector > stl_matrix;
+
+ typedef TinyVector<real,SIZE> gene_vector;
+ typedef TinyMatrix<real,SIZE,SIZE> gene_matrix;
+
+ static inline std::string name() { return "tiny_blitz"; }
+
+ static void free_matrix(gene_matrix & A, int N){}
+
+ static void free_vector(gene_vector & B){}
+
+ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ for (int j=0; j<A_stl.size() ; j++)
+ for (int i=0; i<A_stl[j].size() ; i++)
+ A(i,j)=A_stl[j][i];
+ }
+
+ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ for (int i=0; i<B_stl.size() ; i++)
+ B(i) = B_stl[i];
+ }
+
+ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ for (int i=0; i<B_stl.size() ; i++)
+ B_stl[i] = B(i);
+ }
+
+ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N = A_stl.size();
+ for (int j=0;j<N;j++)
+ {
+ A_stl[j].resize(N);
+ for (int i=0;i<N;i++)
+ A_stl[j][i] = A(i,j);
+ }
+ }
+
+ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ for (int j=0;j<N;j++)
+ for (int i=0;i<N;i++)
+ cible(i,j) = source(i,j);
+ }
+
+ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ for (int i=0;i<N;i++){
+ cible(i) = source(i);
+ }
+ }
+
+ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ X = product(A,B);
+ }
+
+ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X = product(A,B);
+ }
+
+ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){
+ Y += coef * X;
+ }
+
+};
+
+
+#endif
diff --git a/eigen/bench/btl/libs/eigen2/CMakeLists.txt b/eigen/bench/btl/libs/eigen2/CMakeLists.txt
new file mode 100644
index 0000000..a2e8fc6
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen2/CMakeLists.txt
@@ -0,0 +1,19 @@
+
+find_package(Eigen2)
+
+if(EIGEN2_FOUND)
+
+ include_directories(BEFORE ${EIGEN2_INCLUDE_DIR})
+ btl_add_bench(btl_eigen2_linear main_linear.cpp)
+ btl_add_bench(btl_eigen2_vecmat main_vecmat.cpp)
+ btl_add_bench(btl_eigen2_matmat main_matmat.cpp)
+ btl_add_bench(btl_eigen2_adv main_adv.cpp )
+
+ btl_add_target_property(btl_eigen2_linear COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen2")
+ btl_add_target_property(btl_eigen2_vecmat COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen2")
+ btl_add_target_property(btl_eigen2_matmat COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen2")
+ btl_add_target_property(btl_eigen2_adv COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen2")
+
+ btl_add_bench(btl_tiny_eigen2 btl_tiny_eigen2.cpp OFF)
+
+endif() # EIGEN2_FOUND
diff --git a/eigen/bench/btl/libs/eigen2/btl_tiny_eigen2.cpp b/eigen/bench/btl/libs/eigen2/btl_tiny_eigen2.cpp
new file mode 100644
index 0000000..d1515be
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen2/btl_tiny_eigen2.cpp
@@ -0,0 +1,46 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen3_interface.hh"
+#include "static/bench_static.hh"
+#include "action_matrix_vector_product.hh"
+#include "action_matrix_matrix_product.hh"
+#include "action_axpy.hh"
+#include "action_lu_solve.hh"
+#include "action_ata_product.hh"
+#include "action_aat_product.hh"
+#include "action_atv_product.hh"
+#include "action_cholesky.hh"
+#include "action_trisolve.hh"
+
+BTL_MAIN;
+
+int main()
+{
+
+ bench_static<Action_axpy,eigen2_interface>();
+ bench_static<Action_matrix_matrix_product,eigen2_interface>();
+ bench_static<Action_matrix_vector_product,eigen2_interface>();
+ bench_static<Action_atv_product,eigen2_interface>();
+ bench_static<Action_cholesky,eigen2_interface>();
+ bench_static<Action_trisolve,eigen2_interface>();
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/eigen2/eigen2_interface.hh b/eigen/bench/btl/libs/eigen2/eigen2_interface.hh
new file mode 100644
index 0000000..47fe581
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen2/eigen2_interface.hh
@@ -0,0 +1,168 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef EIGEN2_INTERFACE_HH
+#define EIGEN2_INTERFACE_HH
+// #include <cblas.h>
+#include <Eigen/Core>
+#include <Eigen/Cholesky>
+#include <Eigen/LU>
+#include <Eigen/QR>
+#include <vector>
+#include "btl.hh"
+
+using namespace Eigen;
+
+template<class real, int SIZE=Dynamic>
+class eigen2_interface
+{
+
+public :
+
+ enum {IsFixedSize = (SIZE!=Dynamic)};
+
+ typedef real real_type;
+
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector> stl_matrix;
+
+ typedef Eigen::Matrix<real,SIZE,SIZE> gene_matrix;
+ typedef Eigen::Matrix<real,SIZE,1> gene_vector;
+
+ static inline std::string name( void )
+ {
+ #if defined(EIGEN_VECTORIZE_SSE)
+ if (SIZE==Dynamic) return "eigen2"; else return "tiny_eigen2";
+ #elif defined(EIGEN_VECTORIZE_ALTIVEC)
+ if (SIZE==Dynamic) return "eigen2"; else return "tiny_eigen2";
+ #else
+ if (SIZE==Dynamic) return "eigen2_novec"; else return "tiny_eigen2_novec";
+ #endif
+ }
+
+ static void free_matrix(gene_matrix & A, int N) {}
+
+ static void free_vector(gene_vector & B) {}
+
+ static BTL_DONT_INLINE void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ A.resize(A_stl[0].size(), A_stl.size());
+
+ for (int j=0; j<A_stl.size() ; j++){
+ for (int i=0; i<A_stl[j].size() ; i++){
+ A.coeffRef(i,j) = A_stl[j][i];
+ }
+ }
+ }
+
+ static BTL_DONT_INLINE void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ B.resize(B_stl.size(),1);
+
+ for (int i=0; i<B_stl.size() ; i++){
+ B.coeffRef(i) = B_stl[i];
+ }
+ }
+
+ static BTL_DONT_INLINE void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ for (int i=0; i<B_stl.size() ; i++){
+ B_stl[i] = B.coeff(i);
+ }
+ }
+
+ static BTL_DONT_INLINE void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N=A_stl.size();
+
+ for (int j=0;j<N;j++){
+ A_stl[j].resize(N);
+ for (int i=0;i<N;i++){
+ A_stl[j][i] = A.coeff(i,j);
+ }
+ }
+ }
+
+ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ X = (A*B).lazy();
+ }
+
+ static inline void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ X = (A.transpose()*B.transpose()).lazy();
+ }
+
+ static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N){
+ X = (A.transpose()*A).lazy();
+ }
+
+ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){
+ X = (A*A.transpose()).lazy();
+ }
+
+ static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N){
+ X = (A*B)/*.lazy()*/;
+ }
+
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X = (A.transpose()*B)/*.lazy()*/;
+ }
+
+ static inline void axpy(real coef, const gene_vector & X, gene_vector & Y, int N){
+ Y += coef * X;
+ }
+
+ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){
+ Y = a*X + b*Y;
+ }
+
+ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ cible = source;
+ }
+
+ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ cible = source;
+ }
+
+ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector& X, int N){
+ X = L.template marked<LowerTriangular>().solveTriangular(B);
+ }
+
+ static inline void trisolve_lower_matrix(const gene_matrix & L, const gene_matrix& B, gene_matrix& X, int N){
+ X = L.template marked<LowerTriangular>().solveTriangular(B);
+ }
+
+ static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){
+ C = X.llt().matrixL();
+// C = X;
+// Cholesky<gene_matrix>::computeInPlace(C);
+// Cholesky<gene_matrix>::computeInPlaceBlock(C);
+ }
+
+ static inline void lu_decomp(const gene_matrix & X, gene_matrix & C, int N){
+ C = X.lu().matrixLU();
+// C = X.inverse();
+ }
+
+ static inline void tridiagonalization(const gene_matrix & X, gene_matrix & C, int N){
+ C = Tridiagonalization<gene_matrix>(X).packedMatrix();
+ }
+
+ static inline void hessenberg(const gene_matrix & X, gene_matrix & C, int N){
+ C = HessenbergDecomposition<gene_matrix>(X).packedMatrix();
+ }
+
+
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/eigen2/main_adv.cpp b/eigen/bench/btl/libs/eigen2/main_adv.cpp
new file mode 100644
index 0000000..fe33689
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen2/main_adv.cpp
@@ -0,0 +1,44 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen2_interface.hh"
+#include "bench.hh"
+#include "action_trisolve.hh"
+#include "action_trisolve_matrix.hh"
+#include "action_cholesky.hh"
+#include "action_hessenberg.hh"
+#include "action_lu_decomp.hh"
+// #include "action_partial_lu.hh"
+
+BTL_MAIN;
+
+int main()
+{
+ bench<Action_trisolve<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_trisolve_matrix<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_cholesky<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_lu_decomp<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_partial_lu<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ bench<Action_hessenberg<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_tridiagonalization<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/eigen2/main_linear.cpp b/eigen/bench/btl/libs/eigen2/main_linear.cpp
new file mode 100644
index 0000000..c17d16c
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen2/main_linear.cpp
@@ -0,0 +1,34 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen2_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+
+BTL_MAIN;
+
+int main()
+{
+
+ bench<Action_axpy<eigen2_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+ bench<Action_axpby<eigen2_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/eigen2/main_matmat.cpp b/eigen/bench/btl/libs/eigen2/main_matmat.cpp
new file mode 100644
index 0000000..cd9dc9c
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen2/main_matmat.cpp
@@ -0,0 +1,35 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen2_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+
+BTL_MAIN;
+
+int main()
+{
+ bench<Action_matrix_matrix_product<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_ata_product<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_aat_product<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_trmm<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/eigen2/main_vecmat.cpp b/eigen/bench/btl/libs/eigen2/main_vecmat.cpp
new file mode 100644
index 0000000..8b66cd2
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen2/main_vecmat.cpp
@@ -0,0 +1,36 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen2_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+
+BTL_MAIN;
+
+int main()
+{
+ bench<Action_matrix_vector_product<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_atv_product<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+// bench<Action_symv<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+// bench<Action_syr2<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+// bench<Action_ger<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/eigen3/CMakeLists.txt b/eigen/bench/btl/libs/eigen3/CMakeLists.txt
new file mode 100644
index 0000000..00cae23
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen3/CMakeLists.txt
@@ -0,0 +1,65 @@
+
+
+if((NOT EIGEN3_INCLUDE_DIR) AND Eigen_SOURCE_DIR)
+ # unless EIGEN3_INCLUDE_DIR is defined, let's use current Eigen version
+ set(EIGEN3_INCLUDE_DIR ${Eigen_SOURCE_DIR})
+ set(EIGEN3_FOUND TRUE)
+else()
+ find_package(Eigen3)
+endif()
+
+if (EIGEN3_FOUND)
+
+ include_directories(${EIGEN3_INCLUDE_DIR})
+ btl_add_bench(btl_eigen3_linear main_linear.cpp)
+ btl_add_bench(btl_eigen3_vecmat main_vecmat.cpp)
+ btl_add_bench(btl_eigen3_matmat main_matmat.cpp)
+ btl_add_bench(btl_eigen3_adv main_adv.cpp )
+
+ btl_add_target_property(btl_eigen3_linear COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen3")
+ btl_add_target_property(btl_eigen3_vecmat COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen3")
+ btl_add_target_property(btl_eigen3_matmat COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen3")
+ btl_add_target_property(btl_eigen3_adv COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen3")
+
+ option(BTL_BENCH_NOGCCVEC "also bench Eigen explicit vec without GCC's auto vec" OFF)
+ if(CMAKE_COMPILER_IS_GNUCXX AND BTL_BENCH_NOGCCVEC)
+ btl_add_bench(btl_eigen3_nogccvec_linear main_linear.cpp)
+ btl_add_bench(btl_eigen3_nogccvec_vecmat main_vecmat.cpp)
+ btl_add_bench(btl_eigen3_nogccvec_matmat main_matmat.cpp)
+ btl_add_bench(btl_eigen3_nogccvec_adv main_adv.cpp )
+
+ btl_add_target_property(btl_eigen3_nogccvec_linear COMPILE_FLAGS "-fno-exceptions -fno-tree-vectorize -DBTL_PREFIX=eigen3_nogccvec")
+ btl_add_target_property(btl_eigen3_nogccvec_vecmat COMPILE_FLAGS "-fno-exceptions -fno-tree-vectorize -DBTL_PREFIX=eigen3_nogccvec")
+ btl_add_target_property(btl_eigen3_nogccvec_matmat COMPILE_FLAGS "-fno-exceptions -fno-tree-vectorize -DBTL_PREFIX=eigen3_nogccvec")
+ btl_add_target_property(btl_eigen3_nogccvec_adv COMPILE_FLAGS "-fno-exceptions -fno-tree-vectorize -DBTL_PREFIX=eigen3_nogccvec")
+ endif()
+
+
+ if(NOT BTL_NOVEC)
+ btl_add_bench(btl_eigen3_novec_linear main_linear.cpp OFF)
+ btl_add_bench(btl_eigen3_novec_vecmat main_vecmat.cpp OFF)
+ btl_add_bench(btl_eigen3_novec_matmat main_matmat.cpp OFF)
+ btl_add_bench(btl_eigen3_novec_adv main_adv.cpp OFF)
+ btl_add_target_property(btl_eigen3_novec_linear COMPILE_FLAGS "-fno-exceptions -DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_novec")
+ btl_add_target_property(btl_eigen3_novec_vecmat COMPILE_FLAGS "-fno-exceptions -DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_novec")
+ btl_add_target_property(btl_eigen3_novec_matmat COMPILE_FLAGS "-fno-exceptions -DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_novec")
+ btl_add_target_property(btl_eigen3_novec_adv COMPILE_FLAGS "-fno-exceptions -DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_novec")
+
+# if(BUILD_btl_eigen3_adv)
+# target_link_libraries(btl_eigen3_adv ${MKL_LIBRARIES})
+# endif(BUILD_btl_eigen3_adv)
+
+ endif(NOT BTL_NOVEC)
+
+ btl_add_bench(btl_tiny_eigen3 btl_tiny_eigen3.cpp OFF)
+
+ if(NOT BTL_NOVEC)
+ btl_add_bench(btl_tiny_eigen3_novec btl_tiny_eigen3.cpp OFF)
+ btl_add_target_property(btl_tiny_eigen3_novec COMPILE_FLAGS "-DBTL_PREFIX=eigen3_tiny")
+
+ if(BUILD_btl_tiny_eigen3_novec)
+ btl_add_target_property(btl_tiny_eigen3_novec COMPILE_FLAGS "-DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_tiny_novec")
+ endif(BUILD_btl_tiny_eigen3_novec)
+ endif(NOT BTL_NOVEC)
+
+endif (EIGEN3_FOUND)
diff --git a/eigen/bench/btl/libs/eigen3/btl_tiny_eigen3.cpp b/eigen/bench/btl/libs/eigen3/btl_tiny_eigen3.cpp
new file mode 100644
index 0000000..d1515be
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen3/btl_tiny_eigen3.cpp
@@ -0,0 +1,46 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen3_interface.hh"
+#include "static/bench_static.hh"
+#include "action_matrix_vector_product.hh"
+#include "action_matrix_matrix_product.hh"
+#include "action_axpy.hh"
+#include "action_lu_solve.hh"
+#include "action_ata_product.hh"
+#include "action_aat_product.hh"
+#include "action_atv_product.hh"
+#include "action_cholesky.hh"
+#include "action_trisolve.hh"
+
+BTL_MAIN;
+
+int main()
+{
+
+ bench_static<Action_axpy,eigen2_interface>();
+ bench_static<Action_matrix_matrix_product,eigen2_interface>();
+ bench_static<Action_matrix_vector_product,eigen2_interface>();
+ bench_static<Action_atv_product,eigen2_interface>();
+ bench_static<Action_cholesky,eigen2_interface>();
+ bench_static<Action_trisolve,eigen2_interface>();
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/eigen3/eigen3_interface.hh b/eigen/bench/btl/libs/eigen3/eigen3_interface.hh
new file mode 100644
index 0000000..31bcc1f
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen3/eigen3_interface.hh
@@ -0,0 +1,240 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef EIGEN3_INTERFACE_HH
+#define EIGEN3_INTERFACE_HH
+
+#include <Eigen/Eigen>
+#include <vector>
+#include "btl.hh"
+
+using namespace Eigen;
+
+template<class real, int SIZE=Dynamic>
+class eigen3_interface
+{
+
+public :
+
+ enum {IsFixedSize = (SIZE!=Dynamic)};
+
+ typedef real real_type;
+
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector> stl_matrix;
+
+ typedef Eigen::Matrix<real,SIZE,SIZE> gene_matrix;
+ typedef Eigen::Matrix<real,SIZE,1> gene_vector;
+
+ static inline std::string name( void )
+ {
+ return EIGEN_MAKESTRING(BTL_PREFIX);
+ }
+
+ static void free_matrix(gene_matrix & A, int N) {}
+
+ static void free_vector(gene_vector & B) {}
+
+ static BTL_DONT_INLINE void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ A.resize(A_stl[0].size(), A_stl.size());
+
+ for (int j=0; j<A_stl.size() ; j++){
+ for (int i=0; i<A_stl[j].size() ; i++){
+ A.coeffRef(i,j) = A_stl[j][i];
+ }
+ }
+ }
+
+ static BTL_DONT_INLINE void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ B.resize(B_stl.size(),1);
+
+ for (int i=0; i<B_stl.size() ; i++){
+ B.coeffRef(i) = B_stl[i];
+ }
+ }
+
+ static BTL_DONT_INLINE void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ for (int i=0; i<B_stl.size() ; i++){
+ B_stl[i] = B.coeff(i);
+ }
+ }
+
+ static BTL_DONT_INLINE void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N=A_stl.size();
+
+ for (int j=0;j<N;j++){
+ A_stl[j].resize(N);
+ for (int i=0;i<N;i++){
+ A_stl[j][i] = A.coeff(i,j);
+ }
+ }
+ }
+
+ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ X.noalias() = A*B;
+ }
+
+ static inline void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ 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;
+// }
+
+ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){
+ X.template triangularView<Lower>().setZero();
+ X.template selfadjointView<Lower>().rankUpdate(A);
+ }
+
+ static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N){
+ X.noalias() = A*B;
+ }
+
+ static inline void symv(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N){
+ X.noalias() = (A.template selfadjointView<Lower>() * B);
+// internal::product_selfadjoint_vector<real,0,LowerTriangularBit,false,false>(N,A.data(),N, B.data(), 1, X.data(), 1);
+ }
+
+ template<typename Dest, typename Src> static void triassign(Dest& dst, const Src& src)
+ {
+ typedef typename Dest::Scalar Scalar;
+ typedef typename internal::packet_traits<Scalar>::type Packet;
+ const int PacketSize = sizeof(Packet)/sizeof(Scalar);
+ int size = dst.cols();
+ for(int j=0; j<size; j+=1)
+ {
+// const int alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
+ Scalar* A0 = dst.data() + j*dst.stride();
+ int starti = j;
+ int alignedEnd = starti;
+ int alignedStart = (starti) + internal::first_aligned(&A0[starti], size-starti);
+ alignedEnd = alignedStart + ((size-alignedStart)/(2*PacketSize))*(PacketSize*2);
+
+ // do the non-vectorizable part of the assignment
+ for (int index = starti; index<alignedStart ; ++index)
+ {
+ if(Dest::Flags&RowMajorBit)
+ dst.copyCoeff(j, index, src);
+ else
+ dst.copyCoeff(index, j, src);
+ }
+
+ // do the vectorizable part of the assignment
+ for (int index = alignedStart; index<alignedEnd; index+=PacketSize)
+ {
+ if(Dest::Flags&RowMajorBit)
+ dst.template copyPacket<Src, Aligned, Unaligned>(j, index, src);
+ else
+ dst.template copyPacket<Src, Aligned, Unaligned>(index, j, src);
+ }
+
+ // do the non-vectorizable part of the assignment
+ for (int index = alignedEnd; index<size; ++index)
+ {
+ if(Dest::Flags&RowMajorBit)
+ dst.copyCoeff(j, index, src);
+ else
+ dst.copyCoeff(index, j, src);
+ }
+ //dst.col(j).tail(N-j) = src.col(j).tail(N-j);
+ }
+ }
+
+ static EIGEN_DONT_INLINE void syr2(gene_matrix & A, gene_vector & X, gene_vector & Y, int N){
+ // internal::product_selfadjoint_rank2_update<real,0,LowerTriangularBit>(N,A.data(),N, X.data(), 1, Y.data(), 1, -1);
+ for(int j=0; j<N; ++j)
+ A.col(j).tail(N-j) += X[j] * Y.tail(N-j) + Y[j] * X.tail(N-j);
+ }
+
+ static EIGEN_DONT_INLINE void ger(gene_matrix & A, gene_vector & X, gene_vector & Y, int N){
+ for(int j=0; j<N; ++j)
+ A.col(j) += X * Y[j];
+ }
+
+ static EIGEN_DONT_INLINE void rot(gene_vector & A, gene_vector & B, real c, real s, int N){
+ internal::apply_rotation_in_the_plane(A, B, JacobiRotation<real>(c,s));
+ }
+
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X.noalias() = (A.transpose()*B);
+ }
+
+ static inline void axpy(real coef, const gene_vector & X, gene_vector & Y, int N){
+ Y += coef * X;
+ }
+
+ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){
+ Y = a*X + b*Y;
+ }
+
+ static EIGEN_DONT_INLINE void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ cible = source;
+ }
+
+ static EIGEN_DONT_INLINE void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ cible = source;
+ }
+
+ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector& X, int N){
+ X = L.template triangularView<Lower>().solve(B);
+ }
+
+ static inline void trisolve_lower_matrix(const gene_matrix & L, const gene_matrix& B, gene_matrix& X, int N){
+ X = L.template triangularView<Upper>().solve(B);
+ }
+
+ static inline void trmm(const gene_matrix & L, const gene_matrix& B, gene_matrix& X, int N){
+ X.noalias() = L.template triangularView<Lower>() * B;
+ }
+
+ static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){
+ C = X;
+ internal::llt_inplace<real,Lower>::blocked(C);
+ //C = X.llt().matrixL();
+// C = X;
+// Cholesky<gene_matrix>::computeInPlace(C);
+// Cholesky<gene_matrix>::computeInPlaceBlock(C);
+ }
+
+ static inline void lu_decomp(const gene_matrix & X, gene_matrix & C, int N){
+ C = X.fullPivLu().matrixLU();
+ }
+
+ static inline void partial_lu_decomp(const gene_matrix & X, gene_matrix & C, int N){
+ Matrix<DenseIndex,1,Dynamic> piv(N);
+ DenseIndex nb;
+ C = X;
+ internal::partial_lu_inplace(C,piv,nb);
+// C = X.partialPivLu().matrixLU();
+ }
+
+ static inline void tridiagonalization(const gene_matrix & X, gene_matrix & C, int N){
+ typename Tridiagonalization<gene_matrix>::CoeffVectorType aux(N-1);
+ C = X;
+ internal::tridiagonalization_inplace(C, aux);
+ }
+
+ static inline void hessenberg(const gene_matrix & X, gene_matrix & C, int N){
+ C = HessenbergDecomposition<gene_matrix>(X).packedMatrix();
+ }
+
+
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/eigen3/main_adv.cpp b/eigen/bench/btl/libs/eigen3/main_adv.cpp
new file mode 100644
index 0000000..efe5857
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen3/main_adv.cpp
@@ -0,0 +1,44 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen3_interface.hh"
+#include "bench.hh"
+#include "action_trisolve.hh"
+#include "action_trisolve_matrix.hh"
+#include "action_cholesky.hh"
+#include "action_hessenberg.hh"
+#include "action_lu_decomp.hh"
+#include "action_partial_lu.hh"
+
+BTL_MAIN;
+
+int main()
+{
+ bench<Action_trisolve<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_trisolve_matrix<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_cholesky<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_lu_decomp<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_partial_lu<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ bench<Action_hessenberg<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_tridiagonalization<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/eigen3/main_linear.cpp b/eigen/bench/btl/libs/eigen3/main_linear.cpp
new file mode 100644
index 0000000..e8538b7
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen3/main_linear.cpp
@@ -0,0 +1,35 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen3_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+
+BTL_MAIN;
+
+int main()
+{
+
+ bench<Action_axpy<eigen3_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+ bench<Action_axpby<eigen3_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+ bench<Action_rot<eigen3_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/eigen3/main_matmat.cpp b/eigen/bench/btl/libs/eigen3/main_matmat.cpp
new file mode 100644
index 0000000..926fa2b
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen3/main_matmat.cpp
@@ -0,0 +1,35 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen3_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+
+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_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);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/eigen3/main_vecmat.cpp b/eigen/bench/btl/libs/eigen3/main_vecmat.cpp
new file mode 100644
index 0000000..0dda444
--- /dev/null
+++ b/eigen/bench/btl/libs/eigen3/main_vecmat.cpp
@@ -0,0 +1,36 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "eigen3_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+
+BTL_MAIN;
+
+int main()
+{
+ bench<Action_matrix_vector_product<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_atv_product<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_symv<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_syr2<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_ger<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/gmm/CMakeLists.txt b/eigen/bench/btl/libs/gmm/CMakeLists.txt
new file mode 100644
index 0000000..bc25862
--- /dev/null
+++ b/eigen/bench/btl/libs/gmm/CMakeLists.txt
@@ -0,0 +1,6 @@
+
+find_package(GMM)
+if (GMM_FOUND)
+ include_directories(${GMM_INCLUDES})
+ btl_add_bench(btl_gmm main.cpp)
+endif (GMM_FOUND)
diff --git a/eigen/bench/btl/libs/gmm/gmm_LU_solve_interface.hh b/eigen/bench/btl/libs/gmm/gmm_LU_solve_interface.hh
new file mode 100644
index 0000000..dcb9f56
--- /dev/null
+++ b/eigen/bench/btl/libs/gmm/gmm_LU_solve_interface.hh
@@ -0,0 +1,192 @@
+//=====================================================
+// File : blitz_LU_solve_interface.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:31 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef BLITZ_LU_SOLVE_INTERFACE_HH
+#define BLITZ_LU_SOLVE_INTERFACE_HH
+
+#include "blitz/array.h"
+#include <vector>
+
+BZ_USING_NAMESPACE(blitz)
+
+template<class real>
+class blitz_LU_solve_interface : public blitz_interface<real>
+{
+
+public :
+
+ typedef typename blitz_interface<real>::gene_matrix gene_matrix;
+ typedef typename blitz_interface<real>::gene_vector gene_vector;
+
+ typedef blitz::Array<int,1> Pivot_Vector;
+
+ inline static void new_Pivot_Vector(Pivot_Vector & pivot,int N)
+ {
+
+ pivot.resize(N);
+
+ }
+
+ inline static void free_Pivot_Vector(Pivot_Vector & pivot)
+ {
+
+ return;
+
+ }
+
+
+ static inline real matrix_vector_product_sliced(const gene_matrix & A, gene_vector B, int row, int col_start, int col_end)
+ {
+
+ real somme=0.;
+
+ for (int j=col_start ; j<col_end+1 ; j++){
+
+ somme+=A(row,j)*B(j);
+
+ }
+
+ return somme;
+
+ }
+
+
+
+
+ static inline real matrix_matrix_product_sliced(gene_matrix & A, int row, int col_start, int col_end, gene_matrix & B, int row_shift, int col )
+ {
+
+ real somme=0.;
+
+ for (int j=col_start ; j<col_end+1 ; j++){
+
+ somme+=A(row,j)*B(j+row_shift,col);
+
+ }
+
+ return somme;
+
+ }
+
+ inline static void LU_factor(gene_matrix & LU, Pivot_Vector & pivot, int N)
+ {
+
+ ASSERT( LU.rows()==LU.cols() ) ;
+ int index_max = 0 ;
+ real big = 0. ;
+ real theSum = 0. ;
+ real dum = 0. ;
+ // Get the implicit scaling information :
+ gene_vector ImplicitScaling( N ) ;
+ for( int i=0; i<N; i++ ) {
+ big = 0. ;
+ for( int j=0; j<N; j++ ) {
+ if( abs( LU( i, j ) )>=big ) big = abs( LU( i, j ) ) ;
+ }
+ if( big==0. ) {
+ INFOS( "blitz_LU_factor::Singular matrix" ) ;
+ exit( 0 ) ;
+ }
+ ImplicitScaling( i ) = 1./big ;
+ }
+ // Loop over columns of Crout's method :
+ for( int j=0; j<N; j++ ) {
+ for( int i=0; i<j; i++ ) {
+ theSum = LU( i, j ) ;
+ theSum -= matrix_matrix_product_sliced(LU, i, 0, i-1, LU, 0, j) ;
+ // theSum -= sum( LU( i, Range( fromStart, i-1 ) )*LU( Range( fromStart, i-1 ), j ) ) ;
+ LU( i, j ) = theSum ;
+ }
+
+ // Search for the largest pivot element :
+ big = 0. ;
+ for( int i=j; i<N; i++ ) {
+ theSum = LU( i, j ) ;
+ theSum -= matrix_matrix_product_sliced(LU, i, 0, j-1, LU, 0, j) ;
+ // theSum -= sum( LU( i, Range( fromStart, j-1 ) )*LU( Range( fromStart, j-1 ), j ) ) ;
+ LU( i, j ) = theSum ;
+ if( (ImplicitScaling( i )*abs( theSum ))>=big ) {
+ dum = ImplicitScaling( i )*abs( theSum ) ;
+ big = dum ;
+ index_max = i ;
+ }
+ }
+ // Interchanging rows and the scale factor :
+ if( j!=index_max ) {
+ for( int k=0; k<N; k++ ) {
+ dum = LU( index_max, k ) ;
+ LU( index_max, k ) = LU( j, k ) ;
+ LU( j, k ) = dum ;
+ }
+ ImplicitScaling( index_max ) = ImplicitScaling( j ) ;
+ }
+ pivot( j ) = index_max ;
+ if ( LU( j, j )==0. ) LU( j, j ) = 1.e-20 ;
+ // Divide by the pivot element :
+ if( j<N ) {
+ dum = 1./LU( j, j ) ;
+ for( int i=j+1; i<N; i++ ) LU( i, j ) *= dum ;
+ }
+ }
+
+ }
+
+ inline static void LU_solve(const gene_matrix & LU, const Pivot_Vector pivot, gene_vector &B, gene_vector X, int N)
+ {
+
+ // Pour conserver le meme header, on travaille sur X, copie du second-membre B
+ X = B.copy() ;
+ ASSERT( LU.rows()==LU.cols() ) ;
+ firstIndex indI ;
+ // Forward substitution :
+ int ii = 0 ;
+ real theSum = 0. ;
+ for( int i=0; i<N; i++ ) {
+ int ip = pivot( i ) ;
+ theSum = X( ip ) ;
+ // theSum = B( ip ) ;
+ X( ip ) = X( i ) ;
+ // B( ip ) = B( i ) ;
+ if( ii ) {
+ theSum -= matrix_vector_product_sliced(LU, X, i, ii-1, i-1) ;
+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*X( Range( ii-1, i-1 ) ) ) ;
+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*B( Range( ii-1, i-1 ) ) ) ;
+ } else if( theSum ) {
+ ii = i+1 ;
+ }
+ X( i ) = theSum ;
+ // B( i ) = theSum ;
+ }
+ // Backsubstitution :
+ for( int i=N-1; i>=0; i-- ) {
+ theSum = X( i ) ;
+ // theSum = B( i ) ;
+ theSum -= matrix_vector_product_sliced(LU, X, i, i+1, N) ;
+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*X( Range( i+1, toEnd ) ) ) ;
+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*B( Range( i+1, toEnd ) ) ) ;
+ // Store a component of the solution vector :
+ X( i ) = theSum/LU( i, i ) ;
+ // B( i ) = theSum/LU( i, i ) ;
+ }
+
+ }
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/gmm/gmm_interface.hh b/eigen/bench/btl/libs/gmm/gmm_interface.hh
new file mode 100644
index 0000000..3ea303c
--- /dev/null
+++ b/eigen/bench/btl/libs/gmm/gmm_interface.hh
@@ -0,0 +1,144 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef GMM_INTERFACE_HH
+#define GMM_INTERFACE_HH
+
+#include <gmm/gmm.h>
+#include <vector>
+
+using namespace gmm;
+
+template<class real>
+class gmm_interface {
+
+public :
+
+ typedef real real_type ;
+
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector > stl_matrix;
+
+ typedef gmm::dense_matrix<real> gene_matrix;
+ typedef stl_vector gene_vector;
+
+ static inline std::string name( void )
+ {
+ return "gmm";
+ }
+
+ static void free_matrix(gene_matrix & A, int N){
+ return ;
+ }
+
+ static void free_vector(gene_vector & B){
+ return ;
+ }
+
+ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ A.resize(A_stl[0].size(),A_stl.size());
+
+ for (int j=0; j<A_stl.size() ; j++){
+ for (int i=0; i<A_stl[j].size() ; i++){
+ A(i,j) = A_stl[j][i];
+ }
+ }
+ }
+
+ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ B = B_stl;
+ }
+
+ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ B_stl = B;
+ }
+
+ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N=A_stl.size();
+
+ for (int j=0;j<N;j++){
+ A_stl[j].resize(N);
+ for (int i=0;i<N;i++){
+ A_stl[j][i] = A(i,j);
+ }
+ }
+ }
+
+ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ gmm::mult(A,B, X);
+ }
+
+ static inline void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ gmm::mult(gmm::transposed(A),gmm::transposed(B), X);
+ }
+
+ static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N){
+ gmm::mult(gmm::transposed(A),A, X);
+ }
+
+ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){
+ gmm::mult(A,gmm::transposed(A), X);
+ }
+
+ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ gmm::mult(A,B,X);
+ }
+
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ gmm::mult(gmm::transposed(A),B,X);
+ }
+
+ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){
+ gmm::add(gmm::scaled(X,coef), Y);
+ }
+
+ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){
+ gmm::add(gmm::scaled(X,a), gmm::scaled(Y,b), Y);
+ }
+
+ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ gmm::copy(source,cible);
+ }
+
+ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ gmm::copy(source,cible);
+ }
+
+ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector & X, int N){
+ gmm::copy(B,X);
+ gmm::lower_tri_solve(L, X, false);
+ }
+
+ static inline void partial_lu_decomp(const gene_matrix & X, gene_matrix & R, int N){
+ gmm::copy(X,R);
+ std::vector<int> ipvt(N);
+ gmm::lu_factor(R, ipvt);
+ }
+
+ static inline void hessenberg(const gene_matrix & X, gene_matrix & R, int N){
+ gmm::copy(X,R);
+ gmm::Hessenberg_reduction(R,X,false);
+ }
+
+ static inline void tridiagonalization(const gene_matrix & X, gene_matrix & R, int N){
+ gmm::copy(X,R);
+ gmm::Householder_tridiagonalization(R,X,false);
+ }
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/gmm/main.cpp b/eigen/bench/btl/libs/gmm/main.cpp
new file mode 100644
index 0000000..1f0c051
--- /dev/null
+++ b/eigen/bench/btl/libs/gmm/main.cpp
@@ -0,0 +1,51 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "gmm_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+#include "action_hessenberg.hh"
+#include "action_partial_lu.hh"
+
+BTL_MAIN;
+
+int main()
+{
+
+ bench<Action_axpy<gmm_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+ bench<Action_axpby<gmm_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+
+ bench<Action_matrix_vector_product<gmm_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_atv_product<gmm_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+
+ bench<Action_matrix_matrix_product<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_ata_product<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_aat_product<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ bench<Action_trisolve<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ //bench<Action_lu_solve<blitz_LU_solve_interface<REAL_TYPE> > >(MIN_LU,MAX_LU,NB_POINT);
+
+ bench<Action_partial_lu<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ bench<Action_hessenberg<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+ bench<Action_tridiagonalization<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/mtl4/.kdbgrc.main b/eigen/bench/btl/libs/mtl4/.kdbgrc.main
new file mode 100644
index 0000000..fed082f
--- /dev/null
+++ b/eigen/bench/btl/libs/mtl4/.kdbgrc.main
@@ -0,0 +1,12 @@
+[General]
+DebuggerCmdStr=
+DriverName=GDB
+FileVersion=1
+OptionsSelected=
+ProgramArgs=
+TTYLevel=7
+WorkingDirectory=
+
+[Memory]
+ColumnWidths=80,0
+NumExprs=0
diff --git a/eigen/bench/btl/libs/mtl4/CMakeLists.txt b/eigen/bench/btl/libs/mtl4/CMakeLists.txt
new file mode 100644
index 0000000..14b47a8
--- /dev/null
+++ b/eigen/bench/btl/libs/mtl4/CMakeLists.txt
@@ -0,0 +1,6 @@
+
+find_package(MTL4)
+if (MTL4_FOUND)
+ include_directories(${MTL4_INCLUDE_DIR})
+ btl_add_bench(btl_mtl4 main.cpp)
+endif (MTL4_FOUND)
diff --git a/eigen/bench/btl/libs/mtl4/main.cpp b/eigen/bench/btl/libs/mtl4/main.cpp
new file mode 100644
index 0000000..96fcfb9
--- /dev/null
+++ b/eigen/bench/btl/libs/mtl4/main.cpp
@@ -0,0 +1,46 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "mtl4_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+#include "action_cholesky.hh"
+// #include "action_lu_decomp.hh"
+
+BTL_MAIN;
+
+int main()
+{
+
+ bench<Action_axpy<mtl4_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+ bench<Action_axpby<mtl4_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+
+ bench<Action_matrix_vector_product<mtl4_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_atv_product<mtl4_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_matrix_matrix_product<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_ata_product<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_aat_product<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ bench<Action_trisolve<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_cholesky<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_lu_decomp<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/mtl4/mtl4_LU_solve_interface.hh b/eigen/bench/btl/libs/mtl4/mtl4_LU_solve_interface.hh
new file mode 100644
index 0000000..dcb9f56
--- /dev/null
+++ b/eigen/bench/btl/libs/mtl4/mtl4_LU_solve_interface.hh
@@ -0,0 +1,192 @@
+//=====================================================
+// File : blitz_LU_solve_interface.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:31 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef BLITZ_LU_SOLVE_INTERFACE_HH
+#define BLITZ_LU_SOLVE_INTERFACE_HH
+
+#include "blitz/array.h"
+#include <vector>
+
+BZ_USING_NAMESPACE(blitz)
+
+template<class real>
+class blitz_LU_solve_interface : public blitz_interface<real>
+{
+
+public :
+
+ typedef typename blitz_interface<real>::gene_matrix gene_matrix;
+ typedef typename blitz_interface<real>::gene_vector gene_vector;
+
+ typedef blitz::Array<int,1> Pivot_Vector;
+
+ inline static void new_Pivot_Vector(Pivot_Vector & pivot,int N)
+ {
+
+ pivot.resize(N);
+
+ }
+
+ inline static void free_Pivot_Vector(Pivot_Vector & pivot)
+ {
+
+ return;
+
+ }
+
+
+ static inline real matrix_vector_product_sliced(const gene_matrix & A, gene_vector B, int row, int col_start, int col_end)
+ {
+
+ real somme=0.;
+
+ for (int j=col_start ; j<col_end+1 ; j++){
+
+ somme+=A(row,j)*B(j);
+
+ }
+
+ return somme;
+
+ }
+
+
+
+
+ static inline real matrix_matrix_product_sliced(gene_matrix & A, int row, int col_start, int col_end, gene_matrix & B, int row_shift, int col )
+ {
+
+ real somme=0.;
+
+ for (int j=col_start ; j<col_end+1 ; j++){
+
+ somme+=A(row,j)*B(j+row_shift,col);
+
+ }
+
+ return somme;
+
+ }
+
+ inline static void LU_factor(gene_matrix & LU, Pivot_Vector & pivot, int N)
+ {
+
+ ASSERT( LU.rows()==LU.cols() ) ;
+ int index_max = 0 ;
+ real big = 0. ;
+ real theSum = 0. ;
+ real dum = 0. ;
+ // Get the implicit scaling information :
+ gene_vector ImplicitScaling( N ) ;
+ for( int i=0; i<N; i++ ) {
+ big = 0. ;
+ for( int j=0; j<N; j++ ) {
+ if( abs( LU( i, j ) )>=big ) big = abs( LU( i, j ) ) ;
+ }
+ if( big==0. ) {
+ INFOS( "blitz_LU_factor::Singular matrix" ) ;
+ exit( 0 ) ;
+ }
+ ImplicitScaling( i ) = 1./big ;
+ }
+ // Loop over columns of Crout's method :
+ for( int j=0; j<N; j++ ) {
+ for( int i=0; i<j; i++ ) {
+ theSum = LU( i, j ) ;
+ theSum -= matrix_matrix_product_sliced(LU, i, 0, i-1, LU, 0, j) ;
+ // theSum -= sum( LU( i, Range( fromStart, i-1 ) )*LU( Range( fromStart, i-1 ), j ) ) ;
+ LU( i, j ) = theSum ;
+ }
+
+ // Search for the largest pivot element :
+ big = 0. ;
+ for( int i=j; i<N; i++ ) {
+ theSum = LU( i, j ) ;
+ theSum -= matrix_matrix_product_sliced(LU, i, 0, j-1, LU, 0, j) ;
+ // theSum -= sum( LU( i, Range( fromStart, j-1 ) )*LU( Range( fromStart, j-1 ), j ) ) ;
+ LU( i, j ) = theSum ;
+ if( (ImplicitScaling( i )*abs( theSum ))>=big ) {
+ dum = ImplicitScaling( i )*abs( theSum ) ;
+ big = dum ;
+ index_max = i ;
+ }
+ }
+ // Interchanging rows and the scale factor :
+ if( j!=index_max ) {
+ for( int k=0; k<N; k++ ) {
+ dum = LU( index_max, k ) ;
+ LU( index_max, k ) = LU( j, k ) ;
+ LU( j, k ) = dum ;
+ }
+ ImplicitScaling( index_max ) = ImplicitScaling( j ) ;
+ }
+ pivot( j ) = index_max ;
+ if ( LU( j, j )==0. ) LU( j, j ) = 1.e-20 ;
+ // Divide by the pivot element :
+ if( j<N ) {
+ dum = 1./LU( j, j ) ;
+ for( int i=j+1; i<N; i++ ) LU( i, j ) *= dum ;
+ }
+ }
+
+ }
+
+ inline static void LU_solve(const gene_matrix & LU, const Pivot_Vector pivot, gene_vector &B, gene_vector X, int N)
+ {
+
+ // Pour conserver le meme header, on travaille sur X, copie du second-membre B
+ X = B.copy() ;
+ ASSERT( LU.rows()==LU.cols() ) ;
+ firstIndex indI ;
+ // Forward substitution :
+ int ii = 0 ;
+ real theSum = 0. ;
+ for( int i=0; i<N; i++ ) {
+ int ip = pivot( i ) ;
+ theSum = X( ip ) ;
+ // theSum = B( ip ) ;
+ X( ip ) = X( i ) ;
+ // B( ip ) = B( i ) ;
+ if( ii ) {
+ theSum -= matrix_vector_product_sliced(LU, X, i, ii-1, i-1) ;
+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*X( Range( ii-1, i-1 ) ) ) ;
+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*B( Range( ii-1, i-1 ) ) ) ;
+ } else if( theSum ) {
+ ii = i+1 ;
+ }
+ X( i ) = theSum ;
+ // B( i ) = theSum ;
+ }
+ // Backsubstitution :
+ for( int i=N-1; i>=0; i-- ) {
+ theSum = X( i ) ;
+ // theSum = B( i ) ;
+ theSum -= matrix_vector_product_sliced(LU, X, i, i+1, N) ;
+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*X( Range( i+1, toEnd ) ) ) ;
+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*B( Range( i+1, toEnd ) ) ) ;
+ // Store a component of the solution vector :
+ X( i ) = theSum/LU( i, i ) ;
+ // B( i ) = theSum/LU( i, i ) ;
+ }
+
+ }
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/mtl4/mtl4_interface.hh b/eigen/bench/btl/libs/mtl4/mtl4_interface.hh
new file mode 100644
index 0000000..3795ac6
--- /dev/null
+++ b/eigen/bench/btl/libs/mtl4/mtl4_interface.hh
@@ -0,0 +1,144 @@
+//=====================================================
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef MTL4_INTERFACE_HH
+#define MTL4_INTERFACE_HH
+
+#include <boost/numeric/mtl/mtl.hpp>
+#include <boost/numeric/mtl/utility/range_generator.hpp>
+// #include <boost/numeric/mtl/operation/cholesky.hpp>
+#include <vector>
+
+using namespace mtl;
+
+template<class real>
+class mtl4_interface {
+
+public :
+
+ typedef real real_type ;
+
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector > stl_matrix;
+
+ typedef mtl::dense2D<real, mtl::matrix::parameters<mtl::tag::col_major> > gene_matrix;
+ typedef mtl::dense_vector<real> gene_vector;
+
+ static inline std::string name() { return "mtl4"; }
+
+ static void free_matrix(gene_matrix & A, int N){
+ return ;
+ }
+
+ static void free_vector(gene_vector & B){
+ return ;
+ }
+
+ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ A.change_dim(A_stl[0].size(), A_stl.size());
+
+ for (int j=0; j<A_stl.size() ; j++){
+ for (int i=0; i<A_stl[j].size() ; i++){
+ A(i,j) = A_stl[j][i];
+ }
+ }
+ }
+
+ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ B.change_dim(B_stl.size());
+ for (int i=0; i<B_stl.size() ; i++){
+ B[i] = B_stl[i];
+ }
+ }
+
+ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ for (int i=0; i<B_stl.size() ; i++){
+ B_stl[i] = B[i];
+ }
+ }
+
+ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N=A_stl.size();
+ for (int j=0;j<N;j++){
+ A_stl[j].resize(N);
+ for (int i=0;i<N;i++){
+ A_stl[j][i] = A(i,j);
+ }
+ }
+ }
+
+ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ X = (A*B);
+// morton_dense<double, doppled_64_row_mask> C(N,N);
+// C = B;
+// X = (A*C);
+ }
+
+ 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 inline void ata_product(const gene_matrix & A, gene_matrix & X, int N){
+// X = (trans(A)*A);
+// }
+
+ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){
+ X = (A*trans(A));
+ }
+
+ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X = (A*B);
+ }
+
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X = (trans(A)*B);
+ }
+
+ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){
+ Y += coef * X;
+ }
+
+ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){
+ Y = a*X + b*Y;
+ }
+
+// static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){
+// C = X;
+// recursive_cholesky(C);
+// }
+
+// static inline void lu_decomp(const gene_matrix & X, gene_matrix & R, int N){
+// R = X;
+// std::vector<int> ipvt(N);
+// lu_factor(R, ipvt);
+// }
+
+ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector & X, int N){
+ X = lower_trisolve(L, B);
+ }
+
+ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ cible = source;
+ }
+
+ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ cible = source;
+ }
+
+};
+
+#endif
diff --git a/eigen/bench/btl/libs/tvmet/CMakeLists.txt b/eigen/bench/btl/libs/tvmet/CMakeLists.txt
new file mode 100644
index 0000000..25b565b
--- /dev/null
+++ b/eigen/bench/btl/libs/tvmet/CMakeLists.txt
@@ -0,0 +1,6 @@
+
+find_package(Tvmet)
+if (TVMET_FOUND)
+ include_directories(${TVMET_INCLUDE_DIR})
+ btl_add_bench(btl_tvmet main.cpp OFF)
+endif (TVMET_FOUND)
diff --git a/eigen/bench/btl/libs/tvmet/main.cpp b/eigen/bench/btl/libs/tvmet/main.cpp
new file mode 100644
index 0000000..633215c
--- /dev/null
+++ b/eigen/bench/btl/libs/tvmet/main.cpp
@@ -0,0 +1,40 @@
+//=====================================================
+// File : main.cpp
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "tvmet_interface.hh"
+#include "static/bench_static.hh"
+#include "action_matrix_vector_product.hh"
+#include "action_matrix_matrix_product.hh"
+#include "action_atv_product.hh"
+#include "action_axpy.hh"
+
+BTL_MAIN;
+
+int main()
+{
+ bench_static<Action_axpy,tvmet_interface>();
+ bench_static<Action_matrix_matrix_product,tvmet_interface>();
+ bench_static<Action_matrix_vector_product,tvmet_interface>();
+ bench_static<Action_atv_product,tvmet_interface>();
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/tvmet/tvmet_interface.hh b/eigen/bench/btl/libs/tvmet/tvmet_interface.hh
new file mode 100644
index 0000000..b441ada
--- /dev/null
+++ b/eigen/bench/btl/libs/tvmet/tvmet_interface.hh
@@ -0,0 +1,104 @@
+//=====================================================
+// File : tvmet_interface.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef TVMET_INTERFACE_HH
+#define TVMET_INTERFACE_HH
+
+#include <tvmet/tvmet.h>
+#include <tvmet/Vector.h>
+#include <tvmet/Matrix.h>
+
+#include <vector>
+
+using namespace tvmet;
+
+template<class real, int SIZE>
+class tvmet_interface{
+
+public :
+
+ typedef real real_type ;
+
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector > stl_matrix;
+
+ typedef Vector<real,SIZE> gene_vector;
+ typedef Matrix<real,SIZE,SIZE> gene_matrix;
+
+ static inline std::string name() { return "tiny_tvmet"; }
+
+ static void free_matrix(gene_matrix & A, int N){}
+
+ static void free_vector(gene_vector & B){}
+
+ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ for (int j=0; j<A_stl.size() ; j++)
+ for (int i=0; i<A_stl[j].size() ; i++)
+ A(i,j) = A_stl[j][i];
+ }
+
+ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ for (int i=0; i<B_stl.size() ; i++)
+ B[i]=B_stl[i];
+ }
+
+ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ for (int i=0; i<B_stl.size() ; i++){
+ B_stl[i]=B[i];
+ }
+ }
+
+ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N = A_stl.size();
+ for (int j=0;j<N;j++){
+ A_stl[j].resize(N);
+ for (int i=0;i<N;i++)
+ A_stl[j][i] = A(i,j);
+ }
+ }
+
+
+ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ cible = source;
+ }
+
+ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ cible = source;
+ }
+
+ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
+ X = prod(A,B);
+ }
+
+ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X = prod(A,B);
+ }
+
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X = prod(trans(A),B);
+ }
+
+ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){
+ Y+=coef*X;
+ }
+
+};
+
+
+#endif
diff --git a/eigen/bench/btl/libs/ublas/CMakeLists.txt b/eigen/bench/btl/libs/ublas/CMakeLists.txt
new file mode 100644
index 0000000..bdb58be
--- /dev/null
+++ b/eigen/bench/btl/libs/ublas/CMakeLists.txt
@@ -0,0 +1,7 @@
+
+find_package(Boost)
+if (Boost_FOUND)
+ include_directories(${Boost_INCLUDE_DIRS})
+ include_directories(${Boost_INCLUDES})
+ btl_add_bench(btl_ublas main.cpp)
+endif (Boost_FOUND)
diff --git a/eigen/bench/btl/libs/ublas/main.cpp b/eigen/bench/btl/libs/ublas/main.cpp
new file mode 100644
index 0000000..e2e77ee
--- /dev/null
+++ b/eigen/bench/btl/libs/ublas/main.cpp
@@ -0,0 +1,44 @@
+//=====================================================
+// File : main.cpp
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:27 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#include "utilities.h"
+#include "ublas_interface.hh"
+#include "bench.hh"
+#include "basic_actions.hh"
+
+BTL_MAIN;
+
+int main()
+{
+ bench<Action_axpy<ublas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+ bench<Action_axpby<ublas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+
+ bench<Action_matrix_vector_product<ublas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+ bench<Action_atv_product<ublas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+
+ bench<Action_matrix_matrix_product<ublas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_ata_product<ublas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+// bench<Action_aat_product<ublas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ bench<Action_trisolve<ublas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/btl/libs/ublas/ublas_interface.hh b/eigen/bench/btl/libs/ublas/ublas_interface.hh
new file mode 100644
index 0000000..95cad51
--- /dev/null
+++ b/eigen/bench/btl/libs/ublas/ublas_interface.hh
@@ -0,0 +1,141 @@
+//=====================================================
+// File : ublas_interface.hh
+// Author : L. Plagne <laurent.plagne@edf.fr)>
+// Copyright (C) EDF R&D, lun sep 30 14:23:27 CEST 2002
+//=====================================================
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#ifndef UBLAS_INTERFACE_HH
+#define UBLAS_INTERFACE_HH
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+
+using namespace boost::numeric;
+
+template <class real>
+class ublas_interface{
+
+public :
+
+ typedef real real_type ;
+
+ typedef std::vector<real> stl_vector;
+ typedef std::vector<stl_vector> stl_matrix;
+
+ typedef typename boost::numeric::ublas::matrix<real,boost::numeric::ublas::column_major> gene_matrix;
+ typedef typename boost::numeric::ublas::vector<real> gene_vector;
+
+ static inline std::string name( void ) { return "ublas"; }
+
+ static void free_matrix(gene_matrix & A, int N) {}
+
+ static void free_vector(gene_vector & B) {}
+
+ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+ A.resize(A_stl.size(),A_stl[0].size());
+ for (int j=0; j<A_stl.size() ; j++)
+ for (int i=0; i<A_stl[j].size() ; i++)
+ A(i,j)=A_stl[j][i];
+ }
+
+ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+ B.resize(B_stl.size());
+ for (int i=0; i<B_stl.size() ; i++)
+ B(i)=B_stl[i];
+ }
+
+ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+ for (int i=0; i<B_stl.size() ; i++)
+ B_stl[i]=B(i);
+ }
+
+ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+ int N=A_stl.size();
+ for (int j=0;j<N;j++)
+ {
+ A_stl[j].resize(N);
+ for (int i=0;i<N;i++)
+ A_stl[j][i]=A(i,j);
+ }
+ }
+
+ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){
+ for (int i=0;i<N;i++){
+ cible(i) = source(i);
+ }
+ }
+
+ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){
+ for (int i=0;i<N;i++){
+ for (int j=0;j<N;j++){
+ cible(i,j) = source(i,j);
+ }
+ }
+ }
+
+ static inline void matrix_vector_product_slow(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X = prod(A,B);
+ }
+
+ static inline void matrix_matrix_product_slow(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){
+ X = prod(A,B);
+ }
+
+ static inline void axpy_slow(const real coef, const gene_vector & X, gene_vector & Y, int N){
+ Y+=coef*X;
+ }
+
+ // alias free assignements
+
+ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X.assign(prod(A,B));
+ }
+
+ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+ X.assign(prod(trans(A),B));
+ }
+
+ static inline void matrix_matrix_product(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){
+ X.assign(prod(A,B));
+ }
+
+ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){
+ Y.plus_assign(coef*X);
+ }
+
+ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){
+ Y = a*X + b*Y;
+ }
+
+ static inline void ata_product(gene_matrix & A, gene_matrix & X, int N){
+ // X = prod(trans(A),A);
+ X.assign(prod(trans(A),A));
+ }
+
+ static inline void aat_product(gene_matrix & A, gene_matrix & X, int N){
+ // X = prod(A,trans(A));
+ X.assign(prod(A,trans(A)));
+ }
+
+ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector & X, int N){
+ X = solve(L, B, ublas::lower_tag ());
+ }
+
+};
+
+#endif
diff --git a/eigen/bench/check_cache_queries.cpp b/eigen/bench/check_cache_queries.cpp
new file mode 100644
index 0000000..029d44c
--- /dev/null
+++ b/eigen/bench/check_cache_queries.cpp
@@ -0,0 +1,101 @@
+
+#define EIGEN_INTERNAL_DEBUG_CACHE_QUERY
+#include <iostream>
+#include "../Eigen/Core"
+
+using namespace Eigen;
+using namespace std;
+
+#define DUMP_CPUID(CODE) {\
+ int abcd[4]; \
+ abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;\
+ EIGEN_CPUID(abcd, CODE, 0); \
+ std::cout << "The code " << CODE << " gives " \
+ << (int*)(abcd[0]) << " " << (int*)(abcd[1]) << " " \
+ << (int*)(abcd[2]) << " " << (int*)(abcd[3]) << " " << std::endl; \
+ }
+
+int main()
+{
+ cout << "Eigen's L1 = " << internal::queryL1CacheSize() << endl;
+ cout << "Eigen's L2/L3 = " << internal::queryTopLevelCacheSize() << endl;
+ int l1, l2, l3;
+ internal::queryCacheSizes(l1, l2, l3);
+ cout << "Eigen's L1, L2, L3 = " << l1 << " " << l2 << " " << l3 << endl;
+
+ #ifdef EIGEN_CPUID
+
+ int abcd[4];
+ int string[8];
+ char* string_char = (char*)(string);
+
+ // vendor ID
+ EIGEN_CPUID(abcd,0x0,0);
+ string[0] = abcd[1];
+ string[1] = abcd[3];
+ string[2] = abcd[2];
+ string[3] = 0;
+ cout << endl;
+ cout << "vendor id = " << string_char << endl;
+ cout << endl;
+ int max_funcs = abcd[0];
+
+ internal::queryCacheSizes_intel_codes(l1, l2, l3);
+ cout << "Eigen's intel codes L1, L2, L3 = " << l1 << " " << l2 << " " << l3 << endl;
+ if(max_funcs>=4)
+ {
+ internal::queryCacheSizes_intel_direct(l1, l2, l3);
+ cout << "Eigen's intel direct L1, L2, L3 = " << l1 << " " << l2 << " " << l3 << endl;
+ }
+ internal::queryCacheSizes_amd(l1, l2, l3);
+ cout << "Eigen's amd L1, L2, L3 = " << l1 << " " << l2 << " " << l3 << endl;
+ cout << endl;
+
+ // dump Intel direct method
+ if(max_funcs>=4)
+ {
+ l1 = l2 = l3 = 0;
+ int cache_id = 0;
+ int cache_type = 0;
+ do {
+ abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;
+ EIGEN_CPUID(abcd,0x4,cache_id);
+ cache_type = (abcd[0] & 0x0F) >> 0;
+ int cache_level = (abcd[0] & 0xE0) >> 5; // A[7:5]
+ int ways = (abcd[1] & 0xFFC00000) >> 22; // B[31:22]
+ int partitions = (abcd[1] & 0x003FF000) >> 12; // B[21:12]
+ int line_size = (abcd[1] & 0x00000FFF) >> 0; // B[11:0]
+ int sets = (abcd[2]); // C[31:0]
+ int cache_size = (ways+1) * (partitions+1) * (line_size+1) * (sets+1);
+
+ cout << "cache[" << cache_id << "].type = " << cache_type << "\n";
+ cout << "cache[" << cache_id << "].level = " << cache_level << "\n";
+ cout << "cache[" << cache_id << "].ways = " << ways << "\n";
+ cout << "cache[" << cache_id << "].partitions = " << partitions << "\n";
+ cout << "cache[" << cache_id << "].line_size = " << line_size << "\n";
+ cout << "cache[" << cache_id << "].sets = " << sets << "\n";
+ cout << "cache[" << cache_id << "].size = " << cache_size << "\n";
+
+ cache_id++;
+ } while(cache_type>0 && cache_id<16);
+ }
+
+ // dump everything
+ std::cout << endl <<"Raw dump:" << endl;
+ for(int i=0; i<max_funcs; ++i)
+ DUMP_CPUID(i);
+
+ DUMP_CPUID(0x80000000);
+ DUMP_CPUID(0x80000001);
+ DUMP_CPUID(0x80000002);
+ DUMP_CPUID(0x80000003);
+ DUMP_CPUID(0x80000004);
+ DUMP_CPUID(0x80000005);
+ DUMP_CPUID(0x80000006);
+ DUMP_CPUID(0x80000007);
+ DUMP_CPUID(0x80000008);
+ #else
+ cout << "EIGEN_CPUID is not defined" << endl;
+ #endif
+ return 0;
+}
diff --git a/eigen/bench/eig33.cpp b/eigen/bench/eig33.cpp
new file mode 100644
index 0000000..1608b99
--- /dev/null
+++ b/eigen/bench/eig33.cpp
@@ -0,0 +1,196 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// The computeRoots function included in this is based on materials
+// covered by the following copyright and license:
+//
+// Geometric Tools, LLC
+// Copyright (c) 1998-2010
+// Distributed under the Boost Software License, Version 1.0.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <iostream>
+#include <Eigen/Core>
+#include <Eigen/Eigenvalues>
+#include <Eigen/Geometry>
+#include <bench/BenchTimer.h>
+
+using namespace Eigen;
+using namespace std;
+
+template<typename Matrix, typename Roots>
+inline void computeRoots(const Matrix& m, Roots& roots)
+{
+ typedef typename Matrix::Scalar Scalar;
+ const Scalar s_inv3 = 1.0/3.0;
+ const Scalar s_sqrt3 = internal::sqrt(Scalar(3.0));
+
+ // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0. The
+ // eigenvalues are the roots to this equation, all guaranteed to be
+ // real-valued, because the matrix is symmetric.
+ Scalar c0 = m(0,0)*m(1,1)*m(2,2) + Scalar(2)*m(0,1)*m(0,2)*m(1,2) - m(0,0)*m(1,2)*m(1,2) - m(1,1)*m(0,2)*m(0,2) - m(2,2)*m(0,1)*m(0,1);
+ Scalar c1 = m(0,0)*m(1,1) - m(0,1)*m(0,1) + m(0,0)*m(2,2) - m(0,2)*m(0,2) + m(1,1)*m(2,2) - m(1,2)*m(1,2);
+ Scalar c2 = m(0,0) + m(1,1) + m(2,2);
+
+ // Construct the parameters used in classifying the roots of the equation
+ // and in solving the equation for the roots in closed form.
+ Scalar c2_over_3 = c2*s_inv3;
+ Scalar a_over_3 = (c1 - c2*c2_over_3)*s_inv3;
+ if (a_over_3 > Scalar(0))
+ a_over_3 = Scalar(0);
+
+ Scalar half_b = Scalar(0.5)*(c0 + c2_over_3*(Scalar(2)*c2_over_3*c2_over_3 - c1));
+
+ Scalar q = half_b*half_b + a_over_3*a_over_3*a_over_3;
+ if (q > Scalar(0))
+ q = Scalar(0);
+
+ // Compute the eigenvalues by solving for the roots of the polynomial.
+ Scalar rho = internal::sqrt(-a_over_3);
+ Scalar theta = std::atan2(internal::sqrt(-q),half_b)*s_inv3;
+ Scalar cos_theta = internal::cos(theta);
+ Scalar sin_theta = internal::sin(theta);
+ roots(0) = c2_over_3 + Scalar(2)*rho*cos_theta;
+ roots(1) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta);
+ roots(2) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta);
+
+ // Sort in increasing order.
+ if (roots(0) >= roots(1))
+ std::swap(roots(0),roots(1));
+ if (roots(1) >= roots(2))
+ {
+ std::swap(roots(1),roots(2));
+ if (roots(0) >= roots(1))
+ std::swap(roots(0),roots(1));
+ }
+}
+
+template<typename Matrix, typename Vector>
+void eigen33(const Matrix& mat, Matrix& evecs, Vector& evals)
+{
+ typedef typename Matrix::Scalar Scalar;
+ // Scale the matrix so its entries are in [-1,1]. The scaling is applied
+ // only when at least one matrix entry has magnitude larger than 1.
+
+ Scalar scale = mat.cwiseAbs()/*.template triangularView<Lower>()*/.maxCoeff();
+ scale = std::max(scale,Scalar(1));
+ Matrix scaledMat = mat / scale;
+
+ // Compute the eigenvalues
+// scaledMat.setZero();
+ computeRoots(scaledMat,evals);
+
+ // compute the eigen vectors
+ // **here we assume 3 differents eigenvalues**
+
+ // "optimized version" which appears to be slower with gcc!
+// Vector base;
+// Scalar alpha, beta;
+// base << scaledMat(1,0) * scaledMat(2,1),
+// scaledMat(1,0) * scaledMat(2,0),
+// -scaledMat(1,0) * scaledMat(1,0);
+// for(int k=0; k<2; ++k)
+// {
+// alpha = scaledMat(0,0) - evals(k);
+// beta = scaledMat(1,1) - evals(k);
+// evecs.col(k) = (base + Vector(-beta*scaledMat(2,0), -alpha*scaledMat(2,1), alpha*beta)).normalized();
+// }
+// evecs.col(2) = evecs.col(0).cross(evecs.col(1)).normalized();
+
+// // naive version
+// Matrix tmp;
+// tmp = scaledMat;
+// tmp.diagonal().array() -= evals(0);
+// evecs.col(0) = tmp.row(0).cross(tmp.row(1)).normalized();
+//
+// tmp = scaledMat;
+// tmp.diagonal().array() -= evals(1);
+// evecs.col(1) = tmp.row(0).cross(tmp.row(1)).normalized();
+//
+// tmp = scaledMat;
+// tmp.diagonal().array() -= evals(2);
+// evecs.col(2) = tmp.row(0).cross(tmp.row(1)).normalized();
+
+ // a more stable version:
+ if((evals(2)-evals(0))<=Eigen::NumTraits<Scalar>::epsilon())
+ {
+ evecs.setIdentity();
+ }
+ else
+ {
+ Matrix tmp;
+ tmp = scaledMat;
+ tmp.diagonal ().array () -= evals (2);
+ evecs.col (2) = tmp.row (0).cross (tmp.row (1)).normalized ();
+
+ tmp = scaledMat;
+ tmp.diagonal ().array () -= evals (1);
+ evecs.col(1) = tmp.row (0).cross(tmp.row (1));
+ Scalar n1 = evecs.col(1).norm();
+ if(n1<=Eigen::NumTraits<Scalar>::epsilon())
+ evecs.col(1) = evecs.col(2).unitOrthogonal();
+ else
+ evecs.col(1) /= n1;
+
+ // make sure that evecs[1] is orthogonal to evecs[2]
+ evecs.col(1) = evecs.col(2).cross(evecs.col(1).cross(evecs.col(2))).normalized();
+ evecs.col(0) = evecs.col(2).cross(evecs.col(1));
+ }
+
+ // Rescale back to the original size.
+ evals *= scale;
+}
+
+int main()
+{
+ BenchTimer t;
+ int tries = 10;
+ int rep = 400000;
+ typedef Matrix3f Mat;
+ typedef Vector3f Vec;
+ Mat A = Mat::Random(3,3);
+ A = A.adjoint() * A;
+
+ SelfAdjointEigenSolver<Mat> eig(A);
+ BENCH(t, tries, rep, eig.compute(A));
+ std::cout << "Eigen: " << t.best() << "s\n";
+
+ Mat evecs;
+ Vec evals;
+ BENCH(t, tries, rep, eigen33(A,evecs,evals));
+ std::cout << "Direct: " << t.best() << "s\n\n";
+
+ std::cerr << "Eigenvalue/eigenvector diffs:\n";
+ std::cerr << (evals - eig.eigenvalues()).transpose() << "\n";
+ for(int k=0;k<3;++k)
+ if(evecs.col(k).dot(eig.eigenvectors().col(k))<0)
+ evecs.col(k) = -evecs.col(k);
+ std::cerr << evecs - eig.eigenvectors() << "\n\n";
+}
diff --git a/eigen/bench/geometry.cpp b/eigen/bench/geometry.cpp
new file mode 100644
index 0000000..b187a51
--- /dev/null
+++ b/eigen/bench/geometry.cpp
@@ -0,0 +1,126 @@
+
+#include <iostream>
+#include <Eigen/Geometry>
+#include <bench/BenchTimer.h>
+
+using namespace std;
+using namespace Eigen;
+
+#ifndef SCALAR
+#define SCALAR float
+#endif
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+typedef SCALAR Scalar;
+typedef NumTraits<Scalar>::Real RealScalar;
+typedef Matrix<RealScalar,Dynamic,Dynamic> A;
+typedef Matrix</*Real*/Scalar,Dynamic,Dynamic> B;
+typedef Matrix<Scalar,Dynamic,Dynamic> C;
+typedef Matrix<RealScalar,Dynamic,Dynamic> M;
+
+template<typename Transformation, typename Data>
+EIGEN_DONT_INLINE void transform(const Transformation& t, Data& data)
+{
+ EIGEN_ASM_COMMENT("begin");
+ data = t * data;
+ EIGEN_ASM_COMMENT("end");
+}
+
+template<typename Scalar, typename Data>
+EIGEN_DONT_INLINE void transform(const Quaternion<Scalar>& t, Data& data)
+{
+ EIGEN_ASM_COMMENT("begin quat");
+ for(int i=0;i<data.cols();++i)
+ data.col(i) = t * data.col(i);
+ EIGEN_ASM_COMMENT("end quat");
+}
+
+template<typename T> struct ToRotationMatrixWrapper
+{
+ enum {Dim = T::Dim};
+ typedef typename T::Scalar Scalar;
+ ToRotationMatrixWrapper(const T& o) : object(o) {}
+ T object;
+};
+
+template<typename QType, typename Data>
+EIGEN_DONT_INLINE void transform(const ToRotationMatrixWrapper<QType>& t, Data& data)
+{
+ EIGEN_ASM_COMMENT("begin quat via mat");
+ data = t.object.toRotationMatrix() * data;
+ EIGEN_ASM_COMMENT("end quat via mat");
+}
+
+template<typename Scalar, int Dim, typename Data>
+EIGEN_DONT_INLINE void transform(const Transform<Scalar,Dim,Projective>& t, Data& data)
+{
+ data = (t * data.colwise().homogeneous()).template block<Dim,Data::ColsAtCompileTime>(0,0);
+}
+
+template<typename T> struct get_dim { enum { Dim = T::Dim }; };
+template<typename S, int R, int C, int O, int MR, int MC>
+struct get_dim<Matrix<S,R,C,O,MR,MC> > { enum { Dim = R }; };
+
+template<typename Transformation, int N>
+struct bench_impl
+{
+ static EIGEN_DONT_INLINE void run(const Transformation& t)
+ {
+ Matrix<typename Transformation::Scalar,get_dim<Transformation>::Dim,N> data;
+ data.setRandom();
+ bench_impl<Transformation,N-1>::run(t);
+ BenchTimer timer;
+ BENCH(timer,10,100000,transform(t,data));
+ cout.width(9);
+ cout << timer.best() << " ";
+ }
+};
+
+
+template<typename Transformation>
+struct bench_impl<Transformation,0>
+{
+ static EIGEN_DONT_INLINE void run(const Transformation&) {}
+};
+
+template<typename Transformation>
+EIGEN_DONT_INLINE void bench(const std::string& msg, const Transformation& t)
+{
+ cout << msg << " ";
+ bench_impl<Transformation,SIZE>::run(t);
+ std::cout << "\n";
+}
+
+int main(int argc, char ** argv)
+{
+ Matrix<Scalar,3,4> mat34; mat34.setRandom();
+ Transform<Scalar,3,Isometry> iso3(mat34);
+ Transform<Scalar,3,Affine> aff3(mat34);
+ Transform<Scalar,3,AffineCompact> caff3(mat34);
+ Transform<Scalar,3,Projective> proj3(mat34);
+ Quaternion<Scalar> quat;quat.setIdentity();
+ ToRotationMatrixWrapper<Quaternion<Scalar> > quatmat(quat);
+ Matrix<Scalar,3,3> mat33; mat33.setRandom();
+
+ cout.precision(4);
+ std::cout
+ << "N ";
+ for(int i=0;i<SIZE;++i)
+ {
+ cout.width(9);
+ cout << i+1 << " ";
+ }
+ cout << "\n";
+
+ bench("matrix 3x3", mat33);
+ bench("quaternion", quat);
+ bench("quat-mat ", quatmat);
+ bench("isometry3 ", iso3);
+ bench("affine3 ", aff3);
+ bench("c affine3 ", caff3);
+ bench("proj3 ", proj3);
+}
+
diff --git a/eigen/bench/product_threshold.cpp b/eigen/bench/product_threshold.cpp
new file mode 100644
index 0000000..dd6d15a
--- /dev/null
+++ b/eigen/bench/product_threshold.cpp
@@ -0,0 +1,143 @@
+
+#include <iostream>
+#include <Eigen/Core>
+#include <bench/BenchTimer.h>
+
+using namespace Eigen;
+using namespace std;
+
+#define END 9
+
+template<int S> struct map_size { enum { ret = S }; };
+template<> struct map_size<10> { enum { ret = 20 }; };
+template<> struct map_size<11> { enum { ret = 50 }; };
+template<> struct map_size<12> { enum { ret = 100 }; };
+template<> struct map_size<13> { enum { ret = 300 }; };
+
+template<int M, int N,int K> struct alt_prod
+{
+ enum {
+ ret = M==1 && N==1 ? InnerProduct
+ : K==1 ? OuterProduct
+ : M==1 ? GemvProduct
+ : N==1 ? GemvProduct
+ : GemmProduct
+ };
+};
+
+void print_mode(int mode)
+{
+ if(mode==InnerProduct) std::cout << "i";
+ if(mode==OuterProduct) std::cout << "o";
+ if(mode==CoeffBasedProductMode) std::cout << "c";
+ if(mode==LazyCoeffBasedProductMode) std::cout << "l";
+ if(mode==GemvProduct) std::cout << "v";
+ if(mode==GemmProduct) std::cout << "m";
+}
+
+template<int Mode, typename Lhs, typename Rhs, typename Res>
+EIGEN_DONT_INLINE void prod(const Lhs& a, const Rhs& b, Res& c)
+{
+ c.noalias() += typename ProductReturnType<Lhs,Rhs,Mode>::Type(a,b);
+}
+
+template<int M, int N, int K, typename Scalar, int Mode>
+EIGEN_DONT_INLINE void bench_prod()
+{
+ typedef Matrix<Scalar,M,K> Lhs; Lhs a; a.setRandom();
+ typedef Matrix<Scalar,K,N> Rhs; Rhs b; b.setRandom();
+ typedef Matrix<Scalar,M,N> Res; Res c; c.setRandom();
+
+ BenchTimer t;
+ double n = 2.*double(M)*double(N)*double(K);
+ int rep = 100000./n;
+ rep /= 2;
+ if(rep<1) rep = 1;
+ do {
+ rep *= 2;
+ t.reset();
+ BENCH(t,1,rep,prod<CoeffBasedProductMode>(a,b,c));
+ } while(t.best()<0.1);
+
+ t.reset();
+ BENCH(t,5,rep,prod<Mode>(a,b,c));
+
+ print_mode(Mode);
+ std::cout << int(1e-6*n*rep/t.best()) << "\t";
+}
+
+template<int N> struct print_n;
+template<int M, int N, int K> struct loop_on_m;
+template<int M, int N, int K, typename Scalar, int Mode> struct loop_on_n;
+
+template<int M, int N, int K>
+struct loop_on_k
+{
+ static void run()
+ {
+ std::cout << "K=" << K << "\t";
+ print_n<N>::run();
+ std::cout << "\n";
+
+ loop_on_m<M,N,K>::run();
+ std::cout << "\n\n";
+
+ loop_on_k<M,N,K+1>::run();
+ }
+};
+
+template<int M, int N>
+struct loop_on_k<M,N,END> { static void run(){} };
+
+
+template<int M, int N, int K>
+struct loop_on_m
+{
+ static void run()
+ {
+ std::cout << M << "f\t";
+ loop_on_n<M,N,K,float,CoeffBasedProductMode>::run();
+ std::cout << "\n";
+
+ std::cout << M << "f\t";
+ loop_on_n<M,N,K,float,-1>::run();
+ std::cout << "\n";
+
+ loop_on_m<M+1,N,K>::run();
+ }
+};
+
+template<int N, int K>
+struct loop_on_m<END,N,K> { static void run(){} };
+
+template<int M, int N, int K, typename Scalar, int Mode>
+struct loop_on_n
+{
+ static void run()
+ {
+ bench_prod<M,N,K,Scalar,Mode==-1? alt_prod<M,N,K>::ret : Mode>();
+
+ loop_on_n<M,N+1,K,Scalar,Mode>::run();
+ }
+};
+
+template<int M, int K, typename Scalar, int Mode>
+struct loop_on_n<M,END,K,Scalar,Mode> { static void run(){} };
+
+template<int N> struct print_n
+{
+ static void run()
+ {
+ std::cout << map_size<N>::ret << "\t";
+ print_n<N+1>::run();
+ }
+};
+
+template<> struct print_n<END> { static void run(){} };
+
+int main()
+{
+ loop_on_k<1,1,1>::run();
+
+ return 0;
+}
diff --git a/eigen/bench/quat_slerp.cpp b/eigen/bench/quat_slerp.cpp
new file mode 100644
index 0000000..bffb3bf
--- /dev/null
+++ b/eigen/bench/quat_slerp.cpp
@@ -0,0 +1,247 @@
+
+#include <iostream>
+#include <Eigen/Geometry>
+#include <bench/BenchTimer.h>
+using namespace Eigen;
+using namespace std;
+
+
+
+template<typename Q>
+EIGEN_DONT_INLINE Q nlerp(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ return Q((a.coeffs() * (1.0-t) + b.coeffs() * t).normalized());
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_eigen(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ return a.slerp(t,b);
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_legacy(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ typedef typename Q::Scalar Scalar;
+ static const Scalar one = Scalar(1) - dummy_precision<Scalar>();
+ Scalar d = a.dot(b);
+ Scalar absD = internal::abs(d);
+ if (absD>=one)
+ return a;
+
+ // theta is the angle between the 2 quaternions
+ Scalar theta = std::acos(absD);
+ Scalar sinTheta = internal::sin(theta);
+
+ Scalar scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;
+ Scalar scale1 = internal::sin( ( t * theta) ) / sinTheta;
+ if (d<0)
+ scale1 = -scale1;
+
+ return Q(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_legacy_nlerp(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ typedef typename Q::Scalar Scalar;
+ static const Scalar one = Scalar(1) - epsilon<Scalar>();
+ Scalar d = a.dot(b);
+ Scalar absD = internal::abs(d);
+
+ Scalar scale0;
+ Scalar scale1;
+
+ if (absD>=one)
+ {
+ scale0 = Scalar(1) - t;
+ scale1 = t;
+ }
+ else
+ {
+ // theta is the angle between the 2 quaternions
+ Scalar theta = std::acos(absD);
+ Scalar sinTheta = internal::sin(theta);
+
+ scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;
+ scale1 = internal::sin( ( t * theta) ) / sinTheta;
+ if (d<0)
+ scale1 = -scale1;
+ }
+
+ return Q(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+template<typename T>
+inline T sin_over_x(T x)
+{
+ if (T(1) + x*x == T(1))
+ return T(1);
+ else
+ return std::sin(x)/x;
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_rw(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ typedef typename Q::Scalar Scalar;
+
+ Scalar d = a.dot(b);
+ Scalar theta;
+ if (d<0.0)
+ theta = /*M_PI -*/ Scalar(2)*std::asin( (a.coeffs()+b.coeffs()).norm()/2 );
+ else
+ theta = Scalar(2)*std::asin( (a.coeffs()-b.coeffs()).norm()/2 );
+
+ // theta is the angle between the 2 quaternions
+// Scalar theta = std::acos(absD);
+ Scalar sinOverTheta = sin_over_x(theta);
+
+ Scalar scale0 = (Scalar(1)-t)*sin_over_x( ( Scalar(1) - t ) * theta) / sinOverTheta;
+ Scalar scale1 = t * sin_over_x( ( t * theta) ) / sinOverTheta;
+ if (d<0)
+ scale1 = -scale1;
+
+ return Quaternion<Scalar>(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_gael(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ typedef typename Q::Scalar Scalar;
+
+ Scalar d = a.dot(b);
+ Scalar theta;
+// theta = Scalar(2) * atan2((a.coeffs()-b.coeffs()).norm(),(a.coeffs()+b.coeffs()).norm());
+// if (d<0.0)
+// theta = M_PI-theta;
+
+ if (d<0.0)
+ theta = /*M_PI -*/ Scalar(2)*std::asin( (-a.coeffs()-b.coeffs()).norm()/2 );
+ else
+ theta = Scalar(2)*std::asin( (a.coeffs()-b.coeffs()).norm()/2 );
+
+
+ Scalar scale0;
+ Scalar scale1;
+ if(theta*theta-Scalar(6)==-Scalar(6))
+ {
+ scale0 = Scalar(1) - t;
+ scale1 = t;
+ }
+ else
+ {
+ Scalar sinTheta = std::sin(theta);
+ scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;
+ scale1 = internal::sin( ( t * theta) ) / sinTheta;
+ if (d<0)
+ scale1 = -scale1;
+ }
+
+ return Quaternion<Scalar>(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+int main()
+{
+ typedef double RefScalar;
+ typedef float TestScalar;
+
+ typedef Quaternion<RefScalar> Qd;
+ typedef Quaternion<TestScalar> Qf;
+
+ unsigned int g_seed = (unsigned int) time(NULL);
+ std::cout << g_seed << "\n";
+// g_seed = 1259932496;
+ srand(g_seed);
+
+ Matrix<RefScalar,Dynamic,1> maxerr(7);
+ maxerr.setZero();
+
+ Matrix<RefScalar,Dynamic,1> avgerr(7);
+ avgerr.setZero();
+
+ cout << "double=>float=>double nlerp eigen legacy(snap) legacy(nlerp) rightway gael's criteria\n";
+
+ int rep = 100;
+ int iters = 40;
+ for (int w=0; w<rep; ++w)
+ {
+ Qf a, b;
+ a.coeffs().setRandom();
+ a.normalize();
+ b.coeffs().setRandom();
+ b.normalize();
+
+ Qf c[6];
+
+ Qd ar(a.cast<RefScalar>());
+ Qd br(b.cast<RefScalar>());
+ Qd cr;
+
+
+
+ cout.precision(8);
+ cout << std::scientific;
+ for (int i=0; i<iters; ++i)
+ {
+ RefScalar t = 0.65;
+ cr = slerp_rw(ar,br,t);
+
+ Qf refc = cr.cast<TestScalar>();
+ c[0] = nlerp(a,b,t);
+ c[1] = slerp_eigen(a,b,t);
+ c[2] = slerp_legacy(a,b,t);
+ c[3] = slerp_legacy_nlerp(a,b,t);
+ c[4] = slerp_rw(a,b,t);
+ c[5] = slerp_gael(a,b,t);
+
+ VectorXd err(7);
+ err[0] = (cr.coeffs()-refc.cast<RefScalar>().coeffs()).norm();
+// std::cout << err[0] << " ";
+ for (int k=0; k<6; ++k)
+ {
+ err[k+1] = (c[k].coeffs()-refc.coeffs()).norm();
+// std::cout << err[k+1] << " ";
+ }
+ maxerr = maxerr.cwise().max(err);
+ avgerr += err;
+// std::cout << "\n";
+ b = cr.cast<TestScalar>();
+ br = cr;
+ }
+// std::cout << "\n";
+ }
+ avgerr /= RefScalar(rep*iters);
+ cout << "\n\nAccuracy:\n"
+ << " max: " << maxerr.transpose() << "\n";
+ cout << " avg: " << avgerr.transpose() << "\n";
+
+ // perf bench
+ Quaternionf a,b;
+ a.coeffs().setRandom();
+ a.normalize();
+ b.coeffs().setRandom();
+ b.normalize();
+ //b = a;
+ float s = 0.65;
+
+ #define BENCH(FUNC) {\
+ BenchTimer t; \
+ for(int k=0; k<2; ++k) {\
+ t.start(); \
+ for(int i=0; i<1000000; ++i) \
+ FUNC(a,b,s); \
+ t.stop(); \
+ } \
+ cout << " " << #FUNC << " => \t " << t.value() << "s\n"; \
+ }
+
+ cout << "\nSpeed:\n" << std::fixed;
+ BENCH(nlerp);
+ BENCH(slerp_eigen);
+ BENCH(slerp_legacy);
+ BENCH(slerp_legacy_nlerp);
+ BENCH(slerp_rw);
+ BENCH(slerp_gael);
+}
+
diff --git a/eigen/bench/quatmul.cpp b/eigen/bench/quatmul.cpp
new file mode 100644
index 0000000..8d9d792
--- /dev/null
+++ b/eigen/bench/quatmul.cpp
@@ -0,0 +1,47 @@
+#include <iostream>
+#include <Eigen/Core>
+#include <Eigen/Geometry>
+#include <bench/BenchTimer.h>
+
+using namespace Eigen;
+
+template<typename Quat>
+EIGEN_DONT_INLINE void quatmul_default(const Quat& a, const Quat& b, Quat& c)
+{
+ c = a * b;
+}
+
+template<typename Quat>
+EIGEN_DONT_INLINE void quatmul_novec(const Quat& a, const Quat& b, Quat& c)
+{
+ c = internal::quat_product<0, Quat, Quat, typename Quat::Scalar, Aligned>::run(a,b);
+}
+
+template<typename Quat> void bench(const std::string& label)
+{
+ int tries = 10;
+ int rep = 1000000;
+ BenchTimer t;
+
+ Quat a(4, 1, 2, 3);
+ Quat b(2, 3, 4, 5);
+ Quat c;
+
+ std::cout.precision(3);
+
+ BENCH(t, tries, rep, quatmul_default(a,b,c));
+ std::cout << label << " default " << 1e3*t.best(CPU_TIMER) << "ms \t" << 1e-6*double(rep)/(t.best(CPU_TIMER)) << " M mul/s\n";
+
+ BENCH(t, tries, rep, quatmul_novec(a,b,c));
+ std::cout << label << " novec " << 1e3*t.best(CPU_TIMER) << "ms \t" << 1e-6*double(rep)/(t.best(CPU_TIMER)) << " M mul/s\n";
+}
+
+int main()
+{
+ bench<Quaternionf>("float ");
+ bench<Quaterniond>("double");
+
+ return 0;
+
+}
+
diff --git a/eigen/bench/sparse_cholesky.cpp b/eigen/bench/sparse_cholesky.cpp
new file mode 100644
index 0000000..ecb2267
--- /dev/null
+++ b/eigen/bench/sparse_cholesky.cpp
@@ -0,0 +1,216 @@
+// #define EIGEN_TAUCS_SUPPORT
+// #define EIGEN_CHOLMOD_SUPPORT
+#include <iostream>
+#include <Eigen/Sparse>
+
+// g++ -DSIZE=10000 -DDENSITY=0.001 sparse_cholesky.cpp -I.. -DDENSEMATRI -O3 -g0 -DNDEBUG -DNBTRIES=1 -I /home/gael/Coding/LinearAlgebra/taucs_full/src/ -I/home/gael/Coding/LinearAlgebra/taucs_full/build/linux/ -L/home/gael/Coding/LinearAlgebra/taucs_full/lib/linux/ -ltaucs /home/gael/Coding/LinearAlgebra/GotoBLAS/libgoto.a -lpthread -I /home/gael/Coding/LinearAlgebra/SuiteSparse/CHOLMOD/Include/ $CHOLLIB -I /home/gael/Coding/LinearAlgebra/SuiteSparse/UFconfig/ /home/gael/Coding/LinearAlgebra/SuiteSparse/CCOLAMD/Lib/libccolamd.a /home/gael/Coding/LinearAlgebra/SuiteSparse/CHOLMOD/Lib/libcholmod.a -lmetis /home/gael/Coding/LinearAlgebra/SuiteSparse/AMD/Lib/libamd.a /home/gael/Coding/LinearAlgebra/SuiteSparse/CAMD/Lib/libcamd.a /home/gael/Coding/LinearAlgebra/SuiteSparse/CCOLAMD/Lib/libccolamd.a /home/gael/Coding/LinearAlgebra/SuiteSparse/COLAMD/Lib/libcolamd.a -llapack && ./a.out
+
+#define NOGMM
+#define NOMTL
+
+#ifndef SIZE
+#define SIZE 10
+#endif
+
+#ifndef DENSITY
+#define DENSITY 0.01
+#endif
+
+#ifndef REPEAT
+#define REPEAT 1
+#endif
+
+#include "BenchSparseUtil.h"
+
+#ifndef MINDENSITY
+#define MINDENSITY 0.0004
+#endif
+
+#ifndef NBTRIES
+#define NBTRIES 10
+#endif
+
+#define BENCH(X) \
+ timer.reset(); \
+ for (int _j=0; _j<NBTRIES; ++_j) { \
+ timer.start(); \
+ for (int _k=0; _k<REPEAT; ++_k) { \
+ X \
+ } timer.stop(); }
+
+// typedef SparseMatrix<Scalar,UpperTriangular> EigenSparseTriMatrix;
+typedef SparseMatrix<Scalar,SelfAdjoint|LowerTriangular> EigenSparseSelfAdjointMatrix;
+
+void fillSpdMatrix(float density, int rows, int cols, EigenSparseSelfAdjointMatrix& dst)
+{
+ dst.startFill(rows*cols*density);
+ for(int j = 0; j < cols; j++)
+ {
+ dst.fill(j,j) = internal::random<Scalar>(10,20);
+ for(int i = j+1; i < rows; i++)
+ {
+ Scalar v = (internal::random<float>(0,1) < density) ? internal::random<Scalar>() : 0;
+ if (v!=0)
+ dst.fill(i,j) = v;
+ }
+
+ }
+ dst.endFill();
+}
+
+#include <Eigen/Cholesky>
+
+template<int Backend>
+void doEigen(const char* name, const EigenSparseSelfAdjointMatrix& sm1, int flags = 0)
+{
+ std::cout << name << "..." << std::flush;
+ BenchTimer timer;
+ timer.start();
+ SparseLLT<EigenSparseSelfAdjointMatrix,Backend> chol(sm1, flags);
+ timer.stop();
+ std::cout << ":\t" << timer.value() << endl;
+
+ std::cout << " nnz: " << sm1.nonZeros() << " => " << chol.matrixL().nonZeros() << "\n";
+// std::cout << "sparse\n" << chol.matrixL() << "%\n";
+}
+
+int main(int argc, char *argv[])
+{
+ int rows = SIZE;
+ int cols = SIZE;
+ float density = DENSITY;
+ BenchTimer timer;
+
+ VectorXf b = VectorXf::Random(cols);
+ VectorXf x = VectorXf::Random(cols);
+
+ bool densedone = false;
+
+ //for (float density = DENSITY; density>=MINDENSITY; density*=0.5)
+// float density = 0.5;
+ {
+ EigenSparseSelfAdjointMatrix sm1(rows, cols);
+ std::cout << "Generate sparse matrix (might take a while)...\n";
+ fillSpdMatrix(density, rows, cols, sm1);
+ std::cout << "DONE\n\n";
+
+ // dense matrices
+ #ifdef DENSEMATRIX
+ if (!densedone)
+ {
+ densedone = true;
+ std::cout << "Eigen Dense\t" << density*100 << "%\n";
+ DenseMatrix m1(rows,cols);
+ eiToDense(sm1, m1);
+ m1 = (m1 + m1.transpose()).eval();
+ m1.diagonal() *= 0.5;
+
+// BENCH(LLT<DenseMatrix> chol(m1);)
+// std::cout << "dense:\t" << timer.value() << endl;
+
+ BenchTimer timer;
+ timer.start();
+ LLT<DenseMatrix> chol(m1);
+ timer.stop();
+ std::cout << "dense:\t" << timer.value() << endl;
+ int count = 0;
+ for (int j=0; j<cols; ++j)
+ for (int i=j; i<rows; ++i)
+ if (!internal::isMuchSmallerThan(internal::abs(chol.matrixL()(i,j)), 0.1))
+ count++;
+ std::cout << "dense: " << "nnz = " << count << "\n";
+// std::cout << "dense:\n" << m1 << "\n\n" << chol.matrixL() << endl;
+ }
+ #endif
+
+ // eigen sparse matrices
+ doEigen<Eigen::DefaultBackend>("Eigen/Sparse", sm1, Eigen::IncompleteFactorization);
+
+ #ifdef EIGEN_CHOLMOD_SUPPORT
+ doEigen<Eigen::Cholmod>("Eigen/Cholmod", sm1, Eigen::IncompleteFactorization);
+ #endif
+
+ #ifdef EIGEN_TAUCS_SUPPORT
+ doEigen<Eigen::Taucs>("Eigen/Taucs", sm1, Eigen::IncompleteFactorization);
+ #endif
+
+ #if 0
+ // TAUCS
+ {
+ taucs_ccs_matrix A = sm1.asTaucsMatrix();
+
+ //BENCH(taucs_ccs_matrix* chol = taucs_ccs_factor_llt(&A, 0, 0);)
+// BENCH(taucs_supernodal_factor_to_ccs(taucs_ccs_factor_llt_ll(&A));)
+// std::cout << "taucs:\t" << timer.value() << endl;
+
+ taucs_ccs_matrix* chol = taucs_ccs_factor_llt(&A, 0, 0);
+
+ for (int j=0; j<cols; ++j)
+ {
+ for (int i=chol->colptr[j]; i<chol->colptr[j+1]; ++i)
+ std::cout << chol->values.d[i] << " ";
+ }
+ }
+
+ // CHOLMOD
+ #ifdef EIGEN_CHOLMOD_SUPPORT
+ {
+ cholmod_common c;
+ cholmod_start (&c);
+ cholmod_sparse A;
+ cholmod_factor *L;
+
+ A = sm1.asCholmodMatrix();
+ BenchTimer timer;
+// timer.reset();
+ timer.start();
+ std::vector<int> perm(cols);
+// std::vector<int> set(ncols);
+ for (int i=0; i<cols; ++i)
+ perm[i] = i;
+// c.nmethods = 1;
+// c.method[0] = 1;
+
+ c.nmethods = 1;
+ c.method [0].ordering = CHOLMOD_NATURAL;
+ c.postorder = 0;
+ c.final_ll = 1;
+
+ L = cholmod_analyze_p(&A, &perm[0], &perm[0], cols, &c);
+ timer.stop();
+ std::cout << "cholmod/analyze:\t" << timer.value() << endl;
+ timer.reset();
+ timer.start();
+ cholmod_factorize(&A, L, &c);
+ timer.stop();
+ std::cout << "cholmod/factorize:\t" << timer.value() << endl;
+
+ cholmod_sparse* cholmat = cholmod_factor_to_sparse(L, &c);
+
+ cholmod_print_factor(L, "Factors", &c);
+
+ cholmod_print_sparse(cholmat, "Chol", &c);
+ cholmod_write_sparse(stdout, cholmat, 0, 0, &c);
+//
+// cholmod_print_sparse(&A, "A", &c);
+// cholmod_write_sparse(stdout, &A, 0, 0, &c);
+
+
+// for (int j=0; j<cols; ++j)
+// {
+// for (int i=chol->colptr[j]; i<chol->colptr[j+1]; ++i)
+// std::cout << chol->values.s[i] << " ";
+// }
+ }
+ #endif
+
+ #endif
+
+
+
+ }
+
+
+ return 0;
+}
+
diff --git a/eigen/bench/sparse_dense_product.cpp b/eigen/bench/sparse_dense_product.cpp
new file mode 100644
index 0000000..f3f5194
--- /dev/null
+++ b/eigen/bench/sparse_dense_product.cpp
@@ -0,0 +1,187 @@
+
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out
+// -DNOGMM -DNOMTL -DCSPARSE
+// -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a
+#ifndef SIZE
+#define SIZE 650000
+#endif
+
+#ifndef DENSITY
+#define DENSITY 0.01
+#endif
+
+#ifndef REPEAT
+#define REPEAT 1
+#endif
+
+#include "BenchSparseUtil.h"
+
+#ifndef MINDENSITY
+#define MINDENSITY 0.0004
+#endif
+
+#ifndef NBTRIES
+#define NBTRIES 10
+#endif
+
+#define BENCH(X) \
+ timer.reset(); \
+ for (int _j=0; _j<NBTRIES; ++_j) { \
+ timer.start(); \
+ for (int _k=0; _k<REPEAT; ++_k) { \
+ X \
+ } timer.stop(); }
+
+
+#ifdef CSPARSE
+cs* cs_sorted_multiply(const cs* a, const cs* b)
+{
+ cs* A = cs_transpose (a, 1) ;
+ cs* B = cs_transpose (b, 1) ;
+ cs* D = cs_multiply (B,A) ; /* D = B'*A' */
+ cs_spfree (A) ;
+ cs_spfree (B) ;
+ cs_dropzeros (D) ; /* drop zeros from D */
+ cs* C = cs_transpose (D, 1) ; /* C = D', so that C is sorted */
+ cs_spfree (D) ;
+ return C;
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+ int rows = SIZE;
+ int cols = SIZE;
+ float density = DENSITY;
+
+ EigenSparseMatrix sm1(rows,cols);
+ DenseVector v1(cols), v2(cols);
+ v1.setRandom();
+
+ BenchTimer timer;
+ for (float density = DENSITY; density>=MINDENSITY; density*=0.5)
+ {
+ //fillMatrix(density, rows, cols, sm1);
+ fillMatrix2(7, rows, cols, sm1);
+
+ // dense matrices
+ #ifdef DENSEMATRIX
+ {
+ std::cout << "Eigen Dense\t" << density*100 << "%\n";
+ DenseMatrix m1(rows,cols);
+ eiToDense(sm1, m1);
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ v2 = m1 * v1;
+ timer.stop();
+ std::cout << " a * v:\t" << timer.best() << " " << double(REPEAT)/timer.best() << " * / sec " << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ v2 = m1.transpose() * v1;
+ timer.stop();
+ std::cout << " a' * v:\t" << timer.best() << endl;
+ }
+ #endif
+
+ // eigen sparse matrices
+ {
+ std::cout << "Eigen sparse\t" << sm1.nonZeros()/float(sm1.rows()*sm1.cols())*100 << "%\n";
+
+ BENCH(asm("#myc"); v2 = sm1 * v1; asm("#myd");)
+ std::cout << " a * v:\t" << timer.best()/REPEAT << " " << double(REPEAT)/timer.best(REAL_TIMER) << " * / sec " << endl;
+
+
+ BENCH( { asm("#mya"); v2 = sm1.transpose() * v1; asm("#myb"); })
+
+ std::cout << " a' * v:\t" << timer.best()/REPEAT << endl;
+ }
+
+// {
+// DynamicSparseMatrix<Scalar> m1(sm1);
+// std::cout << "Eigen dyn-sparse\t" << m1.nonZeros()/float(m1.rows()*m1.cols())*100 << "%\n";
+//
+// BENCH(for (int k=0; k<REPEAT; ++k) v2 = m1 * v1;)
+// std::cout << " a * v:\t" << timer.value() << endl;
+//
+// BENCH(for (int k=0; k<REPEAT; ++k) v2 = m1.transpose() * v1;)
+// std::cout << " a' * v:\t" << timer.value() << endl;
+// }
+
+ // GMM++
+ #ifndef NOGMM
+ {
+ std::cout << "GMM++ sparse\t" << density*100 << "%\n";
+ //GmmDynSparse gmmT3(rows,cols);
+ GmmSparse m1(rows,cols);
+ eiToGmm(sm1, m1);
+
+ std::vector<Scalar> gmmV1(cols), gmmV2(cols);
+ Map<Matrix<Scalar,Dynamic,1> >(&gmmV1[0], cols) = v1;
+ Map<Matrix<Scalar,Dynamic,1> >(&gmmV2[0], cols) = v2;
+
+ BENCH( asm("#myx"); gmm::mult(m1, gmmV1, gmmV2); asm("#myy"); )
+ std::cout << " a * v:\t" << timer.value() << endl;
+
+ BENCH( gmm::mult(gmm::transposed(m1), gmmV1, gmmV2); )
+ std::cout << " a' * v:\t" << timer.value() << endl;
+ }
+ #endif
+
+ #ifndef NOUBLAS
+ {
+ std::cout << "ublas sparse\t" << density*100 << "%\n";
+ UBlasSparse m1(rows,cols);
+ eiToUblas(sm1, m1);
+
+ boost::numeric::ublas::vector<Scalar> uv1, uv2;
+ eiToUblasVec(v1,uv1);
+ eiToUblasVec(v2,uv2);
+
+// std::vector<Scalar> gmmV1(cols), gmmV2(cols);
+// Map<Matrix<Scalar,Dynamic,1> >(&gmmV1[0], cols) = v1;
+// Map<Matrix<Scalar,Dynamic,1> >(&gmmV2[0], cols) = v2;
+
+ BENCH( uv2 = boost::numeric::ublas::prod(m1, uv1); )
+ std::cout << " a * v:\t" << timer.value() << endl;
+
+// BENCH( boost::ublas::prod(gmm::transposed(m1), gmmV1, gmmV2); )
+// std::cout << " a' * v:\t" << timer.value() << endl;
+ }
+ #endif
+
+ // MTL4
+ #ifndef NOMTL
+ {
+ std::cout << "MTL4\t" << density*100 << "%\n";
+ MtlSparse m1(rows,cols);
+ eiToMtl(sm1, m1);
+ mtl::dense_vector<Scalar> mtlV1(cols, 1.0);
+ mtl::dense_vector<Scalar> mtlV2(cols, 1.0);
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ mtlV2 = m1 * mtlV1;
+ timer.stop();
+ std::cout << " a * v:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ mtlV2 = trans(m1) * mtlV1;
+ timer.stop();
+ std::cout << " a' * v:\t" << timer.value() << endl;
+ }
+ #endif
+
+ std::cout << "\n\n";
+ }
+
+ return 0;
+}
+
diff --git a/eigen/bench/sparse_lu.cpp b/eigen/bench/sparse_lu.cpp
new file mode 100644
index 0000000..5c75001
--- /dev/null
+++ b/eigen/bench/sparse_lu.cpp
@@ -0,0 +1,132 @@
+
+// g++ -I.. sparse_lu.cpp -O3 -g0 -I /usr/include/superlu/ -lsuperlu -lgfortran -DSIZE=1000 -DDENSITY=.05 && ./a.out
+
+#define EIGEN_SUPERLU_SUPPORT
+#define EIGEN_UMFPACK_SUPPORT
+#include <Eigen/Sparse>
+
+#define NOGMM
+#define NOMTL
+
+#ifndef SIZE
+#define SIZE 10
+#endif
+
+#ifndef DENSITY
+#define DENSITY 0.01
+#endif
+
+#ifndef REPEAT
+#define REPEAT 1
+#endif
+
+#include "BenchSparseUtil.h"
+
+#ifndef MINDENSITY
+#define MINDENSITY 0.0004
+#endif
+
+#ifndef NBTRIES
+#define NBTRIES 10
+#endif
+
+#define BENCH(X) \
+ timer.reset(); \
+ for (int _j=0; _j<NBTRIES; ++_j) { \
+ timer.start(); \
+ for (int _k=0; _k<REPEAT; ++_k) { \
+ X \
+ } timer.stop(); }
+
+typedef Matrix<Scalar,Dynamic,1> VectorX;
+
+#include <Eigen/LU>
+
+template<int Backend>
+void doEigen(const char* name, const EigenSparseMatrix& sm1, const VectorX& b, VectorX& x, int flags = 0)
+{
+ std::cout << name << "..." << std::flush;
+ BenchTimer timer; timer.start();
+ SparseLU<EigenSparseMatrix,Backend> lu(sm1, flags);
+ timer.stop();
+ if (lu.succeeded())
+ std::cout << ":\t" << timer.value() << endl;
+ else
+ {
+ std::cout << ":\t FAILED" << endl;
+ return;
+ }
+
+ bool ok;
+ timer.reset(); timer.start();
+ ok = lu.solve(b,&x);
+ timer.stop();
+ if (ok)
+ std::cout << " solve:\t" << timer.value() << endl;
+ else
+ std::cout << " solve:\t" << " FAILED" << endl;
+
+ //std::cout << x.transpose() << "\n";
+}
+
+int main(int argc, char *argv[])
+{
+ int rows = SIZE;
+ int cols = SIZE;
+ float density = DENSITY;
+ BenchTimer timer;
+
+ VectorX b = VectorX::Random(cols);
+ VectorX x = VectorX::Random(cols);
+
+ bool densedone = false;
+
+ //for (float density = DENSITY; density>=MINDENSITY; density*=0.5)
+// float density = 0.5;
+ {
+ EigenSparseMatrix sm1(rows, cols);
+ fillMatrix(density, rows, cols, sm1);
+
+ // dense matrices
+ #ifdef DENSEMATRIX
+ if (!densedone)
+ {
+ densedone = true;
+ std::cout << "Eigen Dense\t" << density*100 << "%\n";
+ DenseMatrix m1(rows,cols);
+ eiToDense(sm1, m1);
+
+ BenchTimer timer;
+ timer.start();
+ FullPivLU<DenseMatrix> lu(m1);
+ timer.stop();
+ std::cout << "Eigen/dense:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ lu.solve(b,&x);
+ timer.stop();
+ std::cout << " solve:\t" << timer.value() << endl;
+// std::cout << b.transpose() << "\n";
+// std::cout << x.transpose() << "\n";
+ }
+ #endif
+
+ #ifdef EIGEN_UMFPACK_SUPPORT
+ x.setZero();
+ doEigen<Eigen::UmfPack>("Eigen/UmfPack (auto)", sm1, b, x, 0);
+ #endif
+
+ #ifdef EIGEN_SUPERLU_SUPPORT
+ x.setZero();
+ doEigen<Eigen::SuperLU>("Eigen/SuperLU (nat)", sm1, b, x, Eigen::NaturalOrdering);
+// doEigen<Eigen::SuperLU>("Eigen/SuperLU (MD AT+A)", sm1, b, x, Eigen::MinimumDegree_AT_PLUS_A);
+// doEigen<Eigen::SuperLU>("Eigen/SuperLU (MD ATA)", sm1, b, x, Eigen::MinimumDegree_ATA);
+ doEigen<Eigen::SuperLU>("Eigen/SuperLU (COLAMD)", sm1, b, x, Eigen::ColApproxMinimumDegree);
+ #endif
+
+ }
+
+ return 0;
+}
+
diff --git a/eigen/bench/sparse_product.cpp b/eigen/bench/sparse_product.cpp
new file mode 100644
index 0000000..d2fc44f
--- /dev/null
+++ b/eigen/bench/sparse_product.cpp
@@ -0,0 +1,323 @@
+
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out
+// -DNOGMM -DNOMTL -DCSPARSE
+// -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a
+
+#include <typeinfo>
+
+#ifndef SIZE
+#define SIZE 1000000
+#endif
+
+#ifndef NNZPERCOL
+#define NNZPERCOL 6
+#endif
+
+#ifndef REPEAT
+#define REPEAT 1
+#endif
+
+#include <algorithm>
+#include "BenchTimer.h"
+#include "BenchUtil.h"
+#include "BenchSparseUtil.h"
+
+#ifndef NBTRIES
+#define NBTRIES 1
+#endif
+
+#define BENCH(X) \
+ timer.reset(); \
+ for (int _j=0; _j<NBTRIES; ++_j) { \
+ timer.start(); \
+ for (int _k=0; _k<REPEAT; ++_k) { \
+ X \
+ } timer.stop(); }
+
+// #ifdef MKL
+//
+// #include "mkl_types.h"
+// #include "mkl_spblas.h"
+//
+// template<typename Lhs,typename Rhs,typename Res>
+// void mkl_multiply(const Lhs& lhs, const Rhs& rhs, Res& res)
+// {
+// char n = 'N';
+// float alpha = 1;
+// char matdescra[6];
+// matdescra[0] = 'G';
+// matdescra[1] = 0;
+// matdescra[2] = 0;
+// matdescra[3] = 'C';
+// mkl_scscmm(&n, lhs.rows(), rhs.cols(), lhs.cols(), &alpha, matdescra,
+// lhs._valuePtr(), lhs._innerIndexPtr(), lhs.outerIndexPtr(),
+// pntre, b, &ldb, &beta, c, &ldc);
+// // mkl_somatcopy('C', 'T', lhs.rows(), lhs.cols(), 1,
+// // lhs._valuePtr(), lhs.rows(), DST, dst_stride);
+// }
+//
+// #endif
+
+
+#ifdef CSPARSE
+cs* cs_sorted_multiply(const cs* a, const cs* b)
+{
+// return cs_multiply(a,b);
+
+ cs* A = cs_transpose(a, 1);
+ cs* B = cs_transpose(b, 1);
+ cs* D = cs_multiply(B,A); /* D = B'*A' */
+ cs_spfree (A) ;
+ cs_spfree (B) ;
+ cs_dropzeros (D) ; /* drop zeros from D */
+ cs* C = cs_transpose (D, 1) ; /* C = D', so that C is sorted */
+ cs_spfree (D) ;
+ return C;
+
+// cs* A = cs_transpose(a, 1);
+// cs* C = cs_transpose(A, 1);
+// return C;
+}
+
+cs* cs_sorted_multiply2(const cs* a, const cs* b)
+{
+ cs* D = cs_multiply(a,b);
+ cs* E = cs_transpose(D,1);
+ cs_spfree(D);
+ cs* C = cs_transpose(E,1);
+ cs_spfree(E);
+ return C;
+}
+#endif
+
+void bench_sort();
+
+int main(int argc, char *argv[])
+{
+// bench_sort();
+
+ int rows = SIZE;
+ int cols = SIZE;
+ float density = DENSITY;
+
+ EigenSparseMatrix sm1(rows,cols), sm2(rows,cols), sm3(rows,cols), sm4(rows,cols);
+
+ BenchTimer timer;
+ for (int nnzPerCol = NNZPERCOL; nnzPerCol>1; nnzPerCol/=1.1)
+ {
+ sm1.setZero();
+ sm2.setZero();
+ fillMatrix2(nnzPerCol, rows, cols, sm1);
+ fillMatrix2(nnzPerCol, rows, cols, sm2);
+// std::cerr << "filling OK\n";
+
+ // dense matrices
+ #ifdef DENSEMATRIX
+ {
+ std::cout << "Eigen Dense\t" << nnzPerCol << "%\n";
+ DenseMatrix m1(rows,cols), m2(rows,cols), m3(rows,cols);
+ eiToDense(sm1, m1);
+ eiToDense(sm2, m2);
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1 * m2;
+ timer.stop();
+ std::cout << " a * b:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1.transpose() * m2;
+ timer.stop();
+ std::cout << " a' * b:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1.transpose() * m2.transpose();
+ timer.stop();
+ std::cout << " a' * b':\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1 * m2.transpose();
+ timer.stop();
+ std::cout << " a * b':\t" << timer.value() << endl;
+ }
+ #endif
+
+ // eigen sparse matrices
+ {
+ std::cout << "Eigen sparse\t" << sm1.nonZeros()/(float(sm1.rows())*float(sm1.cols()))*100 << "% * "
+ << sm2.nonZeros()/(float(sm2.rows())*float(sm2.cols()))*100 << "%\n";
+
+ BENCH(sm3 = sm1 * sm2; )
+ std::cout << " a * b:\t" << timer.value() << endl;
+
+// BENCH(sm3 = sm1.transpose() * sm2; )
+// std::cout << " a' * b:\t" << timer.value() << endl;
+// //
+// BENCH(sm3 = sm1.transpose() * sm2.transpose(); )
+// std::cout << " a' * b':\t" << timer.value() << endl;
+// //
+// BENCH(sm3 = sm1 * sm2.transpose(); )
+// std::cout << " a * b' :\t" << timer.value() << endl;
+
+
+// std::cout << "\n";
+//
+// BENCH( sm3._experimentalNewProduct(sm1, sm2); )
+// std::cout << " a * b:\t" << timer.value() << endl;
+//
+// BENCH(sm3._experimentalNewProduct(sm1.transpose(),sm2); )
+// std::cout << " a' * b:\t" << timer.value() << endl;
+// //
+// BENCH(sm3._experimentalNewProduct(sm1.transpose(),sm2.transpose()); )
+// std::cout << " a' * b':\t" << timer.value() << endl;
+// //
+// BENCH(sm3._experimentalNewProduct(sm1, sm2.transpose());)
+// std::cout << " a * b' :\t" << timer.value() << endl;
+ }
+
+ // eigen dyn-sparse matrices
+ /*{
+ DynamicSparseMatrix<Scalar> m1(sm1), m2(sm2), m3(sm3);
+ std::cout << "Eigen dyn-sparse\t" << m1.nonZeros()/(float(m1.rows())*float(m1.cols()))*100 << "% * "
+ << m2.nonZeros()/(float(m2.rows())*float(m2.cols()))*100 << "%\n";
+
+// timer.reset();
+// timer.start();
+ BENCH(for (int k=0; k<REPEAT; ++k) m3 = m1 * m2;)
+// timer.stop();
+ std::cout << " a * b:\t" << timer.value() << endl;
+// std::cout << sm3 << "\n";
+
+ timer.reset();
+ timer.start();
+// std::cerr << "transpose...\n";
+// EigenSparseMatrix sm4 = sm1.transpose();
+// std::cout << sm4.nonZeros() << " == " << sm1.nonZeros() << "\n";
+// exit(1);
+// std::cerr << "transpose OK\n";
+// std::cout << sm1 << "\n\n" << sm1.transpose() << "\n\n" << sm4.transpose() << "\n\n";
+ BENCH(for (int k=0; k<REPEAT; ++k) m3 = m1.transpose() * m2;)
+// timer.stop();
+ std::cout << " a' * b:\t" << timer.value() << endl;
+
+// timer.reset();
+// timer.start();
+ BENCH( for (int k=0; k<REPEAT; ++k) m3 = m1.transpose() * m2.transpose(); )
+// timer.stop();
+ std::cout << " a' * b':\t" << timer.value() << endl;
+
+// timer.reset();
+// timer.start();
+ BENCH( for (int k=0; k<REPEAT; ++k) m3 = m1 * m2.transpose(); )
+// timer.stop();
+ std::cout << " a * b' :\t" << timer.value() << endl;
+ }*/
+
+ // CSparse
+ #ifdef CSPARSE
+ {
+ std::cout << "CSparse \t" << nnzPerCol << "%\n";
+ cs *m1, *m2, *m3;
+ eiToCSparse(sm1, m1);
+ eiToCSparse(sm2, m2);
+
+ BENCH(
+ {
+ m3 = cs_sorted_multiply(m1, m2);
+ if (!m3)
+ {
+ std::cerr << "cs_multiply failed\n";
+ }
+// cs_print(m3, 0);
+ cs_spfree(m3);
+ }
+ );
+// timer.stop();
+ std::cout << " a * b:\t" << timer.value() << endl;
+
+// BENCH( { m3 = cs_sorted_multiply2(m1, m2); cs_spfree(m3); } );
+// std::cout << " a * b:\t" << timer.value() << endl;
+ }
+ #endif
+
+ #ifndef NOUBLAS
+ {
+ std::cout << "ublas\t" << nnzPerCol << "%\n";
+ UBlasSparse m1(rows,cols), m2(rows,cols), m3(rows,cols);
+ eiToUblas(sm1, m1);
+ eiToUblas(sm2, m2);
+
+ BENCH(boost::numeric::ublas::prod(m1, m2, m3););
+ std::cout << " a * b:\t" << timer.value() << endl;
+ }
+ #endif
+
+ // GMM++
+ #ifndef NOGMM
+ {
+ std::cout << "GMM++ sparse\t" << nnzPerCol << "%\n";
+ GmmDynSparse gmmT3(rows,cols);
+ GmmSparse m1(rows,cols), m2(rows,cols), m3(rows,cols);
+ eiToGmm(sm1, m1);
+ eiToGmm(sm2, m2);
+
+ BENCH(gmm::mult(m1, m2, gmmT3););
+ std::cout << " a * b:\t" << timer.value() << endl;
+
+// BENCH(gmm::mult(gmm::transposed(m1), m2, gmmT3););
+// std::cout << " a' * b:\t" << timer.value() << endl;
+//
+// if (rows<500)
+// {
+// BENCH(gmm::mult(gmm::transposed(m1), gmm::transposed(m2), gmmT3););
+// std::cout << " a' * b':\t" << timer.value() << endl;
+//
+// BENCH(gmm::mult(m1, gmm::transposed(m2), gmmT3););
+// std::cout << " a * b':\t" << timer.value() << endl;
+// }
+// else
+// {
+// std::cout << " a' * b':\t" << "forever" << endl;
+// std::cout << " a * b':\t" << "forever" << endl;
+// }
+ }
+ #endif
+
+ // MTL4
+ #ifndef NOMTL
+ {
+ std::cout << "MTL4\t" << nnzPerCol << "%\n";
+ MtlSparse m1(rows,cols), m2(rows,cols), m3(rows,cols);
+ eiToMtl(sm1, m1);
+ eiToMtl(sm2, m2);
+
+ BENCH(m3 = m1 * m2;);
+ std::cout << " a * b:\t" << timer.value() << endl;
+
+// BENCH(m3 = trans(m1) * m2;);
+// std::cout << " a' * b:\t" << timer.value() << endl;
+//
+// BENCH(m3 = trans(m1) * trans(m2););
+// std::cout << " a' * b':\t" << timer.value() << endl;
+//
+// BENCH(m3 = m1 * trans(m2););
+// std::cout << " a * b' :\t" << timer.value() << endl;
+ }
+ #endif
+
+ std::cout << "\n\n";
+ }
+
+ return 0;
+}
+
+
+
diff --git a/eigen/bench/sparse_randomsetter.cpp b/eigen/bench/sparse_randomsetter.cpp
new file mode 100644
index 0000000..19a76e3
--- /dev/null
+++ b/eigen/bench/sparse_randomsetter.cpp
@@ -0,0 +1,125 @@
+
+#define NOGMM
+#define NOMTL
+
+#include <map>
+#include <ext/hash_map>
+#include <google/dense_hash_map>
+#include <google/sparse_hash_map>
+
+#ifndef SIZE
+#define SIZE 10000
+#endif
+
+#ifndef DENSITY
+#define DENSITY 0.01
+#endif
+
+#ifndef REPEAT
+#define REPEAT 1
+#endif
+
+#include "BenchSparseUtil.h"
+
+#ifndef MINDENSITY
+#define MINDENSITY 0.0004
+#endif
+
+#ifndef NBTRIES
+#define NBTRIES 10
+#endif
+
+#define BENCH(X) \
+ timer.reset(); \
+ for (int _j=0; _j<NBTRIES; ++_j) { \
+ timer.start(); \
+ for (int _k=0; _k<REPEAT; ++_k) { \
+ X \
+ } timer.stop(); }
+
+
+static double rtime;
+static double nentries;
+
+template<typename SetterType>
+void dostuff(const char* name, EigenSparseMatrix& sm1)
+{
+ int rows = sm1.rows();
+ int cols = sm1.cols();
+ sm1.setZero();
+ BenchTimer t;
+ SetterType* set1 = new SetterType(sm1);
+ t.reset(); t.start();
+ for (int k=0; k<nentries; ++k)
+ (*set1)(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1)) += 1;
+ t.stop();
+ std::cout << "std::map => \t" << t.value()-rtime
+ << " nnz=" << set1->nonZeros() << std::flush;
+
+ // getchar();
+
+ t.reset(); t.start(); delete set1; t.stop();
+ std::cout << " back: \t" << t.value() << "\n";
+}
+
+int main(int argc, char *argv[])
+{
+ int rows = SIZE;
+ int cols = SIZE;
+ float density = DENSITY;
+
+ EigenSparseMatrix sm1(rows,cols), sm2(rows,cols);
+
+
+ nentries = rows*cols*density;
+ std::cout << "n = " << nentries << "\n";
+ int dummy;
+ BenchTimer t;
+
+ t.reset(); t.start();
+ for (int k=0; k<nentries; ++k)
+ dummy = internal::random<int>(0,rows-1) + internal::random<int>(0,cols-1);
+ t.stop();
+ rtime = t.value();
+ std::cout << "rtime = " << rtime << " (" << dummy << ")\n\n";
+ const int Bits = 6;
+ for (;;)
+ {
+ dostuff<RandomSetter<EigenSparseMatrix,StdMapTraits,Bits> >("std::map ", sm1);
+ dostuff<RandomSetter<EigenSparseMatrix,GnuHashMapTraits,Bits> >("gnu::hash_map", sm1);
+ dostuff<RandomSetter<EigenSparseMatrix,GoogleDenseHashMapTraits,Bits> >("google::dense", sm1);
+ dostuff<RandomSetter<EigenSparseMatrix,GoogleSparseHashMapTraits,Bits> >("google::sparse", sm1);
+
+// {
+// RandomSetter<EigenSparseMatrix,GnuHashMapTraits,Bits> set1(sm1);
+// t.reset(); t.start();
+// for (int k=0; k<n; ++k)
+// set1(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1)) += 1;
+// t.stop();
+// std::cout << "gnu::hash_map => \t" << t.value()-rtime
+// << " nnz=" << set1.nonZeros() << "\n";getchar();
+// }
+// {
+// RandomSetter<EigenSparseMatrix,GoogleDenseHashMapTraits,Bits> set1(sm1);
+// t.reset(); t.start();
+// for (int k=0; k<n; ++k)
+// set1(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1)) += 1;
+// t.stop();
+// std::cout << "google::dense => \t" << t.value()-rtime
+// << " nnz=" << set1.nonZeros() << "\n";getchar();
+// }
+// {
+// RandomSetter<EigenSparseMatrix,GoogleSparseHashMapTraits,Bits> set1(sm1);
+// t.reset(); t.start();
+// for (int k=0; k<n; ++k)
+// set1(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1)) += 1;
+// t.stop();
+// std::cout << "google::sparse => \t" << t.value()-rtime
+// << " nnz=" << set1.nonZeros() << "\n";getchar();
+// }
+ std::cout << "\n\n";
+ }
+
+ return 0;
+}
+
diff --git a/eigen/bench/sparse_setter.cpp b/eigen/bench/sparse_setter.cpp
new file mode 100644
index 0000000..a9f0b11
--- /dev/null
+++ b/eigen/bench/sparse_setter.cpp
@@ -0,0 +1,485 @@
+
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out
+// -DNOGMM -DNOMTL -DCSPARSE
+// -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a
+#ifndef SIZE
+#define SIZE 100000
+#endif
+
+#ifndef NBPERROW
+#define NBPERROW 24
+#endif
+
+#ifndef REPEAT
+#define REPEAT 2
+#endif
+
+#ifndef NBTRIES
+#define NBTRIES 2
+#endif
+
+#ifndef KK
+#define KK 10
+#endif
+
+#ifndef NOGOOGLE
+#define EIGEN_GOOGLEHASH_SUPPORT
+#include <google/sparse_hash_map>
+#endif
+
+#include "BenchSparseUtil.h"
+
+#define CHECK_MEM
+// #define CHECK_MEM std/**/::cout << "check mem\n"; getchar();
+
+#define BENCH(X) \
+ timer.reset(); \
+ for (int _j=0; _j<NBTRIES; ++_j) { \
+ timer.start(); \
+ for (int _k=0; _k<REPEAT; ++_k) { \
+ X \
+ } timer.stop(); }
+
+typedef std::vector<Vector2i> Coordinates;
+typedef std::vector<float> Values;
+
+EIGEN_DONT_INLINE Scalar* setinnerrand_eigen(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_eigen_dynamic(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_eigen_compact(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_eigen_sumeq(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_eigen_gnu_hash(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_eigen_google_dense(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_eigen_google_sparse(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_scipy(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_ublas_mapped(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_ublas_coord(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_ublas_compressed(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_ublas_genvec(const Coordinates& coords, const Values& vals);
+EIGEN_DONT_INLINE Scalar* setrand_mtl(const Coordinates& coords, const Values& vals);
+
+int main(int argc, char *argv[])
+{
+ int rows = SIZE;
+ int cols = SIZE;
+ bool fullyrand = true;
+
+ BenchTimer timer;
+ Coordinates coords;
+ Values values;
+ if(fullyrand)
+ {
+ Coordinates pool;
+ pool.reserve(cols*NBPERROW);
+ std::cerr << "fill pool" << "\n";
+ for (int i=0; i<cols*NBPERROW; )
+ {
+// DynamicSparseMatrix<int> stencil(SIZE,SIZE);
+ Vector2i ij(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1));
+// if(stencil.coeffRef(ij.x(), ij.y())==0)
+ {
+// stencil.coeffRef(ij.x(), ij.y()) = 1;
+ pool.push_back(ij);
+
+ }
+ ++i;
+ }
+ std::cerr << "pool ok" << "\n";
+ int n = cols*NBPERROW*KK;
+ coords.reserve(n);
+ values.reserve(n);
+ for (int i=0; i<n; ++i)
+ {
+ int i = internal::random<int>(0,pool.size());
+ coords.push_back(pool[i]);
+ values.push_back(internal::random<Scalar>());
+ }
+ }
+ else
+ {
+ for (int j=0; j<cols; ++j)
+ for (int i=0; i<NBPERROW; ++i)
+ {
+ coords.push_back(Vector2i(internal::random<int>(0,rows-1),j));
+ values.push_back(internal::random<Scalar>());
+ }
+ }
+ std::cout << "nnz = " << coords.size() << "\n";
+ CHECK_MEM
+
+ // dense matrices
+ #ifdef DENSEMATRIX
+ {
+ BENCH(setrand_eigen_dense(coords,values);)
+ std::cout << "Eigen Dense\t" << timer.value() << "\n";
+ }
+ #endif
+
+ // eigen sparse matrices
+// if (!fullyrand)
+// {
+// BENCH(setinnerrand_eigen(coords,values);)
+// std::cout << "Eigen fillrand\t" << timer.value() << "\n";
+// }
+ {
+ BENCH(setrand_eigen_dynamic(coords,values);)
+ std::cout << "Eigen dynamic\t" << timer.value() << "\n";
+ }
+// {
+// BENCH(setrand_eigen_compact(coords,values);)
+// std::cout << "Eigen compact\t" << timer.value() << "\n";
+// }
+ {
+ BENCH(setrand_eigen_sumeq(coords,values);)
+ std::cout << "Eigen sumeq\t" << timer.value() << "\n";
+ }
+ {
+// BENCH(setrand_eigen_gnu_hash(coords,values);)
+// std::cout << "Eigen std::map\t" << timer.value() << "\n";
+ }
+ {
+ BENCH(setrand_scipy(coords,values);)
+ std::cout << "scipy\t" << timer.value() << "\n";
+ }
+ #ifndef NOGOOGLE
+ {
+ BENCH(setrand_eigen_google_dense(coords,values);)
+ std::cout << "Eigen google dense\t" << timer.value() << "\n";
+ }
+ {
+ BENCH(setrand_eigen_google_sparse(coords,values);)
+ std::cout << "Eigen google sparse\t" << timer.value() << "\n";
+ }
+ #endif
+
+ #ifndef NOUBLAS
+ {
+// BENCH(setrand_ublas_mapped(coords,values);)
+// std::cout << "ublas mapped\t" << timer.value() << "\n";
+ }
+ {
+ BENCH(setrand_ublas_genvec(coords,values);)
+ std::cout << "ublas vecofvec\t" << timer.value() << "\n";
+ }
+ /*{
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ setrand_ublas_compressed(coords,values);
+ timer.stop();
+ std::cout << "ublas comp\t" << timer.value() << "\n";
+ }
+ {
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ setrand_ublas_coord(coords,values);
+ timer.stop();
+ std::cout << "ublas coord\t" << timer.value() << "\n";
+ }*/
+ #endif
+
+
+ // MTL4
+ #ifndef NOMTL
+ {
+ BENCH(setrand_mtl(coords,values));
+ std::cout << "MTL\t" << timer.value() << "\n";
+ }
+ #endif
+
+ return 0;
+}
+
+EIGEN_DONT_INLINE Scalar* setinnerrand_eigen(const Coordinates& coords, const Values& vals)
+{
+ using namespace Eigen;
+ SparseMatrix<Scalar> mat(SIZE,SIZE);
+ //mat.startFill(2000000/*coords.size()*/);
+ for (int i=0; i<coords.size(); ++i)
+ {
+ mat.insert(coords[i].x(), coords[i].y()) = vals[i];
+ }
+ mat.finalize();
+ CHECK_MEM;
+ return 0;
+}
+
+EIGEN_DONT_INLINE Scalar* setrand_eigen_dynamic(const Coordinates& coords, const Values& vals)
+{
+ using namespace Eigen;
+ DynamicSparseMatrix<Scalar> mat(SIZE,SIZE);
+ mat.reserve(coords.size()/10);
+ for (int i=0; i<coords.size(); ++i)
+ {
+ mat.coeffRef(coords[i].x(), coords[i].y()) += vals[i];
+ }
+ mat.finalize();
+ CHECK_MEM;
+ return &mat.coeffRef(coords[0].x(), coords[0].y());
+}
+
+EIGEN_DONT_INLINE Scalar* setrand_eigen_sumeq(const Coordinates& coords, const Values& vals)
+{
+ using namespace Eigen;
+ int n = coords.size()/KK;
+ DynamicSparseMatrix<Scalar> mat(SIZE,SIZE);
+ for (int j=0; j<KK; ++j)
+ {
+ DynamicSparseMatrix<Scalar> aux(SIZE,SIZE);
+ mat.reserve(n);
+ for (int i=j*n; i<(j+1)*n; ++i)
+ {
+ aux.insert(coords[i].x(), coords[i].y()) += vals[i];
+ }
+ aux.finalize();
+ mat += aux;
+ }
+ return &mat.coeffRef(coords[0].x(), coords[0].y());
+}
+
+EIGEN_DONT_INLINE Scalar* setrand_eigen_compact(const Coordinates& coords, const Values& vals)
+{
+ using namespace Eigen;
+ DynamicSparseMatrix<Scalar> setter(SIZE,SIZE);
+ setter.reserve(coords.size()/10);
+ for (int i=0; i<coords.size(); ++i)
+ {
+ setter.coeffRef(coords[i].x(), coords[i].y()) += vals[i];
+ }
+ SparseMatrix<Scalar> mat = setter;
+ CHECK_MEM;
+ return &mat.coeffRef(coords[0].x(), coords[0].y());
+}
+
+EIGEN_DONT_INLINE Scalar* setrand_eigen_gnu_hash(const Coordinates& coords, const Values& vals)
+{
+ using namespace Eigen;
+ SparseMatrix<Scalar> mat(SIZE,SIZE);
+ {
+ RandomSetter<SparseMatrix<Scalar>, StdMapTraits > setter(mat);
+ for (int i=0; i<coords.size(); ++i)
+ {
+ setter(coords[i].x(), coords[i].y()) += vals[i];
+ }
+ CHECK_MEM;
+ }
+ return &mat.coeffRef(coords[0].x(), coords[0].y());
+}
+
+#ifndef NOGOOGLE
+EIGEN_DONT_INLINE Scalar* setrand_eigen_google_dense(const Coordinates& coords, const Values& vals)
+{
+ using namespace Eigen;
+ SparseMatrix<Scalar> mat(SIZE,SIZE);
+ {
+ RandomSetter<SparseMatrix<Scalar>, GoogleDenseHashMapTraits> setter(mat);
+ for (int i=0; i<coords.size(); ++i)
+ setter(coords[i].x(), coords[i].y()) += vals[i];
+ CHECK_MEM;
+ }
+ return &mat.coeffRef(coords[0].x(), coords[0].y());
+}
+
+EIGEN_DONT_INLINE Scalar* setrand_eigen_google_sparse(const Coordinates& coords, const Values& vals)
+{
+ using namespace Eigen;
+ SparseMatrix<Scalar> mat(SIZE,SIZE);
+ {
+ RandomSetter<SparseMatrix<Scalar>, GoogleSparseHashMapTraits> setter(mat);
+ for (int i=0; i<coords.size(); ++i)
+ setter(coords[i].x(), coords[i].y()) += vals[i];
+ CHECK_MEM;
+ }
+ return &mat.coeffRef(coords[0].x(), coords[0].y());
+}
+#endif
+
+
+template <class T>
+void coo_tocsr(const int n_row,
+ const int n_col,
+ const int nnz,
+ const Coordinates Aij,
+ const Values Ax,
+ int Bp[],
+ int Bj[],
+ T Bx[])
+{
+ //compute number of non-zero entries per row of A coo_tocsr
+ std::fill(Bp, Bp + n_row, 0);
+
+ for (int n = 0; n < nnz; n++){
+ Bp[Aij[n].x()]++;
+ }
+
+ //cumsum the nnz per row to get Bp[]
+ for(int i = 0, cumsum = 0; i < n_row; i++){
+ int temp = Bp[i];
+ Bp[i] = cumsum;
+ cumsum += temp;
+ }
+ Bp[n_row] = nnz;
+
+ //write Aj,Ax into Bj,Bx
+ for(int n = 0; n < nnz; n++){
+ int row = Aij[n].x();
+ int dest = Bp[row];
+
+ Bj[dest] = Aij[n].y();
+ Bx[dest] = Ax[n];
+
+ Bp[row]++;
+ }
+
+ for(int i = 0, last = 0; i <= n_row; i++){
+ int temp = Bp[i];
+ Bp[i] = last;
+ last = temp;
+ }
+
+ //now Bp,Bj,Bx form a CSR representation (with possible duplicates)
+}
+
+template< class T1, class T2 >
+bool kv_pair_less(const std::pair<T1,T2>& x, const std::pair<T1,T2>& y){
+ return x.first < y.first;
+}
+
+
+template<class I, class T>
+void csr_sort_indices(const I n_row,
+ const I Ap[],
+ I Aj[],
+ T Ax[])
+{
+ std::vector< std::pair<I,T> > temp;
+
+ for(I i = 0; i < n_row; i++){
+ I row_start = Ap[i];
+ I row_end = Ap[i+1];
+
+ temp.clear();
+
+ for(I jj = row_start; jj < row_end; jj++){
+ temp.push_back(std::make_pair(Aj[jj],Ax[jj]));
+ }
+
+ std::sort(temp.begin(),temp.end(),kv_pair_less<I,T>);
+
+ for(I jj = row_start, n = 0; jj < row_end; jj++, n++){
+ Aj[jj] = temp[n].first;
+ Ax[jj] = temp[n].second;
+ }
+ }
+}
+
+template <class I, class T>
+void csr_sum_duplicates(const I n_row,
+ const I n_col,
+ I Ap[],
+ I Aj[],
+ T Ax[])
+{
+ I nnz = 0;
+ I row_end = 0;
+ for(I i = 0; i < n_row; i++){
+ I jj = row_end;
+ row_end = Ap[i+1];
+ while( jj < row_end ){
+ I j = Aj[jj];
+ T x = Ax[jj];
+ jj++;
+ while( jj < row_end && Aj[jj] == j ){
+ x += Ax[jj];
+ jj++;
+ }
+ Aj[nnz] = j;
+ Ax[nnz] = x;
+ nnz++;
+ }
+ Ap[i+1] = nnz;
+ }
+}
+
+EIGEN_DONT_INLINE Scalar* setrand_scipy(const Coordinates& coords, const Values& vals)
+{
+ using namespace Eigen;
+ SparseMatrix<Scalar> mat(SIZE,SIZE);
+ mat.resizeNonZeros(coords.size());
+// std::cerr << "setrand_scipy...\n";
+ coo_tocsr<Scalar>(SIZE,SIZE, coords.size(), coords, vals, mat._outerIndexPtr(), mat._innerIndexPtr(), mat._valuePtr());
+// std::cerr << "coo_tocsr ok\n";
+
+ csr_sort_indices(SIZE, mat._outerIndexPtr(), mat._innerIndexPtr(), mat._valuePtr());
+
+ csr_sum_duplicates(SIZE, SIZE, mat._outerIndexPtr(), mat._innerIndexPtr(), mat._valuePtr());
+
+ mat.resizeNonZeros(mat._outerIndexPtr()[SIZE]);
+
+ return &mat.coeffRef(coords[0].x(), coords[0].y());
+}
+
+
+#ifndef NOUBLAS
+EIGEN_DONT_INLINE Scalar* setrand_ublas_mapped(const Coordinates& coords, const Values& vals)
+{
+ using namespace boost;
+ using namespace boost::numeric;
+ using namespace boost::numeric::ublas;
+ mapped_matrix<Scalar> aux(SIZE,SIZE);
+ for (int i=0; i<coords.size(); ++i)
+ {
+ aux(coords[i].x(), coords[i].y()) += vals[i];
+ }
+ CHECK_MEM;
+ compressed_matrix<Scalar> mat(aux);
+ return 0;// &mat(coords[0].x(), coords[0].y());
+}
+/*EIGEN_DONT_INLINE Scalar* setrand_ublas_coord(const Coordinates& coords, const Values& vals)
+{
+ using namespace boost;
+ using namespace boost::numeric;
+ using namespace boost::numeric::ublas;
+ coordinate_matrix<Scalar> aux(SIZE,SIZE);
+ for (int i=0; i<coords.size(); ++i)
+ {
+ aux(coords[i].x(), coords[i].y()) = vals[i];
+ }
+ compressed_matrix<Scalar> mat(aux);
+ return 0;//&mat(coords[0].x(), coords[0].y());
+}
+EIGEN_DONT_INLINE Scalar* setrand_ublas_compressed(const Coordinates& coords, const Values& vals)
+{
+ using namespace boost;
+ using namespace boost::numeric;
+ using namespace boost::numeric::ublas;
+ compressed_matrix<Scalar> mat(SIZE,SIZE);
+ for (int i=0; i<coords.size(); ++i)
+ {
+ mat(coords[i].x(), coords[i].y()) = vals[i];
+ }
+ return 0;//&mat(coords[0].x(), coords[0].y());
+}*/
+EIGEN_DONT_INLINE Scalar* setrand_ublas_genvec(const Coordinates& coords, const Values& vals)
+{
+ using namespace boost;
+ using namespace boost::numeric;
+ using namespace boost::numeric::ublas;
+
+// ublas::vector<coordinate_vector<Scalar> > foo;
+ generalized_vector_of_vector<Scalar, row_major, ublas::vector<coordinate_vector<Scalar> > > aux(SIZE,SIZE);
+ for (int i=0; i<coords.size(); ++i)
+ {
+ aux(coords[i].x(), coords[i].y()) += vals[i];
+ }
+ CHECK_MEM;
+ compressed_matrix<Scalar,row_major> mat(aux);
+ return 0;//&mat(coords[0].x(), coords[0].y());
+}
+#endif
+
+#ifndef NOMTL
+EIGEN_DONT_INLINE void setrand_mtl(const Coordinates& coords, const Values& vals);
+#endif
+
diff --git a/eigen/bench/sparse_transpose.cpp b/eigen/bench/sparse_transpose.cpp
new file mode 100644
index 0000000..c9aacf5
--- /dev/null
+++ b/eigen/bench/sparse_transpose.cpp
@@ -0,0 +1,104 @@
+
+//g++ -O3 -g0 -DNDEBUG sparse_transpose.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out
+// -DNOGMM -DNOMTL
+// -DCSPARSE -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a
+
+#ifndef SIZE
+#define SIZE 10000
+#endif
+
+#ifndef DENSITY
+#define DENSITY 0.01
+#endif
+
+#ifndef REPEAT
+#define REPEAT 1
+#endif
+
+#include "BenchSparseUtil.h"
+
+#ifndef MINDENSITY
+#define MINDENSITY 0.0004
+#endif
+
+#ifndef NBTRIES
+#define NBTRIES 10
+#endif
+
+#define BENCH(X) \
+ timer.reset(); \
+ for (int _j=0; _j<NBTRIES; ++_j) { \
+ timer.start(); \
+ for (int _k=0; _k<REPEAT; ++_k) { \
+ X \
+ } timer.stop(); }
+
+int main(int argc, char *argv[])
+{
+ int rows = SIZE;
+ int cols = SIZE;
+ float density = DENSITY;
+
+ EigenSparseMatrix sm1(rows,cols), sm3(rows,cols);
+
+ BenchTimer timer;
+ for (float density = DENSITY; density>=MINDENSITY; density*=0.5)
+ {
+ fillMatrix(density, rows, cols, sm1);
+
+ // dense matrices
+ #ifdef DENSEMATRIX
+ {
+ DenseMatrix m1(rows,cols), m3(rows,cols);
+ eiToDense(sm1, m1);
+ BENCH(for (int k=0; k<REPEAT; ++k) m3 = m1.transpose();)
+ std::cout << " Eigen dense:\t" << timer.value() << endl;
+ }
+ #endif
+
+ std::cout << "Non zeros: " << sm1.nonZeros()/float(sm1.rows()*sm1.cols())*100 << "%\n";
+
+ // eigen sparse matrices
+ {
+ BENCH(for (int k=0; k<REPEAT; ++k) sm3 = sm1.transpose();)
+ std::cout << " Eigen:\t" << timer.value() << endl;
+ }
+
+ // CSparse
+ #ifdef CSPARSE
+ {
+ cs *m1, *m3;
+ eiToCSparse(sm1, m1);
+
+ BENCH(for (int k=0; k<REPEAT; ++k) { m3 = cs_transpose(m1,1); cs_spfree(m3);})
+ std::cout << " CSparse:\t" << timer.value() << endl;
+ }
+ #endif
+
+ // GMM++
+ #ifndef NOGMM
+ {
+ GmmDynSparse gmmT3(rows,cols);
+ GmmSparse m1(rows,cols), m3(rows,cols);
+ eiToGmm(sm1, m1);
+ BENCH(for (int k=0; k<REPEAT; ++k) gmm::copy(gmm::transposed(m1),m3);)
+ std::cout << " GMM:\t\t" << timer.value() << endl;
+ }
+ #endif
+
+ // MTL4
+ #ifndef NOMTL
+ {
+ MtlSparse m1(rows,cols), m3(rows,cols);
+ eiToMtl(sm1, m1);
+ BENCH(for (int k=0; k<REPEAT; ++k) m3 = trans(m1);)
+ std::cout << " MTL4:\t\t" << timer.value() << endl;
+ }
+ #endif
+
+ std::cout << "\n\n";
+ }
+
+ return 0;
+}
+
diff --git a/eigen/bench/sparse_trisolver.cpp b/eigen/bench/sparse_trisolver.cpp
new file mode 100644
index 0000000..13f4f0a
--- /dev/null
+++ b/eigen/bench/sparse_trisolver.cpp
@@ -0,0 +1,220 @@
+
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out
+// -DNOGMM -DNOMTL
+// -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a
+
+#ifndef SIZE
+#define SIZE 10000
+#endif
+
+#ifndef DENSITY
+#define DENSITY 0.01
+#endif
+
+#ifndef REPEAT
+#define REPEAT 1
+#endif
+
+#include "BenchSparseUtil.h"
+
+#ifndef MINDENSITY
+#define MINDENSITY 0.0004
+#endif
+
+#ifndef NBTRIES
+#define NBTRIES 10
+#endif
+
+#define BENCH(X) \
+ timer.reset(); \
+ for (int _j=0; _j<NBTRIES; ++_j) { \
+ timer.start(); \
+ for (int _k=0; _k<REPEAT; ++_k) { \
+ X \
+ } timer.stop(); }
+
+typedef SparseMatrix<Scalar,UpperTriangular> EigenSparseTriMatrix;
+typedef SparseMatrix<Scalar,RowMajorBit|UpperTriangular> EigenSparseTriMatrixRow;
+
+void fillMatrix(float density, int rows, int cols, EigenSparseTriMatrix& dst)
+{
+ dst.startFill(rows*cols*density);
+ for(int j = 0; j < cols; j++)
+ {
+ for(int i = 0; i < j; i++)
+ {
+ Scalar v = (internal::random<float>(0,1) < density) ? internal::random<Scalar>() : 0;
+ if (v!=0)
+ dst.fill(i,j) = v;
+ }
+ dst.fill(j,j) = internal::random<Scalar>();
+ }
+ dst.endFill();
+}
+
+int main(int argc, char *argv[])
+{
+ int rows = SIZE;
+ int cols = SIZE;
+ float density = DENSITY;
+ BenchTimer timer;
+ #if 1
+ EigenSparseTriMatrix sm1(rows,cols);
+ typedef Matrix<Scalar,Dynamic,1> DenseVector;
+ DenseVector b = DenseVector::Random(cols);
+ DenseVector x = DenseVector::Random(cols);
+
+ bool densedone = false;
+
+ for (float density = DENSITY; density>=MINDENSITY; density*=0.5)
+ {
+ EigenSparseTriMatrix sm1(rows, cols);
+ fillMatrix(density, rows, cols, sm1);
+
+ // dense matrices
+ #ifdef DENSEMATRIX
+ if (!densedone)
+ {
+ densedone = true;
+ std::cout << "Eigen Dense\t" << density*100 << "%\n";
+ DenseMatrix m1(rows,cols);
+ Matrix<Scalar,Dynamic,Dynamic,Dynamic,Dynamic,RowMajorBit> m2(rows,cols);
+ eiToDense(sm1, m1);
+ m2 = m1;
+
+ BENCH(x = m1.marked<UpperTriangular>().solveTriangular(b);)
+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
+// std::cerr << x.transpose() << "\n";
+
+ BENCH(x = m2.marked<UpperTriangular>().solveTriangular(b);)
+ std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;
+// std::cerr << x.transpose() << "\n";
+ }
+ #endif
+
+ // eigen sparse matrices
+ {
+ std::cout << "Eigen sparse\t" << density*100 << "%\n";
+ EigenSparseTriMatrixRow sm2 = sm1;
+
+ BENCH(x = sm1.solveTriangular(b);)
+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
+// std::cerr << x.transpose() << "\n";
+
+ BENCH(x = sm2.solveTriangular(b);)
+ std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;
+// std::cerr << x.transpose() << "\n";
+
+// x = b;
+// BENCH(sm1.inverseProductInPlace(x);)
+// std::cout << " colmajor^-1 * b:\t" << timer.value() << " (inplace)" << endl;
+// std::cerr << x.transpose() << "\n";
+//
+// x = b;
+// BENCH(sm2.inverseProductInPlace(x);)
+// std::cout << " rowmajor^-1 * b:\t" << timer.value() << " (inplace)" << endl;
+// std::cerr << x.transpose() << "\n";
+ }
+
+
+
+ // CSparse
+ #ifdef CSPARSE
+ {
+ std::cout << "CSparse \t" << density*100 << "%\n";
+ cs *m1;
+ eiToCSparse(sm1, m1);
+
+ BENCH(x = b; if (!cs_lsolve (m1, x.data())){std::cerr << "cs_lsolve failed\n"; break;}; )
+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
+ }
+ #endif
+
+ // GMM++
+ #ifndef NOGMM
+ {
+ std::cout << "GMM++ sparse\t" << density*100 << "%\n";
+ GmmSparse m1(rows,cols);
+ gmm::csr_matrix<Scalar> m2;
+ eiToGmm(sm1, m1);
+ gmm::copy(m1,m2);
+ std::vector<Scalar> gmmX(cols), gmmB(cols);
+ Map<Matrix<Scalar,Dynamic,1> >(&gmmX[0], cols) = x;
+ Map<Matrix<Scalar,Dynamic,1> >(&gmmB[0], cols) = b;
+
+ gmmX = gmmB;
+ BENCH(gmm::upper_tri_solve(m1, gmmX, false);)
+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
+// std::cerr << Map<Matrix<Scalar,Dynamic,1> >(&gmmX[0], cols).transpose() << "\n";
+
+ gmmX = gmmB;
+ BENCH(gmm::upper_tri_solve(m2, gmmX, false);)
+ timer.stop();
+ std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;
+// std::cerr << Map<Matrix<Scalar,Dynamic,1> >(&gmmX[0], cols).transpose() << "\n";
+ }
+ #endif
+
+ // MTL4
+ #ifndef NOMTL
+ {
+ std::cout << "MTL4\t" << density*100 << "%\n";
+ MtlSparse m1(rows,cols);
+ MtlSparseRowMajor m2(rows,cols);
+ eiToMtl(sm1, m1);
+ m2 = m1;
+ mtl::dense_vector<Scalar> x(rows, 1.0);
+ mtl::dense_vector<Scalar> b(rows, 1.0);
+
+ BENCH(x = mtl::upper_trisolve(m1,b);)
+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
+// std::cerr << x << "\n";
+
+ BENCH(x = mtl::upper_trisolve(m2,b);)
+ std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;
+// std::cerr << x << "\n";
+ }
+ #endif
+
+
+ std::cout << "\n\n";
+ }
+ #endif
+
+ #if 0
+ // bench small matrices (in-place versus return bye value)
+ {
+ timer.reset();
+ for (int _j=0; _j<10; ++_j) {
+ Matrix4f m = Matrix4f::Random();
+ Vector4f b = Vector4f::Random();
+ Vector4f x = Vector4f::Random();
+ timer.start();
+ for (int _k=0; _k<1000000; ++_k) {
+ b = m.inverseProduct(b);
+ }
+ timer.stop();
+ }
+ std::cout << "4x4 :\t" << timer.value() << endl;
+ }
+
+ {
+ timer.reset();
+ for (int _j=0; _j<10; ++_j) {
+ Matrix4f m = Matrix4f::Random();
+ Vector4f b = Vector4f::Random();
+ Vector4f x = Vector4f::Random();
+ timer.start();
+ for (int _k=0; _k<1000000; ++_k) {
+ m.inverseProductInPlace(x);
+ }
+ timer.stop();
+ }
+ std::cout << "4x4 IP :\t" << timer.value() << endl;
+ }
+ #endif
+
+ return 0;
+}
+
diff --git a/eigen/bench/spbench/CMakeLists.txt b/eigen/bench/spbench/CMakeLists.txt
new file mode 100644
index 0000000..6e0e1b1
--- /dev/null
+++ b/eigen/bench/spbench/CMakeLists.txt
@@ -0,0 +1,78 @@
+
+
+set(BLAS_FOUND TRUE)
+set(LAPACK_FOUND TRUE)
+set(BLAS_LIBRARIES eigen_blas_static)
+set(LAPACK_LIBRARIES eigen_lapack_static)
+
+set(SPARSE_LIBS "")
+
+# find_library(PARDISO_LIBRARIES pardiso412-GNU450-X86-64)
+# if(PARDISO_LIBRARIES)
+# add_definitions("-DEIGEN_PARDISO_SUPPORT")
+# set(SPARSE_LIBS ${SPARSE_LIBS} ${PARDISO_LIBRARIES})
+# endif(PARDISO_LIBRARIES)
+
+find_package(Cholmod)
+if(CHOLMOD_FOUND AND BLAS_FOUND AND LAPACK_FOUND)
+ add_definitions("-DEIGEN_CHOLMOD_SUPPORT")
+ include_directories(${CHOLMOD_INCLUDES})
+ set(SPARSE_LIBS ${SPARSE_LIBS} ${CHOLMOD_LIBRARIES} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
+ set(CHOLMOD_ALL_LIBS ${CHOLMOD_LIBRARIES} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
+endif()
+
+find_package(Umfpack)
+if(UMFPACK_FOUND AND BLAS_FOUND)
+ add_definitions("-DEIGEN_UMFPACK_SUPPORT")
+ include_directories(${UMFPACK_INCLUDES})
+ set(SPARSE_LIBS ${SPARSE_LIBS} ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES})
+ set(UMFPACK_ALL_LIBS ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES})
+endif()
+
+find_package(SuperLU)
+if(SUPERLU_FOUND AND BLAS_FOUND)
+ add_definitions("-DEIGEN_SUPERLU_SUPPORT")
+ include_directories(${SUPERLU_INCLUDES})
+ set(SPARSE_LIBS ${SPARSE_LIBS} ${SUPERLU_LIBRARIES} ${BLAS_LIBRARIES})
+ set(SUPERLU_ALL_LIBS ${SUPERLU_LIBRARIES} ${BLAS_LIBRARIES})
+endif()
+
+
+find_package(Pastix)
+find_package(Scotch)
+find_package(Metis)
+if(PASTIX_FOUND AND BLAS_FOUND)
+ add_definitions("-DEIGEN_PASTIX_SUPPORT")
+ include_directories(${PASTIX_INCLUDES})
+ if(SCOTCH_FOUND)
+ include_directories(${SCOTCH_INCLUDES})
+ set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${SCOTCH_LIBRARIES})
+ elseif(METIS_FOUND)
+ include_directories(${METIS_INCLUDES})
+ 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})
+endif(PASTIX_FOUND AND BLAS_FOUND)
+
+if(METIS_FOUND)
+ include_directories(${METIS_INCLUDES})
+ set (SPARSE_LIBS ${SPARSE_LIBS} ${METIS_LIBRARIES})
+ add_definitions("-DEIGEN_METIS_SUPPORT")
+endif(METIS_FOUND)
+
+find_library(RT_LIBRARY rt)
+if(RT_LIBRARY)
+ set(SPARSE_LIBS ${SPARSE_LIBS} ${RT_LIBRARY})
+endif(RT_LIBRARY)
+
+add_executable(spbenchsolver spbenchsolver.cpp)
+target_link_libraries (spbenchsolver ${SPARSE_LIBS})
+
+add_executable(spsolver sp_solver.cpp)
+target_link_libraries (spsolver ${SPARSE_LIBS})
+
+
+add_executable(test_sparseLU test_sparseLU.cpp)
+target_link_libraries (test_sparseLU ${SPARSE_LIBS})
+
diff --git a/eigen/bench/spbench/sp_solver.cpp b/eigen/bench/spbench/sp_solver.cpp
new file mode 100644
index 0000000..a1f4bac
--- /dev/null
+++ b/eigen/bench/spbench/sp_solver.cpp
@@ -0,0 +1,125 @@
+// Small bench routine for Eigen available in Eigen
+// (C) Desire NUENTSA WAKAM, INRIA
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <Eigen/Jacobi>
+#include <Eigen/Householder>
+#include <Eigen/IterativeLinearSolvers>
+#include <Eigen/LU>
+#include <unsupported/Eigen/SparseExtra>
+//#include <Eigen/SparseLU>
+#include <Eigen/SuperLUSupport>
+// #include <unsupported/Eigen/src/IterativeSolvers/Scaling.h>
+#include <bench/BenchTimer.h>
+#include <unsupported/Eigen/IterativeSolvers>
+using namespace std;
+using namespace Eigen;
+
+int main(int argc, char **args)
+{
+ SparseMatrix<double, ColMajor> A;
+ typedef SparseMatrix<double, ColMajor>::Index Index;
+ typedef Matrix<double, Dynamic, Dynamic> DenseMatrix;
+ typedef Matrix<double, Dynamic, 1> DenseRhs;
+ VectorXd b, x, tmp;
+ BenchTimer timer,totaltime;
+ //SparseLU<SparseMatrix<double, ColMajor> > solver;
+// SuperLU<SparseMatrix<double, ColMajor> > solver;
+ ConjugateGradient<SparseMatrix<double, ColMajor>, Lower,IncompleteCholesky<double,Lower> > solver;
+ ifstream matrix_file;
+ string line;
+ int n;
+ // Set parameters
+// solver.iparm(IPARM_THREAD_NBR) = 4;
+ /* Fill the matrix with sparse matrix stored in Matrix-Market coordinate column-oriented format */
+ if (argc < 2) assert(false && "please, give the matrix market file ");
+
+ timer.start();
+ totaltime.start();
+ loadMarket(A, args[1]);
+ cout << "End charging matrix " << endl;
+ bool iscomplex=false, isvector=false;
+ int sym;
+ getMarketHeader(args[1], sym, iscomplex, isvector);
+ if (iscomplex) { cout<< " Not for complex matrices \n"; return -1; }
+ if (isvector) { cout << "The provided file is not a matrix file\n"; return -1;}
+ if (sym != 0) { // symmetric matrices, only the lower part is stored
+ SparseMatrix<double, ColMajor> temp;
+ temp = A;
+ A = temp.selfadjointView<Lower>();
+ }
+ timer.stop();
+
+ n = A.cols();
+ // ====== TESTS FOR SPARSE TUTORIAL ======
+// cout<< "OuterSize " << A.outerSize() << " inner " << A.innerSize() << endl;
+// SparseMatrix<double, RowMajor> mat1(A);
+// SparseMatrix<double, RowMajor> mat2;
+// cout << " norm of A " << mat1.norm() << endl; ;
+// PermutationMatrix<Dynamic, Dynamic, int> perm(n);
+// perm.resize(n,1);
+// perm.indices().setLinSpaced(n, 0, n-1);
+// mat2 = perm * mat1;
+// mat.subrows();
+// mat2.resize(n,n);
+// mat2.reserve(10);
+// mat2.setConstant();
+// std::cout<< "NORM " << mat1.squaredNorm()<< endl;
+
+ cout<< "Time to load the matrix " << timer.value() <<endl;
+ /* Fill the right hand side */
+
+// solver.set_restart(374);
+ if (argc > 2)
+ loadMarketVector(b, args[2]);
+ else
+ {
+ b.resize(n);
+ tmp.resize(n);
+// tmp.setRandom();
+ for (int i = 0; i < n; i++) tmp(i) = i;
+ b = A * tmp ;
+ }
+// Scaling<SparseMatrix<double> > scal;
+// scal.computeRef(A);
+// b = scal.LeftScaling().cwiseProduct(b);
+
+ /* Compute the factorization */
+ cout<< "Starting the factorization "<< endl;
+ timer.reset();
+ timer.start();
+ cout<< "Size of Input Matrix "<< b.size()<<"\n\n";
+ cout<< "Rows and columns "<< A.rows() <<" " <<A.cols() <<"\n";
+ solver.compute(A);
+// solver.analyzePattern(A);
+// solver.factorize(A);
+ if (solver.info() != Success) {
+ std::cout<< "The solver failed \n";
+ return -1;
+ }
+ timer.stop();
+ float time_comp = timer.value();
+ cout <<" Compute Time " << time_comp<< endl;
+
+ timer.reset();
+ timer.start();
+ x = solver.solve(b);
+// x = scal.RightScaling().cwiseProduct(x);
+ timer.stop();
+ float time_solve = timer.value();
+ cout<< " Time to solve " << time_solve << endl;
+
+ /* Check the accuracy */
+ VectorXd tmp2 = b - A*x;
+ double tempNorm = tmp2.norm()/b.norm();
+ cout << "Relative norm of the computed solution : " << tempNorm <<"\n";
+// cout << "Iterations : " << solver.iterations() << "\n";
+
+ totaltime.stop();
+ cout << "Total time " << totaltime.value() << "\n";
+// std::cout<<x.transpose()<<"\n";
+
+ return 0;
+} \ No newline at end of file
diff --git a/eigen/bench/spbench/spbench.dtd b/eigen/bench/spbench/spbench.dtd
new file mode 100644
index 0000000..0fb51b8
--- /dev/null
+++ b/eigen/bench/spbench/spbench.dtd
@@ -0,0 +1,31 @@
+<!ELEMENT BENCH (AVAILSOLVER+,LINEARSYSTEM+)>
+ <!ELEMENT AVAILSOLVER (SOLVER+)>
+ <!ELEMENT SOLVER (TYPE,PACKAGE)>
+ <!ELEMENT TYPE (#PCDATA)> <!-- One of LU, LLT, LDLT, ITER -->
+ <!ELEMENT PACKAGE (#PCDATA)> <!-- Derived from a library -->
+ <!ELEMENT LINEARSYSTEM (MATRIX,SOLVER_STAT+,BEST_SOLVER,GLOBAL_PARAMS*)>
+ <!ELEMENT MATRIX (NAME,SIZE,ENTRIES,PATTERN?,SYMMETRY,POSDEF?,ARITHMETIC,RHS*)>
+ <!ELEMENT NAME (#PCDATA)>
+ <!ELEMENT SIZE (#PCDATA)>
+ <!ELEMENT ENTRIES (#PCDATA)> <!-- The number of nonzeros elements -->
+ <!ELEMENT PATTERN (#PCDATA)> <!-- Is structural pattern symmetric or not -->
+ <!ELEMENT SYMMETRY (#PCDATA)> <!-- symmmetry with numerical values -->
+ <!ELEMENT POSDEF (#PCDATA)> <!-- Is the matrix positive definite or not -->
+ <!ELEMENT ARITHMETIC (#PCDATA)>
+ <!ELEMENT RHS (SOURCE)> <!-- A matrix can have one or more right hand side associated. -->
+ <!ELEMENT SOURCE (#PCDATA)> <!-- Source of the right hand side, either generated or provided -->
+ <!ELEMENT SOLVER_STAT (PARAMS*,TIME,ERROR,ITER?)>
+ <!ELEMENT PARAMS (#PCDATA)>
+ <!ELEMENT TIME (COMPUTE,SOLVE,TOTAL)>
+ <!ELEMENT COMPUTE (#PCDATA)> <!-- Time to analyze,to factorize, or to setup the preconditioner-->
+ <!ELEMENT SOLVE (#PCDATA)> <!-- Time to solve with all the available rhs -->
+ <!ELEMENT TOTAL (#PCDATA)>
+ <!ELEMENT ERROR (#PCDATA)> <!-- Either the relative error or the relative residual norm -->
+ <!ELEMENT ITER (#PCDATA)> <!-- Number of iterations -->
+ <!ELEMENT BEST_SOLVER CDATA> <!-- Id of the best solver -->
+ <!ELEMENT GLOBAL_PARAMS (#PCDATA)> <!-- Parameters shared by all solvers -->
+
+<!ATTLIST SOLVER ID CDATA #REQUIRED>
+<!ATTLIST SOLVER_STAT ID CDATA #REQUIRED>
+<!ATTLIST BEST_SOLVER ID CDATA #REQUIRED>
+<!ATTLIST RHS ID CDATA #IMPLIED> \ No newline at end of file
diff --git a/eigen/bench/spbench/spbenchsolver.cpp b/eigen/bench/spbench/spbenchsolver.cpp
new file mode 100644
index 0000000..4acd003
--- /dev/null
+++ b/eigen/bench/spbench/spbenchsolver.cpp
@@ -0,0 +1,87 @@
+#include <bench/spbench/spbenchsolver.h>
+
+void bench_printhelp()
+{
+ cout<< " \nbenchsolver : performs a benchmark of all the solvers available in Eigen \n\n";
+ cout<< " MATRIX FOLDER : \n";
+ cout<< " The matrices for the benchmark should be collected in a folder specified with an environment variable EIGEN_MATRIXDIR \n";
+ cout<< " The matrices are stored using the matrix market coordinate format \n";
+ cout<< " The matrix and associated right-hand side (rhs) files are named respectively \n";
+ cout<< " as MatrixName.mtx and MatrixName_b.mtx. If the rhs does not exist, a random one is generated. \n";
+ cout<< " If a matrix is SPD, the matrix should be named as MatrixName_SPD.mtx \n";
+ cout<< " If a true solution exists, it should be named as MatrixName_x.mtx; \n" ;
+ cout<< " it will be used to compute the norm of the error relative to the computed solutions\n\n";
+ cout<< " OPTIONS : \n";
+ cout<< " -h or --help \n print this help and return\n\n";
+ cout<< " -d matrixdir \n Use matrixdir as the matrix folder instead of the one specified in the environment variable EIGEN_MATRIXDIR\n\n";
+ cout<< " -o outputfile.xml \n Output the statistics to a xml file \n\n";
+ cout<< " --eps <RelErr> Sets the relative tolerance for iterative solvers (default 1e-08) \n\n";
+ cout<< " --maxits <MaxIts> Sets the maximum number of iterations (default 1000) \n\n";
+
+}
+int main(int argc, char ** args)
+{
+
+ bool help = ( get_options(argc, args, "-h") || get_options(argc, args, "--help") );
+ if(help) {
+ bench_printhelp();
+ return 0;
+ }
+
+ // Get the location of the test matrices
+ string matrix_dir;
+ if (!get_options(argc, args, "-d", &matrix_dir))
+ {
+ if(getenv("EIGEN_MATRIXDIR") == NULL){
+ std::cerr << "Please, specify the location of the matrices with -d mat_folder or the environment variable EIGEN_MATRIXDIR \n";
+ std::cerr << " Run with --help to see the list of all the available options \n";
+ return -1;
+ }
+ matrix_dir = getenv("EIGEN_MATRIXDIR");
+ }
+
+ std::ofstream statbuf;
+ string statFile ;
+
+ // Get the file to write the statistics
+ bool statFileExists = get_options(argc, args, "-o", &statFile);
+ if(statFileExists)
+ {
+ statbuf.open(statFile.c_str(), std::ios::out);
+ if(statbuf.good()){
+ statFileExists = true;
+ printStatheader(statbuf);
+ statbuf.close();
+ }
+ else
+ std::cerr << "Unable to open the provided file for writting... \n";
+ }
+
+ // Get the maximum number of iterations and the tolerance
+ int maxiters = 1000;
+ double tol = 1e-08;
+ string inval;
+ if (get_options(argc, args, "--eps", &inval))
+ tol = atof(inval.c_str());
+ if(get_options(argc, args, "--maxits", &inval))
+ maxiters = atoi(inval.c_str());
+
+ string current_dir;
+ // Test the real-arithmetics matrices
+ Browse_Matrices<double>(matrix_dir, statFileExists, statFile,maxiters, tol);
+
+ // Test the complex-arithmetics matrices
+ Browse_Matrices<std::complex<double> >(matrix_dir, statFileExists, statFile, maxiters, tol);
+
+ if(statFileExists)
+ {
+ statbuf.open(statFile.c_str(), std::ios::app);
+ statbuf << "</BENCH> \n";
+ cout << "\n Output written in " << statFile << " ...\n";
+ statbuf.close();
+ }
+
+ return 0;
+}
+
+
diff --git a/eigen/bench/spbench/spbenchsolver.h b/eigen/bench/spbench/spbenchsolver.h
new file mode 100644
index 0000000..19c719c
--- /dev/null
+++ b/eigen/bench/spbench/spbenchsolver.h
@@ -0,0 +1,554 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@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 <iostream>
+#include <fstream>
+#include <Eigen/SparseCore>
+#include <bench/BenchTimer.h>
+#include <cstdlib>
+#include <string>
+#include <Eigen/Cholesky>
+#include <Eigen/Jacobi>
+#include <Eigen/Householder>
+#include <Eigen/IterativeLinearSolvers>
+#include <unsupported/Eigen/IterativeSolvers>
+#include <Eigen/LU>
+#include <unsupported/Eigen/SparseExtra>
+#include <Eigen/SparseLU>
+
+#include "spbenchstyle.h"
+
+#ifdef EIGEN_METIS_SUPPORT
+#include <Eigen/MetisSupport>
+#endif
+
+#ifdef EIGEN_CHOLMOD_SUPPORT
+#include <Eigen/CholmodSupport>
+#endif
+
+#ifdef EIGEN_UMFPACK_SUPPORT
+#include <Eigen/UmfPackSupport>
+#endif
+
+#ifdef EIGEN_PARDISO_SUPPORT
+#include <Eigen/PardisoSupport>
+#endif
+
+#ifdef EIGEN_SUPERLU_SUPPORT
+#include <Eigen/SuperLUSupport>
+#endif
+
+#ifdef EIGEN_PASTIX_SUPPORT
+#include <Eigen/PaStiXSupport>
+#endif
+
+// CONSTANTS
+#define EIGEN_UMFPACK 10
+#define EIGEN_SUPERLU 20
+#define EIGEN_PASTIX 30
+#define EIGEN_PARDISO 40
+#define EIGEN_SPARSELU_COLAMD 50
+#define EIGEN_SPARSELU_METIS 51
+#define EIGEN_BICGSTAB 60
+#define EIGEN_BICGSTAB_ILUT 61
+#define EIGEN_GMRES 70
+#define EIGEN_GMRES_ILUT 71
+#define EIGEN_SIMPLICIAL_LDLT 80
+#define EIGEN_CHOLMOD_LDLT 90
+#define EIGEN_PASTIX_LDLT 100
+#define EIGEN_PARDISO_LDLT 110
+#define EIGEN_SIMPLICIAL_LLT 120
+#define EIGEN_CHOLMOD_SUPERNODAL_LLT 130
+#define EIGEN_CHOLMOD_SIMPLICIAL_LLT 140
+#define EIGEN_PASTIX_LLT 150
+#define EIGEN_PARDISO_LLT 160
+#define EIGEN_CG 170
+#define EIGEN_CG_PRECOND 180
+
+using namespace Eigen;
+using namespace std;
+
+
+// Global variables for input parameters
+int MaximumIters; // Maximum number of iterations
+double RelErr; // Relative error of the computed solution
+double best_time_val; // Current best time overall solvers
+int best_time_id; // id of the best solver for the current system
+
+template<typename T> inline typename NumTraits<T>::Real test_precision() { return NumTraits<T>::dummy_precision(); }
+template<> inline float test_precision<float>() { return 1e-3f; }
+template<> inline double test_precision<double>() { return 1e-6; }
+template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }
+template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }
+
+void printStatheader(std::ofstream& out)
+{
+ // Print XML header
+ // NOTE It would have been much easier to write these XML documents using external libraries like tinyXML or Xerces-C++.
+
+ out << "<?xml version='1.0' encoding='UTF-8'?> \n";
+ out << "<?xml-stylesheet type='text/xsl' href='#stylesheet' ?> \n";
+ out << "<!DOCTYPE BENCH [\n<!ATTLIST xsl:stylesheet\n id\t ID #REQUIRED>\n]>";
+ out << "\n\n<!-- Generated by the Eigen library -->\n";
+
+ out << "\n<BENCH> \n" ; //root XML element
+ // Print the xsl style section
+ printBenchStyle(out);
+ // List all available solvers
+ out << " <AVAILSOLVER> \n";
+#ifdef EIGEN_UMFPACK_SUPPORT
+ out <<" <SOLVER ID='" << EIGEN_UMFPACK << "'>\n";
+ out << " <TYPE> LU </TYPE> \n";
+ out << " <PACKAGE> UMFPACK </PACKAGE> \n";
+ out << " </SOLVER> \n";
+#endif
+#ifdef EIGEN_SUPERLU_SUPPORT
+ out <<" <SOLVER ID='" << EIGEN_SUPERLU << "'>\n";
+ out << " <TYPE> LU </TYPE> \n";
+ out << " <PACKAGE> SUPERLU </PACKAGE> \n";
+ out << " </SOLVER> \n";
+#endif
+#ifdef EIGEN_CHOLMOD_SUPPORT
+ out <<" <SOLVER ID='" << EIGEN_CHOLMOD_SIMPLICIAL_LLT << "'>\n";
+ out << " <TYPE> LLT SP</TYPE> \n";
+ out << " <PACKAGE> CHOLMOD </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_CHOLMOD_SUPERNODAL_LLT << "'>\n";
+ out << " <TYPE> LLT</TYPE> \n";
+ out << " <PACKAGE> CHOLMOD </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_CHOLMOD_LDLT << "'>\n";
+ out << " <TYPE> LDLT </TYPE> \n";
+ out << " <PACKAGE> CHOLMOD </PACKAGE> \n";
+ out << " </SOLVER> \n";
+#endif
+#ifdef EIGEN_PARDISO_SUPPORT
+ out <<" <SOLVER ID='" << EIGEN_PARDISO << "'>\n";
+ out << " <TYPE> LU </TYPE> \n";
+ out << " <PACKAGE> PARDISO </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_PARDISO_LLT << "'>\n";
+ out << " <TYPE> LLT </TYPE> \n";
+ out << " <PACKAGE> PARDISO </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_PARDISO_LDLT << "'>\n";
+ out << " <TYPE> LDLT </TYPE> \n";
+ out << " <PACKAGE> PARDISO </PACKAGE> \n";
+ out << " </SOLVER> \n";
+#endif
+#ifdef EIGEN_PASTIX_SUPPORT
+ out <<" <SOLVER ID='" << EIGEN_PASTIX << "'>\n";
+ out << " <TYPE> LU </TYPE> \n";
+ out << " <PACKAGE> PASTIX </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_PASTIX_LLT << "'>\n";
+ out << " <TYPE> LLT </TYPE> \n";
+ out << " <PACKAGE> PASTIX </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_PASTIX_LDLT << "'>\n";
+ out << " <TYPE> LDLT </TYPE> \n";
+ out << " <PACKAGE> PASTIX </PACKAGE> \n";
+ out << " </SOLVER> \n";
+#endif
+
+ out <<" <SOLVER ID='" << EIGEN_BICGSTAB << "'>\n";
+ out << " <TYPE> BICGSTAB </TYPE> \n";
+ out << " <PACKAGE> EIGEN </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_BICGSTAB_ILUT << "'>\n";
+ out << " <TYPE> BICGSTAB_ILUT </TYPE> \n";
+ out << " <PACKAGE> EIGEN </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_GMRES_ILUT << "'>\n";
+ out << " <TYPE> GMRES_ILUT </TYPE> \n";
+ out << " <PACKAGE> EIGEN </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_SIMPLICIAL_LDLT << "'>\n";
+ out << " <TYPE> LDLT </TYPE> \n";
+ out << " <PACKAGE> EIGEN </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_SIMPLICIAL_LLT << "'>\n";
+ out << " <TYPE> LLT </TYPE> \n";
+ out << " <PACKAGE> EIGEN </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_CG << "'>\n";
+ out << " <TYPE> CG </TYPE> \n";
+ out << " <PACKAGE> EIGEN </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+ out <<" <SOLVER ID='" << EIGEN_SPARSELU_COLAMD << "'>\n";
+ out << " <TYPE> LU_COLAMD </TYPE> \n";
+ out << " <PACKAGE> EIGEN </PACKAGE> \n";
+ out << " </SOLVER> \n";
+
+#ifdef EIGEN_METIS_SUPPORT
+ out <<" <SOLVER ID='" << EIGEN_SPARSELU_METIS << "'>\n";
+ out << " <TYPE> LU_METIS </TYPE> \n";
+ out << " <PACKAGE> EIGEN </PACKAGE> \n";
+ out << " </SOLVER> \n";
+#endif
+ out << " </AVAILSOLVER> \n";
+
+}
+
+
+template<typename Solver, typename Scalar>
+void call_solver(Solver &solver, const int solver_id, const typename Solver::MatrixType& A, const Matrix<Scalar, Dynamic, 1>& b, const Matrix<Scalar, Dynamic, 1>& refX,std::ofstream& statbuf)
+{
+
+ double total_time;
+ double compute_time;
+ double solve_time;
+ double rel_error;
+ Matrix<Scalar, Dynamic, 1> x;
+ BenchTimer timer;
+ timer.reset();
+ timer.start();
+ solver.compute(A);
+ if (solver.info() != Success)
+ {
+ std::cerr << "Solver failed ... \n";
+ return;
+ }
+ timer.stop();
+ compute_time = timer.value();
+ statbuf << " <TIME>\n";
+ statbuf << " <COMPUTE> " << timer.value() << "</COMPUTE>\n";
+ std::cout<< "COMPUTE TIME : " << timer.value() <<std::endl;
+
+ timer.reset();
+ timer.start();
+ x = solver.solve(b);
+ if (solver.info() == NumericalIssue)
+ {
+ std::cerr << "Solver failed ... \n";
+ return;
+ }
+ timer.stop();
+ solve_time = timer.value();
+ statbuf << " <SOLVE> " << timer.value() << "</SOLVE>\n";
+ std::cout<< "SOLVE TIME : " << timer.value() <<std::endl;
+
+ total_time = solve_time + compute_time;
+ statbuf << " <TOTAL> " << total_time << "</TOTAL>\n";
+ std::cout<< "TOTAL TIME : " << total_time <<std::endl;
+ statbuf << " </TIME>\n";
+
+ // Verify the relative error
+ if(refX.size() != 0)
+ rel_error = (refX - x).norm()/refX.norm();
+ else
+ {
+ // Compute the relative residual norm
+ Matrix<Scalar, Dynamic, 1> temp;
+ temp = A * x;
+ rel_error = (b-temp).norm()/b.norm();
+ }
+ statbuf << " <ERROR> " << rel_error << "</ERROR>\n";
+ std::cout<< "REL. ERROR : " << rel_error << "\n\n" ;
+ if ( rel_error <= RelErr )
+ {
+ // check the best time if convergence
+ if(!best_time_val || (best_time_val > total_time))
+ {
+ best_time_val = total_time;
+ best_time_id = solver_id;
+ }
+ }
+}
+
+template<typename Solver, typename Scalar>
+void call_directsolver(Solver& solver, const int solver_id, const typename Solver::MatrixType& A, const Matrix<Scalar, Dynamic, 1>& b, const Matrix<Scalar, Dynamic, 1>& refX, std::string& statFile)
+{
+ std::ofstream statbuf(statFile.c_str(), std::ios::app);
+ statbuf << " <SOLVER_STAT ID='" << solver_id <<"'>\n";
+ call_solver(solver, solver_id, A, b, refX,statbuf);
+ statbuf << " </SOLVER_STAT>\n";
+ statbuf.close();
+}
+
+template<typename Solver, typename Scalar>
+void call_itersolver(Solver &solver, const int solver_id, const typename Solver::MatrixType& A, const Matrix<Scalar, Dynamic, 1>& b, const Matrix<Scalar, Dynamic, 1>& refX, std::string& statFile)
+{
+ solver.setTolerance(RelErr);
+ solver.setMaxIterations(MaximumIters);
+
+ std::ofstream statbuf(statFile.c_str(), std::ios::app);
+ statbuf << " <SOLVER_STAT ID='" << solver_id <<"'>\n";
+ call_solver(solver, solver_id, A, b, refX,statbuf);
+ statbuf << " <ITER> "<< solver.iterations() << "</ITER>\n";
+ statbuf << " </SOLVER_STAT>\n";
+ std::cout << "ITERATIONS : " << solver.iterations() <<"\n\n\n";
+
+}
+
+
+template <typename Scalar>
+void SelectSolvers(const SparseMatrix<Scalar>&A, unsigned int sym, Matrix<Scalar, Dynamic, 1>& b, const Matrix<Scalar, Dynamic, 1>& refX, std::string& statFile)
+{
+ typedef SparseMatrix<Scalar, ColMajor> SpMat;
+ // First, deal with Nonsymmetric and symmetric matrices
+ best_time_id = 0;
+ best_time_val = 0.0;
+ //UMFPACK
+ #ifdef EIGEN_UMFPACK_SUPPORT
+ {
+ cout << "Solving with UMFPACK LU ... \n";
+ UmfPackLU<SpMat> solver;
+ call_directsolver(solver, EIGEN_UMFPACK, A, b, refX,statFile);
+ }
+ #endif
+ //SuperLU
+ #ifdef EIGEN_SUPERLU_SUPPORT
+ {
+ cout << "\nSolving with SUPERLU ... \n";
+ SuperLU<SpMat> solver;
+ call_directsolver(solver, EIGEN_SUPERLU, A, b, refX,statFile);
+ }
+ #endif
+
+ // PaStix LU
+ #ifdef EIGEN_PASTIX_SUPPORT
+ {
+ cout << "\nSolving with PASTIX LU ... \n";
+ PastixLU<SpMat> solver;
+ call_directsolver(solver, EIGEN_PASTIX, A, b, refX,statFile) ;
+ }
+ #endif
+
+ //PARDISO LU
+ #ifdef EIGEN_PARDISO_SUPPORT
+ {
+ cout << "\nSolving with PARDISO LU ... \n";
+ PardisoLU<SpMat> solver;
+ call_directsolver(solver, EIGEN_PARDISO, A, b, refX,statFile);
+ }
+ #endif
+
+ // Eigen SparseLU METIS
+ cout << "\n Solving with Sparse LU AND COLAMD ... \n";
+ SparseLU<SpMat, COLAMDOrdering<int> > solver;
+ call_directsolver(solver, EIGEN_SPARSELU_COLAMD, A, b, refX, statFile);
+ // Eigen SparseLU METIS
+ #ifdef EIGEN_METIS_SUPPORT
+ {
+ cout << "\n Solving with Sparse LU AND METIS ... \n";
+ SparseLU<SpMat, MetisOrdering<int> > solver;
+ call_directsolver(solver, EIGEN_SPARSELU_METIS, A, b, refX, statFile);
+ }
+ #endif
+
+ //BiCGSTAB
+ {
+ cout << "\nSolving with BiCGSTAB ... \n";
+ BiCGSTAB<SpMat> solver;
+ call_itersolver(solver, EIGEN_BICGSTAB, A, b, refX,statFile);
+ }
+ //BiCGSTAB+ILUT
+ {
+ cout << "\nSolving with BiCGSTAB and ILUT ... \n";
+ BiCGSTAB<SpMat, IncompleteLUT<Scalar> > solver;
+ call_itersolver(solver, EIGEN_BICGSTAB_ILUT, A, b, refX,statFile);
+ }
+
+
+ //GMRES
+// {
+// cout << "\nSolving with GMRES ... \n";
+// GMRES<SpMat> solver;
+// call_itersolver(solver, EIGEN_GMRES, A, b, refX,statFile);
+// }
+ //GMRES+ILUT
+ {
+ cout << "\nSolving with GMRES and ILUT ... \n";
+ GMRES<SpMat, IncompleteLUT<Scalar> > solver;
+ call_itersolver(solver, EIGEN_GMRES_ILUT, A, b, refX,statFile);
+ }
+
+ // Hermitian and not necessarily positive-definites
+ if (sym != NonSymmetric)
+ {
+ // Internal Cholesky
+ {
+ cout << "\nSolving with Simplicial LDLT ... \n";
+ SimplicialLDLT<SpMat, Lower> solver;
+ call_directsolver(solver, EIGEN_SIMPLICIAL_LDLT, A, b, refX,statFile);
+ }
+
+ // CHOLMOD
+ #ifdef EIGEN_CHOLMOD_SUPPORT
+ {
+ cout << "\nSolving with CHOLMOD LDLT ... \n";
+ CholmodDecomposition<SpMat, Lower> solver;
+ solver.setMode(CholmodLDLt);
+ call_directsolver(solver,EIGEN_CHOLMOD_LDLT, A, b, refX,statFile);
+ }
+ #endif
+
+ //PASTIX LLT
+ #ifdef EIGEN_PASTIX_SUPPORT
+ {
+ cout << "\nSolving with PASTIX LDLT ... \n";
+ PastixLDLT<SpMat, Lower> solver;
+ call_directsolver(solver,EIGEN_PASTIX_LDLT, A, b, refX,statFile);
+ }
+ #endif
+
+ //PARDISO LLT
+ #ifdef EIGEN_PARDISO_SUPPORT
+ {
+ cout << "\nSolving with PARDISO LDLT ... \n";
+ PardisoLDLT<SpMat, Lower> solver;
+ call_directsolver(solver,EIGEN_PARDISO_LDLT, A, b, refX,statFile);
+ }
+ #endif
+ }
+
+ // Now, symmetric POSITIVE DEFINITE matrices
+ if (sym == SPD)
+ {
+
+ //Internal Sparse Cholesky
+ {
+ cout << "\nSolving with SIMPLICIAL LLT ... \n";
+ SimplicialLLT<SpMat, Lower> solver;
+ call_directsolver(solver,EIGEN_SIMPLICIAL_LLT, A, b, refX,statFile);
+ }
+
+ // CHOLMOD
+ #ifdef EIGEN_CHOLMOD_SUPPORT
+ {
+ // CholMOD SuperNodal LLT
+ cout << "\nSolving with CHOLMOD LLT (Supernodal)... \n";
+ CholmodDecomposition<SpMat, Lower> solver;
+ solver.setMode(CholmodSupernodalLLt);
+ call_directsolver(solver,EIGEN_CHOLMOD_SUPERNODAL_LLT, A, b, refX,statFile);
+ // CholMod Simplicial LLT
+ cout << "\nSolving with CHOLMOD LLT (Simplicial) ... \n";
+ solver.setMode(CholmodSimplicialLLt);
+ call_directsolver(solver,EIGEN_CHOLMOD_SIMPLICIAL_LLT, A, b, refX,statFile);
+ }
+ #endif
+
+ //PASTIX LLT
+ #ifdef EIGEN_PASTIX_SUPPORT
+ {
+ cout << "\nSolving with PASTIX LLT ... \n";
+ PastixLLT<SpMat, Lower> solver;
+ call_directsolver(solver,EIGEN_PASTIX_LLT, A, b, refX,statFile);
+ }
+ #endif
+
+ //PARDISO LLT
+ #ifdef EIGEN_PARDISO_SUPPORT
+ {
+ cout << "\nSolving with PARDISO LLT ... \n";
+ PardisoLLT<SpMat, Lower> solver;
+ call_directsolver(solver,EIGEN_PARDISO_LLT, A, b, refX,statFile);
+ }
+ #endif
+
+ // Internal CG
+ {
+ cout << "\nSolving with CG ... \n";
+ ConjugateGradient<SpMat, Lower> solver;
+ call_itersolver(solver,EIGEN_CG, A, b, refX,statFile);
+ }
+ //CG+IdentityPreconditioner
+// {
+// cout << "\nSolving with CG and IdentityPreconditioner ... \n";
+// ConjugateGradient<SpMat, Lower, IdentityPreconditioner> solver;
+// call_itersolver(solver,EIGEN_CG_PRECOND, A, b, refX,statFile);
+// }
+ } // End SPD matrices
+}
+
+/* Browse all the matrices available in the specified folder
+ * and solve the associated linear system.
+ * The results of each solve are printed in the standard output
+ * and optionally in the provided html file
+ */
+template <typename Scalar>
+void Browse_Matrices(const string folder, bool statFileExists, std::string& statFile, int maxiters, double tol)
+{
+ MaximumIters = maxiters; // Maximum number of iterations, global variable
+ RelErr = tol; //Relative residual error as stopping criterion for iterative solvers
+ MatrixMarketIterator<Scalar> it(folder);
+ for ( ; it; ++it)
+ {
+ //print the infos for this linear system
+ if(statFileExists)
+ {
+ std::ofstream statbuf(statFile.c_str(), std::ios::app);
+ statbuf << "<LINEARSYSTEM> \n";
+ statbuf << " <MATRIX> \n";
+ statbuf << " <NAME> " << it.matname() << " </NAME>\n";
+ statbuf << " <SIZE> " << it.matrix().rows() << " </SIZE>\n";
+ statbuf << " <ENTRIES> " << it.matrix().nonZeros() << "</ENTRIES>\n";
+ if (it.sym()!=NonSymmetric)
+ {
+ statbuf << " <SYMMETRY> Symmetric </SYMMETRY>\n" ;
+ if (it.sym() == SPD)
+ statbuf << " <POSDEF> YES </POSDEF>\n";
+ else
+ statbuf << " <POSDEF> NO </POSDEF>\n";
+
+ }
+ else
+ {
+ statbuf << " <SYMMETRY> NonSymmetric </SYMMETRY>\n" ;
+ statbuf << " <POSDEF> NO </POSDEF>\n";
+ }
+ statbuf << " </MATRIX> \n";
+ statbuf.close();
+ }
+
+ cout<< "\n\n===================================================== \n";
+ cout<< " ====== SOLVING WITH MATRIX " << it.matname() << " ====\n";
+ cout<< " =================================================== \n\n";
+ Matrix<Scalar, Dynamic, 1> refX;
+ if(it.hasrefX()) refX = it.refX();
+ // Call all suitable solvers for this linear system
+ SelectSolvers<Scalar>(it.matrix(), it.sym(), it.rhs(), refX, statFile);
+
+ if(statFileExists)
+ {
+ std::ofstream statbuf(statFile.c_str(), std::ios::app);
+ statbuf << " <BEST_SOLVER ID='"<< best_time_id
+ << "'></BEST_SOLVER>\n";
+ statbuf << " </LINEARSYSTEM> \n";
+ statbuf.close();
+ }
+ }
+}
+
+bool get_options(int argc, char **args, string option, string* value=0)
+{
+ int idx = 1, found=false;
+ while (idx<argc && !found){
+ if (option.compare(args[idx]) == 0){
+ found = true;
+ if(value) *value = args[idx+1];
+ }
+ idx+=2;
+ }
+ return found;
+}
diff --git a/eigen/bench/spbench/spbenchstyle.h b/eigen/bench/spbench/spbenchstyle.h
new file mode 100644
index 0000000..17a05ce
--- /dev/null
+++ b/eigen/bench/spbench/spbenchstyle.h
@@ -0,0 +1,94 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@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 SPBENCHSTYLE_H
+#define SPBENCHSTYLE_H
+
+void printBenchStyle(std::ofstream& out)
+{
+ out << "<xsl:stylesheet id='stylesheet' version='1.0' \
+ xmlns:xsl='http://www.w3.org/1999/XSL/Transform' >\n \
+ <xsl:template match='xsl:stylesheet' />\n \
+ <xsl:template match='/'> <!-- Root of the document -->\n \
+ <html>\n \
+ <head> \n \
+ <style type='text/css'> \n \
+ td { white-space: nowrap;}\n \
+ </style>\n \
+ </head>\n \
+ <body>";
+ out<<"<table border='1' width='100%' height='100%'>\n \
+ <TR> <!-- Write the table header -->\n \
+ <TH>Matrix</TH> <TH>N</TH> <TH> NNZ</TH> <TH> Sym</TH> <TH> SPD</TH> <TH> </TH>\n \
+ <xsl:for-each select='BENCH/AVAILSOLVER/SOLVER'>\n \
+ <xsl:sort select='@ID' data-type='number'/>\n \
+ <TH>\n \
+ <xsl:value-of select='TYPE' />\n \
+ <xsl:text></xsl:text>\n \
+ <xsl:value-of select='PACKAGE' />\n \
+ <xsl:text></xsl:text>\n \
+ </TH>\n \
+ </xsl:for-each>\n \
+ </TR>";
+
+ out<<" <xsl:for-each select='BENCH/LINEARSYSTEM'>\n \
+ <TR> <!-- print statistics for one linear system-->\n \
+ <TH rowspan='4'> <xsl:value-of select='MATRIX/NAME' /> </TH>\n \
+ <TD rowspan='4'> <xsl:value-of select='MATRIX/SIZE' /> </TD>\n \
+ <TD rowspan='4'> <xsl:value-of select='MATRIX/ENTRIES' /> </TD>\n \
+ <TD rowspan='4'> <xsl:value-of select='MATRIX/SYMMETRY' /> </TD>\n \
+ <TD rowspan='4'> <xsl:value-of select='MATRIX/POSDEF' /> </TD>\n \
+ <TH> Compute Time </TH>\n \
+ <xsl:for-each select='SOLVER_STAT'>\n \
+ <xsl:sort select='@ID' data-type='number'/>\n \
+ <TD> <xsl:value-of select='TIME/COMPUTE' /> </TD>\n \
+ </xsl:for-each>\n \
+ </TR>";
+ out<<" <TR>\n \
+ <TH> Solve Time </TH>\n \
+ <xsl:for-each select='SOLVER_STAT'>\n \
+ <xsl:sort select='@ID' data-type='number'/>\n \
+ <TD> <xsl:value-of select='TIME/SOLVE' /> </TD>\n \
+ </xsl:for-each>\n \
+ </TR>\n \
+ <TR>\n \
+ <TH> Total Time </TH>\n \
+ <xsl:for-each select='SOLVER_STAT'>\n \
+ <xsl:sort select='@ID' data-type='number'/>\n \
+ <xsl:choose>\n \
+ <xsl:when test='@ID=../BEST_SOLVER/@ID'>\n \
+ <TD style='background-color:red'> <xsl:value-of select='TIME/TOTAL' /> </TD>\n \
+ </xsl:when>\n \
+ <xsl:otherwise>\n \
+ <TD> <xsl:value-of select='TIME/TOTAL' /></TD>\n \
+ </xsl:otherwise>\n \
+ </xsl:choose>\n \
+ </xsl:for-each>\n \
+ </TR>";
+ out<<" <TR>\n \
+ <TH> Error </TH>\n \
+ <xsl:for-each select='SOLVER_STAT'>\n \
+ <xsl:sort select='@ID' data-type='number'/>\n \
+ <TD> <xsl:value-of select='ERROR' />\n \
+ <xsl:if test='ITER'>\n \
+ <xsl:text>(</xsl:text>\n \
+ <xsl:value-of select='ITER' />\n \
+ <xsl:text>)</xsl:text>\n \
+ </xsl:if> </TD>\n \
+ </xsl:for-each>\n \
+ </TR>\n \
+ </xsl:for-each>\n \
+ </table>\n \
+ </body>\n \
+ </html>\n \
+ </xsl:template>\n \
+ </xsl:stylesheet>\n\n";
+
+}
+#endif \ No newline at end of file
diff --git a/eigen/bench/spbench/test_sparseLU.cpp b/eigen/bench/spbench/test_sparseLU.cpp
new file mode 100644
index 0000000..f8ecbe6
--- /dev/null
+++ b/eigen/bench/spbench/test_sparseLU.cpp
@@ -0,0 +1,93 @@
+// Small bench routine for Eigen available in Eigen
+// (C) Desire NUENTSA WAKAM, INRIA
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <unsupported/Eigen/SparseExtra>
+#include <Eigen/SparseLU>
+#include <bench/BenchTimer.h>
+#ifdef EIGEN_METIS_SUPPORT
+#include <Eigen/MetisSupport>
+#endif
+
+using namespace std;
+using namespace Eigen;
+
+int main(int argc, char **args)
+{
+// typedef complex<double> scalar;
+ typedef double scalar;
+ SparseMatrix<scalar, ColMajor> A;
+ typedef SparseMatrix<scalar, ColMajor>::Index Index;
+ typedef Matrix<scalar, Dynamic, Dynamic> DenseMatrix;
+ typedef Matrix<scalar, Dynamic, 1> DenseRhs;
+ Matrix<scalar, Dynamic, 1> b, x, tmp;
+// SparseLU<SparseMatrix<scalar, ColMajor>, AMDOrdering<int> > solver;
+// #ifdef EIGEN_METIS_SUPPORT
+// SparseLU<SparseMatrix<scalar, ColMajor>, MetisOrdering<int> > solver;
+// std::cout<< "ORDERING : METIS\n";
+// #else
+ SparseLU<SparseMatrix<scalar, ColMajor>, COLAMDOrdering<int> > solver;
+ std::cout<< "ORDERING : COLAMD\n";
+// #endif
+
+ ifstream matrix_file;
+ string line;
+ int n;
+ BenchTimer timer;
+
+ // Set parameters
+ /* Fill the matrix with sparse matrix stored in Matrix-Market coordinate column-oriented format */
+ if (argc < 2) assert(false && "please, give the matrix market file ");
+ loadMarket(A, args[1]);
+ cout << "End charging matrix " << endl;
+ bool iscomplex=false, isvector=false;
+ int sym;
+ getMarketHeader(args[1], sym, iscomplex, isvector);
+// if (iscomplex) { cout<< " Not for complex matrices \n"; return -1; }
+ if (isvector) { cout << "The provided file is not a matrix file\n"; return -1;}
+ if (sym != 0) { // symmetric matrices, only the lower part is stored
+ SparseMatrix<scalar, ColMajor> temp;
+ temp = A;
+ A = temp.selfadjointView<Lower>();
+ }
+ n = A.cols();
+ /* Fill the right hand side */
+
+ if (argc > 2)
+ loadMarketVector(b, args[2]);
+ else
+ {
+ b.resize(n);
+ tmp.resize(n);
+// tmp.setRandom();
+ for (int i = 0; i < n; i++) tmp(i) = i;
+ b = A * tmp ;
+ }
+
+ /* Compute the factorization */
+// solver.isSymmetric(true);
+ timer.start();
+// solver.compute(A);
+ solver.analyzePattern(A);
+ timer.stop();
+ cout << "Time to analyze " << timer.value() << std::endl;
+ timer.reset();
+ timer.start();
+ solver.factorize(A);
+ timer.stop();
+ cout << "Factorize Time " << timer.value() << std::endl;
+ timer.reset();
+ timer.start();
+ x = solver.solve(b);
+ timer.stop();
+ cout << "solve time " << timer.value() << std::endl;
+ /* Check the accuracy */
+ Matrix<scalar, Dynamic, 1> tmp2 = b - A*x;
+ scalar tempNorm = tmp2.norm()/b.norm();
+ cout << "Relative norm of the computed solution : " << tempNorm <<"\n";
+ cout << "Number of nonzeros in the factor : " << solver.nnzL() + solver.nnzU() << std::endl;
+
+ return 0;
+} \ No newline at end of file
diff --git a/eigen/bench/spmv.cpp b/eigen/bench/spmv.cpp
new file mode 100644
index 0000000..959bab0
--- /dev/null
+++ b/eigen/bench/spmv.cpp
@@ -0,0 +1,233 @@
+
+//g++-4.4 -DNOMTL -Wl,-rpath /usr/local/lib/oski -L /usr/local/lib/oski/ -l oski -l oski_util -l oski_util_Tid -DOSKI -I ~/Coding/LinearAlgebra/mtl4/ spmv.cpp -I .. -O2 -DNDEBUG -lrt -lm -l oski_mat_CSC_Tid -loskilt && ./a.out r200000 c200000 n100 t1 p1
+
+#define SCALAR double
+
+#include <iostream>
+#include <algorithm>
+#include "BenchTimer.h"
+#include "BenchSparseUtil.h"
+
+#define SPMV_BENCH(CODE) BENCH(t,tries,repeats,CODE);
+
+// #ifdef MKL
+//
+// #include "mkl_types.h"
+// #include "mkl_spblas.h"
+//
+// template<typename Lhs,typename Rhs,typename Res>
+// void mkl_multiply(const Lhs& lhs, const Rhs& rhs, Res& res)
+// {
+// char n = 'N';
+// float alpha = 1;
+// char matdescra[6];
+// matdescra[0] = 'G';
+// matdescra[1] = 0;
+// matdescra[2] = 0;
+// matdescra[3] = 'C';
+// mkl_scscmm(&n, lhs.rows(), rhs.cols(), lhs.cols(), &alpha, matdescra,
+// lhs._valuePtr(), lhs._innerIndexPtr(), lhs.outerIndexPtr(),
+// pntre, b, &ldb, &beta, c, &ldc);
+// // mkl_somatcopy('C', 'T', lhs.rows(), lhs.cols(), 1,
+// // lhs._valuePtr(), lhs.rows(), DST, dst_stride);
+// }
+//
+// #endif
+
+int main(int argc, char *argv[])
+{
+ int size = 10000;
+ int rows = size;
+ int cols = size;
+ int nnzPerCol = 40;
+ int tries = 2;
+ int repeats = 2;
+
+ bool need_help = false;
+ for(int i = 1; i < argc; i++)
+ {
+ if(argv[i][0] == 'r')
+ {
+ rows = atoi(argv[i]+1);
+ }
+ else if(argv[i][0] == 'c')
+ {
+ cols = atoi(argv[i]+1);
+ }
+ else if(argv[i][0] == 'n')
+ {
+ nnzPerCol = atoi(argv[i]+1);
+ }
+ else if(argv[i][0] == 't')
+ {
+ tries = atoi(argv[i]+1);
+ }
+ else if(argv[i][0] == 'p')
+ {
+ repeats = atoi(argv[i]+1);
+ }
+ else
+ {
+ need_help = true;
+ }
+ }
+ if(need_help)
+ {
+ std::cout << argv[0] << " r<nb rows> c<nb columns> n<non zeros per column> t<nb tries> p<nb repeats>\n";
+ return 1;
+ }
+
+ std::cout << "SpMV " << rows << " x " << cols << " with " << nnzPerCol << " non zeros per column. (" << repeats << " repeats, and " << tries << " tries)\n\n";
+
+ EigenSparseMatrix sm(rows,cols);
+ DenseVector dv(cols), res(rows);
+ dv.setRandom();
+
+ BenchTimer t;
+ while (nnzPerCol>=4)
+ {
+ std::cout << "nnz: " << nnzPerCol << "\n";
+ sm.setZero();
+ fillMatrix2(nnzPerCol, rows, cols, sm);
+
+ // dense matrices
+ #ifdef DENSEMATRIX
+ {
+ DenseMatrix dm(rows,cols), (rows,cols);
+ eiToDense(sm, dm);
+
+ SPMV_BENCH(res = dm * sm);
+ std::cout << "Dense " << t.value()/repeats << "\t";
+
+ SPMV_BENCH(res = dm.transpose() * sm);
+ std::cout << t.value()/repeats << endl;
+ }
+ #endif
+
+ // eigen sparse matrices
+ {
+ SPMV_BENCH(res.noalias() += sm * dv; )
+ std::cout << "Eigen " << t.value()/repeats << "\t";
+
+ SPMV_BENCH(res.noalias() += sm.transpose() * dv; )
+ std::cout << t.value()/repeats << endl;
+ }
+
+ // CSparse
+ #ifdef CSPARSE
+ {
+ std::cout << "CSparse \n";
+ cs *csm;
+ eiToCSparse(sm, csm);
+
+// BENCH();
+// timer.stop();
+// std::cout << " a * b:\t" << timer.value() << endl;
+
+// BENCH( { m3 = cs_sorted_multiply2(m1, m2); cs_spfree(m3); } );
+// std::cout << " a * b:\t" << timer.value() << endl;
+ }
+ #endif
+
+ #ifdef OSKI
+ {
+ oski_matrix_t om;
+ oski_vecview_t ov, ores;
+ oski_Init();
+ om = oski_CreateMatCSC(sm._outerIndexPtr(), sm._innerIndexPtr(), sm._valuePtr(), rows, cols,
+ SHARE_INPUTMAT, 1, INDEX_ZERO_BASED);
+ ov = oski_CreateVecView(dv.data(), cols, STRIDE_UNIT);
+ ores = oski_CreateVecView(res.data(), rows, STRIDE_UNIT);
+
+ SPMV_BENCH( oski_MatMult(om, OP_NORMAL, 1, ov, 0, ores) );
+ std::cout << "OSKI " << t.value()/repeats << "\t";
+
+ SPMV_BENCH( oski_MatMult(om, OP_TRANS, 1, ov, 0, ores) );
+ std::cout << t.value()/repeats << "\n";
+
+ // tune
+ t.reset();
+ t.start();
+ oski_SetHintMatMult(om, OP_NORMAL, 1.0, SYMBOLIC_VEC, 0.0, SYMBOLIC_VEC, ALWAYS_TUNE_AGGRESSIVELY);
+ oski_TuneMat(om);
+ t.stop();
+ double tuning = t.value();
+
+ SPMV_BENCH( oski_MatMult(om, OP_NORMAL, 1, ov, 0, ores) );
+ std::cout << "OSKI tuned " << t.value()/repeats << "\t";
+
+ SPMV_BENCH( oski_MatMult(om, OP_TRANS, 1, ov, 0, ores) );
+ std::cout << t.value()/repeats << "\t(" << tuning << ")\n";
+
+
+ oski_DestroyMat(om);
+ oski_DestroyVecView(ov);
+ oski_DestroyVecView(ores);
+ oski_Close();
+ }
+ #endif
+
+ #ifndef NOUBLAS
+ {
+ using namespace boost::numeric;
+ UblasMatrix um(rows,cols);
+ eiToUblas(sm, um);
+
+ boost::numeric::ublas::vector<Scalar> uv(cols), ures(rows);
+ Map<Matrix<Scalar,Dynamic,1> >(&uv[0], cols) = dv;
+ Map<Matrix<Scalar,Dynamic,1> >(&ures[0], rows) = res;
+
+ SPMV_BENCH(ublas::axpy_prod(um, uv, ures, true));
+ std::cout << "ublas " << t.value()/repeats << "\t";
+
+ SPMV_BENCH(ublas::axpy_prod(boost::numeric::ublas::trans(um), uv, ures, true));
+ std::cout << t.value()/repeats << endl;
+ }
+ #endif
+
+ // GMM++
+ #ifndef NOGMM
+ {
+ GmmSparse gm(rows,cols);
+ eiToGmm(sm, gm);
+
+ std::vector<Scalar> gv(cols), gres(rows);
+ Map<Matrix<Scalar,Dynamic,1> >(&gv[0], cols) = dv;
+ Map<Matrix<Scalar,Dynamic,1> >(&gres[0], rows) = res;
+
+ SPMV_BENCH(gmm::mult(gm, gv, gres));
+ std::cout << "GMM++ " << t.value()/repeats << "\t";
+
+ SPMV_BENCH(gmm::mult(gmm::transposed(gm), gv, gres));
+ std::cout << t.value()/repeats << endl;
+ }
+ #endif
+
+ // MTL4
+ #ifndef NOMTL
+ {
+ MtlSparse mm(rows,cols);
+ eiToMtl(sm, mm);
+ mtl::dense_vector<Scalar> mv(cols, 1.0);
+ mtl::dense_vector<Scalar> mres(rows, 1.0);
+
+ SPMV_BENCH(mres = mm * mv);
+ std::cout << "MTL4 " << t.value()/repeats << "\t";
+
+ SPMV_BENCH(mres = trans(mm) * mv);
+ std::cout << t.value()/repeats << endl;
+ }
+ #endif
+
+ std::cout << "\n";
+
+ if(nnzPerCol==1)
+ break;
+ nnzPerCol -= nnzPerCol/2;
+ }
+
+ return 0;
+}
+
+
+
diff --git a/eigen/bench/vdw_new.cpp b/eigen/bench/vdw_new.cpp
new file mode 100644
index 0000000..d260404
--- /dev/null
+++ b/eigen/bench/vdw_new.cpp
@@ -0,0 +1,56 @@
+#include <iostream>
+#include <Eigen/Core>
+
+using namespace Eigen;
+
+#ifndef SCALAR
+#define SCALAR float
+#endif
+
+#ifndef SIZE
+#define SIZE 10000
+#endif
+
+#ifndef REPEAT
+#define REPEAT 10000
+#endif
+
+typedef Matrix<SCALAR, Eigen::Dynamic, 1> Vec;
+
+using namespace std;
+
+SCALAR E_VDW(const Vec &interactions1, const Vec &interactions2)
+{
+ return (interactions2.cwise()/interactions1)
+ .cwise().cube()
+ .cwise().square()
+ .cwise().square()
+ .sum();
+}
+
+int main()
+{
+ //
+ // 1 2 3 4 ... (interactions)
+ // ka . . . . ...
+ // rab . . . . ...
+ // energy . . . . ...
+ // ... ... ... ... ... ...
+ // (variables
+ // for
+ // interaction)
+ //
+ Vec interactions1(SIZE), interactions2(SIZE); // SIZE is the number of vdw interactions in our system
+ // SetupCalculations()
+ SCALAR rab = 1.0;
+ interactions1.setConstant(2.4);
+ interactions2.setConstant(rab);
+
+ // Energy()
+ SCALAR energy = 0.0;
+ for (unsigned int i = 0; i<REPEAT; ++i) {
+ energy += E_VDW(interactions1, interactions2);
+ energy *= 1 + 1e-20 * i; // prevent compiler from optimizing the loop
+ }
+ cout << "energy = " << energy << endl;
+}