// Boost.uBLAS // // Copyright (c) 2018 Fady Essam // 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 boost_numeric_ublas_opencl_elementwise_hpp_ #define boost_numeric_ublas_opencl_elementwise_hpp_ #include #include #include namespace boost { namespace numeric { namespace ublas { namespace opencl { namespace compute = boost::compute; namespace lambda = boost::compute::lambda; template void element_wise(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, O op, compute::command_queue& queue) { assert(a.device() == b.device() && a.device() == result.device() && a.device() == queue.get_device()); assert(a.size1() == b.size1() && a.size2() == b.size2()); compute::transform(a.begin(), a.end(), b.begin(), result.begin(), op, queue); queue.finish(); } template void element_wise(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, O op, compute::command_queue &queue) { ublas::matrix adev(a, queue); ublas::matrix bdev(b, queue); ublas::matrix rdev(a.size1(), b.size2(), queue.get_context()); element_wise(adev, bdev, rdev, op, queue); rdev.to_host(result, queue); } template ublas::matrix element_wise(ublas::matrix const &a, ublas::matrix const &b, O op, compute::command_queue &queue) { ublas::matrix result(a.size1(), b.size2()); element_wise(a, b, result, op, queue); return result; } template void element_wise(ublas::vector const &a, ublas::vector const &b, ublas::vector &result, O op, compute::command_queue& queue) { assert(a.device() == b.device() && a.device() == result.device() && a.device() == queue.get_device()); assert(a.size() == b.size()); compute::transform(a.begin(), a.end(), b.begin(), result.begin(), op, queue); queue.finish(); } template void element_wise(ublas::vector const &a, ublas::vector const &b, ublas::vector& result, O op, compute::command_queue &queue) { ublas::vector adev(a, queue); ublas::vector bdev(b, queue); ublas::vector rdev(a.size(), queue.get_context()); element_wise(adev, bdev, rdev, op, queue); rdev.to_host(result, queue); } template ublas::vector element_wise(ublas::vector const &a, ublas::vector const &b, O op, compute::command_queue &queue) { ublas::vector result(a.size()); element_wise(a, b, result, op, queue); return result; } template void element_add(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, compute::command_queue &queue) { element_wise(a, b, result, compute::plus(), queue); } template void element_add(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, compute::command_queue &queue) { element_wise(a, b, result, compute::plus(), queue); } template ublas::matrix element_add(ublas::matrix const &a, ublas::matrix const &b, compute::command_queue &queue) { return element_wise(a, b, compute::plus(), queue); } template void element_add(ublas::vector const &a, ublas::vector const &b, ublas::vector &result, compute::command_queue& queue) { element_wise(a, b, result, compute::plus(), queue); } template void element_add(ublas::vector const &a, ublas::vector const &b, ublas::vector &result, compute::command_queue &queue) { element_wise(a, b, result, compute::plus(), queue); } template ublas::vector element_add(ublas::vector const &a, ublas::vector const &b, compute::command_queue &queue) { return element_wise(a, b, compute::plus(), queue); } template void element_add(ublas::matrix const &m, T value, ublas::matrix &result, compute::command_queue& queue) { assert(m.device() == result.device() && m.device() == queue.get_device()); assert(m.size1() == result.size1() && m.size2() == result.size2()); compute::transform(m.begin(), m.end(), result.begin(), lambda::_1 + value, queue); queue.finish(); } template void element_add(ublas::matrix const &m, T value, ublas::matrix &result, compute::command_queue& queue) { ublas::matrix mdev(m, queue); ublas::matrix rdev(result.size1(), result.size2(), queue.get_context()); element_add(mdev, value, rdev, queue); rdev.to_host(result, queue); } template ublas::matrix element_add(ublas::matrix const &m, T value, compute::command_queue& queue) { ublas::matrix result(m.size1(), m.size2()); element_add(m, value, result, queue); return result; } template void element_add(ublas::vector const &v, T value, ublas::vector &result, compute::command_queue& queue) { assert(v.device() == result.device() && v.device() == queue.get_device()); assert(v.size() == result.size()); compute::transform(v.begin(), v.end(), result.begin(), lambda::_1 + value, queue); queue.finish(); } template void element_add(ublas::vector const &v, T value, ublas::vector &result, compute::command_queue& queue) { ublas::vector vdev(v, queue); ublas::vector rdev(v.size(), queue.get_context()); element_add(vdev, value, rdev, queue); rdev.to_host(result, queue); } template ublas::vector element_add(ublas::vector const &v, T value, compute::command_queue& queue) { ublas::vector result(v.size()); element_add(v, value, result, queue); return result; } template void element_sub(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, compute::command_queue& queue) { element_wise(a, b, compute::minus(), result, queue); } template void element_sub(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, compute::command_queue &queue) { element_wise(a, b, result, compute::minus(), queue); } template ublas::matrix element_sub(ublas::matrix const &a, ublas::matrix const &b, compute::command_queue &queue) { return element_wise(a, b, compute::minus(), queue); } template void element_sub(ublas::vector const &a, ublas::vector const &b, ublas::vector &result, compute::command_queue& queue) { element_wise(a, b, result, compute::minus(), queue); } template void element_sub(ublas::vector const &a, ublas::vector const &b, ublas::vector &result, compute::command_queue &queue) { element_wise(a, b, result, compute::minus(), queue); } template ublas::vector element_sub(ublas::vector const &a, ublas::vector const &b, compute::command_queue &queue) { return element_wise(a, b, compute::minus(), queue); } template void element_sub(ublas::matrix const &m, T value, ublas::matrix &result, compute::command_queue& queue) { assert(m.device() == result.device() && m.device() == queue.get_device()); assert(m.size1() == result.size1() && m.size2() == result.size2()); compute::transform(m.begin(), m.end(), result.begin(), lambda::_1 - value, queue); queue.finish(); } template void element_sub(ublas::matrix const &m, T value, ublas::matrix &result, compute::command_queue& queue) { ublas::matrix mdev(m, queue); ublas::matrix rdev(result.size1(), result.size2(), queue.get_context()); element_sub(mdev, value, rdev, queue); rdev.to_host(result, queue); } template ublas::matrix element_sub(ublas::matrix const &m, T value, compute::command_queue& queue) { ublas::matrix result(m.size1(), m.size2()); element_sub(m, value, result, queue); return result; } template void element_sub(ublas::vector const &v, T value, ublas::vector &result, compute::command_queue& queue) { assert(v.device() == result.device() && v.device() == queue.get_device()); assert(v.size() == result.size()); compute::transform(v.begin(), v.end(), result.begin(), lambda::_1 - value, queue); queue.finish(); } template void element_sub(ublas::vector const &v, T value, ublas::vector &result, compute::command_queue& queue) { ublas::vector vdev(v, queue); ublas::vector rdev(v.size(), queue.get_context()); element_sub(vdev, value, rdev, queue); rdev.to_host(result, queue); } template ublas::vector element_sub(ublas::vector const &v, T value, compute::command_queue& queue) { ublas::vector result(v.size()); element_sub(v, value, result, queue); return result; } template void element_prod(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, compute::command_queue& queue) { element_wise(a, b, result, compute::multiplies(), queue); } template void element_prod(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, compute::command_queue &queue) { element_wise(a, b, result, compute::multiplies(), queue); } template ublas::matrix element_prod(ublas::matrix const &a, ublas::matrix const &b, compute::command_queue &queue) { return element_wise(a, b, compute::multiplies(), queue); } template void element_prod(ublas::vector const &a, ublas::vector const &b, ublas::vector &result, compute::command_queue& queue) { element_wise(a, b, result, compute::multiplies(), queue); } template void element_prod(ublas::vector const &a, ublas::vector const &b, ublas::vector &result, compute::command_queue &queue) { element_wise(a, b, result, compute::multiplies(), queue); } template ublas::vector element_prod(ublas::vector const &a, ublas::vector const &b, compute::command_queue &queue) { return element_wise(a, b, compute::multiplies(), queue); } template void element_scale(ublas::matrix const &m, T value, ublas::matrix &result, compute::command_queue& queue) { assert(m.device() == result.device() && m.device() == queue.get_device()); assert(m.size1() == result.size1() && m.size2() == result.size2()); compute::transform(m.begin(), m.end(), result.begin(), lambda::_1 * value, queue); queue.finish(); } template void element_scale(ublas::matrix const &m, T value, ublas::matrix &result, compute::command_queue& queue) { ublas::matrix mdev(m, queue); ublas::matrix rdev(result.size1(), result.size2(), queue.get_context()); element_scale(mdev, value, rdev, queue); rdev.to_host(result, queue); } template ublas::matrix element_scale(ublas::matrix const &m, T value, compute::command_queue& queue) { ublas::matrix result(m.size1(), m.size2()); element_scale(m, value, result, queue); return result; } template void element_scale(ublas::vector const &v, T value, ublas::vector &result, compute::command_queue& queue) { assert(v.device() == result.device() && v.device() == queue.get_device()); assert(v.size() == result.size()); compute::transform(v.begin(), v.end(), result.begin(), lambda::_1 * value, queue); queue.finish(); } template void element_scale(ublas::vector const &v, T value, ublas::vector & result, compute::command_queue& queue) { ublas::vector vdev(v, queue); ublas::vector rdev(v.size(), queue.get_context()); element_scale(vdev, value, rdev, queue); rdev.to_host(result, queue); } template ublas::vector element_scale(ublas::vector const &v, T value, compute::command_queue& queue) { ublas::vector result(v.size()); element_scale(v, value, result, queue); return result; } template void element_div(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, compute::command_queue& queue) { element_wise(a, b, result, compute::divides(), queue); } template void element_div(ublas::matrix const &a, ublas::matrix const &b, ublas::matrix &result, compute::command_queue &queue) { element_wise(a, b, result, compute::divides(), queue); } template ublas::matrix element_div(ublas::matrix const &a, ublas::matrix const &b, compute::command_queue &queue) { return element_wise(a, b, compute::divides(), queue); } template void element_div(ublas::vector const &a, ublas::vector const &b, ublas::vector &result, compute::command_queue& queue) { element_wise(a, b, result, compute::divides(), queue); } template void element_div(ublas::vector const &a, ublas::vector const &b, ublas::vector &result, compute::command_queue &queue) { element_wise(a, b, result, compute::divides(), queue); } template ublas::vector element_div(ublas::vector const &a, ublas::vector const &b, compute::command_queue &queue) { return element_wise(a, b, compute::divides(), queue); } }}}} #endif