[opengtl-commits] [371] add a tool to benchmark openctl |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/opengtl-commits Archives
]
Revision: 371
Author: cyrille
Date: 2008-09-07 09:38:53 +0200 (Sun, 07 Sep 2008)
Log Message:
-----------
add a tool to benchmark openctl
Modified Paths:
--------------
trunk/OpenGTL/OpenCTL/tools/CMakeLists.txt
Added Paths:
-----------
trunk/OpenGTL/OpenCTL/tools/benchmark/
trunk/OpenGTL/OpenCTL/tools/benchmark/CMakeLists.txt
trunk/OpenGTL/OpenCTL/tools/benchmark/CtlBenchmark.cpp
Modified: trunk/OpenGTL/OpenCTL/tools/CMakeLists.txt
===================================================================
--- trunk/OpenGTL/OpenCTL/tools/CMakeLists.txt 2008-09-07 07:37:50 UTC (rev 370)
+++ trunk/OpenGTL/OpenCTL/tools/CMakeLists.txt 2008-09-07 07:38:53 UTC (rev 371)
@@ -1,2 +1,3 @@
add_subdirectory(compiler)
add_subdirectory(interpreter)
+add_subdirectory(benchmark)
Added: trunk/OpenGTL/OpenCTL/tools/benchmark/CMakeLists.txt
===================================================================
--- trunk/OpenGTL/OpenCTL/tools/benchmark/CMakeLists.txt (rev 0)
+++ trunk/OpenGTL/OpenCTL/tools/benchmark/CMakeLists.txt 2008-09-07 07:38:53 UTC (rev 371)
@@ -0,0 +1,8 @@
+include_directories( ${CMAKE_SOURCE_DIR} )
+
+set(ctlbenchmark_SRCS
+ CtlBenchmark.cpp
+ )
+
+add_executable(ctlbenchmark ${ctlbenchmark_SRCS})
+target_link_libraries(ctlbenchmark OpenCTL )
Added: trunk/OpenGTL/OpenCTL/tools/benchmark/CtlBenchmark.cpp
===================================================================
--- trunk/OpenGTL/OpenCTL/tools/benchmark/CtlBenchmark.cpp (rev 0)
+++ trunk/OpenGTL/OpenCTL/tools/benchmark/CtlBenchmark.cpp 2008-09-07 07:38:53 UTC (rev 371)
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2007-2008 Cyrille Berger <cberger@xxxxxxxxxxx>
+ *
+ * This library 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;
+ * version 2 of the License.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// C++ Headers
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <sys/time.h>
+#include <vector>
+
+#include <GTLCore/Array.h>
+#include <GTLCore/PixelDescription.h>
+#include <GTLCore/Type.h>
+
+// OpenCTL Headers
+#include <OpenCTL/Module.h>
+#include <OpenCTL/ModulesManager.h>
+#include <OpenCTL/Program.h>
+#include <OpenCTL/Version.h>
+
+class PointF {
+ public:
+ PointF(double x, double y) : m_x(x), m_y(y)
+ {
+ }
+ double x() const { return m_x; }
+ double y() const { return m_y; }
+ private:
+ double m_x, m_y;
+};
+
+float interpolateCubic1D (const std::vector<PointF>& table, double p)
+{
+ if( p <= table[0].x() ) return table[0].y();
+ if( p >= table[table.size()-1].x() ) return table[table.size()-1].y();
+
+ for( std::size_t i = 0; i < table.size() - 1; ++i )
+ {
+ if( table[i].x() <= p && p < table[i+1].x() )
+ {
+ double s = (p - table[i].x()) / (table[i+1].x() - table[i].x());
+ double dx1 = (table[i+1].x() - table[i].x());
+ double dy1 = (table[i+1].y() - table[i].y());
+
+ double m0;
+ double m1;
+ if( i > 0 )
+ {
+ double dy0 = (table[i].y() - table[i-1].y());
+ double dx0 = (table[i].x() - table[i-1].x());
+ m0 = (dy1 + dx1 * dy0 / dx0) / 2;
+ }
+ if( i < table.size()-2 )
+ {
+ double dx2 = (table[i+2].x() - table[i+1].x());
+ double dy2 = (table[i+2].y() - table[i+1].y());
+ m1 = (dy1 + dx1 * dy2 / dx2) / 2;
+ }
+ if( i == 0) {
+ m0 = (3 * dy1 - m1) / 2;
+ }
+ if( i == table.size()-2 )
+ {
+ m1 = (3 * dy1 - m0) / 2;
+ }
+ return table[i].y() * (2 * s*s*s - 3 * s*s + 1) +
+ m0 * (s*s*s - 2 * s*s + s) +
+ table[i+1].y() * (-2 * s*s*s + 3 * s*s) +
+ m1 * (s*s*s - s*s);
+ }
+ }
+ return 0.0;
+}
+
+void printVersion()
+{
+ std::cout << OpenCTL::LibraryShortName << " - " << OpenCTL::LibraryName << " - " << OpenCTL::LibraryVersionString << std::endl;
+ std::cout << OpenCTL::LibraryCopyright << std::endl;
+ std::cout << "CTL Version : " << OpenCTL::LanguageVersion << std::endl;
+}
+void printHelp()
+{
+ std::cout << "Usage : ctlbenchmark" << std::endl;
+ std::cout << std::endl;
+ std::cout << " -h --help print this message" << std::endl;
+ std::cout << " -v --version print the version information" << std::endl;
+}
+
+#define ARG_IS(a,b) argv[ai] == GTLCore::String(a) or argv[ai] == GTLCore::String(b)
+
+class Benchmark {
+ public:
+ Benchmark(int runCount, GTLCore::Array* array ) : m_array(array), m_runCount(runCount) {}
+ void start()
+ {
+ initialise();
+ m_totalTime = 0;
+ m_bestTime = 0x0FFFFFFF;
+ m_worseTime = 0;
+ timeval timeBefore, timeAfter;
+ for(int i = 0; i < m_runCount; ++i)
+ {
+ gettimeofday( &timeBefore, 0 );
+ run();
+ gettimeofday( &timeAfter, 0 );
+ int delta = timeAfter.tv_usec - timeBefore.tv_usec + 1000000 * (timeAfter.tv_sec - timeBefore.tv_sec);
+ if(delta > m_worseTime) m_worseTime = delta;
+ if(delta < m_bestTime) m_bestTime = delta;
+ m_totalTime += delta;
+ }
+ return;
+ }
+ int totalTime()
+ {
+ return m_totalTime;
+ }
+ int bestTime()
+ {
+ return m_bestTime;
+ }
+ int worseTime()
+ {
+ return m_worseTime;
+ }
+ int meanTime()
+ {
+ return m_totalTime / m_runCount;
+ }
+ void dump()
+ {
+ std::cout << "Total: " << totalTime() << " mean: " << meanTime() << " best: " << bestTime() << " worse: " << worseTime() << std::endl;
+ }
+ protected:
+ virtual void initialise() = 0;
+ virtual void run() = 0;
+ GTLCore::Array* array() { return m_array; }
+ private:
+ GTLCore::Array* m_array;
+ int m_runCount;
+ int m_totalTime;
+ int m_bestTime;
+ int m_worseTime;
+};
+
+class CtlBenchmark : public Benchmark {
+ protected:
+ CtlBenchmark(const std::vector< PointF >& _points, int runCount, GTLCore::Array* array ) : Benchmark(runCount, array ), points(_points), program(0) {}
+ GTLCore::String sourceCode() const;
+ void compile();
+ void apply();
+ private:
+ GTLCore::String valueListToCTL( const std::vector<PointF>& _points, double _scale ) const;
+ std::vector< PointF > points;
+ OpenCTL::Program* program;
+};
+
+void CtlBenchmark::compile()
+{
+ OpenCTL::Module p("");
+ p.setSource( sourceCode() );
+ p.compile();
+ if(not p.isCompiled())
+ {
+ std::cout << "Error: " << std::endl << p.compilationErrorsMessage() << std::endl;
+ abort();
+ }
+ program = new OpenCTL::Program( "apply", &p, GTLCore::PixelDescription( GTLCore::Type::Float, 4) );
+}
+
+void CtlBenchmark::apply()
+{
+ program->apply( *array(), *array() );
+}
+
+GTLCore::String CtlBenchmark::valueListToCTL( const std::vector<PointF>& _points, double _scale ) const
+{
+ GTLCore::String result = "{ {";
+ for(std::size_t i = 0; i < _points.size(); ++i)
+ {
+ PointF point = _points[i];
+ result += GTLCore::String::number(point.x() * _scale) + "," + GTLCore::String::number(point.y() * _scale) + "}";
+ if( i != _points.size() - 1)
+ {
+ result += ",{";
+ }
+ }
+ return result + " }";
+}
+
+GTLCore::String CtlBenchmark::sourceCode() const
+{
+ 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, rIn); \
+ gOut = interpolateCubic1D( lightTable, gIn); \
+ bOut = interpolateCubic1D( lightTable, bIn); \
+ aOut = aIn; \
+ }";
+ return program16Src;
+}
+
+class CompileEachTimeCtlBenchmark : public CtlBenchmark {
+ public:
+ CompileEachTimeCtlBenchmark(const std::vector< PointF >& points, int runCount, GTLCore::Array* array ) : CtlBenchmark(points, runCount, array ) {}
+ protected:
+ virtual void initialise()
+ {
+ }
+ virtual void run()
+ {
+ compile();
+ apply();
+ }
+};
+
+class CompileOnceCtlBenchmark : public CtlBenchmark {
+ public:
+ CompileOnceCtlBenchmark(const std::vector< PointF >& points, int runCount, GTLCore::Array* array ) : CtlBenchmark(points, runCount, array ) {}
+ protected:
+ virtual void initialise()
+ {
+ compile();
+ }
+ virtual void run()
+ {
+ apply();
+ }
+};
+
+int main(int argc, char** argv)
+{
+ GTLCore::String fileName = "";
+ for(int ai = 1; ai < argc; ai++)
+ {
+ if(ARG_IS("-h","--help"))
+ {
+ printHelp();
+ return EXIT_SUCCESS;
+ } else if(ARG_IS("-v","--version"))
+ {
+ printVersion();
+ return EXIT_SUCCESS;
+ } else {
+ if( ai != argc - 1)
+ {
+ std::cerr << "Invalid command line parameters." << std::endl;
+ } else {
+ fileName = argv[ai];
+ }
+ }
+ }
+ std::vector< PointF > points;
+ points.push_back( PointF( 0.0, 0.0) );
+ points.push_back( PointF( 0.3, 0.2) );
+ points.push_back( PointF( 0.5, 0.5) );
+ points.push_back( PointF( 0.6, 0.8) );
+ points.push_back( PointF( 1.0, 1.0) );
+
+ GTLCore::PixelDescription pd( GTLCore::Type::Float, 4);
+ GTLCore::Array array( 1000000 * pd.bitsSize() / 8 );
+
+ {
+ std::cout << "Compile once " << std::endl;
+ CompileOnceCtlBenchmark benchmark(points, 100, &array);
+ benchmark.start();
+ benchmark.dump();
+ }
+
+ {
+ std::cout << "Compile each time " << std::endl;
+ CompileEachTimeCtlBenchmark benchmark(points, 100, &array);
+ benchmark.start();
+ benchmark.dump();
+ }
+
+/* if( fileName == "")
+ {
+ printHelp();
+ } else {
+ GTLCore::String source;
+ std::ifstream in;
+ in.open(fileName.c_str() );
+ if(not in)
+ {
+ std::cerr << "Impossible to open file " << fileName << std::endl;
+ return EXIT_FAILURE;
+ }
+ GTLCore::String str;
+ std::getline(in,str);
+ while ( in ) {
+ source += str;
+ source += "\n";
+ std::getline(in,str);
+ }
+ OpenCTL::Module p(fileName);
+ p.setSource( source );
+ p.compile();
+ if(not p.isCompiled())
+ {
+ std::cout << "Error: " << std::endl << p.compilationErrorsMessage() << std::endl;
+ return EXIT_FAILURE;
+ }
+ if( showAssembly )
+ {
+ std::cout << p.asmSourceCode();
+ }
+ }*/
+ return EXIT_SUCCESS;
+}