OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WTHREADEDPERVOXELOPERATION_TEST_H 00026 #define WTHREADEDPERVOXELOPERATION_TEST_H 00027 00028 #include <vector> 00029 00030 #include <cxxtest/TestSuite.h> 00031 00032 #include "../../common/WThreadedFunction.h" 00033 #include "../../common/WLogger.h" 00034 #include "../WDataHandlerEnums.h" 00035 #include "../WDataSetSingle.h" 00036 #include "../WThreadedPerVoxelOperation.h" 00037 00038 /** 00039 * \class WThreadedPerVoxelOperationTest 00040 * 00041 * Test the WThreadedPerVoxelOperation template. 00042 */ 00043 class WThreadedPerVoxelOperationTest : public CxxTest::TestSuite 00044 { 00045 //! the test instance of the template 00046 typedef WThreadedPerVoxelOperation< int, 2, float, 3 > TPVO; 00047 00048 //! the type of valueset used in the test 00049 typedef TPVO::ValueSetType ValueSetType; 00050 00051 //! the input type of the test function 00052 typedef TPVO::TransmitType ArrayType; 00053 00054 //! the output type of the test function 00055 typedef TPVO::OutTransmitType OutArrayType; 00056 00057 public: 00058 /** 00059 * Setup logger and other stuff for each test. 00060 */ 00061 void setUp() 00062 { 00063 WLogger::startup(); 00064 } 00065 00066 /** 00067 * Test if everything gets instantiated correctly or if 00068 * incorrect values properly lead to exceptions. 00069 */ 00070 void testInstantiation() 00071 { 00072 boost::shared_ptr< WDataSetSingle > ds = buildTestData(); 00073 00074 TS_ASSERT_THROWS( TPVO t( boost::shared_ptr< WDataSetSingle >(), 00075 boost::bind( &WThreadedPerVoxelOperationTest::func, this, _1 ) ), WException ); 00076 TS_ASSERT_THROWS( TPVO t( ds, TPVO::FunctionType() ), WException ); 00077 TS_ASSERT_THROWS( TPVO t( boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( ds->getValueSet(), 00078 boost::shared_ptr< WGrid >() ) ), 00079 boost::bind( &WThreadedPerVoxelOperationTest::func, this, _1 ) ), WException ); 00080 TS_ASSERT_THROWS( TPVO t( boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( boost::shared_ptr< WValueSetBase >(), 00081 ds->getGrid() ) ), 00082 boost::bind( &WThreadedPerVoxelOperationTest::func, this, _1 ) ), WException ); 00083 00084 TS_ASSERT_THROWS_NOTHING( TPVO t( ds, boost::bind( &WThreadedPerVoxelOperationTest::func, this, _1 ) ) ); 00085 00086 TPVO t( ds, boost::bind( &WThreadedPerVoxelOperationTest::func, this, _1 ) ); 00087 00088 TS_ASSERT_EQUALS( ds->getGrid(), t.m_grid ); 00089 } 00090 00091 /** 00092 * Now test the whole class as a multithreaded function. 00093 */ 00094 void testMultithreadedFunction() 00095 { 00096 boost::shared_ptr< WDataSetSingle > ds = buildTestData(); 00097 boost::shared_ptr< TPVO > t( new TPVO( ds, boost::bind( &WThreadedPerVoxelOperationTest::func, this, _1 ) ) ); 00098 00099 m_exception = false; 00100 m_threadsDone = false; 00101 00102 WThreadedFunction< TPVO > f( 5, t ); 00103 f.getThreadsDoneCondition()->subscribeSignal( boost::bind( &WThreadedPerVoxelOperationTest::handleThreadsDone, this ) ); 00104 f.subscribeExceptionSignal( boost::bind( &WThreadedPerVoxelOperationTest::handleException, this, _1 ) ); 00105 00106 TS_ASSERT_THROWS_NOTHING( f.run() ); 00107 TS_ASSERT_THROWS_NOTHING( f.wait() ); 00108 TS_ASSERT( !m_exception ); 00109 TS_ASSERT( m_threadsDone ); 00110 00111 boost::shared_ptr< WDataSetSingle > res = t->getResult(); 00112 00113 float shouldBe[] = { 00114 2.0f, 2.0f, 5.0f, 00115 -5.0f, 4.0f, -7.0f, 00116 8.0f, 8.0f, 23.0f, 00117 -4.0f, 3.0f, -6.0f, 00118 -28.0f, 13.0f, -44.0f, 00119 3.0f, 4.0f, 9.0f, 00120 -4.0f, 5.0f, -4.0f, 00121 2.0f, -4.0f, -1.0f 00122 }; 00123 00124 TS_ASSERT( res ); 00125 TS_ASSERT( res->getValueSet() ); 00126 TS_ASSERT_EQUALS( res->getGrid(), ds->getGrid() ); 00127 TS_ASSERT_EQUALS( res->getValueSet()->dimension(), 3 ); 00128 TS_ASSERT_EQUALS( res->getValueSet()->order(), 1 ); 00129 TS_ASSERT_EQUALS( res->getValueSet()->size(), 8 ); 00130 00131 boost::shared_ptr< WValueSet< float > > vs = boost::dynamic_pointer_cast< WValueSet< float > >( res->getValueSet() ); 00132 00133 TS_ASSERT( vs ); 00134 TS_ASSERT( vs->rawData() ); 00135 TS_ASSERT_EQUALS( vs->rawDataVectorPointer()->size(), 24 ); 00136 TS_ASSERT_SAME_DATA( vs->rawData(), shouldBe, 8 * 3 * sizeof( float ) ); 00137 } 00138 00139 private: 00140 /** 00141 * The test operation. 00142 * 00143 * \param a The subarray of the input valueset that denotes the voxel's data. 00144 * \return The output data as an array. 00145 */ 00146 OutArrayType const func( ArrayType const& a ) const 00147 { 00148 OutArrayType o; 00149 o[ 0 ] = static_cast< float >( a[ 1 ] ); 00150 o[ 1 ] = static_cast< float >( a[ 0 ] + 1 ); 00151 o[ 2 ] = static_cast< float >( a[ 0 ] + 2 * a[ 1 ] ); 00152 return o; 00153 } 00154 00155 /** 00156 * Build a test dataset. 00157 * 00158 * \return The test dataset. 00159 */ 00160 boost::shared_ptr< WDataSetSingle > buildTestData() 00161 { 00162 int a[] = { 1, 2, 3, -5, 7, 8, 2, -4, 12, -28, 3, 3, 4, -4, -5, 2 }; 00163 boost::shared_ptr< std::vector< int > > v( new std::vector< int >( a, a + 16 ) ); 00164 dataType r = DataType< int >::type; 00165 boost::shared_ptr< ValueSetType > vs( new ValueSetType( 1, 2, v, r ) ); 00166 boost::shared_ptr< WGridRegular3D > g( new WGridRegular3D( 2, 2, 2 ) ); 00167 return boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( vs, g ) ); 00168 } 00169 00170 /** 00171 * Handle an exception. 00172 */ 00173 void handleException( WException const& ) 00174 { 00175 m_exception = true; 00176 } 00177 00178 //! a flag that is used to check if any exceptions were thrown 00179 bool m_exception; 00180 00181 /** 00182 * This function gets called when all threads are done. 00183 */ 00184 void handleThreadsDone() 00185 { 00186 m_threadsDone = true; 00187 } 00188 00189 //! a flag indicating if all threads are done 00190 bool m_threadsDone; 00191 }; 00192 00193 #endif // WTHREADEDPERVOXELOPERATION_TEST_H