All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
matrix_operations.hpp
Go to the documentation of this file.
#ifndef VIENNACL_LINALG_OPENCL_MATRIX_OPERATIONS_HPP_
#define VIENNACL_LINALG_OPENCL_MATRIX_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/scalar.hpp"
#include "viennacl/vector.hpp"
#include "viennacl/vector_proxy.hpp"
#include "viennacl/tools/tools.hpp"
#include "viennacl/meta/enable_if.hpp"
#include "viennacl/meta/predicate.hpp"
#include "viennacl/meta/result_of.hpp"
#include "viennacl/traits/size.hpp"
#include "viennacl/traits/start.hpp"
#include "viennacl/traits/handle.hpp"
#include "viennacl/traits/stride.hpp"
#include "viennacl/linalg/opencl/common.hpp"
#include "viennacl/linalg/opencl/kernels/svd.hpp"
#include "viennacl/linalg/opencl/kernels/vector.hpp"
#include "viennacl/linalg/opencl/kernels/matrix.hpp"
#include "viennacl/linalg/opencl/kernels/matrix_element.hpp"
namespace viennacl
{
namespace linalg
{
namespace opencl
{
namespace detail
{
template<typename NumericT>
viennacl::ocl::kernel & kernel_for_matrix(matrix_base<NumericT> const & M, std::string const & kernel_name)
{
viennacl::ocl::context & ctx = traits::opencl_context(M);
viennacl::ocl::program * program;
if (M.row_major())
{
typedef viennacl::linalg::opencl::kernels::matrix<NumericT, row_major> KernelClass;
KernelClass::init(ctx);
program = &ctx.get_program(KernelClass::program_name());
}
else
{
typedef viennacl::linalg::opencl::kernels::matrix<NumericT, column_major> KernelClass;
KernelClass::init(ctx);
program = &ctx.get_program(KernelClass::program_name());
}
return program->get_kernel(kernel_name);
}
template<typename NumericT>
viennacl::ocl::kernel & element_kernel_for_matrix(matrix_base<NumericT> const & M, std::string const & kernel_name)
{
viennacl::ocl::context & ctx = traits::opencl_context(M);
viennacl::ocl::program * program;
if (M.row_major())
{
typedef viennacl::linalg::opencl::kernels::matrix_element<NumericT, row_major> KernelClass;
KernelClass::init(ctx);
program = &ctx.get_program(KernelClass::program_name());
}
else
{
typedef viennacl::linalg::opencl::kernels::matrix_element<NumericT, column_major> KernelClass;
KernelClass::init(ctx);
program = &ctx.get_program(KernelClass::program_name());
}
return program->get_kernel(kernel_name);
}
template<typename NumericT>
viennacl::ocl::kernel & legacy_kernel_for_matrix(matrix_base<NumericT> const & M, std::string const & kernel_name)
{
viennacl::ocl::context & ctx = traits::opencl_context(M);
viennacl::ocl::program * program;
if (M.row_major())
{
typedef viennacl::linalg::opencl::kernels::matrix_legacy<NumericT, row_major> KernelClass;
KernelClass::init(ctx);
program = &ctx.get_program(KernelClass::program_name());
}
else
{
typedef viennacl::linalg::opencl::kernels::matrix_legacy<NumericT, column_major> KernelClass;
KernelClass::init(ctx);
program = &ctx.get_program(KernelClass::program_name());
}
return program->get_kernel(kernel_name);
}
}
//
// Introductory note: By convention, all dimensions are already checked in the dispatcher frontend. No need to double-check again in here!
//
const std::string SVD_BIDIAG_PACK_KERNEL = "bidiag_pack";
const std::string SVD_HOUSEHOLDER_UPDATE_A_LEFT_KERNEL = "house_update_A_left";
const std::string SVD_HOUSEHOLDER_UPDATE_A_RIGHT_KERNEL = "house_update_A_right";
const std::string SVD_HOUSEHOLDER_UPDATE_QL_KERNEL = "house_update_QL";
const std::string SVD_GIVENS_NEXT_KERNEL = "givens_next";
const std::string SVD_COPY_COL_KERNEL = "copy_col";
const std::string SVD_COPY_ROW_KERNEL = "copy_row";
template<typename DestNumericT, typename SrcNumericT>
void convert(matrix_base<DestNumericT> & dest, matrix_base<SrcNumericT> const & src)
{
assert(dest.row_major() == src.row_major() && bool("Addition/subtraction on mixed matrix layouts not supported yet!"));
assert(viennacl::traits::opencl_handle(dest).context() == viennacl::traits::opencl_handle(src).context() && bool("Matrices do not reside in the same OpenCL context. Automatic migration not yet supported!"));
std::string kernel_name("convert_");
kernel_name += dest.row_major() ? "row_" : "col_";
kernel_name += viennacl::ocl::type_to_string<DestNumericT>::apply();
kernel_name += "_";
kernel_name += viennacl::ocl::type_to_string<SrcNumericT>::apply();
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(dest).context());
viennacl::linalg::opencl::kernels::matrix_convert::init(ctx);
viennacl::ocl::kernel& k = ctx.get_kernel(viennacl::linalg::opencl::kernels::matrix_convert::program_name(), kernel_name);
viennacl::ocl::enqueue(k( dest, cl_uint(dest.start1()), cl_uint(dest.stride1()), cl_uint(dest.size1()), cl_uint(dest.internal_size1()), cl_uint(dest.start2()), cl_uint(dest.stride2()), cl_uint(dest.size2()), cl_uint(dest.internal_size2()),
src, cl_uint( src.start1()), cl_uint( src.stride1()), cl_uint( src.size1()), cl_uint( src.internal_size1()), cl_uint( src.start2()), cl_uint( src.stride2()), cl_uint( src.size2()), cl_uint( src.internal_size2())
) );
}
//
// Introductory note: By convention, all dimensions are already checked in the dispatcher frontend. No need to double-check again in here!
//
template <typename NumericT,
typename ScalarT1>
void am(matrix_base<NumericT> & mat1,
matrix_base<NumericT> const & mat2, ScalarT1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha)
{
viennacl::ocl::kernel & k= detail::kernel_for_matrix(mat1, (viennacl::is_cpu_scalar<ScalarT1>::value ? "am_cpu" : "am_gpu"));
cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha);
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(mat1),
cl_uint(viennacl::traits::start1(mat1)), cl_uint(viennacl::traits::start2(mat1)),
cl_uint(viennacl::traits::stride1(mat1)), cl_uint(viennacl::traits::stride2(mat1)),
cl_uint(viennacl::traits::size1(mat1)), cl_uint(viennacl::traits::size2(mat1)),
cl_uint(viennacl::traits::internal_size1(mat1)), cl_uint(viennacl::traits::internal_size2(mat1)),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<NumericT>(alpha)),
options_alpha,
viennacl::traits::opencl_handle(mat2),
cl_uint(viennacl::traits::start1(mat2)), cl_uint(viennacl::traits::start2(mat2)),
cl_uint(viennacl::traits::stride1(mat2)), cl_uint(viennacl::traits::stride2(mat2)),
cl_uint(viennacl::traits::internal_size1(mat2)), cl_uint(viennacl::traits::internal_size2(mat2))
)
);
}
template <typename NumericT,
typename ScalarT1, typename ScalarT2>
void ambm(matrix_base<NumericT> & mat1,
matrix_base<NumericT> const & mat2, ScalarT1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha,
matrix_base<NumericT> const & mat3, ScalarT2 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
{
std::string kernel_name;
if ( viennacl::is_cpu_scalar<ScalarT1>::value && viennacl::is_cpu_scalar<ScalarT2>::value)
kernel_name = "ambm_cpu_cpu";
else if ( viennacl::is_cpu_scalar<ScalarT1>::value && !viennacl::is_cpu_scalar<ScalarT2>::value)
kernel_name = "ambm_cpu_gpu";
else if (!viennacl::is_cpu_scalar<ScalarT1>::value && viennacl::is_cpu_scalar<ScalarT2>::value)
kernel_name = "ambm_gpu_cpu";
else
kernel_name = "ambm_gpu_gpu";
viennacl::ocl::kernel & k = detail::kernel_for_matrix(mat1, kernel_name);
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::enqueue(k(viennacl::traits::opencl_handle(mat1),
cl_uint(viennacl::traits::start1(mat1)), cl_uint(viennacl::traits::start2(mat1)),
cl_uint(viennacl::traits::stride1(mat1)), cl_uint(viennacl::traits::stride2(mat1)),
cl_uint(viennacl::traits::size1(mat1)), cl_uint(viennacl::traits::size2(mat1)),
cl_uint(viennacl::traits::internal_size1(mat1)), cl_uint(viennacl::traits::internal_size2(mat1)),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<NumericT>(alpha)),
options_alpha,
viennacl::traits::opencl_handle(mat2),
cl_uint(viennacl::traits::start1(mat2)), cl_uint(viennacl::traits::start2(mat2)),
cl_uint(viennacl::traits::stride1(mat2)), cl_uint(viennacl::traits::stride2(mat2)),
cl_uint(viennacl::traits::internal_size1(mat2)), cl_uint(viennacl::traits::internal_size2(mat2)),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<NumericT>(beta)),
options_beta,
viennacl::traits::opencl_handle(mat3),
cl_uint(viennacl::traits::start1(mat3)), cl_uint(viennacl::traits::start2(mat3)),
cl_uint(viennacl::traits::stride1(mat3)), cl_uint(viennacl::traits::stride2(mat3)),
cl_uint(viennacl::traits::internal_size1(mat3)), cl_uint(viennacl::traits::internal_size2(mat3))
)
);
}
template <typename NumericT,
typename ScalarT1, typename ScalarT2>
void ambm_m(matrix_base<NumericT> & mat1,
matrix_base<NumericT> const & mat2, ScalarT1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha,
matrix_base<NumericT> const & mat3, ScalarT2 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
{
std::string kernel_name;
if ( viennacl::is_cpu_scalar<ScalarT1>::value && viennacl::is_cpu_scalar<ScalarT2>::value)
kernel_name = "ambm_m_cpu_cpu";
else if ( viennacl::is_cpu_scalar<ScalarT1>::value && !viennacl::is_cpu_scalar<ScalarT2>::value)
kernel_name = "ambm_m_cpu_gpu";
else if (!viennacl::is_cpu_scalar<ScalarT1>::value && viennacl::is_cpu_scalar<ScalarT2>::value)
kernel_name = "ambm_m_gpu_cpu";
else
kernel_name = "ambm_m_gpu_gpu";
viennacl::ocl::kernel & k = detail::kernel_for_matrix(mat1, kernel_name);
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::enqueue(k(viennacl::traits::opencl_handle(mat1),
cl_uint(viennacl::traits::start1(mat1)), cl_uint(viennacl::traits::start2(mat1)),
cl_uint(viennacl::traits::stride1(mat1)), cl_uint(viennacl::traits::stride2(mat1)),
cl_uint(viennacl::traits::size1(mat1)), cl_uint(viennacl::traits::size2(mat1)),
cl_uint(viennacl::traits::internal_size1(mat1)), cl_uint(viennacl::traits::internal_size2(mat1)),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<NumericT>(alpha)),
options_alpha,
viennacl::traits::opencl_handle(mat2),
cl_uint(viennacl::traits::start1(mat2)), cl_uint(viennacl::traits::start2(mat2)),
cl_uint(viennacl::traits::stride1(mat2)), cl_uint(viennacl::traits::stride2(mat2)),
cl_uint(viennacl::traits::internal_size1(mat2)), cl_uint(viennacl::traits::internal_size2(mat2)),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<NumericT>(beta)),
options_beta,
viennacl::traits::opencl_handle(mat3),
cl_uint(viennacl::traits::start1(mat3)), cl_uint(viennacl::traits::start2(mat3)),
cl_uint(viennacl::traits::stride1(mat3)), cl_uint(viennacl::traits::stride2(mat3)),
cl_uint(viennacl::traits::internal_size1(mat3)), cl_uint(viennacl::traits::internal_size2(mat3))
)
);
}
template<typename NumericT,
typename SizeT, typename DistanceT>
void trans(const matrix_expression<const matrix_base<NumericT, SizeT, DistanceT>,const matrix_base<NumericT, SizeT, DistanceT>, op_trans> & proxy,
matrix_base<NumericT> & temp_trans)
{
std::string kernel_name("trans_kernel");
viennacl::ocl::kernel& kernel = detail::legacy_kernel_for_matrix(proxy.lhs(),kernel_name);
viennacl::ocl::enqueue(kernel(proxy.lhs(),
static_cast<cl_uint>(proxy.lhs().start1()), static_cast<cl_uint>(proxy.lhs().start2()),
static_cast<cl_uint>(proxy.lhs().internal_size1()), static_cast<cl_uint>(proxy.lhs().internal_size2()),
static_cast<cl_uint>(proxy.lhs().size1()), static_cast<cl_uint>(proxy.lhs().size2()),
static_cast<cl_uint>(proxy.lhs().stride1()), static_cast<cl_uint>(proxy.lhs().stride2()),
temp_trans,
static_cast<cl_uint>(temp_trans.start1()), static_cast<cl_uint>(temp_trans.start2()),
static_cast<cl_uint>(temp_trans.internal_size1()), static_cast<cl_uint>(temp_trans.internal_size2()),
static_cast<cl_uint>(temp_trans.stride1()), static_cast<cl_uint>(temp_trans.stride2())));
}
template <typename NumericT>
void matrix_assign(matrix_base<NumericT> & mat, NumericT s, bool clear = false)
{
cl_uint s1 = clear ? cl_uint(viennacl::traits::internal_size1(mat)) : cl_uint(viennacl::traits::size1(mat));
cl_uint s2 = clear ? cl_uint(viennacl::traits::internal_size2(mat)) : cl_uint(viennacl::traits::size2(mat));
viennacl::ocl::kernel & k = detail::kernel_for_matrix(mat, "assign_cpu");
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(mat),
cl_uint(viennacl::traits::start1(mat)), cl_uint(viennacl::traits::start2(mat)),
cl_uint(viennacl::traits::stride1(mat)), cl_uint(viennacl::traits::stride2(mat)),
s1, s2,
cl_uint(viennacl::traits::internal_size1(mat)), cl_uint(viennacl::traits::internal_size2(mat)),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<NumericT>(s))
)
);
}
template <typename NumericT>
void matrix_diagonal_assign(matrix_base<NumericT> & mat, NumericT s)
{
viennacl::ocl::kernel & k = detail::kernel_for_matrix(mat, "diagonal_assign_cpu");
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(mat),
cl_uint(viennacl::traits::start1(mat)), cl_uint(viennacl::traits::start2(mat)),
cl_uint(viennacl::traits::stride1(mat)), cl_uint(viennacl::traits::stride2(mat)),
cl_uint(viennacl::traits::size1(mat)), cl_uint(viennacl::traits::size2(mat)),
cl_uint(viennacl::traits::internal_size1(mat)), cl_uint(viennacl::traits::internal_size2(mat)),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<NumericT>(s))
)
);
}
template <typename NumericT>
void matrix_diag_from_vector(const vector_base<NumericT> & vec, int k, matrix_base<NumericT> & mat)
{
// Step 1: set everything to zero
matrix_assign(mat, NumericT(0));
// Step 2: set the diagonal:
// reuse vector ambm kernel for assigning the elements:
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(mat).context());
typedef viennacl::linalg::opencl::kernels::vector<NumericT> KernelClass;
KernelClass::init(ctx);
cl_uint options_alpha = 0;
viennacl::ocl::packed_cl_uint size_mat;
if (mat.row_major())
{
vcl_size_t first_row_index = 0;
vcl_size_t first_col_index = 0;
if (k < 0)
first_row_index = vcl_size_t(-k);
else
first_col_index = vcl_size_t(k);
size_mat.start = cl_uint( (viennacl::traits::start1(mat) + first_row_index * viennacl::traits::stride1(mat)) * viennacl::traits::internal_size2(mat)
+ viennacl::traits::start2(mat) + first_col_index * viennacl::traits::stride2(mat));
size_mat.stride = cl_uint(viennacl::traits::stride1(mat) * viennacl::traits::internal_size2(mat) + viennacl::traits::stride2(mat));
size_mat.size = cl_uint(viennacl::traits::size(vec));
size_mat.internal_size = cl_uint(viennacl::traits::internal_size(vec));
}
else
{
vcl_size_t first_row_index = 0;
vcl_size_t first_col_index = 0;
if (k < 0)
first_row_index = vcl_size_t(-k);
else
first_col_index = vcl_size_t(k);
size_mat.start = cl_uint( viennacl::traits::start1(mat) + first_row_index * viennacl::traits::stride1(mat)
+ (viennacl::traits::start2(mat) + first_col_index * viennacl::traits::stride2(mat)) * viennacl::traits::internal_size1(mat));
size_mat.stride = cl_uint(viennacl::traits::stride2(mat) * viennacl::traits::internal_size1(mat) + viennacl::traits::stride1(mat));
size_mat.size = cl_uint(viennacl::traits::size(vec));
size_mat.internal_size = cl_uint(viennacl::traits::internal_size(vec));
}
viennacl::ocl::packed_cl_uint size_vec;
size_vec.start = cl_uint(viennacl::traits::start(vec));
size_vec.stride = cl_uint(viennacl::traits::stride(vec));
size_vec.size = cl_uint(viennacl::traits::size(vec));
size_vec.internal_size = cl_uint(viennacl::traits::internal_size(vec));
viennacl::ocl::kernel & kern = ctx.get_kernel(KernelClass::program_name(), "av_cpu");
viennacl::ocl::enqueue(kern(viennacl::traits::opencl_handle(mat),
size_mat,
viennacl::traits::opencl_handle(NumericT(1)),
options_alpha,
viennacl::traits::opencl_handle(vec),
size_vec)
);
}
template <typename NumericT>
void matrix_diag_to_vector(const matrix_base<NumericT> & mat, int k, vector_base<NumericT> & vec)
{
// reuse vector ambm kernel for assigning the elements:
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(mat).context());
typedef viennacl::linalg::opencl::kernels::vector<NumericT> KernelClass;
KernelClass::init(ctx);
cl_uint options_alpha = 0;
viennacl::ocl::packed_cl_uint size_mat;
if (mat.row_major())
{
vcl_size_t first_row_index = 0;
vcl_size_t first_col_index = 0;
if (k < 0)
first_row_index = vcl_size_t(-k);
else
first_col_index = vcl_size_t(k);
size_mat.start = cl_uint( (viennacl::traits::start1(mat) + first_row_index * viennacl::traits::stride1(mat)) * viennacl::traits::internal_size2(mat)
+ viennacl::traits::start2(mat) + first_col_index * viennacl::traits::stride2(mat));
size_mat.stride = cl_uint(viennacl::traits::stride1(mat) * viennacl::traits::internal_size2(mat) + viennacl::traits::stride2(mat));
size_mat.size = cl_uint(viennacl::traits::size(vec));
size_mat.internal_size = cl_uint(viennacl::traits::internal_size(vec));
}
else
{
vcl_size_t first_row_index = 0;
vcl_size_t first_col_index = 0;
if (k < 0)
first_row_index = vcl_size_t(-k);
else
first_col_index = vcl_size_t(k);
size_mat.start = cl_uint( viennacl::traits::start1(mat) + first_row_index * viennacl::traits::stride1(mat)
+ (viennacl::traits::start2(mat) + first_col_index * viennacl::traits::stride2(mat)) * viennacl::traits::internal_size1(mat));
size_mat.stride = cl_uint(viennacl::traits::stride2(mat) * viennacl::traits::internal_size1(mat) + viennacl::traits::stride1(mat));
size_mat.size = cl_uint(viennacl::traits::size(vec));
size_mat.internal_size = cl_uint(viennacl::traits::internal_size(vec));
}
viennacl::ocl::packed_cl_uint size_vec;
size_vec.start = cl_uint(viennacl::traits::start(vec));
size_vec.stride = cl_uint(viennacl::traits::stride(vec));
size_vec.size = cl_uint(viennacl::traits::size(vec));
size_vec.internal_size = cl_uint(viennacl::traits::internal_size(vec));
viennacl::ocl::kernel & kern = ctx.get_kernel(KernelClass::program_name(), "av_cpu");
viennacl::ocl::enqueue(kern(viennacl::traits::opencl_handle(vec),
size_vec,
viennacl::traits::opencl_handle(NumericT(1)),
options_alpha,
viennacl::traits::opencl_handle(mat),
size_mat)
);
}
template <typename NumericT>
void matrix_row(matrix_base<NumericT> const & mat, unsigned int i, vector_base<NumericT> & vec)
{
// reuse vector ambm kernel for assigning the elements:
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(mat).context());
typedef viennacl::linalg::opencl::kernels::vector<NumericT> KernelClass;
KernelClass::init(ctx);
cl_uint options_alpha = 0;
viennacl::ocl::packed_cl_uint size_mat;
if (mat.row_major())
{
size_mat.start = cl_uint((viennacl::traits::start1(mat) + i * viennacl::traits::stride1(mat)) * viennacl::traits::internal_size2(mat) + viennacl::traits::start2(mat));
size_mat.stride = cl_uint(viennacl::traits::stride2(mat));
size_mat.size = cl_uint(viennacl::traits::size(vec));
size_mat.internal_size = cl_uint(viennacl::traits::internal_size(vec));
}
else
{
size_mat.start = cl_uint((viennacl::traits::start1(mat) + i * viennacl::traits::stride1(mat)) + viennacl::traits::start2(mat) * viennacl::traits::internal_size1(mat));
size_mat.stride = cl_uint(viennacl::traits::stride2(mat) * viennacl::traits::internal_size1(mat));
size_mat.size = cl_uint(viennacl::traits::size(vec));
size_mat.internal_size = cl_uint(viennacl::traits::internal_size(vec));
}
viennacl::ocl::packed_cl_uint size_vec;
size_vec.start = cl_uint(viennacl::traits::start(vec));
size_vec.stride = cl_uint(viennacl::traits::stride(vec));
size_vec.size = cl_uint(viennacl::traits::size(vec));
size_vec.internal_size = cl_uint(viennacl::traits::internal_size(vec));
viennacl::ocl::kernel & kern = ctx.get_kernel(KernelClass::program_name(), "av_cpu");
viennacl::ocl::enqueue(kern(viennacl::traits::opencl_handle(vec),
size_vec,
viennacl::traits::opencl_handle(NumericT(1)),
options_alpha,
viennacl::traits::opencl_handle(mat),
size_mat)
);
}
template <typename NumericT>
void matrix_column(const matrix_base<NumericT> & mat, unsigned int j, vector_base<NumericT> & vec)
{
// reuse vector ambm kernel for assigning the elements:
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(mat).context());
typedef viennacl::linalg::opencl::kernels::vector<NumericT> KernelClass;
KernelClass::init(ctx);
cl_uint options_alpha = 0;
viennacl::ocl::packed_cl_uint size_mat;
if (mat.row_major())
{
size_mat.start = cl_uint(viennacl::traits::start1(mat) * viennacl::traits::internal_size2(mat) + viennacl::traits::start2(mat) + j * viennacl::traits::stride2(mat));
size_mat.stride = cl_uint(viennacl::traits::stride2(mat) * viennacl::traits::internal_size2(mat));
size_mat.size = cl_uint(viennacl::traits::size(vec));
size_mat.internal_size = cl_uint(viennacl::traits::internal_size(vec));
}
else
{
size_mat.start = cl_uint(viennacl::traits::start1(mat) + (viennacl::traits::start2(mat) + j * viennacl::traits::stride2(mat)) * viennacl::traits::internal_size1(mat));
size_mat.stride = cl_uint(viennacl::traits::stride2(mat));
size_mat.size = cl_uint(viennacl::traits::size(vec));
size_mat.internal_size = cl_uint(viennacl::traits::internal_size(vec));
}
viennacl::ocl::packed_cl_uint size_vec;
size_vec.start = cl_uint(viennacl::traits::start(vec));
size_vec.stride = cl_uint(viennacl::traits::stride(vec));
size_vec.size = cl_uint(viennacl::traits::size(vec));
size_vec.internal_size = cl_uint(viennacl::traits::internal_size(vec));
viennacl::ocl::kernel & kern = ctx.get_kernel(KernelClass::program_name(), "av_cpu");
viennacl::ocl::enqueue(kern(viennacl::traits::opencl_handle(vec),
size_vec,
viennacl::traits::opencl_handle(NumericT(1)),
options_alpha,
viennacl::traits::opencl_handle(mat),
size_mat)
);
}
//
//
// Binary operations A = B .* C and A = B ./ C
template <typename T, typename OP>
void element_op(matrix_base<T> & A,
matrix_expression<const matrix_base<T>, const matrix_base<T>, op_element_binary<OP> > const & proxy)
{
assert(viennacl::traits::opencl_handle(A).context() == viennacl::traits::opencl_handle(proxy.lhs()).context() && bool("Matrices do not reside in the same OpenCL context. Automatic migration not yet supported!"));
assert(viennacl::traits::opencl_handle(A).context() == viennacl::traits::opencl_handle(proxy.rhs()).context() && bool("Matrices do not reside in the same OpenCL context. Automatic migration not yet supported!"));
viennacl::ocl::kernel & k = detail::kernel_for_matrix(A, "element_op");
cl_uint op_type = 2; //0: product, 1: division, 2: power
if (viennacl::is_division<OP>::value)
op_type = 1;
else if (viennacl::is_product<OP>::value)
op_type = 0;
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(A),
cl_uint(viennacl::traits::start1(A)), cl_uint(viennacl::traits::start2(A)),
cl_uint(viennacl::traits::stride1(A)), cl_uint(viennacl::traits::stride2(A)),
cl_uint(viennacl::traits::size1(A)), cl_uint(viennacl::traits::size2(A)),
cl_uint(viennacl::traits::internal_size1(A)), cl_uint(viennacl::traits::internal_size2(A)),
viennacl::traits::opencl_handle(proxy.lhs()),
cl_uint(viennacl::traits::start1(proxy.lhs())), cl_uint(viennacl::traits::start2(proxy.lhs())),
cl_uint(viennacl::traits::stride1(proxy.lhs())), cl_uint(viennacl::traits::stride2(proxy.lhs())),
cl_uint(viennacl::traits::internal_size1(proxy.lhs())), cl_uint(viennacl::traits::internal_size2(proxy.lhs())),
viennacl::traits::opencl_handle(proxy.rhs()),
cl_uint(viennacl::traits::start1(proxy.rhs())), cl_uint(viennacl::traits::start2(proxy.rhs())),
cl_uint(viennacl::traits::stride1(proxy.rhs())), cl_uint(viennacl::traits::stride2(proxy.rhs())),
cl_uint(viennacl::traits::internal_size1(proxy.rhs())), cl_uint(viennacl::traits::internal_size2(proxy.rhs())),
op_type)
);
}
// Unary operations
template <typename T, typename OP>
void element_op(matrix_base<T> & A,
matrix_expression<const matrix_base<T>, const matrix_base<T>, op_element_unary<OP> > const & proxy)
{
assert(viennacl::traits::opencl_handle(A).context() == viennacl::traits::opencl_handle(proxy.lhs()).context() && bool("Matrices do not reside in the same OpenCL context. Automatic migration not yet supported!"));
assert(viennacl::traits::opencl_handle(A).context() == viennacl::traits::opencl_handle(proxy.rhs()).context() && bool("Matrices do not reside in the same OpenCL context. Automatic migration not yet supported!"));
viennacl::ocl::kernel & k = detail::element_kernel_for_matrix(A, detail::op_to_string(OP()) + "_assign");
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(A),
cl_uint(viennacl::traits::start1(A)), cl_uint(viennacl::traits::start2(A)),
cl_uint(viennacl::traits::stride1(A)), cl_uint(viennacl::traits::stride2(A)),
cl_uint(viennacl::traits::size1(A)), cl_uint(viennacl::traits::size2(A)),
cl_uint(viennacl::traits::internal_size1(A)), cl_uint(viennacl::traits::internal_size2(A)),
viennacl::traits::opencl_handle(proxy.lhs()),
cl_uint(viennacl::traits::start1(proxy.lhs())), cl_uint(viennacl::traits::start2(proxy.lhs())),
cl_uint(viennacl::traits::stride1(proxy.lhs())), cl_uint(viennacl::traits::stride2(proxy.lhs())),
cl_uint(viennacl::traits::internal_size1(proxy.lhs())), cl_uint(viennacl::traits::internal_size2(proxy.lhs())))
);
}
//
//
// A * x
template <typename NumericT>
void prod_impl(const matrix_base<NumericT> & mat, bool trans_A,
const vector_base<NumericT> & vec,
vector_base<NumericT> & result)
{
assert(viennacl::traits::handle(vec) != viennacl::traits::handle(result) && bool("No direct inplace transposed matrix-vector product possible. Introduce a temporary!"));
viennacl::ocl::kernel & k = detail::kernel_for_matrix(mat, trans_A ? "trans_vec_mul" : "vec_mul");
viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(mat),
cl_uint(viennacl::traits::start1(mat)), cl_uint(viennacl::traits::start2(mat)),
cl_uint(viennacl::traits::stride1(mat)), cl_uint(viennacl::traits::stride2(mat)),
cl_uint(viennacl::traits::size1(mat)), cl_uint(viennacl::traits::size2(mat)),
cl_uint(viennacl::traits::internal_size1(mat)), cl_uint(viennacl::traits::internal_size2(mat)),
viennacl::traits::opencl_handle(vec),
cl_uint(viennacl::traits::start(vec)),
cl_uint(viennacl::traits::stride(vec)),
cl_uint(viennacl::traits::size(vec)),
viennacl::traits::opencl_handle(result),
cl_uint(viennacl::traits::start(result)),
cl_uint(viennacl::traits::stride(result)),
cl_uint(viennacl::traits::size(result)),
viennacl::ocl::local_mem(sizeof(NumericT) * k.local_work_size())
) );
}
//
template<typename NumericT, typename ScalarType >
void prod_impl(matrix_base<NumericT> const & A, bool A_trans,
matrix_base<NumericT> const & B, bool B_trans,
matrix_base<NumericT> & C,
ScalarType alpha,
ScalarType beta)
{
bool effective_A_trans = A_trans ^ A.row_major();
bool effective_B_trans = B_trans ^ B.row_major();
char cAt = effective_A_trans ? 'T' : 'N';
char cBt = effective_B_trans ? 'T' : 'N';
std::string kernel_prefix("prod_");
kernel_prefix+=cAt;
kernel_prefix+=cBt;
scheduler::statement statement = scheduler::preset::mat_mat_prod(alpha, &A, effective_A_trans, &B, effective_B_trans, beta, &C);
kernels::matrix_prod<NumericT>::execution_handler(C.row_major(), viennacl::traits::opencl_context(C)).execute(kernel_prefix, statement);
}
//
//
template<typename NumericT, typename ScalarT1>
void scaled_rank_1_update(matrix_base<NumericT> & A,
ScalarT1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha,
const vector_base<NumericT> & vec1,
const vector_base<NumericT> & vec2)
{
assert( (viennacl::traits::size1(A) == viennacl::traits::size(vec1)) && bool("Size mismatch in scaled_rank_1_update: size1(A) != size(v1)"));
assert( (viennacl::traits::size2(A) == viennacl::traits::size(vec2)) && bool("Size mismatch in scaled_rank_1_update: size2(A) != size(v2)"));
cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha);
bool is_cpu = viennacl::is_cpu_scalar<ScalarT1>::value;
viennacl::ocl::kernel& kernel= detail::legacy_kernel_for_matrix(A, is_cpu ? "scaled_rank1_update_cpu" : "scaled_rank1_update_gpu");
viennacl::ocl::enqueue(kernel(viennacl::traits::opencl_handle(A),
cl_uint(viennacl::traits::start1(A)), cl_uint(viennacl::traits::start2(A)),
cl_uint(viennacl::traits::stride1(A)), cl_uint(viennacl::traits::stride2(A)),
cl_uint(viennacl::traits::size1(A)), cl_uint(viennacl::traits::size2(A)),
cl_uint(viennacl::traits::internal_size1(A)), cl_uint(viennacl::traits::internal_size2(A)),
viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<NumericT>(alpha)),
options_alpha,
viennacl::traits::opencl_handle(vec1),
cl_uint(viennacl::traits::start(vec1)),
cl_uint(viennacl::traits::stride(vec1)),
cl_uint(viennacl::traits::size(vec1)),
viennacl::traits::opencl_handle(vec2),
cl_uint(viennacl::traits::start(vec2)),
cl_uint(viennacl::traits::stride(vec2)),
cl_uint(viennacl::traits::size(vec2))
)
);
}
//
template <typename SCALARTYPE, typename VectorType>
void bidiag_pack_svd(viennacl::matrix<SCALARTYPE>& A,
VectorType & dh,
VectorType & sh
)
{
viennacl::vector<SCALARTYPE> D(dh.size());
viennacl::vector<SCALARTYPE> S(sh.size());
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(A).context());
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<SCALARTYPE>::program_name(), SVD_BIDIAG_PACK_KERNEL);
viennacl::ocl::enqueue(kernel(
A,
D,
S,
static_cast<cl_uint>(A.size1()),
static_cast<cl_uint>(A.size2()),
static_cast<cl_uint>(A.internal_size2())
));
fast_copy(D, dh);
fast_copy(S, sh);
}
template <typename NumericT>
void bidiag_pack(matrix_base<NumericT> & A,
viennacl::vector<NumericT> & dh,
viennacl::vector<NumericT> & sh
)
{
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(A).context());
if(A.row_major())
{
viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::program_name(), SVD_BIDIAG_PACK_KERNEL);
viennacl::ocl::enqueue(kernel(
A,
dh,
sh,
cl_uint(viennacl::traits::size1(A)),
cl_uint(viennacl::traits::size2(A)),
cl_uint(viennacl::traits::internal_size2(A))
));
}
else
{
viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::program_name(), SVD_BIDIAG_PACK_KERNEL);
viennacl::ocl::enqueue(kernel(
A,
dh,
sh,
cl_uint(viennacl::traits::size1(A)),
cl_uint(viennacl::traits::size2(A)),
cl_uint(viennacl::traits::internal_size2(A))
));
}
}
template <typename NumericT>
void house_update_A_left(matrix_base<NumericT> & A,
vector_base<NumericT> & D,
vcl_size_t start)
{
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(A).context());
if(A.row_major())
{
viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::program_name(), SVD_HOUSEHOLDER_UPDATE_A_LEFT_KERNEL);
viennacl::ocl::enqueue(kernel(
A,
D,
static_cast<cl_uint>(start + 1),
static_cast<cl_uint>(start),
cl_uint(viennacl::traits::size1(A)),
cl_uint(viennacl::traits::size2(A)),
cl_uint(viennacl::traits::internal_size2(A)),
viennacl::ocl::local_mem(static_cast<cl_uint>(128 * 4))
));
}
else
{
viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::program_name(), SVD_HOUSEHOLDER_UPDATE_A_LEFT_KERNEL);
viennacl::ocl::enqueue(kernel(
A,
D,
static_cast<cl_uint>(start + 1),
static_cast<cl_uint>(start),
cl_uint(viennacl::traits::size1(A)),
cl_uint(viennacl::traits::size2(A)),
cl_uint(viennacl::traits::internal_size2(A)),
viennacl::ocl::local_mem(static_cast<cl_uint>(128 * 4))
));
}
}
template <typename NumericT>
void house_update_A_right(matrix_base<NumericT> & A,
vector_base<NumericT> & D)
{
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(A).context());
if(A.row_major())
{
viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::program_name(), SVD_HOUSEHOLDER_UPDATE_A_RIGHT_KERNEL);
viennacl::ocl::enqueue(kernel(
A,
D,
static_cast<cl_uint>(0),
static_cast<cl_uint>(0),
cl_uint(viennacl::traits::size1(A)),
cl_uint(viennacl::traits::size2(A)),
cl_uint(viennacl::traits::internal_size2(A)),
viennacl::ocl::local_mem(static_cast<cl_uint>(128 * sizeof(NumericT)))
));
}
else
{
viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::program_name(), SVD_HOUSEHOLDER_UPDATE_A_RIGHT_KERNEL);
viennacl::ocl::enqueue(kernel(
A,
D,
static_cast<cl_uint>(0),
static_cast<cl_uint>(0),
cl_uint(viennacl::traits::size1(A)),
cl_uint(viennacl::traits::size2(A)),
cl_uint(viennacl::traits::internal_size2(A)),
viennacl::ocl::local_mem(static_cast<cl_uint>(128 * sizeof(NumericT)))
));
}
}
template <typename NumericT>
void house_update_QL(matrix_base<NumericT> & Q,
vector_base<NumericT> & D,
vcl_size_t A_size1)
{
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(Q).context());
if(Q.row_major())
{
viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::program_name(), SVD_HOUSEHOLDER_UPDATE_QL_KERNEL);
viennacl::ocl::enqueue(kernel(
Q,
D,
cl_uint(A_size1),
cl_uint(viennacl::traits::internal_size2(Q)),
viennacl::ocl::local_mem(static_cast<cl_uint>(128 * sizeof(NumericT)))
));
}
else
{
viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::program_name(), SVD_HOUSEHOLDER_UPDATE_QL_KERNEL);
viennacl::ocl::enqueue(kernel(
Q,
D,
cl_uint(A_size1),
cl_uint(viennacl::traits::internal_size2(Q)),
viennacl::ocl::local_mem(static_cast<cl_uint>(128 * sizeof(NumericT)))
));
}
}
template<typename NumericT>
void givens_next(matrix_base<NumericT> & matrix,
vector_base<NumericT>& tmp1,
vector_base<NumericT>& tmp2,
int l,
int m
)
{
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(matrix).context());
if(matrix.row_major())
{
viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::program_name(), SVD_GIVENS_NEXT_KERNEL);
kernel.global_work_size(0, viennacl::tools::align_to_multiple<cl_uint>(cl_uint(viennacl::traits::size1(matrix)), 256));
kernel.local_work_size(0, 256);
viennacl::ocl::enqueue(kernel(
matrix,
tmp1,
tmp2,
cl_uint(viennacl::traits::size1(matrix)),
cl_uint(viennacl::traits::internal_size2(matrix)),
static_cast<cl_uint>(l),
static_cast<cl_uint>(m - 1)
));
}
else
{
viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::program_name(), SVD_GIVENS_NEXT_KERNEL);
kernel.global_work_size(0, viennacl::tools::align_to_multiple<cl_uint>(cl_uint(viennacl::traits::size1(matrix)), 256));
kernel.local_work_size(0, 256);
viennacl::ocl::enqueue(kernel(
matrix,
tmp1,
tmp2,
cl_uint(viennacl::traits::size1(matrix)),
cl_uint(viennacl::traits::internal_size2(matrix)),
static_cast<cl_uint>(l),
static_cast<cl_uint>(m - 1)
));
}
}
template <typename NumericT>
void copy_vec(matrix_base<NumericT>& A,
vector_base<NumericT> & V,
vcl_size_t row_start,
vcl_size_t col_start,
bool copy_col
)
{
std::string kernel_name = copy_col ? SVD_COPY_COL_KERNEL : SVD_COPY_ROW_KERNEL;
viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(A).context());
if(A.row_major())
{
viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, row_major>::program_name(), kernel_name);
viennacl::ocl::enqueue(kernel(
A,
V,
static_cast<cl_uint>(row_start),
static_cast<cl_uint>(col_start),
copy_col ? cl_uint(viennacl::traits::size1(A))
: cl_uint(viennacl::traits::size2(A)),
static_cast<cl_uint>(A.internal_size2())
));
}
else
{
viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::init(ctx);
viennacl::ocl::kernel& kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::svd<NumericT, column_major>::program_name(), kernel_name);
viennacl::ocl::enqueue(kernel(
A,
V,
static_cast<cl_uint>(row_start),
static_cast<cl_uint>(col_start),
copy_col ? cl_uint(viennacl::traits::size1(A))
: cl_uint(viennacl::traits::size2(A)),
static_cast<cl_uint>(A.internal_size2())
));
}
}
} // namespace opencl
} //namespace linalg
} //namespace viennacl
#endif
viennacl::ocl::packed_cl_uint::stride
cl_uint stride
Increment between integers.
Definition: kernel.hpp:50
viennacl::linalg::opencl::trans
void trans(const matrix_expression< const matrix_base< NumericT, SizeT, DistanceT >, const matrix_base< NumericT, SizeT, DistanceT >, op_trans > &proxy, matrix_base< NumericT > &temp_trans)
Definition: matrix_operations.hpp:276
viennacl::linalg::opencl::matrix_assign
void matrix_assign(matrix_base< NumericT > &mat, NumericT s, bool clear=false)
Definition: matrix_operations.hpp:294
viennacl::ocl::packed_cl_uint
Helper class for packing four cl_uint numbers into a uint4 type for access inside an OpenCL kernel...
Definition: kernel.hpp:45
viennacl::linalg::opencl::matrix_diag_from_vector
void matrix_diag_from_vector(const vector_base< NumericT > &vec, int k, matrix_base< NumericT > &mat)
Definition: matrix_operations.hpp:325
viennacl::linalg::opencl::matrix_diag_to_vector
void matrix_diag_to_vector(const matrix_base< NumericT > &mat, int k, vector_base< NumericT > &vec)
Definition: matrix_operations.hpp:386
device.hpp
Represents an OpenCL device within ViennaCL.
viennacl::traits::stride1
result_of::size_type< matrix_base< NumericT > >::type stride1(matrix_base< NumericT > const &s)
Definition: stride.hpp:55
viennacl::linalg::opencl::SVD_HOUSEHOLDER_UPDATE_A_LEFT_KERNEL
const std::string SVD_HOUSEHOLDER_UPDATE_A_LEFT_KERNEL
Definition: matrix_operations.hpp:126
viennacl::linalg::opencl::ambm
void ambm(matrix_base< NumericT > &mat1, matrix_base< NumericT > const &mat2, ScalarT1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, matrix_base< NumericT > const &mat3, ScalarT2 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: matrix_operations.hpp:187
viennacl::linalg::opencl::prod_impl
void prod_impl(const matrix_base< NumericT > &mat, bool trans_A, const vector_base< NumericT > &vec, vector_base< NumericT > &result)
Carries out matrix-vector multiplication.
Definition: matrix_operations.hpp:620
viennacl::linalg::opencl::matrix_column
void matrix_column(const matrix_base< NumericT > &mat, unsigned int j, vector_base< NumericT > &vec)
Definition: matrix_operations.hpp:486
size.hpp
Generic size and resize functionality for different vector and matrix types.
viennacl::ocl::kernel
Represents an OpenCL kernel within ViennaCL.
Definition: kernel.hpp:58
viennacl::ocl::context::get_program
viennacl::ocl::program & get_program(std::string const &name)
Returns the program with the provided name.
Definition: context.hpp:532
start.hpp
Extracts the underlying OpenCL start index handle from a vector, a matrix, an expression etc...
viennacl::ocl::packed_cl_uint::start
cl_uint start
Starting value of the integer stride.
Definition: kernel.hpp:48
tools.hpp
Various little tools used here and there in ViennaCL.
viennacl::traits::internal_size1
vcl_size_t internal_size1(matrix_base< NumericT > const &mat)
Helper routine for obtaining the internal number of entries per row of a ViennaCL matrix...
Definition: size.hpp:386
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::traits::size1
vcl_size_t size1(MatrixType const &mat)
Generic routine for obtaining the number of rows of a matrix (ViennaCL, uBLAS, etc.)
Definition: size.hpp:163
viennacl::linalg::opencl::SVD_BIDIAG_PACK_KERNEL
const std::string SVD_BIDIAG_PACK_KERNEL
Definition: matrix_operations.hpp:125
viennacl::ocl::context
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:55
viennacl::traits::internal_size2
vcl_size_t internal_size2(matrix_base< NumericT > const &mat)
Helper routine for obtaining the internal number of entries per column of a ViennaCL matrix...
Definition: size.hpp:394
viennacl::matrix_base< NumericT >
viennacl::matrix_expression
Expression template class for representing a tree of expressions which ultimately result in a matrix...
Definition: forwards.h:341
viennacl::matrix_base::stride2
size_type stride2() const
Returns the number of columns.
Definition: matrix_def.hpp:234
viennacl::linalg::opencl::SVD_GIVENS_NEXT_KERNEL
const std::string SVD_GIVENS_NEXT_KERNEL
Definition: matrix_operations.hpp:129
viennacl::linalg::opencl::SVD_HOUSEHOLDER_UPDATE_A_RIGHT_KERNEL
const std::string SVD_HOUSEHOLDER_UPDATE_A_RIGHT_KERNEL
Definition: matrix_operations.hpp:127
viennacl::traits::stride
result_of::size_type< viennacl::vector_base< T > >::type stride(viennacl::vector_base< T > const &s)
Definition: stride.hpp:45
viennacl::traits::clear
void clear(VectorType &vec)
Generic routine for setting all entries of a vector to zero. This is the version for non-ViennaCL obj...
Definition: clear.hpp:43
forwards.h
This file provides the forward declarations for the main types used within ViennaCL.
viennacl::traits::start1
result_of::size_type< T >::type start1(T const &obj)
Definition: start.hpp:65
viennacl::matrix
A dense matrix class.
Definition: forwards.h:375
viennacl::linalg::opencl::kernels::svd::init
static void init(viennacl::ocl::context &ctx)
Definition: svd.hpp:652
stride.hpp
Determines row and column increments for matrices and matrix proxies.
viennacl::linalg::opencl::bidiag_pack
void bidiag_pack(matrix_base< NumericT > &A, viennacl::vector< NumericT > &dh, viennacl::vector< NumericT > &sh)
Definition: matrix_operations.hpp:758
s2
viennacl::scalar< int > s2
Definition: global_variables.cpp:58
s1
viennacl::scalar< float > s1
Definition: global_variables.cpp:57
viennacl::traits::internal_size
vcl_size_t internal_size(vector_base< NumericT > const &vec)
Helper routine for obtaining the buffer length of a ViennaCL vector.
Definition: size.hpp:375
viennacl::linalg::opencl::detail::element_kernel_for_matrix
viennacl::ocl::kernel & element_kernel_for_matrix(matrix_base< NumericT > const &M, std::string const &kernel_name)
Definition: matrix_operations.hpp:80
viennacl::traits::size2
result_of::size_type< MatrixType >::type size2(MatrixType const &mat)
Generic routine for obtaining the number of columns of a matrix (ViennaCL, uBLAS, etc...
Definition: size.hpp:201
viennacl::linalg::opencl::scaled_rank_1_update
void scaled_rank_1_update(matrix_base< NumericT > &A, ScalarT1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, const vector_base< NumericT > &vec1, const vector_base< NumericT > &vec2)
The implementation of the operation mat += alpha * vec1 * vec2^T, i.e. a scaled rank 1 update...
Definition: matrix_operations.hpp:696
svd.hpp
OpenCL kernel file for singular value decomposition.
viennacl::linalg::opencl::SVD_COPY_ROW_KERNEL
const std::string SVD_COPY_ROW_KERNEL
Definition: matrix_operations.hpp:131
viennacl::ocl::packed_cl_uint::internal_size
cl_uint internal_size
Internal length of the buffer. Might be larger than 'size' due to padding.
Definition: kernel.hpp:54
common.hpp
Common implementations shared by OpenCL-based operations.
NumericT
float NumericT
Definition: bisect.cpp:40
viennacl::linalg::opencl::copy_vec
void copy_vec(matrix_base< NumericT > &A, vector_base< NumericT > &V, vcl_size_t row_start, vcl_size_t col_start, bool copy_col)
Definition: matrix_operations.hpp:970
viennacl::linalg::opencl::house_update_A_right
void house_update_A_right(matrix_base< NumericT > &A, vector_base< NumericT > &D)
Definition: matrix_operations.hpp:840
viennacl::linalg::opencl::kernels::matrix_element
Main kernel class for generating OpenCL kernels for elementwise-operations such as element_sin() on/w...
Definition: matrix_element.hpp:77
viennacl::linalg::opencl::house_update_QL
void house_update_QL(matrix_base< NumericT > &Q, vector_base< NumericT > &D, vcl_size_t A_size1)
Definition: matrix_operations.hpp:884
viennacl::linalg::opencl::kernels::matrix_prod::execution_handler
static device_specific::execution_handler & execution_handler(bool is_row_major, viennacl::ocl::context &ctx)
Definition: matrix.hpp:972
viennacl::linalg::opencl::detail::kernel_for_matrix
viennacl::ocl::kernel & kernel_for_matrix(matrix_base< NumericT > const &M, std::string const &kernel_name)
Definition: matrix_operations.hpp:60
viennacl::traits::size
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:239
viennacl::traits::start2
result_of::size_type< T >::type start2(T const &obj)
Definition: start.hpp:84
viennacl::ocl::local_mem
A class representing local (shared) OpenCL memory. Typically used as kernel argument.
Definition: local_mem.hpp:33
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::linalg::opencl::kernels::svd
Main kernel class for generating OpenCL kernels for singular value decomposition of dense matrices...
Definition: svd.hpp:644
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
vector.hpp
OpenCL kernel file for vector operations.
handle.hpp
Implementation of a smart-pointer-like class for handling OpenCL handles.
viennacl::traits::start
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:44
viennacl::linalg::opencl::detail::make_options
cl_uint make_options(vcl_size_t length, bool reciprocal, bool flip_sign)
Definition: common.hpp:42
viennacl::linalg::opencl::kernels::matrix_legacy
Main kernel class for generating OpenCL kernels for operations on/with dense matrix objects of type v...
Definition: matrix.hpp:1018
viennacl::linalg::opencl::SVD_HOUSEHOLDER_UPDATE_QL_KERNEL
const std::string SVD_HOUSEHOLDER_UPDATE_QL_KERNEL
Definition: matrix_operations.hpp:128
viennacl::linalg::opencl::matrix_diagonal_assign
void matrix_diagonal_assign(matrix_base< NumericT > &mat, NumericT s)
Definition: matrix_operations.hpp:311
viennacl::matrix_base::stride1
size_type stride1() const
Returns the number of rows.
Definition: matrix_def.hpp:232
viennacl::vector_base< NumericT >
viennacl::linalg::opencl::am
void am(matrix_base< NumericT > &mat1, matrix_base< NumericT > const &mat2, ScalarT1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha)
Definition: matrix_operations.hpp:161
viennacl::vcl_size_t
std::size_t vcl_size_t
Definition: forwards.h:75
viennacl::matrix_base::size2
size_type size2() const
Returns the number of columns.
Definition: matrix_def.hpp:226
viennacl::linalg::opencl::bidiag_pack_svd
void bidiag_pack_svd(viennacl::matrix< SCALARTYPE > &A, VectorType &dh, VectorType &sh)
Definition: matrix_operations.hpp:732
viennacl::vector
Definition: forwards.h:266
viennacl::ocl::program
Wrapper class for an OpenCL program.
Definition: program.hpp:42
viennacl::device_specific::execute
void execute(template_base const &T, statements_container const &statements, viennacl::ocl::context &ctx=viennacl::ocl::current_context(), bool force_compilation=false)
Definition: execute.hpp:44
viennacl::is_division
Helper metafunction for checking whether the provided type is viennacl::op_div (for division) ...
Definition: predicate.hpp:466
viennacl::linalg::opencl::house_update_A_left
void house_update_A_left(matrix_base< NumericT > &A, vector_base< NumericT > &D, vcl_size_t start)
Definition: matrix_operations.hpp:797
viennacl::linalg::opencl::element_op
void element_op(matrix_base< T > &A, matrix_expression< const matrix_base< T >, const matrix_base< T >, op_element_binary< OP > > const &proxy)
Implementation of binary element-wise operations A = OP(B,C)
Definition: matrix_operations.hpp:540
viennacl::matrix_base::size1
size_type size1() const
Returns the number of rows.
Definition: matrix_def.hpp:224
vector_proxy.hpp
Proxy classes for vectors.
viennacl::traits::stride2
result_of::size_type< matrix_base< NumericT > >::type stride2(matrix_base< NumericT > const &s)
Definition: stride.hpp:65
predicate.hpp
All the predicates used within ViennaCL. Checks for expressions to be vectors, etc.
viennacl::linalg::opencl::convert
void convert(matrix_base< DestNumericT > &dest, matrix_base< SrcNumericT > const &src)
Definition: matrix_operations.hpp:134
viennacl::scheduler::preset::mat_mat_prod
statement mat_mat_prod(NumericT alpha, viennacl::matrix_base< NumericT > const *A, bool A_trans, viennacl::matrix_base< NumericT > const *B, bool B_trans, NumericT beta, viennacl::matrix_base< NumericT > const *C)
Definition: preset.hpp:33
viennacl::linalg::opencl::kernels::matrix
Main kernel class for generating OpenCL kernels for operations on/with dense matrix objects of type v...
Definition: matrix.hpp:926
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::linalg::opencl::detail::legacy_kernel_for_matrix
viennacl::ocl::kernel & legacy_kernel_for_matrix(matrix_base< NumericT > const &M, std::string const &kernel_name)
Definition: matrix_operations.hpp:100
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.
vector.hpp
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
viennacl::matrix_base::row_major
bool row_major() const
Definition: matrix_def.hpp:248
ScalarType
float ScalarType
Definition: fft_1d.cpp:42
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
viennacl::linalg::opencl::givens_next
void givens_next(matrix_base< NumericT > &matrix, vector_base< NumericT > &tmp1, vector_base< NumericT > &tmp2, int l, int m)
Definition: matrix_operations.hpp:922
viennacl::op_trans
A tag class representing transposed matrices.
Definition: forwards.h:220
viennacl::matrix_base::start2
size_type start2() const
Returns the number of columns.
Definition: matrix_def.hpp:230
viennacl::op_element_binary
A tag class representing element-wise binary operations (like multiplication) on vectors or matrices...
Definition: forwards.h:130
viennacl::matrix_base::internal_size2
size_type internal_size2() const
Returns the internal number of columns. Usually required for launching OpenCL kernels only...
Definition: matrix_def.hpp:240
viennacl::scheduler::statement
The main class for representing a statement such as x = inner_prod(y,z); at runtime.
Definition: forwards.h:502
viennacl::linalg::opencl::SVD_COPY_COL_KERNEL
const std::string SVD_COPY_COL_KERNEL
Definition: matrix_operations.hpp:130
viennacl::linalg::opencl::ambm_m
void ambm_m(matrix_base< NumericT > &mat1, matrix_base< NumericT > const &mat2, ScalarT1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, matrix_base< NumericT > const &mat3, ScalarT2 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: matrix_operations.hpp:232
viennacl::matrix_base::internal_size1
size_type internal_size1() const
Returns the internal number of rows. Usually required for launching OpenCL kernels only...
Definition: matrix_def.hpp:238
handle.hpp
Extracts the underlying OpenCL handle from a vector, a matrix, an expression etc. ...
viennacl::ocl::program::get_kernel
viennacl::ocl::kernel & get_kernel(std::string const &name)
Returns the kernel with the provided name.
Definition: context.hpp:773
viennacl::traits::handle
viennacl::backend::mem_handle & handle(T &obj)
Returns the generic memory handle of an object. Non-const version.
Definition: handle.hpp:41
viennacl::is_product
Helper metafunction for checking whether the provided type is viennacl::op_prod (for products/multipl...
Definition: predicate.hpp:436
viennacl::linalg::opencl::detail::op_to_string
std::string op_to_string(op_abs)
Definition: common.hpp:78
viennacl::linalg::opencl::kernels::matrix_convert::init
static void init(viennacl::ocl::context &ctx)
Definition: matrix.hpp:1115
viennacl::ocl::type_to_string
Helper class for converting a type to its string representation.
Definition: utils.hpp:57
matrix_element.hpp
OpenCL kernel file for element-wise matrix operations.
viennacl::op_element_unary
A tag class representing element-wise unary operations (like sin()) on vectors or matrices...
Definition: forwards.h:134
scalar.hpp
Implementation of the ViennaCL scalar class.
result_of.hpp
A collection of compile time type deductions.
viennacl::linalg::opencl::kernels::matrix_convert::program_name
static std::string program_name()
Definition: matrix.hpp:1110
viennacl::linalg::opencl::kernels::vector
Main kernel class for generating OpenCL kernels for operations on/with viennacl::vector<> without inv...
Definition: vector.hpp:679
enable_if.hpp
Simple enable-if variant that uses the SFINAE pattern.
viennacl::matrix_base::start1
size_type start1() const
Returns the number of rows.
Definition: matrix_def.hpp:228
viennacl::ocl::packed_cl_uint::size
cl_uint size
Number of values in the stride.
Definition: kernel.hpp:52
matrix.hpp
Runtime generation of OpenCL kernels for matrix operations.
viennacl::fast_copy
void fast_copy(const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_begin, const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_end, CPU_ITERATOR cpu_begin)
viennacl::linalg::opencl::matrix_row
void matrix_row(matrix_base< NumericT > const &mat, unsigned int i, vector_base< NumericT > &vec)
Definition: matrix_operations.hpp:443