[opengtl-commits] [459] * compare arrays output in the benchmark

[ Thread Index | Date Index | More lists.tuxfamily.org/opengtl-commits Archives ]


Revision: 459
Author:   cyrille
Date:     2008-10-29 09:05:42 +0100 (Wed, 29 Oct 2008)

Log Message:
-----------
* compare arrays output in the benchmark
* fix native benchmark looping over a 1/8th of the pixels

Modified Paths:
--------------
    trunk/OpenGTL/OpenCTL/tools/benchmark/CtlBenchmark.cpp


Modified: trunk/OpenGTL/OpenCTL/tools/benchmark/CtlBenchmark.cpp
===================================================================
--- trunk/OpenGTL/OpenCTL/tools/benchmark/CtlBenchmark.cpp	2008-10-18 07:21:42 UTC (rev 458)
+++ trunk/OpenGTL/OpenCTL/tools/benchmark/CtlBenchmark.cpp	2008-10-29 08:05:42 UTC (rev 459)
@@ -21,6 +21,8 @@
 #include <iostream>
 #include <fstream>
 #include <cstdlib>
+#include <cmath>
+#include <cstring>
 #include <sys/time.h>
 #include <vector>
 
@@ -28,7 +30,10 @@
 #include <GTLCore/Optimiser.h>
 #include <GTLCore/PixelDescription.h>
 #include <GTLCore/Type.h>
+#include <GTLCore/Debug.h>
 
+#define COUMPONENT_NAME "ctlbenchmark"
+
 // OpenCTL Headers
 #include <OpenCTL/Module.h>
 #include <OpenCTL/ModulesManager.h>
@@ -118,10 +123,12 @@
       timeval timeBefore, timeAfter;
       for(int i = 0; i < m_runCount; ++i)
       {
+        preRun();
         gettimeofday( &timeBefore, 0 );
         run();
         gettimeofday( &timeAfter, 0 );
         int delta = timeAfter.tv_usec - timeBefore.tv_usec + 1000000 * (timeAfter.tv_sec - timeBefore.tv_sec);
+        postRun();
         if(delta > m_worseTime) m_worseTime = delta;
         if(delta < m_bestTime) m_bestTime = delta;
         m_totalTime += delta;
@@ -151,6 +158,8 @@
   protected:
     virtual void initialise() = 0;
     virtual void run() = 0;
+    virtual void preRun() = 0;
+    virtual void postRun() = 0;
   private:
     int m_runCount;
     int m_totalTime;
@@ -158,26 +167,67 @@
     int m_worseTime;
 };
 
+float randomNum( int n )
+{
+  return 0.5*(cos(pow(n, 4)) + 1);
+}
+
+void randomArray( GTLCore::Array* array )
+{
+  for( std::size_t i = 0; i < array->size() / sizeof(float); ++i)
+  {
+    array->data<float>()[ i ] = randomNum( i );
+  }
+}
+
+bool compareArrays( const GTLCore::Array* array1, const GTLCore::Array* array2 )
+{
+  GTL_ASSERT( array1 != array2 );
+  GTL_ASSERT( array1->size() == array2->size() );
+  if( memcmp( array1->rawData(), array2->rawData(), array2->size() ) != 0 )
+  {
+    for( unsigned int i = 0; i < array2->size() / sizeof(float); ++i )
+    {
+      if( fabs( array1->data<float>()[ i ] - array2->data<float>()[ i ] ) > 1e-6 )
+      {
+        GTL_DEBUG( i << " " << array1->data<float>()[ i ] << " " << array2->data<float>()[ i ] << " " << fabs( array1->data<float>()[ i ] - array2->data<float>()[ i ] ) );
+        return false;
+      }
+    }
+    return true;
+  } else {
+    return true;
+  }
+}
+
 class NativeBenchmark : public Benchmark {
   public:
-    NativeBenchmark( const std::vector< PointF >& _points, int runCount, GTLCore::Array* array ) : Benchmark( runCount), points(_points), m_array(array)
+    NativeBenchmark( const std::vector< PointF >& _points, int runCount, GTLCore::Array* array, const GTLCore::Array* refArray ) : Benchmark( runCount), points(_points), m_array(array), m_refArray( refArray )
     {
       
     }
   protected:
     virtual void initialise() {}
+    virtual void preRun();
+    virtual void postRun();
     virtual void run();
   private:
      std::vector< PointF > points;
     GTLCore::Array* m_array;
+    const GTLCore::Array* m_refArray;
 };
 
+void NativeBenchmark::preRun()
+{
+  randomArray( m_array );
+}
+
 void NativeBenchmark::run()
 {
   GTLCore::PixelDescription pd( GTLCore::Type::Float, 4);
-  float* arr = m_array->data<float>();
-  for( int i = 0; i < m_array->size(); i += pd.bitsSize())
+  for( int i = 0; i < m_array->size(); i += pd.bitsSize() / 8)
   {
+    float* arr = reinterpret_cast<float*>(m_array->rawData() + i);
     arr[0] = interpolateCubic1D( points, interpolateCubic1D( points, arr[0] ) );
     arr[1] = interpolateCubic1D( points, interpolateCubic1D( points, arr[1] ) );
     arr[2] = interpolateCubic1D( points, interpolateCubic1D( points, arr[2] ) );
@@ -185,26 +235,43 @@
   }
 }
 
+void NativeBenchmark::postRun()
+{
+    if(not compareArrays( m_array, m_refArray ) )
+    {
+      abort();
+    }
+}
+
 class CtlBenchmark : public Benchmark {
   protected:
-    CtlBenchmark(int _level, const std::vector< PointF >& _points, int runCount, GTLCore::Array* array ) : Benchmark(runCount ), points(_points), program(0), m_array(array) {}
-    GTLCore::String sourceCode() const;
+    CtlBenchmark(int _level, const std::vector< PointF >& _points, int runCount, GTLCore::Array* array, const GTLCore::Array* refArray ) : Benchmark(runCount ), points(_points), program(0), m_array(array), m_refArray( refArray ) {}
+    void preRun();
     void compile();
+    virtual void postRun();
     void apply();
     GTLCore::Array* array() { return m_array; }
+  public:
+    static GTLCore::String sourceCode( const std::vector<PointF>& _points);
+    static GTLCore::String valueListToCTL( const std::vector<PointF>& _points, double _scale );
   private:
-     GTLCore::String valueListToCTL( const std::vector<PointF>& _points, double _scale ) const;
      std::vector< PointF > points;
      OpenCTL::Program* program;
      int m_level;
-    GTLCore::Array* m_array;
+     GTLCore::Array* m_array;
+     const GTLCore::Array* m_refArray;
 };
 
+void CtlBenchmark::preRun()
+{
+  randomArray( m_array );
+}
+
 void CtlBenchmark::compile()
 {
   GTLCore::Optimiser::instance()->setLevel( m_level );
   OpenCTL::Module p("");
-  p.setSource( sourceCode() );
+  p.setSource( sourceCode(points) );
   p.compile();
   if(not p.isCompiled())
   {
@@ -214,12 +281,20 @@
   program = new OpenCTL::Program( "apply", &p, GTLCore::PixelDescription( GTLCore::Type::Float, 4) );
 }
 
+void CtlBenchmark::postRun()
+{
+    if(not compareArrays( m_array, m_refArray ) )
+    {
+      abort();
+    }
+}
+
 void CtlBenchmark::apply()
 {
   program->apply( *array(), *array() );
 }
 
-GTLCore::String CtlBenchmark::valueListToCTL( const std::vector<PointF>& _points, double _scale ) const
+GTLCore::String CtlBenchmark::valueListToCTL( const std::vector<PointF>& _points, double _scale )
 {
   GTLCore::String result = "{ {";
   for(std::size_t i = 0; i < _points.size(); ++i)
@@ -234,9 +309,9 @@
   return result + " }";
 }
 
-GTLCore::String CtlBenchmark::sourceCode() const
+GTLCore::String CtlBenchmark::sourceCode(const std::vector<PointF>& _points)
 {
-  GTLCore::String program16Src = "const float lightTable[][2] = " + valueListToCTL( points, 1.0 ) + ";";
+  GTLCore::String program16Src = "const float lightTable[][2] = " + valueListToCTL( _points, 1.0 ) + ";";
   program16Src += "void apply( float rIn, float gIn, float bIn, float aIn, output float rOut, output float gOut, output float bOut, output float aOut) \
   { \
       rOut = interpolateCubic1D( lightTable, interpolateCubic1D( lightTable, rIn) ); \
@@ -249,7 +324,7 @@
 
 class CompileEachTimeCtlBenchmark : public CtlBenchmark {
   public:
-    CompileEachTimeCtlBenchmark(int _level, const std::vector< PointF >& points, int runCount, GTLCore::Array* array ) : CtlBenchmark(_level, points, runCount, array ) {}
+    CompileEachTimeCtlBenchmark(int _level, const std::vector< PointF >& points, int runCount, GTLCore::Array* array, const GTLCore::Array* refArray  ) : CtlBenchmark(_level, points, runCount, array, refArray ) {}
   protected:
     virtual void initialise()
     {
@@ -263,7 +338,7 @@
 
 class CompileOnceCtlBenchmark : public CtlBenchmark {
   public:
-    CompileOnceCtlBenchmark(int _level, const std::vector< PointF >& points, int runCount, GTLCore::Array* array ) : CtlBenchmark(_level, points, runCount, array ) {}
+    CompileOnceCtlBenchmark(int _level, const std::vector< PointF >& points, int runCount, GTLCore::Array* array, const GTLCore::Array* refArray  ) : CtlBenchmark(_level, points, runCount, array, refArray ) {}
   protected:
     virtual void initialise()
     {
@@ -275,6 +350,21 @@
     }
 };
 
+void computeRefArray( GTLCore::Array& _array, const std::vector< PointF >& points )
+{
+  OpenCTL::Module p("");
+  p.setSource( CtlBenchmark::sourceCode(points) );
+  p.compile();
+  if(not p.isCompiled())
+  {
+    std::cout << "Error: " << std::endl << p.compilationErrorsMessage() << std::endl;
+    abort();
+  }
+  OpenCTL::Program program( "apply", &p, GTLCore::PixelDescription( GTLCore::Type::Float, 4) );
+  randomArray( &_array );
+  program.apply( _array, _array );
+}
+
 int main(int argc, char** argv)
 {
   GTLCore::String fileName = "";
@@ -305,11 +395,18 @@
   points.push_back( PointF( 1.0, 1.0) );
   
   GTLCore::PixelDescription pd( GTLCore::Type::Float, 4);
-  GTLCore::Array array( 1000000 * pd.bitsSize() / 8 );
   
+  int runs = 100;
+  int arraySize = 1000000;
+  
+  GTLCore::Array array( arraySize * pd.bitsSize() / 8 );
+  GTLCore::Array refArray( arraySize * pd.bitsSize() / 8 );
+  
+  computeRefArray( refArray, points );
+  
   {
     std::cout << "Native" << std::endl;
-    NativeBenchmark benchmark( points, 100, &array );
+    NativeBenchmark benchmark( points, runs, &array, &refArray );
     benchmark.start();
     benchmark.dump();
   }
@@ -317,7 +414,7 @@
   for(int level = 0; level <= GTLCore::Optimiser::maximumRecommendedLevel(); ++level)
   {
     std::cout << "Compile once = " << level << std::endl;
-    CompileOnceCtlBenchmark benchmark(level, points, 100, &array);
+    CompileOnceCtlBenchmark benchmark(level, points, runs, &array, &refArray);
     benchmark.start();
     benchmark.dump();
   }
@@ -325,7 +422,7 @@
   for(int level = 0; level <= GTLCore::Optimiser::maximumRecommendedLevel(); ++level)
   {
     std::cout << "Compile each time for level = " << level << std::endl;
-    CompileEachTimeCtlBenchmark benchmark(level, points, 100, &array);
+    CompileEachTimeCtlBenchmark benchmark(level, points, runs, &array, &refArray);
     benchmark.start();
     benchmark.dump();
   }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/