All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
scalar_operations.hpp
Go to the documentation of this file.
#ifndef VIENNACL_LINALG_OPENCL_SCALAR_OPERATIONS_HPP_
#define VIENNACL_LINALG_OPENCL_SCALAR_OPERATIONS_HPP_
/* =========================================================================
Copyright (c) 2010-2016, Institute for Microelectronics,
Institute for Analysis and Scientific Computing,
TU Wien.
Portions of this software are copyright by UChicago Argonne, LLC.
-----------------
ViennaCL - The Vienna Computing Library
-----------------
Project Head: Karl Rupp rupp@iue.tuwien.ac.at
(A list of authors and contributors can be found in the manual)
License: MIT (X11), see file LICENSE in the base directory
============================================================================= */
#include "viennacl/forwards.h"
#include "viennacl/ocl/device.hpp"
#include "viennacl/ocl/handle.hpp"
#include "viennacl/ocl/kernel.hpp"
#include "viennacl/tools/tools.hpp"
#include "viennacl/linalg/opencl/kernels/scalar.hpp"
#include "viennacl/linalg/opencl/common.hpp"
#include "viennacl/meta/predicate.hpp"
#include "viennacl/meta/result_of.hpp"
#include "viennacl/meta/enable_if.hpp"
#include "viennacl/traits/size.hpp"
#include "viennacl/traits/start.hpp"
#include "viennacl/traits/handle.hpp"
#include "viennacl/traits/stride.hpp"
#include "viennacl/traits/handle.hpp"
namespace viennacl
{
namespace linalg
{
namespace opencl
{
template<typename ScalarT1,
typename ScalarT2, typename NumericT>
typename viennacl::enable_if< viennacl::is_scalar<ScalarT1>::value
&& viennacl::is_scalar<ScalarT2>::value
&& viennacl::is_any_scalar<NumericT>::value
>::type
as(ScalarT1 & s1,
ScalarT2 const & s2, NumericT const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha)
{
assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!"));
typedef typename viennacl::result_of::cpu_value_type<ScalarT1>::type value_type;
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context());
viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx);
cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha);
bool is_cpu = viennacl::is_cpu_scalar<NumericT>::value;
viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), is_cpu ? "as_cpu" : "as_gpu");
k.local_work_size(0, 1);
k.global_work_size(0, 1);
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(alpha)),
options_alpha,
viennacl::traits::opencl_handle(s2) )
);
}
template<typename ScalarT1,
typename ScalarT2, typename NumericT2,
typename ScalarT3, typename NumericT3>
typename viennacl::enable_if< viennacl::is_scalar<ScalarT1>::value
&& viennacl::is_scalar<ScalarT2>::value
&& viennacl::is_scalar<ScalarT3>::value
&& viennacl::is_any_scalar<NumericT2>::value
&& viennacl::is_any_scalar<NumericT3>::value
>::type
asbs(ScalarT1 & s1,
ScalarT2 const & s2, NumericT2 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha,
ScalarT3 const & s3, NumericT3 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
{
assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!"));
assert( &viennacl::traits::opencl_handle(s2).context() == &viennacl::traits::opencl_handle(s3).context() && bool("Operands not in the same OpenCL context!"));
typedef typename viennacl::result_of::cpu_value_type<ScalarT1>::type value_type;
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context());
viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx);
std::string kernel_name;
bool is_cpu_2 = viennacl::is_cpu_scalar<NumericT2>::value;
bool is_cpu_3 = viennacl::is_cpu_scalar<NumericT3>::value;
if (is_cpu_2 && is_cpu_3)
kernel_name = "asbs_cpu_cpu";
else if (is_cpu_2 && !is_cpu_3)
kernel_name = "asbs_cpu_gpu";
else if (!is_cpu_2 && is_cpu_3)
kernel_name = "asbs_gpu_cpu";
else
kernel_name = "asbs_gpu_gpu";
cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha);
cl_uint options_beta = detail::make_options(len_beta, reciprocal_beta, flip_sign_beta);
viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), kernel_name);
k.local_work_size(0, 1);
k.global_work_size(0, 1);
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(alpha)),
options_alpha,
viennacl::traits::opencl_handle(s2),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(beta)),
options_beta,
viennacl::traits::opencl_handle(s3) )
);
}
template<typename ScalarT1,
typename ScalarT2, typename NumericT2,
typename ScalarT3, typename NumericT3>
typename viennacl::enable_if< viennacl::is_scalar<ScalarT1>::value
&& viennacl::is_scalar<ScalarT2>::value
&& viennacl::is_scalar<ScalarT3>::value
&& viennacl::is_any_scalar<NumericT2>::value
&& viennacl::is_any_scalar<NumericT3>::value
>::type
asbs_s(ScalarT1 & s1,
ScalarT2 const & s2, NumericT2 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha,
ScalarT3 const & s3, NumericT3 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
{
assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!"));
assert( &viennacl::traits::opencl_handle(s2).context() == &viennacl::traits::opencl_handle(s3).context() && bool("Operands not in the same OpenCL context!"));
typedef typename viennacl::result_of::cpu_value_type<ScalarT1>::type value_type;
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context());
viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx);
std::string kernel_name;
if (viennacl::is_cpu_scalar<NumericT2>::value && viennacl::is_cpu_scalar<NumericT3>::value)
kernel_name = "asbs_s_cpu_cpu";
else if (viennacl::is_cpu_scalar<NumericT2>::value && !viennacl::is_cpu_scalar<NumericT3>::value)
kernel_name = "asbs_s_cpu_gpu";
else if (!viennacl::is_cpu_scalar<NumericT2>::value && viennacl::is_cpu_scalar<NumericT3>::value)
kernel_name = "asbs_s_gpu_cpu";
else
kernel_name = "asbs_s_gpu_gpu";
cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha);
cl_uint options_beta = detail::make_options(len_beta, reciprocal_beta, flip_sign_beta);
viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), kernel_name);
k.local_work_size(0, 1);
k.global_work_size(0, 1);
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(alpha)),
options_alpha,
viennacl::traits::opencl_handle(s2),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(beta)),
options_beta,
viennacl::traits::opencl_handle(s3) )
);
}
template<typename ScalarT1, typename ScalarT2>
typename viennacl::enable_if< viennacl::is_scalar<ScalarT1>::value
&& viennacl::is_scalar<ScalarT2>::value
>::type
swap(ScalarT1 & s1, ScalarT2 & s2)
{
assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!"));
typedef typename viennacl::result_of::cpu_value_type<ScalarT1>::type value_type;
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context());
viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx);
viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), "swap");
k.local_work_size(0, 1);
k.global_work_size(0, 1);
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1),
viennacl::traits::opencl_handle(s2))
);
}
} //namespace opencl
} //namespace linalg
} //namespace viennacl
#endif
viennacl::enable_if
Simple enable-if variant that uses the SFINAE pattern.
Definition: enable_if.hpp:30
device.hpp
Represents an OpenCL device within ViennaCL.
scalar.hpp
OpenCL kernel file for scalar operations.
size.hpp
Generic size and resize functionality for different vector and matrix types.
viennacl::linalg::opencl::swap
viennacl::enable_if< viennacl::is_scalar< ScalarT1 >::value &&viennacl::is_scalar< ScalarT2 >::value >::type swap(ScalarT1 &s1, ScalarT2 &s2)
Swaps the contents of two scalars, data is copied.
Definition: scalar_operations.hpp:182
viennacl::ocl::kernel
Represents an OpenCL kernel within ViennaCL.
Definition: kernel.hpp:58
start.hpp
Extracts the underlying OpenCL start index handle from a vector, a matrix, an expression etc...
tools.hpp
Various little tools used here and there in ViennaCL.
viennacl::ocl::kernel::local_work_size
size_type local_work_size(int index=0) const
Returns the local work size at the respective dimension.
Definition: kernel.hpp:742
viennacl::ocl::context
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:55
forwards.h
This file provides the forward declarations for the main types used within ViennaCL.
stride.hpp
Determines row and column increments for matrices and matrix proxies.
s2
viennacl::scalar< int > s2
Definition: global_variables.cpp:58
s1
viennacl::scalar< float > s1
Definition: global_variables.cpp:57
common.hpp
Common implementations shared by OpenCL-based operations.
NumericT
float NumericT
Definition: bisect.cpp:40
viennacl::linalg::opencl::kernels::scalar
Main kernel class for generating OpenCL kernels for operations involving viennacl::scalar<>, but not viennacl::vector<> or viennacl::matrix<>.
Definition: scalar.hpp:243
viennacl::linalg::opencl::asbs_s
viennacl::enable_if< viennacl::is_scalar< ScalarT1 >::value &&viennacl::is_scalar< ScalarT2 >::value &&viennacl::is_scalar< ScalarT3 >::value &&viennacl::is_any_scalar< NumericT2 >::value &&viennacl::is_any_scalar< NumericT3 >::value >::type asbs_s(ScalarT1 &s1, ScalarT2 const &s2, NumericT2 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, ScalarT3 const &s3, NumericT3 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: scalar_operations.hpp:135
viennacl::is_cpu_scalar
Helper struct for checking whether a type is a host scalar type (e.g. float, double) ...
Definition: forwards.h:448
viennacl::ocl::context::get_kernel
viennacl::ocl::kernel & get_kernel(std::string const &program_name, std::string const &kernel_name)
Convenience function for retrieving the kernel of a program directly from the context.
Definition: context.hpp:605
viennacl::linalg::opencl::kernels::scalar::init
static void init(viennacl::ocl::context &ctx)
Definition: scalar.hpp:250
viennacl::is_any_scalar
Helper struct for checking whether the provided type represents a scalar (either host, from ViennaCL, or a flip-sign proxy)
Definition: forwards.h:469
handle.hpp
Implementation of a smart-pointer-like class for handling OpenCL handles.
viennacl::linalg::opencl::detail::make_options
cl_uint make_options(vcl_size_t length, bool reciprocal, bool flip_sign)
Definition: common.hpp:42
viennacl::vcl_size_t
std::size_t vcl_size_t
Definition: forwards.h:75
viennacl::result_of::cpu_value_type::type
T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type
Definition: result_of.hpp:271
viennacl::linalg::opencl::asbs
viennacl::enable_if< viennacl::is_scalar< ScalarT1 >::value &&viennacl::is_scalar< ScalarT2 >::value &&viennacl::is_scalar< ScalarT3 >::value &&viennacl::is_any_scalar< NumericT2 >::value &&viennacl::is_any_scalar< NumericT3 >::value >::type asbs(ScalarT1 &s1, ScalarT2 const &s2, NumericT2 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, ScalarT3 const &s3, NumericT3 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: scalar_operations.hpp:86
viennacl::linalg::opencl::as
viennacl::enable_if< viennacl::is_scalar< ScalarT1 >::value &&viennacl::is_scalar< ScalarT2 >::value &&viennacl::is_any_scalar< NumericT >::value >::type as(ScalarT1 &s1, ScalarT2 const &s2, NumericT const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha)
Definition: scalar_operations.hpp:54
predicate.hpp
All the predicates used within ViennaCL. Checks for expressions to be vectors, etc.
viennacl::is_scalar
Helper struct for checking whether a type is a viennacl::scalar<>
Definition: forwards.h:455
viennacl::traits::context
viennacl::context context(T const &t)
Returns an ID for the currently active memory domain of an object.
Definition: context.hpp:40
viennacl::ocl::enqueue
void enqueue(KernelType &k, viennacl::ocl::command_queue const &queue)
Enqueues a kernel in the provided queue.
Definition: enqueue.hpp:50
kernel.hpp
Representation of an OpenCL kernel in ViennaCL.
viennacl::ocl::kernel::global_work_size
size_type global_work_size(int index=0) const
Returns the global work size at the respective dimension.
Definition: kernel.hpp:751
handle.hpp
Extracts the underlying OpenCL handle from a vector, a matrix, an expression etc. ...
result_of.hpp
A collection of compile time type deductions.
enable_if.hpp
Simple enable-if variant that uses the SFINAE pattern.