diff options
Diffstat (limited to 'eigen/bench')
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_(¬rans,¬rans,&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_(¬rans,¬rans,&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_(¬rans,¬rans,&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_(¬rans,¬rans,&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)(¬rans,&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)(¬rans,¬rans,&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)(¬rans,¬rans,&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,¬rans,&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, ¬rans, &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, ¬rans, &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, ¬rans,&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; +} |