1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013-2015 Kyle Lutz <kyle.r.lutz@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10
11 #include <iostream>
12 #include <vector>
13
14 #include <boost/program_options.hpp>
15
16 #include <boost/compute/container/vector.hpp>
17 #include <boost/compute/core.hpp>
18 #include <boost/compute/random.hpp>
19
20 #include "perf.hpp"
21
22 namespace compute = boost::compute;
23 namespace po = boost::program_options;
24
25 template<class Engine>
perf_random_number_engine(const size_t size,const size_t trials,compute::command_queue & queue)26 void perf_random_number_engine(const size_t size,
27 const size_t trials,
28 compute::command_queue& queue)
29 {
30 typedef typename Engine::result_type T;
31
32 // create random number engine
33 Engine engine(queue);
34
35 // create vector on the device
36 std::cout << "size = " << size << std::endl;
37 compute::vector<T> vector(size, queue.get_context());
38
39 // generate random numbers
40 perf_timer t;
41 for(size_t i = 0; i < trials; i++){
42 t.start();
43 engine.generate(vector.begin(), vector.end(), queue);
44 queue.finish();
45 t.stop();
46 }
47
48 // print result
49 std::cout << "time: " << t.min_time() / 1e6 << " ms" << std::endl;
50 std::cout << "rate: " << perf_rate<T>(size, t.min_time()) << " MB/s" << std::endl;
51 }
52
main(int argc,char * argv[])53 int main(int argc, char *argv[])
54 {
55 // setup and parse command line options
56 po::options_description options("options");
57 options.add_options()
58 ("help", "show usage instructions")
59 ("size", po::value<size_t>()->default_value(8192), "number of values")
60 ("trials", po::value<size_t>()->default_value(3), "number of trials")
61 ("engine", po::value<std::string>()->default_value("default_random_engine"), "random number engine")
62 ;
63 po::variables_map vm;
64 po::store(po::parse_command_line(argc, argv, options), vm);
65 po::notify(vm);
66
67 if(vm.count("help")) {
68 std::cout << options << std::endl;
69 return 0;
70 }
71
72 // setup context and queue for the default device
73 compute::device device = compute::system::default_device();
74 compute::context context(device);
75 compute::command_queue queue(context, device);
76
77 // get command line options
78 const size_t size = vm["size"].as<size_t>();
79 const size_t trials = vm["trials"].as<size_t>();
80 const std::string& engine = vm["engine"].as<std::string>();
81
82 // run benchmark
83 if(engine == "default_random_engine"){
84 perf_random_number_engine<compute::default_random_engine>(size, trials, queue);
85 }
86 else if(engine == "mersenne_twister_engine"){
87 perf_random_number_engine<compute::mt19937>(size, trials, queue);
88 }
89 else if(engine == "linear_congruential_engine"){
90 perf_random_number_engine<compute::linear_congruential_engine<> >(size, trials, queue);
91 }
92 else if(engine == "threefry_engine"){
93 perf_random_number_engine<compute::threefry_engine<> >(size, trials, queue);
94 }
95 else {
96 std::cerr << "error: unknown random number engine '" << engine << "'" << std::endl;
97 return -1;
98 }
99
100 return 0;
101 }
102