From 99dfd5757996cd78e8b00a8b6d9b705eb176418d Mon Sep 17 00:00:00 2001 From: Karsten Ahnert Date: Mon, 25 Jun 2012 14:12:47 +0200 Subject: [PATCH] add vexcl example and section in the tutorial --- doc/index.html | 4 +- libs/numeric/odeint/doc/odeint.qbk | 7 +- libs/numeric/odeint/doc/tutorial.qbk | 2 + .../odeint/doc/tutorial_vexcl_opencl.qbk | 34 ++++++++ libs/numeric/odeint/examples/vexcl/Jamfile | 23 ++++++ .../odeint/examples/vexcl/lorenz_ensemble.cpp | 82 +++++++++++++++++++ 6 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 libs/numeric/odeint/doc/tutorial_vexcl_opencl.qbk create mode 100644 libs/numeric/odeint/examples/vexcl/Jamfile create mode 100644 libs/numeric/odeint/examples/vexcl/lorenz_ensemble.cpp diff --git a/doc/index.html b/doc/index.html index a07a30fc..f3205b58 100644 --- a/doc/index.html +++ b/doc/index.html @@ -51,6 +51,8 @@ topics
Using Cuda and Thrust
+
Using + OpenCL and VexCL
All examples
References
@@ -92,7 +94,7 @@ - +

Last revised: June 23, 2012 at 11:15:35 GMT

Last revised: June 25, 2012 at 12:11:49 GMT


diff --git a/libs/numeric/odeint/doc/odeint.qbk b/libs/numeric/odeint/doc/odeint.qbk index c851e015..c75a4c3c 100644 --- a/libs/numeric/odeint/doc/odeint.qbk +++ b/libs/numeric/odeint/doc/odeint.qbk @@ -31,17 +31,18 @@ [@http://www.boost.org/doc/libs/release/libs/fusion/index.html Boost.Fusion]] [def __boost_graph [@http://www.boost.org/doc/libs/1_47_0/libs/graph/doc/table_of_contents.html Boost.Graph]] + [def __thrust [@http://code.google.com/p/thrust/ Thrust]] [def __ublas [@http://www.boost.org/doc/libs/release/libs/numeric/ublas/index.html Boost.UBlas]] - [def __intel_mkl [@http://software.intel.com/en-us/articles/intel-mkl/ Intel Math Kernel Library]] - [def __gsl [@http://www.gsl.org GSL]] - +[def __vexcl + [@https://github.com/ddemidov/vexcl VexCL]] + [def __concepts [link boost_numeric_odeint.concepts Concepts]] [def __system diff --git a/libs/numeric/odeint/doc/tutorial.qbk b/libs/numeric/odeint/doc/tutorial.qbk index 9a992b38..de47c401 100644 --- a/libs/numeric/odeint/doc/tutorial.qbk +++ b/libs/numeric/odeint/doc/tutorial.qbk @@ -12,6 +12,8 @@ [include tutorial_thrust_cuda.qbk] +[include tutorial_vexcl_opencl.qbk] + [section All examples] diff --git a/libs/numeric/odeint/doc/tutorial_vexcl_opencl.qbk b/libs/numeric/odeint/doc/tutorial_vexcl_opencl.qbk new file mode 100644 index 00000000..ef0a3042 --- /dev/null +++ b/libs/numeric/odeint/doc/tutorial_vexcl_opencl.qbk @@ -0,0 +1,34 @@ +[section Using OpenCL and VexCL] + +[import ../examples/vexcl/lorenz_ensemble.cpp] + +In the previous section the usage of odeint in combination with __thrust was shown. In this section we show how one can use OpenCL with odeint. The point of odeint is not to implement its own low-level data structures and algorithms, but to use high level libraries doing this task. Here, we will use the __vexcl framework to use OpenCL. __vexcl is a nice library for general computations and it uses heavily expression templates. With the help of __vexcl it is possible to write very compact and expressive application. + +[note vexcl needs C++11 features! So you have to compile with C++11 support enabled.] + +To use __vexcl one needs to include one additional header which includes the data-types and algorithms from vexcl and the adaption to odeint. Adaption to odeint means here only to adapt the resizing functionality of __vexcl to odeint. + +[vexcl_includes] + +To demonstrate the use of __vexcl we integrate an ensemble of Lorenz system. The example is very similar to the parameter study of the Lorenz system in the previous section except that we do not compute the Lyapunov exponents. Again, we vary the parameter R of the Lorenz system an solve a whole ensemble of Lorenz systems in parallel (each with a different parameter R). First, we define the state type and a vector type + +[vexcl_state_types ] + +The `vector_type` is used to represent the parameter R. The `state_type` is a multi-vector of three sub vectors and is used to represent. The first component of this multi-vector represent all `x` components of the Lorenz system, while the second all `y` components and the third all `z` components. The components of this vector can be obtained via + +`` +auto &x = X(0); +auto &y = X(1); +auto &z = X(2); +`` + +As already mentioned __vexcl supports expression templates and we will use them to implement the system function for the Lorenz ensemble: + +[vexcl_system] + +It's very easy, isn't it? These three little lines do all the computations for you. There is no need to write your own OpenCL kernels. __vexcl does everything for you. Next we have to write the main application. This is also very easy. We initialize the vector of parameters (R) and the initial state. Since __vexcl supports odeint we can already use the `vector_space_algebra` in combination with the `default_operations` for the stepper and we are done: + +[vexcl_main] + + +[endsect] diff --git a/libs/numeric/odeint/examples/vexcl/Jamfile b/libs/numeric/odeint/examples/vexcl/Jamfile new file mode 100644 index 00000000..0b49846d --- /dev/null +++ b/libs/numeric/odeint/examples/vexcl/Jamfile @@ -0,0 +1,23 @@ +import boost ; +import os ; + +boost.use-project ; + + +# change these lines to fit you configuration +local HOME = [ os.environ HOME ] ; +VEXCL_INCLUDE = $(HOME)/boost/vexcl ; +CUDA_INCLUDE = /usr/local/cuda/include ; + + +lib opencl : : OpenCL ; + +project : requirements + /boost//headers + ../../../../.. + $(VEXCL_INCLUDE) + $(CUDA_INCLUDE) + gcc:-std=c++0x + ; + +exe lorenz_ensemble : lorenz_ensemble.cpp opencl ; \ No newline at end of file diff --git a/libs/numeric/odeint/examples/vexcl/lorenz_ensemble.cpp b/libs/numeric/odeint/examples/vexcl/lorenz_ensemble.cpp new file mode 100644 index 00000000..1ef506ea --- /dev/null +++ b/libs/numeric/odeint/examples/vexcl/lorenz_ensemble.cpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include + +#include + +#include +//[ vexcl_includes +#include +//] + +namespace odeint = boost::numeric::odeint; + +//[ vexcl_state_types +typedef vex::vector< double > vector_type; +typedef vex::multivector< double, 3 > state_type; +//] + + +//[ vexcl_system +const double sigma = 10.0; +const double b = 8.0 / 3.0; + +struct sys_func +{ + const vector_type &R; + + sys_func( const vector_type &_R ) : R( _R ) { } + + void operator()( const state_type &x , state_type &dxdt , double t ) const + { + dxdt(0) = -sigma * ( x(0) - x(1) ); + dxdt(1) = R * x(0) - x(1) - x(0) * x(2); + dxdt(2) = - b * x(2) + x(0) * x(1); + } +}; +//] + + +int main( int argc , char **argv ) +{ + using namespace std; + using namespace odeint; + + //[ vexcl_main + // setup the opencl context + vex::Context ctx( vex::Filter::Type(CL_DEVICE_TYPE_GPU) ); + std::cout << ctx << std::endl; + + // set up number of system, time step and integration time + const size_t n = 1024 * 1024; + const double dt = 0.01; + const double t_max = 100.0; + + // initialize R + double Rmin = 0.1 , Rmax = 50.0 , dR = ( Rmax - Rmin ) / double( n - 1 ); + std::vector x( n * 3 ) , r( n ); + for( size_t i=0 ; i stepper; + + // solve the system + integrate_const( stepper , sys_func( R ) , X , 0.0 , t_max , dt ); + //] + + std::vector< double > res( 3 * n ); + vex::copy( X(0) , res ); + for( size_t i=0 ; i