1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Various sanity tests with exceptions: 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// - no memory leak when a custom scalar type trow an exceptions 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// - todo: complete the list of tests! 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_STACK_ALLOCATION_LIMIT 100000000 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "main.h" 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct my_exception 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath my_exception() {} 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ~my_exception() {} 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass ScalarWithExceptions 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions() { init(); } 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions(const float& _v) { init(); *v = _v; } 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions(const ScalarWithExceptions& other) { init(); *v = *(other.v); } 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ~ScalarWithExceptions() { 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath delete v; 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath instances--; 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void init() { 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v = new float; 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath instances++; 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions operator+(const ScalarWithExceptions& other) const 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath countdown--; 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(countdown<=0) 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath throw my_exception(); 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return ScalarWithExceptions(*v+*other.v); 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions operator-(const ScalarWithExceptions& other) const 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { return ScalarWithExceptions(*v-*other.v); } 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions operator*(const ScalarWithExceptions& other) const 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { return ScalarWithExceptions((*v)*(*other.v)); } 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions& operator+=(const ScalarWithExceptions& other) 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { *v+=*other.v; return *this; } 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions& operator-=(const ScalarWithExceptions& other) 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { *v-=*other.v; return *this; } 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions& operator=(const ScalarWithExceptions& other) 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { *v = *(other.v); return *this; } 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool operator==(const ScalarWithExceptions& other) const 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { return *v==*other.v; } 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool operator!=(const ScalarWithExceptions& other) const 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { return *v!=*other.v; } 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath float* v; 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static int instances; 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static int countdown; 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezScalarWithExceptions real(const ScalarWithExceptions &x) { return x; } 737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezScalarWithExceptions imag(const ScalarWithExceptions & ) { return 0; } 747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezScalarWithExceptions conj(const ScalarWithExceptions &x) { return x; } 757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint ScalarWithExceptions::instances = 0; 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint ScalarWithExceptions::countdown = 0; 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define CHECK_MEMLEAK(OP) { \ 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarWithExceptions::countdown = 100; \ 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int before = ScalarWithExceptions::instances; \ 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool exception_thrown = false; \ 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath try { OP; } \ 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath catch (my_exception) { \ 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath exception_thrown = true; \ 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY(ScalarWithExceptions::instances==before && "memory leak detected in " && EIGEN_MAKESTRING(OP)); \ 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } \ 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY(exception_thrown && " no exception thrown in " && EIGEN_MAKESTRING(OP)); \ 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid memoryleak() 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,1> VectorType; 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,Dynamic> MatrixType; 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int n = 50; 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VectorType v0(n), v1(n); 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixType m0(n,n), m1(n,n), m2(n,n); 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v0.setOnes(); v1.setOnes(); 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m0.setOnes(); m1.setOnes(); m2.setOnes(); 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CHECK_MEMLEAK(v0 = m0 * m1 * v1); 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CHECK_MEMLEAK(m2 = m0 * m1 * m2); 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CHECK_MEMLEAK((v0+v1).dot(v0+v1)); 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY(ScalarWithExceptions::instances==0 && "global memory leak detected in " && EIGEN_MAKESTRING(OP)); \ 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid test_exceptions() 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST( memoryleak() ); 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 114