1 //
2 // Copyright (c) 2018 Stefan Seefeld
3 // All rights reserved.
4 //
5 // This file is part of Boost.uBLAS. It is made available under the
6 // Boost Software License, Version 1.0.
7 // (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt)
8
9 #define BOOST_UBLAS_ENABLE_OPENCL
10 #include <boost/numeric/ublas/opencl.hpp>
11 #include <boost/program_options.hpp>
12 #include "benchmark.hpp"
13 #include <complex>
14 #include <string>
15
16 namespace po = boost::program_options;
17 namespace ublas = boost::numeric::ublas;
18 namespace bm = boost::numeric::ublas::benchmark;
19 namespace opencl = boost::numeric::ublas::opencl;
20
21 namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl {
22
23 template <typename S, bool C> class prod;
24
25 template <typename M, bool C>
26 class prod<void(M,M,M), C> : public benchmark<void(M,M,M), C>
27 {
28 public:
prod(std::string const & name)29 prod(std::string const &name) : benchmark<void(M,M,M), C>(name) {}
operation(long l)30 virtual void operation(long l)
31 {
32 ublas::opencl::prod(*this->a, *this->b, *this->c, this->queue);
33 }
34 };
35
36 }}}}}
37
38 template <typename T>
benchmark(std::string const & type,bool copy)39 void benchmark(std::string const &type, bool copy)
40 {
41 using matrix = ublas::matrix<T>;
42 std::string name = "opencl::prod(matrix<" + type + ">)";
43 std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096});
44 if (copy)
45 {
46 bm::opencl::prod<void(matrix, matrix, matrix), true> p(name);
47 p.run(sizes);
48 }
49 else
50 {
51 bm::opencl::prod<void(matrix, matrix, matrix), false> p(name);
52 p.run(sizes);
53 }
54 }
55
main(int argc,char ** argv)56 int main(int argc, char **argv)
57 {
58 opencl::library lib;
59 po::variables_map vm;
60 try
61 {
62 po::options_description desc("Matrix product (OpenCL)\n"
63 "Allowed options");
64 desc.add_options()("help,h", "produce help message");
65 desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)");
66 desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing");
67
68 po::store(po::parse_command_line(argc, argv, desc), vm);
69 po::notify(vm);
70
71 if (vm.count("help"))
72 {
73 std::cout << desc << std::endl;
74 return 0;
75 }
76 }
77 catch(std::exception &e)
78 {
79 std::cerr << "error: " << e.what() << std::endl;
80 return 1;
81 }
82 std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float";
83 bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false;
84 if (type == "float")
85 benchmark<float>("float", copy);
86 else if (type == "double")
87 benchmark<double>("double", copy);
88 else if (type == "fcomplex")
89 benchmark<std::complex<float>>("std::complex<float>", copy);
90 else if (type == "dcomplex")
91 benchmark<std::complex<double>>("std::complex<double>", copy);
92 else
93 std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl;
94 }
95