• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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