diff options
-rw-r--r-- | Eigen/QtAlignedMalloc | 29 | ||||
-rw-r--r-- | Mainpage.dox | 2 | ||||
-rw-r--r-- | bench/sparse_dense_product.cpp | 54 | ||||
-rw-r--r-- | bench/sparse_product.cpp | 38 | ||||
-rw-r--r-- | test/CMakeLists.txt | 12 | ||||
-rw-r--r-- | test/qtvector.cpp | 170 | ||||
-rw-r--r-- | test/stdvector.cpp | 2 |
7 files changed, 265 insertions, 42 deletions
diff --git a/Eigen/QtAlignedMalloc b/Eigen/QtAlignedMalloc new file mode 100644 index 000000000..38a108381 --- /dev/null +++ b/Eigen/QtAlignedMalloc @@ -0,0 +1,29 @@ + +#ifndef EIGEN_QTMALLOC_MODULE_H +#define EIGEN_QTMALLOC_MODULE_H + +#include "Core" + +#if (!EIGEN_MALLOC_ALREADY_ALIGNED) + +void *qMalloc(size_t size) +{ + return Eigen::ei_aligned_malloc(size); +} + +void qFree(void *ptr) +{ + Eigen::ei_aligned_free(ptr); +} + +void *qRealloc(void *ptr, size_t size) +{ + void* newPtr = Eigen::ei_aligned_malloc(size); + memcpy(newPtr, ptr, size); + Eigen::ei_aligned_free(ptr); + return newPtr; +} + +#endif + +#endif // EIGEN_QTMALLOC_MODULE_H diff --git a/Mainpage.dox b/Mainpage.dox index 00ea4c96b..c7135b0a5 100644 --- a/Mainpage.dox +++ b/Mainpage.dox @@ -4,7 +4,7 @@ // to api.kde.org's scripts // DOXYGEN_SET_PROJECT_NAME = Eigen2 -// DOXYGEN_SET_PROJECT_NUMBER = "2.0-beta6" +// DOXYGEN_SET_PROJECT_NUMBER = "2.0 - trunk" // DOXYGEN_SET_CREATE_SUBDIRS = NO // DOXYGEN_SET_BRIEF_MEMBER_DESC = YES diff --git a/bench/sparse_dense_product.cpp b/bench/sparse_dense_product.cpp index 3caf8598a..9b9af8819 100644 --- a/bench/sparse_dense_product.cpp +++ b/bench/sparse_dense_product.cpp @@ -91,51 +91,25 @@ int main(int argc, char *argv[]) { std::cout << "Eigen sparse\t" << sm1.nonZeros()/float(sm1.rows()*sm1.cols())*100 << "%\n"; -// timer.reset(); -// timer.start(); BENCH(for (int k=0; k<REPEAT; ++k) v2 = sm1 * v1;) -// timer.stop(); std::cout << " a * v:\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) v2 = sm1.transpose() * v1;) -// timer.stop(); + + BENCH(for (int k=0; k<REPEAT; ++k) { asm("#mya"); v2 = sm1.transpose() * v1; asm("#myb"); }) + std::cout << " a' * v:\t" << timer.value() << endl; } - - // CSparse - #ifdef CSPARSE - { - std::cout << "CSparse \t" << density*100 << "%\n"; - cs *m1, *m2, *m3; - eiToCSparse(sm1, m1); - eiToCSparse(sm2, m2); - - timer.reset(); - timer.start(); - for (int k=0; k<REPEAT; ++k) - { - m3 = cs_sorted_multiply(m1, m2); - if (!m3) - { - std::cerr << "cs_multiply failed\n"; -// break; - } -// cs_print(m3, 0); - cs_spfree(m3); - } - timer.stop(); - std::cout << " a * b:\t" << timer.value() << endl; - } - #endif + +// { +// 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 diff --git a/bench/sparse_product.cpp b/bench/sparse_product.cpp index dfb4b4335..61eb213e6 100644 --- a/bench/sparse_product.cpp +++ b/bench/sparse_product.cpp @@ -137,6 +137,44 @@ int main(int argc, char *argv[]) // timer.stop(); 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()*m1.cols())*100 << "% * " + << m2.nonZeros()/float(m2.rows()*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 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 021799f5e..44c0ead20 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -64,6 +64,15 @@ else(GOOGLEHASH_FOUND) set(EIGEN_MISSING_BACKENDS ${EIGEN_MISSING_BACKENDS} GoogleHash) endif(GOOGLEHASH_FOUND) +find_package(Qt4) +if(QT4_FOUND) + add_definitions("-DEIGEN_GOOGLEHASH_SUPPORT") + include(${QT_USE_FILE}) + set(EIGEN_TESTED_BACKENDS ${EIGEN_TESTED_BACKENDS} "Qt4 support") +else(QT4_FOUND) + set(EIGEN_MISSING_BACKENDS ${EIGEN_MISSING_BACKENDS} "Qt4 support") +endif(QT4_FOUND) + if(CMAKE_COMPILER_IS_GNUCXX) if(CMAKE_SYSTEM_NAME MATCHES Linux) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g2") @@ -195,6 +204,9 @@ ei_add_test(parametrizedline) ei_add_test(alignedbox) ei_add_test(regression) ei_add_test(stdvector) +if(QT4_FOUND) + ei_add_test(qtvector " " ${QT_QTCORE_LIBRARY}) +endif(QT4_FOUND) ei_add_test(sparse_vector) ei_add_test(sparse_basic) ei_add_test(sparse_solvers " " "${SPARSE_LIBS}") diff --git a/test/qtvector.cpp b/test/qtvector.cpp new file mode 100644 index 000000000..cc938885a --- /dev/null +++ b/test/qtvector.cpp @@ -0,0 +1,170 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, 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. +// +// Eigen 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 Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see <http://www.gnu.org/licenses/>. + +#define EIGEN_WORK_AROUND_QT_BUG_CALLING_WRONG_OPERATOR_NEW_FIXED_IN_QT_4_5 + +#include "main.h" +#include <QtCore/QVector> +#include <Eigen/Geometry> +#include <Eigen/QtAlignedMalloc> + +template<typename MatrixType> +void check_qtvector_matrix(const MatrixType& m) +{ + int rows = m.rows(); + int cols = m.cols(); + MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols); + QVector<MatrixType> v(10, MatrixType(rows,cols)), w(20, y); + v[5] = x; + w[6] = v[5]; + VERIFY_IS_APPROX(w[6], v[5]); + v = w; + for(int i = 0; i < 20; i++) + { + VERIFY_IS_APPROX(w[i], v[i]); + } + + v.resize(21); + v[20].set(x); + VERIFY_IS_APPROX(v[20], x); + v.fill(y,22); + //v.resize(22); + VERIFY_IS_APPROX(v[21], y); + v.push_back(x); + VERIFY_IS_APPROX(v[22], x); + VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType)); + + // do a lot of push_back such that the vector gets internally resized + // (with memory reallocation) + MatrixType* ref = &w[0]; + for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i) + v.push_back(w[i%w.size()]); + for(int i=23; i<v.size(); ++i) + { + VERIFY(v[i]==w[(i-23)%w.size()]); + } +} + +template<typename TransformType> +void check_qtvector_transform(const TransformType&) +{ + typedef typename TransformType::MatrixType MatrixType; + TransformType x(MatrixType::Random()), y(MatrixType::Random()); + QVector<TransformType> v(10), w(20, y); + v[5] = x; + w[6] = v[5]; + VERIFY_IS_APPROX(w[6], v[5]); + v = w; + for(int i = 0; i < 20; i++) + { + VERIFY_IS_APPROX(w[i], v[i]); + } + + v.resize(21); + v[20] = x; + VERIFY_IS_APPROX(v[20], x); + v.fill(y,22); + //v.resize(22); + VERIFY_IS_APPROX(v[21], y); + v.push_back(x); + VERIFY_IS_APPROX(v[22], x); + VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType)); + + // do a lot of push_back such that the vector gets internally resized + // (with memory reallocation) + TransformType* ref = &w[0]; + for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i) + v.push_back(w[i%w.size()]); + for(unsigned int i=23; i<v.size(); ++i) + { + VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix()); + } +} + +template<typename QuaternionType> +void check_qtvector_quaternion(const QuaternionType&) +{ + typedef typename QuaternionType::Coefficients Coefficients; + QuaternionType x(Coefficients::Random()), y(Coefficients::Random()); + QVector<QuaternionType> v(10), w(20, y); + v[5] = x; + w[6] = v[5]; + VERIFY_IS_APPROX(w[6], v[5]); + v = w; + for(int i = 0; i < 20; i++) + { + VERIFY_IS_APPROX(w[i], v[i]); + } + + v.resize(21); + v[20] = x; + VERIFY_IS_APPROX(v[20], x); + v.fill(y,22); + //v.resize(22); + VERIFY_IS_APPROX(v[21], y); + v.push_back(x); + VERIFY_IS_APPROX(v[22], x); + VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType)); + + // do a lot of push_back such that the vector gets internally resized + // (with memory reallocation) + QuaternionType* ref = &w[0]; + for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i) + v.push_back(w[i%w.size()]); + for(unsigned int i=23; i<v.size(); ++i) + { + VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs()); + } +} + +void test_qtvector() +{ + // some non vectorizable fixed sizes + CALL_SUBTEST(check_qtvector_matrix(Vector2f())); + CALL_SUBTEST(check_qtvector_matrix(Matrix3f())); + CALL_SUBTEST(check_qtvector_matrix(Matrix3d())); + + // some vectorizable fixed sizes + CALL_SUBTEST(check_qtvector_matrix(Matrix2f())); + CALL_SUBTEST(check_qtvector_matrix(Vector4f())); + CALL_SUBTEST(check_qtvector_matrix(Matrix4f())); + CALL_SUBTEST(check_qtvector_matrix(Matrix4d())); + + // some dynamic sizes + CALL_SUBTEST(check_qtvector_matrix(MatrixXd(1,1))); + CALL_SUBTEST(check_qtvector_matrix(VectorXd(20))); + CALL_SUBTEST(check_qtvector_matrix(RowVectorXf(20))); + CALL_SUBTEST(check_qtvector_matrix(MatrixXcf(10,10))); + + // some Transform + CALL_SUBTEST(check_qtvector_transform(Transform2f())); + CALL_SUBTEST(check_qtvector_transform(Transform3f())); + CALL_SUBTEST(check_qtvector_transform(Transform3d())); + //CALL_SUBTEST(check_qtvector_transform(Transform4d())); + + // some Quaternion + CALL_SUBTEST(check_qtvector_quaternion(Quaternionf())); + CALL_SUBTEST(check_qtvector_quaternion(Quaternionf())); +} diff --git a/test/stdvector.cpp b/test/stdvector.cpp index ac7a2967e..be9fc275b 100644 --- a/test/stdvector.cpp +++ b/test/stdvector.cpp @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. Eigen itself is part of the KDE project. // -// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public |