diff options
Diffstat (limited to '')
24 files changed, 1820 insertions, 0 deletions
diff --git a/src/boost/libs/numeric/ublas/benchmarks/Jamfile b/src/boost/libs/numeric/ublas/benchmarks/Jamfile new file mode 100644 index 00000000..ab2f77e8 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/Jamfile @@ -0,0 +1,23 @@ +# +# Copyright (c) 2018 Stefan Seefeld +# Use, modification and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file +# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +project boost/ublas/benchmarks + : requirements <library>/boost/program_options//boost_program_options + ; + +exe add : add.cpp ; +exe mm_prod : mm_prod.cpp ; +exe mv_prod : mv_prod.cpp ; +exe inner_prod : inner_prod.cpp ; +exe outer_prod : outer_prod.cpp ; + +exe reference/add : reference/add.cpp ; +exe reference/mm_prod : reference/mm_prod.cpp ; +exe reference/mv_prod : reference/mv_prod.cpp ; +exe reference/inner_prod : reference/inner_prod.cpp ; +exe reference/outer_prod : reference/outer_prod.cpp ; + +build-project opencl ; diff --git a/src/boost/libs/numeric/ublas/benchmarks/add.cpp b/src/boost/libs/numeric/ublas/benchmarks/add.cpp new file mode 100644 index 00000000..0bab90bc --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/add.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "add.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + bm::add<vector(vector, vector)> a("add(vector<" + type + ">, vector<" + type + ">)"); + a.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Vector-vector addition\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/add.hpp b/src/boost/libs/numeric/ublas/benchmarks/add.hpp new file mode 100644 index 00000000..d5d03d09 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/add.hpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include "init.hpp" +#include "benchmark.hpp" + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class add; + +template <typename R, typename O1, typename O2> +class add<R(O1, O2)> : public benchmark +{ +public: + add(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = a + b; + } +private: + O1 a; + O2 b; + R c; +}; + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/benchmark.hpp b/src/boost/libs/numeric/ublas/benchmarks/benchmark.hpp new file mode 100644 index 00000000..b06cbe55 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/benchmark.hpp @@ -0,0 +1,52 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#include <iostream> +#include <chrono> +#include <ctime> +#include <cmath> +#include <string> +#include <vector> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +class benchmark +{ + using clock = std::chrono::system_clock; +public: + benchmark(std::string const &name) : name_(name) {} + void print_header() + { + std::cout << "# benchmark : " << name_ << '\n' + << "# size \ttime (ms)" << std::endl; + } + virtual void setup(long) {} + virtual void operation(long) {} + virtual void teardown() {} + + void run(std::vector<long> const &sizes, unsigned times = 10) + { + print_header(); + for (auto s : sizes) + { + setup(s); + auto start = clock::now(); + for (unsigned i = 0; i != times; ++i) + operation(s); + auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() - start); + teardown(); + std::cout << s << '\t' << duration.count()*1./times << std::endl; + } + } +private: + std::string name_; +}; + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/init.hpp b/src/boost/libs/numeric/ublas/benchmarks/init.hpp new file mode 100644 index 00000000..1528389c --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/init.hpp @@ -0,0 +1,37 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +void init(vector<T> &v, unsigned long size, int max_value) +{ + v = vector<T>(size); + for (unsigned long i = 0; i < v.size(); ++i) + v(i) = std::rand() % max_value; +} + +template <typename T, typename L> +void init(matrix<T, L> &m, unsigned long size1, unsigned long size2, int max_value) +{ + m = matrix<T, L>(size1, size2); + for (unsigned long i = 0; i < m.size1(); ++i) + for (unsigned long j = 0; j < m.size2(); ++j) + m(i, j) = std::rand() % max_value; +} + +template <typename T, typename L> +void init(matrix<T, L> &m, unsigned long size, int max_value) +{ + return init(m, size, size, max_value); +} + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/inner_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/inner_prod.cpp new file mode 100644 index 00000000..9d95a333 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/inner_prod.cpp @@ -0,0 +1,89 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "init.hpp" +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class inner_prod; + +template <typename R, typename V1, typename V2> +class inner_prod<R(V1, V2)> : public benchmark +{ +public: + inner_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = ublas::inner_prod(a, b); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + bm::inner_prod<T(vector, vector)> p("inner_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Inner product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/mm_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/mm_prod.cpp new file mode 100644 index 00000000..f87271c7 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/mm_prod.cpp @@ -0,0 +1,62 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "prod.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using matrix = ublas::matrix<T, ublas::basic_row_major<>>; + bm::prod<matrix(matrix, matrix)> p("prod(matrix<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512}));//, 1024})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/mv_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/mv_prod.cpp new file mode 100644 index 00000000..bc6da204 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/mv_prod.cpp @@ -0,0 +1,64 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "prod.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using matrix = ublas::matrix<T, ublas::basic_row_major<>>; + using vector = ublas::vector<T>; + bm::prod<vector(matrix, vector)> p("prod(matrix<" + type + ">, vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/Jamfile b/src/boost/libs/numeric/ublas/benchmarks/opencl/Jamfile new file mode 100644 index 00000000..670ec66b --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/Jamfile @@ -0,0 +1,27 @@ +# +# Copyright (c) 2018 Stefan Seefeld +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or +# copy at http://www.boost.org/LICENSE_1_0.txt) + +import ac ; + +# work around a bug in Boost.Build +import ../../opencl ; +import ../../clblas ; +using opencl ; +using clblas ; + +project boost/ublas/benchmarks/opencl + : requirements + <library>/boost/program_options//boost_program_options + <toolset>gcc:<cxxflags>-Wno-ignored-attributes + [ ac.check-library /clblas//clblas : <library>/clblas//clblas <library>/opencl//opencl : <build>no ] + ; + +exe add : add.cpp ; +exe mm_prod : mm_prod.cpp ; +exe mv_prod : mv_prod.cpp ; +exe inner_prod : inner_prod.cpp ; +exe outer_prod : outer_prod.cpp ; diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/add.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/add.cpp new file mode 100644 index 00000000..b998cd2c --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/add.cpp @@ -0,0 +1,93 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or +// copy at http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class add; + +template <typename V, bool C> +class add<void(V,V,V), C> : public benchmark<void(V,V,V), C> +{ +public: + add(std::string const &name) : benchmark<void(V,V,V), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::element_add(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + std::string name = "opencl::elementwise_add(vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::add<void(vector, vector, vector), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::add<void(vector, vector, vector), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product (OpenCL)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/benchmark.hpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/benchmark.hpp new file mode 100644 index 00000000..fb607599 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/benchmark.hpp @@ -0,0 +1,214 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or +// copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef opencl_benchmark_hpp_ +#define opencl_benchmark_hpp_ +#define BOOST_UBLAS_ENABLE_OPENCL + +#include <boost/numeric/ublas/opencl.hpp> +#include "../benchmark.hpp" +#include "init.hpp" +#include <memory> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { +namespace opencl { + +struct base +{ + base(compute::device d = compute::system::default_device()) + : context(d), + queue(context, d) + {} + compute::context context; + compute::command_queue queue; +}; + +template <typename T, bool C> struct data_factory; +template <typename T> +struct data_factory<T, true> +{ + typedef T type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long) { return ptr_type(new T());} +}; +template <typename T> +struct data_factory<T, false> +{ + typedef T type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long, compute::context) { return ptr_type(new T());} +}; +template <> +struct data_factory<void, true> +{ + typedef void type; + typedef void *ptr_type; + static ptr_type create(long) { return 0;} +}; +template <> +struct data_factory<void, false> +{ + typedef void type; + typedef void *ptr_type; + static ptr_type create(long, compute::context) { return 0;} +}; +template <typename T> +struct data_factory<ublas::vector<T>, true> +{ + typedef ublas::vector<T> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l) { return ptr_type(new type(l));} +}; +template <typename T> +struct data_factory<ublas::vector<T>, false> +{ + typedef ublas::vector<T, ublas::opencl::storage> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l, compute::context c) + { return ptr_type(new type(l, c));} +}; +template <typename T, typename L> +struct data_factory<ublas::matrix<T, L>, true> +{ + typedef ublas::matrix<T, L> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l) + { return ptr_type(new type(l, l));} +}; +template <typename T, typename L> +struct data_factory<ublas::matrix<T, L>, false> +{ + typedef ublas::matrix<T, L, ublas::opencl::storage> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l, compute::context c) + { return ptr_type(new type(l, l, c));} +}; + +template <typename S, bool> class benchmark; + +template <typename R, typename O> +class benchmark<R(O), true> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " with copy") + {} + virtual void setup(long l) + { + r = data_factory<R, true>::create(l); + a = data_factory<O, true>::create(l); + init(*a, l, 200); + } + typename data_factory<R, true>::ptr_type r; + typename data_factory<O, true>::ptr_type a; +}; + +template <typename R, typename O1, typename O2> +class benchmark<R(O1, O2), true> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " with copy") + {} + virtual void setup(long l) + { + r = data_factory<R, true>::create(l); + a = data_factory<O1, true>::create(l); + init(*a, l, 200); + b = data_factory<O2, true>::create(l); + init(*b, l, 200); + } + typename data_factory<R, true>::ptr_type r; + typename data_factory<O1, true>::ptr_type a; + typename data_factory<O2, true>::ptr_type b; +}; + +template <typename R, typename O1, typename O2, typename O3> +class benchmark<R(O1, O2, O3), true> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " with copy") + {} + virtual void setup(long l) + { + r = data_factory<R, true>::create(l); + a = data_factory<O1, true>::create(l); + init(*a, l, 200); + b = data_factory<O2, true>::create(l); + init(*b, l, 200); + c = data_factory<O3, true>::create(l); + init(*c, l, 200); + } + typename data_factory<R, true>::ptr_type r; + typename data_factory<O1, true>::ptr_type a; + typename data_factory<O2, true>::ptr_type b; + typename data_factory<O3, true>::ptr_type c; +}; + +template <typename R, typename O> +class benchmark<R(O), false> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " w/o copy") + {} + virtual void setup(long l) + { + r = data_factory<R, false>::create(l, context); + a = data_factory<O, false>::create(l, context); + init(*a, l, 200); + } + typename data_factory<R, false>::ptr_type r; + typename data_factory<O, false>::ptr_type a; +}; + +template <typename R, typename O1, typename O2> +class benchmark<R(O1, O2), false> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) : base(), ublas::benchmark::benchmark(name + " w/o copy") {} + virtual void setup(long l) + { + r = data_factory<R, false>::create(l, context); + a = data_factory<O1, false>::create(l, context); + init(*a, l, 200); + b = data_factory<O2, false>::create(l, context); + init(*b, l, 200); + } + typename data_factory<R, false>::ptr_type r; + typename data_factory<O1, false>::ptr_type a; + typename data_factory<O2, false>::ptr_type b; +}; + +template <typename R, typename O1, typename O2, typename O3> +class benchmark<R(O1, O2, O3), false> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) : base(), ublas::benchmark::benchmark(name + " w/o copy") {} + virtual void setup(long l) + { + r = data_factory<R, false>::create(l, context); + a = data_factory<O1, false>::create(l, context); + init(*a, l, 200); + b = data_factory<O2, false>::create(l, context); + init(*b, l, 200); + c = data_factory<O3, false>::create(l, context); + init(*c, l, 200); + } + typename data_factory<R, false>::ptr_type r; + typename data_factory<O1, false>::ptr_type a; + typename data_factory<O2, false>::ptr_type b; + typename data_factory<O3, false>::ptr_type c; +}; +}}}}} + +#endif diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/init.hpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/init.hpp new file mode 100644 index 00000000..a1141028 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/init.hpp @@ -0,0 +1,40 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#include <boost/numeric/ublas/opencl.hpp> +#include "../init.hpp" + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +void init(T &v, unsigned long size, int max_value) +{ + // TBD +} + +template <typename T> +void init(vector<T, opencl::storage> &v, unsigned long size, int max_value) +{ + // TBD +} + +template <typename T> +void init(matrix<T, opencl::storage> &m, unsigned long size1, unsigned long size2, int max_value) +{ + // TBD +} + +template <typename T> +void init(matrix<T, opencl::storage> &m, unsigned long size, int max_value) +{ + init(m, size, size, max_value); +} + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/inner_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/inner_prod.cpp new file mode 100644 index 00000000..a25664cb --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/inner_prod.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class inner_prod; + +template <typename R, typename V, bool C> +class inner_prod<R(V,V), C> : public benchmark<R(V,V), C> +{ +public: + inner_prod(std::string const &name) : benchmark<R(V,V), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::inner_prod(*this->a, *this->b, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + std::string name = "opencl::inner_prod(vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536}); + if (copy) + { + bm::opencl::inner_prod<T(vector,vector), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::inner_prod<T(vector,vector), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Inner product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + // else if (type == "fcomplex") + // benchmark<std::complex<float>>("std::complex<float>", copy); + // else if (type == "dcomplex") + // benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/mm_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/mm_prod.cpp new file mode 100644 index 00000000..e306031f --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/mm_prod.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class prod; + +template <typename M, bool C> +class prod<void(M,M,M), C> : public benchmark<void(M,M,M), C> +{ +public: + prod(std::string const &name) : benchmark<void(M,M,M), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::prod(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using matrix = ublas::matrix<T>; + std::string name = "opencl::prod(matrix<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::prod<void(matrix, matrix, matrix), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::prod<void(matrix, matrix, matrix), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Matrix product (OpenCL)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/mv_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/mv_prod.cpp new file mode 100644 index 00000000..70344a4b --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/mv_prod.cpp @@ -0,0 +1,95 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class prod; + +template <typename M, typename V, bool C> +class prod<void(M,V,V), C> : public benchmark<void(M,V,V), C> +{ +public: + prod(std::string const &name) : benchmark<void(M,V,V), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::prod(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + std::string name = "opencl::prod(matrix<" + type + ", vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::prod<void(matrix, vector, vector), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::prod<void(matrix, vector, vector), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product (OpenCL)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/outer_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/outer_prod.cpp new file mode 100644 index 00000000..b00bb840 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/outer_prod.cpp @@ -0,0 +1,95 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class outer_prod; + +template <typename V, typename M, bool C> +class outer_prod<void(V,V,M), C> : public benchmark<void(V,V,M), C> +{ +public: + outer_prod(std::string const &name) : benchmark<void(V,V,M), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::outer_prod(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + std::string name = "opencl::outer_prod(vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::outer_prod<void(vector, vector, matrix), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::outer_prod<void(vector, vector, matrix), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Outer product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/outer_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/outer_prod.cpp new file mode 100644 index 00000000..b907c360 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/outer_prod.cpp @@ -0,0 +1,90 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "init.hpp" +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class outer_prod; + +template <typename R, typename V1, typename V2> +class outer_prod<R(V1, V2)> : public benchmark +{ +public: + outer_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = ublas::outer_prod(a, b); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + bm::outer_prod<matrix(vector, vector)> p("outer_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Outer product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/plot.py b/src/boost/libs/numeric/ublas/benchmarks/plot.py new file mode 100755 index 00000000..1ca5e5a7 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/plot.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# Copyright (c) 2018 Stefan Seefeld +# All rights reserved. +# +# This file is part of Boost.uBLAS. It is made available under the +# Boost Software License, Version 1.0. +# (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +import argparse +import matplotlib.pyplot as plt +import numpy as np + + +class plot(object): + + def __init__(self, label, data): + self.label = label + self.data = data + + +def load_file(filename): + + lines = open(filename, 'r').readlines() + label = lines[0][1:-1].strip() + lines = [l.strip() for l in lines] + lines = [l.split('#', 1)[0] for l in lines] + lines = [l for l in lines if l] + data = [l.split() for l in lines] + return plot(label, list(zip(*data))) + + +def main(argv): + + parser = argparse.ArgumentParser(prog=argv[0], description='benchmark plotter') + parser.add_argument('data', nargs='+', help='benchmark data to plot') + parser.add_argument('--log', choices=['no', 'all', 'x', 'y'], help='use a logarithmic scale') + args = parser.parse_args(argv[1:]) + runs = [load_file(d) for d in args.data] + plt.title('Benchmark plot') + plt.xlabel('size') + plt.ylabel('time (s)') + if args.log == 'all': + plot = plt.loglog + elif args.log == 'x': + plot = plt.semilogx + elif args.log == 'y': + plot = plt.semilogy + else: + plot = plt.plot + plots = [plot(r.data[0], r.data[1], label=r.label) for r in runs] + plt.legend() + plt.show() + return True + + +if __name__ == '__main__': + + import sys + sys.exit(0 if main(sys.argv) else 1) diff --git a/src/boost/libs/numeric/ublas/benchmarks/prod.hpp b/src/boost/libs/numeric/ublas/benchmarks/prod.hpp new file mode 100644 index 00000000..243bafcb --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/prod.hpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include "init.hpp" +#include "benchmark.hpp" + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class prod; + +template <typename R, typename O1, typename O2> +class prod<R(O1, O2)> : public benchmark +{ +public: + prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = ublas::prod(a, b); + } +private: + O1 a; + O2 b; + R c; +}; + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/add.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/add.cpp new file mode 100644 index 00000000..d5b98870 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/add.cpp @@ -0,0 +1,88 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +class add : public benchmark +{ +public: + add(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + c(i) = a(i) + b(i); + } +private: + ublas::vector<T> a; + ublas::vector<T> b; + ublas::vector<T> c; +}; + +}}}} + +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + bm::add<T> p("ref::add(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Vector-vector addition (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/inner_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/inner_prod.cpp new file mode 100644 index 00000000..dc175257 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/inner_prod.cpp @@ -0,0 +1,91 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class inner_prod; + +template <typename R, typename V1, typename V2> +class inner_prod<R(V1, V2)> : public benchmark +{ +public: + inner_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = R(0); + for (int i = 0; i < l; ++i) + c += a(i) * b(i); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + bm::inner_prod<T(vector, vector)> p("ref::inner_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Inner product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/mm_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/mm_prod.cpp new file mode 100644 index 00000000..4b436316 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/mm_prod.cpp @@ -0,0 +1,93 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +class prod : public benchmark +{ +public: + prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + for (int j = 0; j < l; ++j) + { + c(i,j) = 0; + for (int k = 0; k < l; ++k) + c(i,j) += a(i,k) * b(k,j); + } + } +private: + ublas::matrix<T> a; + ublas::matrix<T> b; + ublas::matrix<T> c; +}; + +}}}} + +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + // using matrix = ublas::matrix<T, ublas::basic_row_major<>>; + bm::prod<T> p("ref::prod(matrix<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512}));//, 1024})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/mv_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/mv_prod.cpp new file mode 100644 index 00000000..e3a15745 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/mv_prod.cpp @@ -0,0 +1,92 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +class prod : public benchmark +{ +public: + prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + { + c(i) = 0; + for (int j = 0; j < l; ++j) + c(i) += a(i,j) * b(j); + } + } +private: + ublas::matrix<T> a; + ublas::vector<T> b; + ublas::vector<T> c; +}; + +}}}} + +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + bm::prod<T> p("ref::prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/outer_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/outer_prod.cpp new file mode 100644 index 00000000..a300066c --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/outer_prod.cpp @@ -0,0 +1,92 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class outer_prod; + +template <typename R, typename V1, typename V2> +class outer_prod<R(V1, V2)> : public benchmark +{ +public: + outer_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + for (int j = 0; j < l; ++j) + c(i,j) = - a(i) * b(j); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + bm::outer_prod<matrix(vector, vector)> p("ref::outer_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Outer product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} |