All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vector.hpp
Go to the documentation of this file.
#ifndef VIENNACL_VECTOR_HPP_
#define VIENNACL_VECTOR_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/detail/vector_def.hpp"
#include "viennacl/backend/memory.hpp"
#include "viennacl/scalar.hpp"
#include "viennacl/tools/tools.hpp"
#include "viennacl/tools/entry_proxy.hpp"
#include "viennacl/linalg/detail/op_executor.hpp"
#include "viennacl/linalg/vector_operations.hpp"
#include "viennacl/meta/result_of.hpp"
#include "viennacl/context.hpp"
#include "viennacl/traits/handle.hpp"
namespace viennacl
{
//
// Vector expression
//
template<typename LHS, typename RHS, typename OP>
class vector_expression
{
typedef typename viennacl::result_of::reference_if_nonscalar<LHS>::type lhs_reference_type;
typedef typename viennacl::result_of::reference_if_nonscalar<RHS>::type rhs_reference_type;
public:
enum { alignment = 1 };
typedef vcl_size_t size_type;
vector_expression(LHS & l, RHS & r) : lhs_(l), rhs_(r) {}
lhs_reference_type lhs() const { return lhs_; }
rhs_reference_type rhs() const { return rhs_; }
size_type size() const { return viennacl::traits::size(*this); }
private:
lhs_reference_type lhs_;
rhs_reference_type rhs_;
};
template<class NumericT, unsigned int AlignmentV>
class const_vector_iterator
{
typedef const_vector_iterator<NumericT, AlignmentV> self_type;
public:
typedef scalar<NumericT> value_type;
typedef vcl_size_t size_type;
typedef vcl_ptrdiff_t difference_type;
typedef viennacl::backend::mem_handle handle_type;
//const_vector_iterator() {}
const_vector_iterator(vector_base<NumericT> const & vec,
size_type index,
size_type start = 0,
size_type stride = 1) : elements_(vec.handle()), index_(index), start_(start), stride_(stride) {}
const_vector_iterator(handle_type const & elements,
size_type index,
size_type start = 0,
size_type stride = 1) : elements_(elements), index_(index), start_(start), stride_(stride) {}
value_type operator*(void) const
{
value_type result;
result = const_entry_proxy<NumericT>(start_ + index_ * stride(), elements_);
return result;
}
self_type operator++(void) { ++index_; return *this; }
self_type operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
bool operator==(self_type const & other) const { return index_ == other.index_; }
bool operator!=(self_type const & other) const { return index_ != other.index_; }
// self_type & operator=(self_type const & other)
// {
// index_ = other._index;
// elements_ = other._elements;
// return *this;
// }
difference_type operator-(self_type const & other) const
{
assert( (other.start_ == start_) && (other.stride_ == stride_) && bool("Iterators are not from the same vector (proxy)!"));
return static_cast<difference_type>(index_) - static_cast<difference_type>(other.index_);
}
self_type operator+(difference_type diff) const { return self_type(elements_, size_type(difference_type(index_) + diff), start_, stride_); }
//vcl_size_t index() const { return index_; }
size_type offset() const { return start_ + index_ * stride(); }
size_type stride() const { return stride_; }
handle_type const & handle() const { return elements_; }
protected:
handle_type const & elements_;
size_type index_; //offset from the beginning of elements_
size_type start_;
size_type stride_;
};
template<class NumericT, unsigned int AlignmentV>
class vector_iterator : public const_vector_iterator<NumericT, AlignmentV>
{
typedef const_vector_iterator<NumericT, AlignmentV> base_type;
typedef vector_iterator<NumericT, AlignmentV> self_type;
public:
typedef typename base_type::handle_type handle_type;
typedef typename base_type::size_type size_type;
typedef typename base_type::difference_type difference_type;
vector_iterator(handle_type const & elements,
size_type index,
size_type start = 0,
size_type stride = 1) : base_type(elements, index, start, stride), elements_(elements) {}
vector_iterator(vector_base<NumericT> & vec,
size_type index,
size_type start = 0,
size_type stride = 1) : base_type(vec, index, start, stride), elements_(vec.handle()) {}
//vector_iterator(base_type const & b) : base_type(b) {}
entry_proxy<NumericT> operator*(void)
{
return entry_proxy<NumericT>(base_type::start_ + base_type::index_ * base_type::stride(), elements_);
}
difference_type operator-(self_type const & other) const { difference_type result = base_type::index_; return (result - static_cast<difference_type>(other.index_)); }
self_type operator+(difference_type diff) const { return self_type(elements_, static_cast<vcl_size_t>(static_cast<difference_type>(base_type::index_) + diff), base_type::start_, base_type::stride_); }
handle_type & handle() { return elements_; }
handle_type const & handle() const { return base_type::elements_; }
//operator base_type() const
//{
// return base_type(base_type::elements_, base_type::index_, base_type::start_, base_type::stride_);
//}
private:
handle_type elements_;
};
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT>::vector_base() : size_(0), start_(0), stride_(1), internal_size_(0) { /* Note: One must not call ::init() here because a vector might have been created globally before the backend has become available */ }
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT>::vector_base(viennacl::backend::mem_handle & h,
size_type vec_size, size_type vec_start, size_type vec_stride)
: size_(vec_size), start_(vec_start), stride_(vec_stride), internal_size_(vec_size), elements_(h) {}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT>::vector_base(size_type vec_size, viennacl::context ctx)
: size_(vec_size), start_(0), stride_(1), internal_size_(viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size))
{
if (size_ > 0)
{
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), ctx);
clear();
}
}
// CUDA or host memory:
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT>::vector_base(NumericT * ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, vcl_size_t start, size_type stride)
: size_(vec_size), start_(start), stride_(stride), internal_size_(vec_size)
{
if (mem_type == viennacl::CUDA_MEMORY)
{
#ifdef VIENNACL_WITH_CUDA
elements_.switch_active_handle_id(viennacl::CUDA_MEMORY);
elements_.cuda_handle().reset(reinterpret_cast<char*>(ptr_to_mem));
elements_.cuda_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
#else
throw cuda_not_available_exception();
#endif
}
else if (mem_type == viennacl::MAIN_MEMORY)
{
elements_.switch_active_handle_id(viennacl::MAIN_MEMORY);
elements_.ram_handle().reset(reinterpret_cast<char*>(ptr_to_mem));
elements_.ram_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
}
elements_.raw_size(sizeof(NumericT) * vec_size);
}
#ifdef VIENNACL_WITH_OPENCL
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT>::vector_base(cl_mem existing_mem, size_type vec_size, size_type start, size_type stride, viennacl::context ctx)
: size_(vec_size), start_(start), stride_(stride), internal_size_(vec_size)
{
elements_.switch_active_handle_id(viennacl::OPENCL_MEMORY);
elements_.opencl_handle() = existing_mem;
elements_.opencl_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
elements_.opencl_handle().context(ctx.opencl_context());
elements_.raw_size(sizeof(NumericT) * vec_size);
}
#endif
template<class NumericT, typename SizeT, typename DistanceT>
template<typename LHS, typename RHS, typename OP>
vector_base<NumericT, SizeT, DistanceT>::vector_base(vector_expression<const LHS, const RHS, OP> const & proxy)
: size_(viennacl::traits::size(proxy)), start_(0), stride_(1), internal_size_(viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size))
{
if (size_ > 0)
{
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(proxy));
clear();
}
self_type::operator=(proxy);
}
// Copy CTOR:
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT>::vector_base(const vector_base<NumericT, SizeT, DistanceT> & other) :
size_(other.size_), start_(0), stride_(1),
internal_size_(viennacl::tools::align_to_multiple<size_type>(other.size_, dense_padding_size))
{
elements_.switch_active_handle_id(viennacl::traits::active_handle_id(other));
if (internal_size() > 0)
{
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(other));
clear();
self_type::operator=(other);
}
}
// Conversion CTOR:
template<typename NumericT, typename SizeT, typename DistanceT>
template<typename OtherNumericT>
vector_base<NumericT, SizeT, DistanceT>::vector_base(const vector_base<OtherNumericT> & other) :
size_(other.size()), start_(0), stride_(1),
internal_size_(viennacl::tools::align_to_multiple<size_type>(other.size(), dense_padding_size))
{
elements_.switch_active_handle_id(viennacl::traits::active_handle_id(other));
if (internal_size() > 0)
{
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(other));
clear();
self_type::operator=(other);
}
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator=(const self_type & vec)
{
assert( ( (vec.size() == size()) || (size() == 0) )
&& bool("Incompatible vector sizes!"));
if (&vec==this)
return *this;
if (vec.size() > 0)
{
if (size_ == 0)
{
size_ = vec.size();
internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
elements_.switch_active_handle_id(vec.handle().get_active_handle_id());
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(vec));
pad();
}
viennacl::linalg::av(*this,
vec, cpu_value_type(1.0), 1, false, false);
}
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
template<typename LHS, typename RHS, typename OP>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator=(const vector_expression<const LHS, const RHS, OP> & proxy)
{
assert( ( (viennacl::traits::size(proxy) == size()) || (size() == 0) )
&& bool("Incompatible vector sizes!"));
// initialize the necessary buffer
if (size() == 0)
{
size_ = viennacl::traits::size(proxy);
internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(proxy));
pad();
}
linalg::detail::op_executor<self_type, op_assign, vector_expression<const LHS, const RHS, OP> >::apply(*this, proxy);
return *this;
}
// convert from vector with other numeric type
template<class NumericT, typename SizeT, typename DistanceT>
template<typename OtherNumericT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>:: operator = (const vector_base<OtherNumericT> & v1)
{
assert( ( (v1.size() == size()) || (size() == 0) )
&& bool("Incompatible vector sizes!"));
if (size() == 0)
{
size_ = v1.size();
if (size_ > 0)
{
internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(v1));
pad();
}
}
viennacl::linalg::convert(*this, v1);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator = (unit_vector<NumericT> const & v)
{
assert( ( (v.size() == size()) || (size() == 0) )
&& bool("Incompatible vector sizes!"));
if (size() == 0)
{
size_ = v.size();
internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
if (size_ > 0)
{
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), v.context());
clear();
}
}
else
viennacl::linalg::vector_assign(*this, NumericT(0));
if (size_ > 0)
this->operator()(v.index()) = NumericT(1);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator = (zero_vector<NumericT> const & v)
{
assert( ( (v.size() == size()) || (size() == 0) )
&& bool("Incompatible vector sizes!"));
if (size() == 0)
{
size_ = v.size();
internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
if (size_ > 0)
{
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), v.context());
clear();
}
}
else
viennacl::linalg::vector_assign(*this, NumericT(0));
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator = (scalar_vector<NumericT> const & v)
{
assert( ( (v.size() == size()) || (size() == 0) )
&& bool("Incompatible vector sizes!"));
if (size() == 0)
{
size_ = v.size();
internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
if (size_ > 0)
{
viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), v.context());
pad();
}
}
if (size_ > 0)
viennacl::linalg::vector_assign(*this, v[0]);
return *this;
}
//Note: The following operator overloads are defined in matrix_operations.hpp, compressed_matrix_operations.hpp and coordinate_matrix_operations.hpp
//This is certainly not the nicest approach and will most likely by changed in the future, but it works :-)
//matrix<>
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator=(const viennacl::vector_expression< const matrix_base<NumericT>, const vector_base<NumericT>, viennacl::op_prod> & proxy)
{
assert(viennacl::traits::size1(proxy.lhs()) == size() && bool("Size check failed for v1 = A * v2: size1(A) != size(v1)"));
// check for the special case x = A * x
if (viennacl::traits::handle(proxy.rhs()) == viennacl::traits::handle(*this))
{
viennacl::vector<NumericT> result(viennacl::traits::size1(proxy.lhs()));
viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
*this = result;
}
else
{
viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
}
return *this;
}
//transposed_matrix_proxy:
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator=(const vector_expression< const matrix_expression< const matrix_base<NumericT>, const matrix_base<NumericT>, op_trans >,
const vector_base<NumericT>,
op_prod> & proxy)
{
assert(viennacl::traits::size1(proxy.lhs()) == size() && bool("Size check failed in v1 = trans(A) * v2: size2(A) != size(v1)"));
// check for the special case x = trans(A) * x
if (viennacl::traits::handle(proxy.rhs()) == viennacl::traits::handle(*this))
{
viennacl::vector<NumericT> result(viennacl::traits::size1(proxy.lhs()));
viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
*this = result;
}
else
{
viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
}
return *this;
}
//read-write access to an element of the vector
template<class NumericT, typename SizeT, typename DistanceT>
entry_proxy<NumericT> vector_base<NumericT, SizeT, DistanceT>::operator()(size_type index)
{
assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
assert( index < size() && bool("Index out of bounds!") );
return entry_proxy<NumericT>(start_ + stride_ * index, elements_);
}
template<class NumericT, typename SizeT, typename DistanceT>
entry_proxy<NumericT> vector_base<NumericT, SizeT, DistanceT>::operator[](size_type index)
{
assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
assert( index < size() && bool("Index out of bounds!") );
return entry_proxy<NumericT>(start_ + stride_ * index, elements_);
}
template<class NumericT, typename SizeT, typename DistanceT>
const_entry_proxy<NumericT> vector_base<NumericT, SizeT, DistanceT>::operator()(size_type index) const
{
assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
assert( index < size() && bool("Index out of bounds!") );
return const_entry_proxy<NumericT>(start_ + stride_ * index, elements_);
}
template<class NumericT, typename SizeT, typename DistanceT>
const_entry_proxy<NumericT> vector_base<NumericT, SizeT, DistanceT>::operator[](size_type index) const
{
assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
assert( index < size() && bool("Index out of bounds!") );
return const_entry_proxy<NumericT>(start_ + stride_ * index, elements_);
}
//
// Operator overloads with implicit conversion (thus cannot be made global without introducing additional headache)
//
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator += (const self_type & vec)
{
assert(vec.size() == size() && bool("Incompatible vector sizes!"));
if (size() > 0)
viennacl::linalg::avbv(*this,
*this, NumericT(1.0), 1, false, false,
vec, NumericT(1.0), 1, false, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator -= (const self_type & vec)
{
assert(vec.size() == size() && bool("Incompatible vector sizes!"));
if (size() > 0)
viennacl::linalg::avbv(*this,
*this, NumericT(1.0), 1, false, false,
vec, NumericT(-1.0), 1, false, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (char val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, false, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (short val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, false, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (int val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, false, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (long val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, false, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (float val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, false, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (double val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, false, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (char val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, true, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (short val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, true, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (int val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, true, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (long val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, true, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (float val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, true, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (double val)
{
if (size() > 0)
viennacl::linalg::av(*this,
*this, NumericT(val), 1, true, false);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
vector_base<NumericT, SizeT, DistanceT>::operator * (char value) const
{
return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
vector_base<NumericT, SizeT, DistanceT>::operator * (short value) const
{
return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
vector_base<NumericT, SizeT, DistanceT>::operator * (int value) const
{
return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
vector_base<NumericT, SizeT, DistanceT>::operator * (long value) const
{
return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
vector_base<NumericT, SizeT, DistanceT>::operator * (float value) const
{
return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
vector_base<NumericT, SizeT, DistanceT>::operator * (double value) const
{
return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
vector_base<NumericT, SizeT, DistanceT>::operator / (char value) const
{
return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
vector_base<NumericT, SizeT, DistanceT>::operator / (short value) const
{
return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
vector_base<NumericT, SizeT, DistanceT>::operator / (int value) const
{
return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
vector_base<NumericT, SizeT, DistanceT>::operator / (long value) const
{
return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
vector_base<NumericT, SizeT, DistanceT>::operator / (float value) const
{
return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
vector_base<NumericT, SizeT, DistanceT>::operator / (double value) const
{
return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_expression<const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
vector_base<NumericT, SizeT, DistanceT>::operator-() const
{
return vector_expression<const self_type, const NumericT, op_mult>(*this, NumericT(-1.0));
}
//
//
template<class NumericT, typename SizeT, typename DistanceT>
typename vector_base<NumericT, SizeT, DistanceT>::iterator vector_base<NumericT, SizeT, DistanceT>::begin()
{
return iterator(*this, 0, start_, stride_);
}
template<class NumericT, typename SizeT, typename DistanceT>
typename vector_base<NumericT, SizeT, DistanceT>::iterator vector_base<NumericT, SizeT, DistanceT>::end()
{
return iterator(*this, size(), start_, stride_);
}
template<class NumericT, typename SizeT, typename DistanceT>
typename vector_base<NumericT, SizeT, DistanceT>::const_iterator vector_base<NumericT, SizeT, DistanceT>::begin() const
{
return const_iterator(*this, 0, start_, stride_);
}
template<class NumericT, typename SizeT, typename DistanceT>
typename vector_base<NumericT, SizeT, DistanceT>::const_iterator vector_base<NumericT, SizeT, DistanceT>::end() const
{
return const_iterator(*this, size(), start_, stride_);
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::swap(self_type & other)
{
viennacl::linalg::vector_swap(*this, other);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
void vector_base<NumericT, SizeT, DistanceT>::clear()
{
viennacl::linalg::vector_assign(*this, cpu_value_type(0.0), true);
}
template<class NumericT, typename SizeT, typename DistanceT>
vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::fast_swap(self_type & other)
{
assert(this->size_ == other.size_ && bool("Vector size mismatch"));
this->elements_.swap(other.elements_);
return *this;
}
template<class NumericT, typename SizeT, typename DistanceT>
void vector_base<NumericT, SizeT, DistanceT>::pad()
{
if (internal_size() != size())
{
std::vector<NumericT> pad(internal_size() - size());
viennacl::backend::memory_write(elements_, sizeof(NumericT) * size(), sizeof(NumericT) * pad.size(), &(pad[0]));
}
}
template<class NumericT, typename SizeT, typename DistanceT>
void vector_base<NumericT, SizeT, DistanceT>::switch_memory_context(viennacl::context new_ctx)
{
viennacl::backend::switch_memory_context<NumericT>(elements_, new_ctx);
}
//TODO: Think about implementing the following public member functions
//void insert_element(unsigned int i, NumericT val){}
//void erase_element(unsigned int i){}
template<class NumericT, typename SizeT, typename DistanceT>
void vector_base<NumericT, SizeT, DistanceT>::resize(size_type new_size, bool preserve)
{
resize_impl(new_size, viennacl::traits::context(*this), preserve);
}
template<class NumericT, typename SizeT, typename DistanceT>
void vector_base<NumericT, SizeT, DistanceT>::resize(size_type new_size, viennacl::context ctx, bool preserve)
{
resize_impl(new_size, ctx, preserve);
}
template<class NumericT, typename SizeT, typename DistanceT>
void vector_base<NumericT, SizeT, DistanceT>::resize_impl(size_type new_size, viennacl::context ctx, bool preserve)
{
assert(new_size > 0 && bool("Positive size required when resizing vector!"));
if (new_size != size_)
{
vcl_size_t new_internal_size = viennacl::tools::align_to_multiple<vcl_size_t>(new_size, dense_padding_size);
std::vector<NumericT> temp(size_);
if (preserve && size_ > 0)
fast_copy(*this, temp);
temp.resize(new_size); //drop all entries above new_size
temp.resize(new_internal_size); //enlarge to fit new internal size
if (new_internal_size != internal_size())
{
viennacl::backend::memory_create(elements_, sizeof(NumericT)*new_internal_size, ctx, NULL);
}
fast_copy(temp, *this);
size_ = new_size;
internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
pad();
}
}
template<class NumericT, unsigned int AlignmentV>
class vector : public vector_base<NumericT>
{
typedef vector<NumericT, AlignmentV> self_type;
typedef vector_base<NumericT> base_type;
public:
typedef typename base_type::size_type size_type;
typedef typename base_type::difference_type difference_type;
explicit vector() : base_type() { /* Note: One must not call ::init() here because the vector might have been created globally before the backend has become available */ }
explicit vector(size_type vec_size) : base_type(vec_size) {}
explicit vector(size_type vec_size, viennacl::context ctx) : base_type(vec_size, ctx) {}
explicit vector(NumericT * ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, size_type start = 0, size_type stride = 1)
: base_type(ptr_to_mem, mem_type, vec_size, start, stride) {}
#ifdef VIENNACL_WITH_OPENCL
explicit vector(cl_mem existing_mem, size_type vec_size, size_type start = 0, size_type stride = 1) : base_type(existing_mem, vec_size, start, stride) {}
explicit vector(size_type vec_size, viennacl::ocl::context const & ctx) : base_type(vec_size, ctx) {}
#endif
template<typename LHS, typename RHS, typename OP>
vector(vector_expression<const LHS, const RHS, OP> const & proxy) : base_type(proxy) {}
vector(const base_type & v) : base_type(v.size(), viennacl::traits::context(v))
{
if (v.size() > 0)
base_type::operator=(v);
}
vector(const self_type & v) : base_type(v.size(), viennacl::traits::context(v))
{
if (v.size() > 0)
base_type::operator=(v);
}
vector(unit_vector<NumericT> const & v) : base_type(v.size())
{
if (v.size() > 0)
this->operator()(v.index()) = NumericT(1);;
}
vector(zero_vector<NumericT> const & v) : base_type(v.size(), v.context())
{
if (v.size() > 0)
viennacl::linalg::vector_assign(*this, NumericT(0.0));
}
vector(scalar_vector<NumericT> const & v) : base_type(v.size(), v.context())
{
if (v.size() > 0)
viennacl::linalg::vector_assign(*this, v[0]);
}
// the following is used to circumvent an issue with Clang 3.0 when 'using base_type::operator=;' directly
template<typename T>
self_type & operator=(T const & other)
{
base_type::operator=(other);
return *this;
}
using base_type::operator+=;
using base_type::operator-=;
//enlarge or reduce allocated memory and set unused memory to zero
void resize(size_type new_size, bool preserve = true)
{
base_type::resize(new_size, preserve);
}
void resize(size_type new_size, viennacl::context ctx, bool preserve = true)
{
base_type::resize(new_size, ctx, preserve);
}
self_type & fast_swap(self_type & other)
{
base_type::fast_swap(other);
return *this;
}
void switch_memory_context(viennacl::context new_ctx)
{
base_type::switch_memory_context(new_ctx);
}
}; //vector
template<typename ScalarT>
class vector_tuple
{
typedef vector_base<ScalarT> VectorType;
public:
// 2 vectors
vector_tuple(VectorType const & v0, VectorType const & v1) : const_vectors_(2), non_const_vectors_()
{
const_vectors_[0] = &v0;
const_vectors_[1] = &v1;
}
vector_tuple(VectorType & v0, VectorType & v1) : const_vectors_(2), non_const_vectors_(2)
{
const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
}
// 3 vectors
vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2) : const_vectors_(3), non_const_vectors_()
{
const_vectors_[0] = &v0;
const_vectors_[1] = &v1;
const_vectors_[2] = &v2;
}
vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2) : const_vectors_(3), non_const_vectors_(3)
{
const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
}
// 4 vectors
vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2, VectorType const & v3) : const_vectors_(4), non_const_vectors_()
{
const_vectors_[0] = &v0;
const_vectors_[1] = &v1;
const_vectors_[2] = &v2;
const_vectors_[3] = &v3;
}
vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2, VectorType & v3) : const_vectors_(4), non_const_vectors_(4)
{
const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
const_vectors_[3] = &v3; non_const_vectors_[3] = &v3;
}
// add more overloads here
// generic interface:
vector_tuple(std::vector<VectorType const *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_()
{
for (vcl_size_t i=0; i<vecs.size(); ++i)
const_vectors_[i] = vecs[i];
}
vector_tuple(std::vector<VectorType *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_(vecs.size())
{
for (vcl_size_t i=0; i<vecs.size(); ++i)
{
const_vectors_[i] = vecs[i];
non_const_vectors_[i] = vecs[i];
}
}
vcl_size_t size() const { return non_const_vectors_.size(); }
vcl_size_t const_size() const { return const_vectors_.size(); }
VectorType & at(vcl_size_t i) const { return *(non_const_vectors_.at(i)); }
VectorType const & const_at(vcl_size_t i) const { return *(const_vectors_.at(i)); }
private:
std::vector<VectorType const *> const_vectors_;
std::vector<VectorType *> non_const_vectors_;
};
// 2 args
template<typename ScalarT>
vector_tuple<ScalarT> tie(vector_base<ScalarT> const & v0, vector_base<ScalarT> const & v1) { return vector_tuple<ScalarT>(v0, v1); }
template<typename ScalarT>
vector_tuple<ScalarT> tie(vector_base<ScalarT> & v0, vector_base<ScalarT> & v1) { return vector_tuple<ScalarT>(v0, v1); }
// 3 args
template<typename ScalarT>
vector_tuple<ScalarT> tie(vector_base<ScalarT> const & v0, vector_base<ScalarT> const & v1, vector_base<ScalarT> const & v2) { return vector_tuple<ScalarT>(v0, v1, v2); }
template<typename ScalarT>
vector_tuple<ScalarT> tie(vector_base<ScalarT> & v0, vector_base<ScalarT> & v1, vector_base<ScalarT> & v2) { return vector_tuple<ScalarT>(v0, v1, v2); }
// 4 args
template<typename ScalarT>
vector_tuple<ScalarT> tie(vector_base<ScalarT> const & v0, vector_base<ScalarT> const & v1, vector_base<ScalarT> const & v2, vector_base<ScalarT> const & v3)
{
return vector_tuple<ScalarT>(v0, v1, v2, v3);
}
template<typename ScalarT>
vector_tuple<ScalarT> tie(vector_base<ScalarT> & v0, vector_base<ScalarT> & v1, vector_base<ScalarT> & v2, vector_base<ScalarT> & v3)
{
return vector_tuple<ScalarT>(v0, v1, v2, v3);
}
// 5 args
template<typename ScalarT>
vector_tuple<ScalarT> tie(vector_base<ScalarT> const & v0,
vector_base<ScalarT> const & v1,
vector_base<ScalarT> const & v2,
vector_base<ScalarT> const & v3,
vector_base<ScalarT> const & v4)
{
typedef vector_base<ScalarT> const * VectorPointerType;
std::vector<VectorPointerType> vec(5);
vec[0] = &v0;
vec[1] = &v1;
vec[2] = &v2;
vec[3] = &v3;
vec[4] = &v4;
return vector_tuple<ScalarT>(vec);
}
template<typename ScalarT>
vector_tuple<ScalarT> tie(vector_base<ScalarT> & v0,
vector_base<ScalarT> & v1,
vector_base<ScalarT> & v2,
vector_base<ScalarT> & v3,
vector_base<ScalarT> & v4)
{
typedef vector_base<ScalarT> * VectorPointerType;
std::vector<VectorPointerType> vec(5);
vec[0] = &v0;
vec[1] = &v1;
vec[2] = &v2;
vec[3] = &v3;
vec[4] = &v4;
return vector_tuple<ScalarT>(vec);
}
// TODO: Add more arguments to tie() here. Maybe use some preprocessor magic to accomplish this.
//
//
template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
void fast_copy(const const_vector_iterator<NumericT, AlignmentV> & gpu_begin,
const const_vector_iterator<NumericT, AlignmentV> & gpu_end,
CPU_ITERATOR cpu_begin )
{
if (gpu_begin != gpu_end)
{
if (gpu_begin.stride() == 1)
{
viennacl::backend::memory_read(gpu_begin.handle(),
sizeof(NumericT)*gpu_begin.offset(),
sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(gpu_end - gpu_begin),
&(*cpu_begin));
}
else
{
vcl_size_t gpu_size = static_cast<vcl_size_t>(gpu_end - gpu_begin);
std::vector<NumericT> temp_buffer(gpu_begin.stride() * gpu_size);
viennacl::backend::memory_read(gpu_begin.handle(), sizeof(NumericT)*gpu_begin.offset(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
for (vcl_size_t i=0; i<gpu_size; ++i)
{
(&(*cpu_begin))[i] = temp_buffer[i * gpu_begin.stride()];
}
}
}
}
template<typename NumericT, typename CPUVECTOR>
void fast_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
{
viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
}
template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
void async_copy(const const_vector_iterator<NumericT, AlignmentV> & gpu_begin,
const const_vector_iterator<NumericT, AlignmentV> & gpu_end,
CPU_ITERATOR cpu_begin )
{
if (gpu_begin != gpu_end)
{
if (gpu_begin.stride() == 1)
{
viennacl::backend::memory_read(gpu_begin.handle(),
sizeof(NumericT)*gpu_begin.offset(),
sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(gpu_end - gpu_begin),
&(*cpu_begin),
true);
}
else // no async copy possible, so fall-back to fast_copy
fast_copy(gpu_begin, gpu_end, cpu_begin);
}
}
template<typename NumericT, typename CPUVECTOR>
void async_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
{
viennacl::async_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
}
template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
void copy(const const_vector_iterator<NumericT, AlignmentV> & gpu_begin,
const const_vector_iterator<NumericT, AlignmentV> & gpu_end,
CPU_ITERATOR cpu_begin )
{
assert(gpu_end - gpu_begin >= 0 && bool("Iterators incompatible"));
if (gpu_end - gpu_begin != 0)
{
std::vector<NumericT> temp_buffer(static_cast<vcl_size_t>(gpu_end - gpu_begin));
fast_copy(gpu_begin, gpu_end, temp_buffer.begin());
//now copy entries to cpu_vec:
std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_begin);
}
}
template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
void copy(const vector_iterator<NumericT, AlignmentV> & gpu_begin,
const vector_iterator<NumericT, AlignmentV> & gpu_end,
CPU_ITERATOR cpu_begin )
{
viennacl::copy(const_vector_iterator<NumericT, AlignmentV>(gpu_begin),
const_vector_iterator<NumericT, AlignmentV>(gpu_end),
cpu_begin);
}
template<typename NumericT, typename CPUVECTOR>
void copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
{
viennacl::copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
}
#ifdef VIENNACL_WITH_EIGEN
template<typename NumericT, unsigned int AlignmentV>
void copy(vector<NumericT, AlignmentV> const & gpu_vec,
Eigen::Matrix<NumericT, Eigen::Dynamic, 1> & eigen_vec)
{
viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
}
template<typename NumericT, unsigned int AlignmentV, int EigenMapTypeV, typename EigenStrideT>
void copy(vector<NumericT, AlignmentV> const & gpu_vec,
Eigen::Map<Eigen::Matrix<NumericT, Eigen::Dynamic, 1>, EigenMapTypeV, EigenStrideT> & eigen_vec)
{
viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
}
#endif
//
//
template<typename CPU_ITERATOR, typename NumericT, unsigned int AlignmentV>
void fast_copy(CPU_ITERATOR const & cpu_begin,
CPU_ITERATOR const & cpu_end,
vector_iterator<NumericT, AlignmentV> gpu_begin)
{
if (cpu_end - cpu_begin > 0)
{
if (gpu_begin.stride() == 1)
{
viennacl::backend::memory_write(gpu_begin.handle(),
sizeof(NumericT)*gpu_begin.offset(),
sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(cpu_end - cpu_begin), &(*cpu_begin));
}
else //writing to slice:
{
vcl_size_t cpu_size = static_cast<vcl_size_t>(cpu_end - cpu_begin);
std::vector<NumericT> temp_buffer(gpu_begin.stride() * cpu_size);
viennacl::backend::memory_read(gpu_begin.handle(), sizeof(NumericT)*gpu_begin.offset(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
for (vcl_size_t i=0; i<cpu_size; ++i)
temp_buffer[i * gpu_begin.stride()] = (&(*cpu_begin))[i];
viennacl::backend::memory_write(gpu_begin.handle(), sizeof(NumericT)*gpu_begin.offset(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
}
}
}
template<typename CPUVECTOR, typename NumericT>
void fast_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
{
viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
}
template<typename CPU_ITERATOR, typename NumericT, unsigned int AlignmentV>
void async_copy(CPU_ITERATOR const & cpu_begin,
CPU_ITERATOR const & cpu_end,
vector_iterator<NumericT, AlignmentV> gpu_begin)
{
if (cpu_end - cpu_begin > 0)
{
if (gpu_begin.stride() == 1)
{
viennacl::backend::memory_write(gpu_begin.handle(),
sizeof(NumericT)*gpu_begin.offset(),
sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(cpu_end - cpu_begin), &(*cpu_begin),
true);
}
else // fallback to blocking copy. There's nothing we can do to prevent this
fast_copy(cpu_begin, cpu_end, gpu_begin);
}
}
template<typename CPUVECTOR, typename NumericT>
void async_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
{
viennacl::async_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
}
//from cpu to gpu. Safe assumption: cpu_vector does not necessarily occupy a linear memory segment, but is not larger than the allocated memory on the GPU
template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
void copy(CPU_ITERATOR const & cpu_begin,
CPU_ITERATOR const & cpu_end,
vector_iterator<NumericT, AlignmentV> gpu_begin)
{
assert(cpu_end - cpu_begin > 0 && bool("Iterators incompatible"));
if (cpu_begin != cpu_end)
{
//we require that the size of the gpu_vector is larger or equal to the cpu-size
std::vector<NumericT> temp_buffer(static_cast<vcl_size_t>(cpu_end - cpu_begin));
std::copy(cpu_begin, cpu_end, temp_buffer.begin());
viennacl::fast_copy(temp_buffer.begin(), temp_buffer.end(), gpu_begin);
}
}
// for things like copy(std_vec.begin(), std_vec.end(), vcl_vec.begin() + 1);
template<typename HostVectorT, typename T>
void copy(HostVectorT const & cpu_vec, vector_base<T> & gpu_vec)
{
viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
}
template<typename HostVectorT, typename T, unsigned int AlignmentV>
void copy(HostVectorT const & cpu_vec, vector<T, AlignmentV> & gpu_vec)
{
if (gpu_vec.size() == 0)
gpu_vec.resize(static_cast<vcl_size_t>(cpu_vec.end() - cpu_vec.begin()));
viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
}
#ifdef VIENNACL_WITH_EIGEN
template<typename NumericT, unsigned int AlignmentV>
void copy(Eigen::Matrix<NumericT, Eigen::Dynamic, 1> const & eigen_vec,
vector<NumericT, AlignmentV> & gpu_vec)
{
viennacl::fast_copy(eigen_vec.data(), eigen_vec.data() + eigen_vec.size(), gpu_vec.begin());
}
template<typename NumericT, int EigenMapTypeV, typename EigenStrideT, unsigned int AlignmentV>
void copy(Eigen::Map<Eigen::Matrix<NumericT, Eigen::Dynamic, 1>, EigenMapTypeV, EigenStrideT> const & eigen_vec,
vector<NumericT, AlignmentV> & gpu_vec)
{
viennacl::fast_copy(eigen_vec.data(), eigen_vec.data() + eigen_vec.size(), gpu_vec.begin());
}
#endif
//
//
template<typename NumericT, unsigned int AlignmentV_SRC, unsigned int AlignmentV_DEST>
void copy(const_vector_iterator<NumericT, AlignmentV_SRC> const & gpu_src_begin,
const_vector_iterator<NumericT, AlignmentV_SRC> const & gpu_src_end,
vector_iterator<NumericT, AlignmentV_DEST> gpu_dest_begin)
{
assert(gpu_src_end - gpu_src_begin >= 0);
assert(gpu_src_begin.stride() == 1 && bool("ViennaCL ERROR: copy() for GPU->GPU not implemented for slices! Use operator= instead for the moment."));
if (gpu_src_begin.stride() == 1 && gpu_dest_begin.stride() == 1)
{
if (gpu_src_begin != gpu_src_end)
viennacl::backend::memory_copy(gpu_src_begin.handle(), gpu_dest_begin.handle(),
sizeof(NumericT) * gpu_src_begin.offset(),
sizeof(NumericT) * gpu_dest_begin.offset(),
sizeof(NumericT) * (gpu_src_end.offset() - gpu_src_begin.offset()));
}
else
{
assert( false && bool("not implemented yet"));
}
}
template<typename NumericT, unsigned int AlignmentV_SRC, unsigned int AlignmentV_DEST>
void copy(vector_iterator<NumericT, AlignmentV_SRC> const & gpu_src_begin,
vector_iterator<NumericT, AlignmentV_SRC> const & gpu_src_end,
vector_iterator<NumericT, AlignmentV_DEST> gpu_dest_begin)
{
viennacl::copy(static_cast<const_vector_iterator<NumericT, AlignmentV_SRC> >(gpu_src_begin),
static_cast<const_vector_iterator<NumericT, AlignmentV_SRC> >(gpu_src_end),
gpu_dest_begin);
}
template<typename NumericT, unsigned int AlignmentV_SRC, unsigned int AlignmentV_DEST>
void copy(vector<NumericT, AlignmentV_SRC> const & gpu_src_vec,
vector<NumericT, AlignmentV_DEST> & gpu_dest_vec )
{
viennacl::copy(gpu_src_vec.begin(), gpu_src_vec.end(), gpu_dest_vec.begin());
}
//global functions for handling vectors:
template<typename T>
std::ostream & operator<<(std::ostream & os, vector_base<T> const & val)
{
std::vector<T> tmp(val.size());
viennacl::copy(val.begin(), val.end(), tmp.begin());
os << "[" << val.size() << "](";
for (typename std::vector<T>::size_type i=0; i<val.size(); ++i)
{
if (i > 0)
os << ",";
os << tmp[i];
}
os << ")";
return os;
}
template<typename LHS, typename RHS, typename OP>
std::ostream & operator<<(std::ostream & os, vector_expression<LHS, RHS, OP> const & proxy)
{
typedef typename viennacl::result_of::cpu_value_type<typename LHS::value_type>::type ScalarType;
viennacl::vector<ScalarType> result = proxy;
os << result;
return os;
}
template<typename T>
void swap(vector_base<T> & vec1, vector_base<T> & vec2)
{
viennacl::linalg::vector_swap(vec1, vec2);
}
template<typename NumericT, unsigned int AlignmentV>
vector<NumericT, AlignmentV> & fast_swap(vector<NumericT, AlignmentV> & v1,
vector<NumericT, AlignmentV> & v2)
{
return v1.fast_swap(v2);
}
//
//
//
//
//
// operator *=
//
template<typename T, typename S1>
typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
vector_base<T> &
>::type
operator *= (vector_base<T> & v1, S1 const & gpu_val)
{
bool flip_sign = viennacl::is_flip_sign_scalar<S1>::value;
if (v1.size() > 0)
viennacl::linalg::av(v1,
v1, gpu_val, 1, false, flip_sign);
return v1;
}
//
// operator /=
//
template<typename T, typename S1>
typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
vector_base<T> &
>::type
operator /= (vector_base<T> & v1, S1 const & gpu_val)
{
bool flip_sign = viennacl::is_flip_sign_scalar<S1>::value;
if (v1.size() > 0)
viennacl::linalg::av(v1,
v1, gpu_val, 1, true, flip_sign);
return v1;
}
//
// operator +
//
template<typename LHS1, typename RHS1, typename OP1,
typename LHS2, typename RHS2, typename OP2>
vector_expression< const vector_expression< LHS1, RHS1, OP1>,
const vector_expression< LHS2, RHS2, OP2>,
viennacl::op_add>
operator + (vector_expression<LHS1, RHS1, OP1> const & proxy1,
vector_expression<LHS2, RHS2, OP2> const & proxy2)
{
assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
return vector_expression< const vector_expression<LHS1, RHS1, OP1>,
const vector_expression<LHS2, RHS2, OP2>,
viennacl::op_add>(proxy1, proxy2);
}
template<typename LHS, typename RHS, typename OP, typename T>
vector_expression< const vector_expression<LHS, RHS, OP>,
const vector_base<T>,
viennacl::op_add>
operator + (vector_expression<LHS, RHS, OP> const & proxy,
vector_base<T> const & vec)
{
assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
return vector_expression< const vector_expression<LHS, RHS, OP>,
const vector_base<T>,
viennacl::op_add>(proxy, vec);
}
template<typename T, typename LHS, typename RHS, typename OP>
vector_expression< const vector_base<T>,
const vector_expression<LHS, RHS, OP>,
viennacl::op_add>
operator + (vector_base<T> const & vec,
vector_expression<LHS, RHS, OP> const & proxy)
{
assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
return vector_expression< const vector_base<T>,
const vector_expression<LHS, RHS, OP>,
viennacl::op_add>(vec, proxy);
}
template<typename T>
vector_expression< const vector_base<T>, const vector_base<T>, op_add>
operator + (const vector_base<T> & v1, const vector_base<T> & v2)
{
return vector_expression< const vector_base<T>, const vector_base<T>, op_add>(v1, v2);
}
//
// operator -
//
template<typename LHS1, typename RHS1, typename OP1,
typename LHS2, typename RHS2, typename OP2>
vector_expression< const vector_expression< LHS1, RHS1, OP1>,
const vector_expression< LHS2, RHS2, OP2>,
viennacl::op_sub>
operator - (vector_expression<LHS1, RHS1, OP1> const & proxy1,
vector_expression<LHS2, RHS2, OP2> const & proxy2)
{
assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
return vector_expression< const vector_expression<LHS1, RHS1, OP1>,
const vector_expression<LHS2, RHS2, OP2>,
viennacl::op_sub>(proxy1, proxy2);
}
template<typename LHS, typename RHS, typename OP, typename T>
vector_expression< const vector_expression<LHS, RHS, OP>,
const vector_base<T>,
viennacl::op_sub>
operator - (vector_expression<LHS, RHS, OP> const & proxy,
vector_base<T> const & vec)
{
assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
return vector_expression< const vector_expression<LHS, RHS, OP>,
const vector_base<T>,
viennacl::op_sub>(proxy, vec);
}
template<typename T, typename LHS, typename RHS, typename OP>
vector_expression< const vector_base<T>,
const vector_expression<LHS, RHS, OP>,
viennacl::op_sub>
operator - (vector_base<T> const & vec,
vector_expression<LHS, RHS, OP> const & proxy)
{
assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
return vector_expression< const vector_base<T>,
const vector_expression<LHS, RHS, OP>,
viennacl::op_sub>(vec, proxy);
}
template<typename T>
vector_expression< const vector_base<T>, const vector_base<T>, op_sub>
operator - (const vector_base<T> & v1, const vector_base<T> & v2)
{
return vector_expression< const vector_base<T>, const vector_base<T>, op_sub>(v1, v2);
}
//
// operator *
//
template<typename S1, typename T>
typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
vector_expression< const vector_base<T>, const S1, op_mult> >::type
operator * (S1 const & value, vector_base<T> const & vec)
{
return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
}
template<typename T>
vector_expression< const vector_base<T>, const T, op_mult>
operator * (char value, vector_base<T> const & vec)
{
return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
}
template<typename T>
vector_expression< const vector_base<T>, const T, op_mult>
operator * (short value, vector_base<T> const & vec)
{
return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
}
template<typename T>
vector_expression< const vector_base<T>, const T, op_mult>
operator * (int value, vector_base<T> const & vec)
{
return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
}
template<typename T>
vector_expression< const vector_base<T>, const T, op_mult>
operator * (long value, vector_base<T> const & vec)
{
return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
}
template<typename T>
vector_expression< const vector_base<T>, const T, op_mult>
operator * (float value, vector_base<T> const & vec)
{
return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
}
template<typename T>
vector_expression< const vector_base<T>, const T, op_mult>
operator * (double value, vector_base<T> const & vec)
{
return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
}
template<typename LHS, typename RHS, typename OP, typename T>
vector_expression< const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult>
operator * (scalar_expression<LHS, RHS, OP> const & expr, vector_base<T> const & vec)
{
return vector_expression< const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult>(vec, expr);
}
template<typename T, typename S1>
typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
vector_expression< const vector_base<T>, const S1, op_mult> >::type
operator * (vector_base<T> const & vec, S1 const & value)
{
return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
}
template<typename T>
vector_expression< const vector_base<T>, const T, op_mult>
operator * (vector_base<T> const & vec, T const & value)
{
return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
}
template<typename LHS, typename RHS, typename OP, typename S1>
typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult> >::type
operator * (vector_expression< LHS, RHS, OP> const & proxy,
S1 const & val)
{
return viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult>(proxy, val);
}
template<typename S1, typename LHS, typename RHS, typename OP>
typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult> >::type
operator * (S1 const & val,
vector_expression<LHS, RHS, OP> const & proxy)
{
return viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult>(proxy, val);
}
//
// operator /
//
template<typename S1, typename LHS, typename RHS, typename OP>
typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_div> >::type
operator / (vector_expression< LHS, RHS, OP> const & proxy,
S1 const & val)
{
return viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_div>(proxy, val);
}
template<typename T, typename S1>
typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
vector_expression< const vector_base<T>, const S1, op_div> >::type
operator / (vector_base<T> const & v1, S1 const & s1)
{
return vector_expression<const vector_base<T>, const S1, op_div>(v1, s1);
}
//
// Specify available operations:
//
namespace linalg
{
namespace detail
{
// x = y
template<typename T>
struct op_executor<vector_base<T>, op_assign, vector_base<T> >
{
static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
{
viennacl::linalg::av(lhs, rhs, T(1), 1, false, false);
}
};
// x = inner_prod(z, {y0, y1, ...})
template<typename T>
struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> const & rhs)
{
viennacl::linalg::inner_prod_impl(rhs.lhs(), rhs.rhs(), lhs);
}
};
// x += y
template<typename T>
struct op_executor<vector_base<T>, op_inplace_add, vector_base<T> >
{
static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
{
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, false);
}
};
// x -= y
template<typename T>
struct op_executor<vector_base<T>, op_inplace_sub, vector_base<T> >
{
static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
{
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, true);
}
};
// x = alpha * y
template<typename T, typename ScalarType>
struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
{
// generic case: ScalarType is a scalar expression
template<typename LHS, typename RHS, typename OP>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
{
T alpha = proxy.rhs();
viennacl::linalg::av(lhs, proxy.lhs(), alpha, 1, false, false);
}
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
{
viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
}
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
{
viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
}
};
// x += alpha * y
template<typename T, typename ScalarType>
struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
{
// generic case: ScalarType is a scalar expression
template<typename LHS, typename RHS, typename OP>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
{
T alpha = proxy.rhs();
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, false);
}
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
{
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
}
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
{
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
}
};
// x -= alpha * y
template<typename T, typename ScalarType>
struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
{
// generic case: ScalarType is a scalar expression
template<typename LHS, typename RHS, typename OP>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
{
T alpha = proxy.rhs();
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, true);
}
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
{
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
}
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
{
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
}
};
// x = alpha * vec_expr
template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
{
vector<T> temp(proxy.lhs());
lhs = temp * proxy.rhs();
}
};
// x += alpha * vec_expr
template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
{
vector<T> temp(proxy.lhs());
lhs += temp * proxy.rhs();
}
};
// x -= alpha * vec_expr
template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
{
vector<T> temp(proxy.lhs());
lhs -= temp * proxy.rhs();
}
};
// x = y / alpha
template<typename T, typename ScalarType>
struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_div> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
{
viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, true, false);
}
};
// x += y / alpha
template<typename T, typename ScalarType>
struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_div> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
{
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, false);
}
};
// x -= y / alpha
template<typename T, typename ScalarType>
struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_div> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
{
viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, true);
}
};
// x = vec_expr / alpha
template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
{
vector<T> temp(proxy.lhs());
lhs = temp / proxy.rhs();
}
};
// x += vec_expr / alpha
template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
{
vector<T> temp(proxy.lhs());
lhs += temp / proxy.rhs();
}
};
// x -= vec_expr / alpha
template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
{
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
{
vector<T> temp(proxy.lhs());
lhs -= temp / proxy.rhs();
}
};
// generic x = vec_expr1 + vec_expr2:
template<typename T, typename LHS, typename RHS>
struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_add> >
{
// generic x = vec_expr1 + vec_expr2:
template<typename LHS1, typename RHS1>
static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
{
bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
if (op_aliasing_lhs || op_aliasing_rhs)
{
vector_base<T> temp(proxy.lhs());
op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
lhs = temp;
}
else
{
op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
}
}
// x = y + z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs(), T(1), 1, false, false);
}
// x = alpha * y + z
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
const vector_base<T>,
op_add> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs(), T(1), 1, false, false);
}
// x = y / alpha + z
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
const vector_base<T>,
op_add> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs(), T(1), 1, false, false);
}
// x = y + beta * z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const T, op_mult>,
op_add> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
}
// x = y + z / beta
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const T, op_div>,
op_add> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
}
// x = alpha * y + beta * z
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
const vector_expression<const vector_base<T>, const T, op_mult>,
op_add> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
}
// x = alpha * y + z / beta
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
const vector_expression<const vector_base<T>, const T, op_div>,
op_add> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
}
// x = y / alpha + beta * z
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
const vector_expression<const vector_base<T>, const T, op_mult>,
op_add> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
}
// x = y / alpha + z / beta
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
const vector_expression<const vector_base<T>, const T, op_div>,
op_add> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
}
};
// generic x += vec_expr1 + vec_expr2:
template<typename T, typename LHS, typename RHS>
struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_add> >
{
// generic x += vec_expr1 + vec_expr2:
template<typename LHS1, typename RHS1>
static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
{
bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
if (op_aliasing_lhs || op_aliasing_rhs)
{
vector_base<T> temp(proxy.lhs());
op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
lhs += temp;
}
else
{
op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
}
}
// x += y + z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs(), T(1), 1, false, false);
}
// x += alpha * y + z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
const vector_base<T>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs(), T(1), 1, false, false);
}
// x += y / alpha + z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
const vector_base<T>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs(), T(1), 1, false, false);
}
// x += y + beta * z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
}
// x += y + z / beta
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_div>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
}
// x += alpha * y + beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
}
// x += alpha * y + z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
}
// x += y / alpha + beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
}
// x += y / alpha + z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
}
};
// generic x -= vec_expr1 + vec_expr2:
template<typename T, typename LHS, typename RHS>
struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_add> >
{
// generic x -= vec_expr1 + vec_expr2:
template<typename LHS1, typename RHS1>
static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
{
bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
if (op_aliasing_lhs || op_aliasing_rhs)
{
vector_base<T> temp(proxy.lhs());
op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
lhs -= temp;
}
else
{
op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
}
}
// x -= y + z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, true,
proxy.rhs(), T(1), 1, false, true);
}
// x -= alpha * y + z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
const vector_base<T>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
proxy.rhs(), T(1), 1, false, true);
}
// x -= y / alpha + z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
const vector_base<T>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
proxy.rhs(), T(1), 1, false, true);
}
// x -= y + beta * z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
}
// x -= y + z / beta
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_div>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
}
// x -= alpha * y + beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
}
// x -= alpha * y + z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
}
// x -= y / alpha + beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
}
// x -= y / alpha + z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_add> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
}
};
// generic x = vec_expr1 - vec_expr2:
template<typename T, typename LHS, typename RHS>
struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_sub> >
{
// generic x = vec_expr1 - vec_expr2:
template<typename LHS1, typename RHS1>
static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
{
bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
if (op_aliasing_lhs || op_aliasing_rhs)
{
vector_base<T> temp(proxy.lhs());
op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
lhs = temp;
}
else
{
op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
}
}
// x = y - z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs(), T(1), 1, false, true);
}
// x = alpha * y - z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
const vector_base<T>,
op_sub> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs(), T(1), 1, false, true);
}
// x = y / alpha - z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
const vector_base<T>,
op_sub> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs(), T(1), 1, false, true);
}
// x = y - beta * z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
op_sub> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
}
// x = y - z / beta
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_div>,
op_sub> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
}
// x = alpha * y - beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_sub> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
}
// x = alpha * y - z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_sub> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
}
// x = y / alpha - beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_sub> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
}
// x = y / alpha - z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_sub> const & proxy)
{
viennacl::linalg::avbv(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
}
};
// generic x += vec_expr1 - vec_expr2:
template<typename T, typename LHS, typename RHS>
struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_sub> >
{
// generic x += vec_expr1 - vec_expr2:
template<typename LHS1, typename RHS1>
static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
{
bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
if (op_aliasing_lhs || op_aliasing_rhs)
{
vector_base<T> temp(proxy.lhs());
op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
lhs += temp;
}
else
{
op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
}
}
// x += y - z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs(), T(1), 1, false, true);
}
// x += alpha * y - z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
const vector_base<T>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs(), T(1), 1, false, true);
}
// x += y / alpha - z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
const vector_base<T>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs(), T(1), 1, false, true);
}
// x += y - beta * z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
}
// x += y - z / beta
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_div>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
}
// x += alpha * y - beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
}
// x += alpha * y - z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
}
// x += y / alpha - beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
}
// x += y / alpha - z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
}
};
// generic x -= vec_expr1 - vec_expr2:
template<typename T, typename LHS, typename RHS>
struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_sub> >
{
// generic x -= vec_expr1 - vec_expr2:
template<typename LHS1, typename RHS1>
static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
{
bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
if (op_aliasing_lhs || op_aliasing_rhs)
{
vector_base<T> temp(proxy.lhs());
op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
lhs -= temp;
}
else
{
op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
}
}
// x -= y - z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, true,
proxy.rhs(), T(1), 1, false, false);
}
// x -= alpha * y - z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
const vector_base<T>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
proxy.rhs(), T(1), 1, false, false);
}
// x -= y / alpha - z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
const vector_base<T>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
proxy.rhs(), T(1), 1, false, false);
}
// x -= y - beta * z
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
}
// x -= y - z / beta
template<typename ScalarType>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
const vector_expression<const vector_base<T>, const ScalarType, op_div>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs(), T(1), 1, false, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
}
// x -= alpha * y - beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
}
// x -= alpha * y - z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
}
// x -= y / alpha - beta * z
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
}
// x -= y / alpha - z / beta
template<typename ScalarType1, typename ScalarType2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
op_sub> const & proxy)
{
viennacl::linalg::avbv_v(lhs,
proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
}
};
// generic x = vec_expr1 .* vec_expr2:
template<typename T, typename LHS, typename RHS, typename OP>
struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
{
// x = y .* z or x = y ./ z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
{
viennacl::linalg::element_op(lhs, proxy);
}
// x = y .* vec_expr or x = y ./ vec_expr
template<typename LHS2, typename RHS2, typename OP2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_expression<const LHS2, const RHS2, OP2>, op_element_binary<OP> > const & proxy)
{
vector<T> temp(proxy.rhs());
viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
}
// x = vec_expr .* z or x = vec_expr ./ z
template<typename LHS1, typename RHS1, typename OP1>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>, const vector_base<T>, op_element_binary<OP> > const & proxy)
{
vector<T> temp(proxy.lhs());
viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
}
// x = vec_expr .* vec_expr or z = vec_expr .* vec_expr
template<typename LHS1, typename RHS1, typename OP1,
typename LHS2, typename RHS2, typename OP2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
const vector_expression<const LHS2, const RHS2, OP2>,
op_element_binary<OP> > const & proxy)
{
vector<T> temp1(proxy.lhs());
vector<T> temp2(proxy.rhs());
viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
}
};
// generic x += vec_expr1 .* vec_expr2:
template<typename T, typename LHS, typename RHS, typename OP>
struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
{
// x += y .* z or x += y ./ z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
{
viennacl::vector<T> temp(proxy);
lhs += temp;
}
// x += y .* vec_expr or x += y ./ vec_expr
template<typename LHS2, typename RHS2, typename OP2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_expression<const LHS2, const RHS2, OP2>, op_element_binary<OP> > const & proxy)
{
vector<T> temp(proxy.rhs());
vector<T> temp2(temp.size());
viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
lhs += temp2;
}
// x += vec_expr .* z or x += vec_expr ./ z
template<typename LHS1, typename RHS1, typename OP1>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>, const vector_base<T>, op_element_binary<OP> > const & proxy)
{
vector<T> temp(proxy.lhs());
vector<T> temp2(temp.size());
viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
lhs += temp2;
}
// x += vec_expr .* vec_expr or x += vec_expr ./ vec_expr
template<typename LHS1, typename RHS1, typename OP1,
typename LHS2, typename RHS2, typename OP2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
const vector_expression<const LHS2, const RHS2, OP2>,
op_element_binary<OP> > const & proxy)
{
vector<T> temp1(proxy.lhs());
vector<T> temp2(proxy.rhs());
vector<T> temp3(temp1.size());
viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
lhs += temp3;
}
};
// generic x -= vec_expr1 .* vec_expr2:
template<typename T, typename LHS, typename RHS, typename OP>
struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
{
// x -= y .* z or x -= y ./ z
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
{
viennacl::vector<T> temp(proxy);
lhs -= temp;
}
// x -= y .* vec_expr or x -= y ./ vec_expr
template<typename LHS2, typename RHS2, typename OP2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_expression<const LHS2, const RHS2, OP2>, op_element_binary<OP> > const & proxy)
{
vector<T> temp(proxy.rhs());
vector<T> temp2(temp.size());
viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
lhs -= temp2;
}
// x -= vec_expr .* z or x -= vec_expr ./ z
template<typename LHS1, typename RHS1, typename OP1>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>, const vector_base<T>, op_element_binary<OP> > const & proxy)
{
vector<T> temp(proxy.lhs());
vector<T> temp2(temp.size());
viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
lhs -= temp2;
}
// x -= vec_expr .* vec_expr or x -= vec_expr ./ vec_expr
template<typename LHS1, typename RHS1, typename OP1,
typename LHS2, typename RHS2, typename OP2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
const vector_expression<const LHS2, const RHS2, OP2>,
op_element_binary<OP> > const & proxy)
{
vector<T> temp1(proxy.lhs());
vector<T> temp2(proxy.rhs());
vector<T> temp3(temp1.size());
viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
lhs -= temp3;
}
};
template<typename T, typename LHS, typename RHS, typename OP>
struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
{
// x = OP(y)
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
{
viennacl::linalg::element_op(lhs, proxy);
}
// x = OP(vec_expr)
template<typename LHS2, typename RHS2, typename OP2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
const vector_expression<const LHS2, const RHS2, OP2>,
op_element_unary<OP> > const & proxy)
{
vector<T> temp(proxy.rhs());
viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> >(temp, temp));
}
};
template<typename T, typename LHS, typename RHS, typename OP>
struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
{
// x += OP(y)
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
{
vector<T> temp(proxy);
lhs += temp;
}
// x += OP(vec_expr)
template<typename LHS2, typename RHS2, typename OP2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
const vector_expression<const LHS2, const RHS2, OP2>,
op_element_unary<OP> > const & proxy)
{
vector<T> temp(proxy.rhs());
viennacl::linalg::element_op(temp, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> >(temp, temp)); // inplace operation is safe here
lhs += temp;
}
};
template<typename T, typename LHS, typename RHS, typename OP>
struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
{
// x -= OP(y)
static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
{
vector<T> temp(proxy);
lhs -= temp;
}
// x -= OP(vec_expr)
template<typename LHS2, typename RHS2, typename OP2>
static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
const vector_expression<const LHS2, const RHS2, OP2>,
op_element_unary<OP> > const & proxy)
{
vector<T> temp(proxy.rhs());
viennacl::linalg::element_op(temp, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> >(temp, temp)); // inplace operation is safe here
lhs -= temp;
}
};
template<typename T, typename UserMatrixT>
struct op_executor<vector_base<T>, op_assign, vector_expression<const UserMatrixT, const vector_base<T>, op_prod> >
{
static void apply(vector_base<T> & lhs, vector_expression<const UserMatrixT, const vector_base<T>, op_prod> const & rhs)
{
rhs.lhs().apply(rhs.rhs(), lhs);
}
};
} // namespace detail
} // namespace linalg
} // namespace viennacl
#endif
viennacl::vector_base< NumericT >::difference_type
DistanceT difference_type
Definition: vector_def.hpp:113
viennacl::enable_if
Simple enable-if variant that uses the SFINAE pattern.
Definition: enable_if.hpp:30
viennacl::op_mult
A tag class representing multiplication by a scalar.
Definition: forwards.h:92
viennacl::vector_tuple::const_size
vcl_size_t const_size() const
Definition: vector.hpp:1143
viennacl::const_vector_iterator< NumericT, AlignmentV >
viennacl::cuda_not_available_exception
Definition: forwards.h:585
viennacl::backend::memory_write
void memory_write(mem_handle &dst_buffer, vcl_size_t dst_offset, vcl_size_t bytes_to_write, const void *ptr, bool async=false)
Writes data from main RAM identified by 'ptr' to the buffer identified by 'dst_buffer'.
Definition: memory.hpp:220
viennacl::const_vector_iterator::handle
handle_type const & handle() const
Definition: vector.hpp:174
viennacl::vector_base::vector_base
vector_base()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:251
viennacl::scalar
This class represents a single scalar value on the GPU and behaves mostly like a built-in scalar type...
Definition: forwards.h:227
viennacl::vector_base::operator*
vector_expression< const self_type, const NumericT, op_mult > operator*(char value) const
Scales the vector by a char (8-bit integer) 'alpha' and returns an expression template.
Definition: vector.hpp:742
viennacl::vector::vector
vector(scalar_vector< NumericT > const &v)
Creates the vector from the supplied scalar vector.
Definition: vector.hpp:1023
viennacl::vector_tuple::at
VectorType & at(vcl_size_t i) const
Definition: vector.hpp:1145
viennacl::const_vector_iterator::index_
size_type index_
Definition: vector.hpp:179
viennacl::linalg::detail::op_executor
Worker class for decomposing expression templates.
Definition: op_executor.hpp:80
viennacl::const_entry_proxy
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
Definition: forwards.h:236
viennacl::vector::size_type
base_type::size_type size_type
Definition: vector.hpp:956
viennacl::fast_swap
vector< NumericT, AlignmentV > & fast_swap(vector< NumericT, AlignmentV > &v1, vector< NumericT, AlignmentV > &v2)
Swaps the content of two vectors by swapping OpenCL handles only, NO data is copied.
Definition: vector.hpp:1659
op_executor.hpp
Defines the worker class for decomposing an expression tree into small chunks, which can be processed...
vector_operations.hpp
Implementations of vector operations.
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2, VectorType const &v3)
Definition: vector.hpp:1108
viennacl::const_vector_iterator::const_vector_iterator
const_vector_iterator(vector_base< NumericT > const &vec, size_type index, size_type start=0, size_type stride=1)
Constructor.
Definition: vector.hpp:125
viennacl::is_flip_sign_scalar
Helper struct for checking whether a type represents a sign flip on a viennacl::scalar<> ...
Definition: forwards.h:462
viennacl::implicit_vector_base::index
vcl_size_t index() const
Definition: vector_def.hpp:49
viennacl::vector_base::switch_memory_context
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:899
tools.hpp
Various little tools used here and there in ViennaCL.
viennacl::vector_base::operator[]
entry_proxy< NumericT > operator[](size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:571
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::const_vector_iterator::operator-
difference_type operator-(self_type const &other) const
Definition: vector.hpp:161
viennacl::tools::shared_ptr::inc
void inc()
Definition: shared_ptr.hpp:154
viennacl::vector_base::swap
self_type & swap(self_type &other)
Swaps the entries of the two vectors.
Definition: vector.hpp:867
viennacl::ocl::context
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:55
viennacl::op_sub
A tag class representing subtraction.
Definition: forwards.h:90
entry_proxy.hpp
A proxy class for entries in a vector.
viennacl::linalg::avbv_v
void avbv_v(vector_base< T > &vec1, vector_base< T > const &vec2, ScalarType1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, vector_base< T > const &vec3, ScalarType2 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: vector_operations.hpp:144
viennacl::OPENCL_MEMORY
Definition: forwards.h:349
viennacl::const_vector_iterator::operator==
bool operator==(self_type const &other) const
Definition: vector.hpp:151
viennacl::matrix_base< NumericT >
viennacl::vector::vector
vector(vector_expression< const LHS, const RHS, OP > const &proxy)
Definition: vector.hpp:994
viennacl::matrix_expression
Expression template class for representing a tree of expressions which ultimately result in a matrix...
Definition: forwards.h:341
viennacl::vector::operator=
self_type & operator=(T const &other)
Definition: vector.hpp:1031
viennacl::vector_base::pad
void pad()
Pads vectors with alignment > 1 with trailing zeros if the internal size is larger than the visible s...
Definition: vector.hpp:889
viennacl::const_vector_iterator::elements_
handle_type const & elements_
The index of the entry the iterator is currently pointing to.
Definition: vector.hpp:178
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
viennacl::vector_tuple::vector_tuple
vector_tuple(std::vector< VectorType const * > const &vecs)
Definition: vector.hpp:1127
forwards.h
This file provides the forward declarations for the main types used within ViennaCL.
viennacl::zero_vector
Definition: vector_def.hpp:93
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2)
Definition: vector.hpp:1099
viennacl::op_div
A tag class representing division.
Definition: forwards.h:98
viennacl::backend::memory_read
void memory_read(mem_handle const &src_buffer, vcl_size_t src_offset, vcl_size_t bytes_to_read, void *ptr, bool async=false)
Reads data from a buffer back to main RAM.
Definition: memory.hpp:261
viennacl::vector_base::operator/
vector_expression< const self_type, const NumericT, op_div > operator/(char value) const
Scales the vector by a char (8-bit integer) 'alpha' and returns an expression template.
Definition: vector.hpp:786
viennacl::operator/=
viennacl::enable_if< viennacl::is_scalar< S1 >::value, matrix_base< NumericT > & >::type operator/=(matrix_base< NumericT > &m1, S1 const &gpu_val)
Scales a matrix by a GPU scalar value.
Definition: matrix.hpp:1674
viennacl::operator*
viennacl::enable_if< viennacl::is_any_scalar< S1 >::value, matrix_expression< const matrix_base< NumericT >, const S1, op_mult >>::type operator*(S1 const &value, matrix_base< NumericT > const &m1)
Operator overload for the expression alpha * m1, where alpha is a host scalar (float or double) and m...
Definition: matrix.hpp:1374
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::vector_base::operator-=
self_type & operator-=(const self_type &vec)
Definition: vector.hpp:616
viennacl::vector::vector
vector(const self_type &v)
Definition: vector.hpp:1002
viennacl::scalar_expression
A proxy for scalar expressions (e.g. from inner vector products)
Definition: forwards.h:230
viennacl::vector_expression::lhs
lhs_reference_type lhs() const
Get left hand side operand.
Definition: vector.hpp:74
viennacl::vector_expression
An expression template class that represents a binary operation that yields a vector.
Definition: forwards.h:239
viennacl::linalg::element_op
void element_op(matrix_base< T > &A, matrix_expression< const matrix_base< T >, const matrix_base< T >, OP > const &proxy)
Implementation of the element-wise operation A = B .* C and A = B ./ C for matrices (using MATLAB syn...
Definition: matrix_operations.hpp:702
viennacl::const_vector_iterator::operator*
value_type operator*(void) const
Dereferences the iterator and returns the value of the element. For convenience only, performance is poor due to OpenCL overhead!
Definition: vector.hpp:142
viennacl::linalg::detail::op_aliasing
bool op_aliasing(vector_base< NumericT > const &, B const &)
Definition: op_executor.hpp:36
viennacl::const_vector_iterator::value_type
scalar< NumericT > value_type
Definition: vector.hpp:112
viennacl::vector_base::resize
void resize(size_type new_size, bool preserve=true)
Resizes the allocated memory for the vector. Pads the memory to be a multiple of 'AlignmentV'.
Definition: vector.hpp:909
viennacl::vector_base::operator+=
self_type & operator+=(const self_type &vec)
Definition: vector.hpp:604
viennacl::operator-
viennacl::vector< NumericT > operator-(const vector_base< NumericT > &v1, const vector_expression< const matrix_base< NumericT >, const vector_base< NumericT >, op_prod > &proxy)
Implementation of the operation 'result = v1 - A * v2', where A is a matrix.
Definition: matrix_operations.hpp:1200
viennacl::swap
void swap(vector_base< T > &vec1, vector_base< T > &vec2)
Swaps the contents of two vectors, data is copied.
Definition: vector.hpp:1648
context.hpp
Implementation of a OpenCL-like context, which serves as a unification of {OpenMP, CUDA, OpenCL} at the user API.
viennacl::vector::vector
vector(const base_type &v)
Definition: vector.hpp:996
viennacl::vector::vector
vector(unit_vector< NumericT > const &v)
Creates the vector from the supplied unit vector.
Definition: vector.hpp:1009
viennacl::vector_expression::vector_expression
vector_expression(LHS &l, RHS &r)
Definition: vector.hpp:70
NumericT
float NumericT
Definition: bisect.cpp:40
viennacl::vector_base::operator-
vector_expression< const self_type, const NumericT, op_mult > operator-() const
Sign flip for the vector. Emulated to be equivalent to -1.0 * vector.
Definition: vector.hpp:830
viennacl::vector_base::operator()
entry_proxy< NumericT > operator()(size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:562
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType const &v0, VectorType const &v1)
Definition: vector.hpp:1080
viennacl::context
Represents a generic 'context' similar to an OpenCL context, but is backend-agnostic and thus also su...
Definition: context.hpp:39
viennacl::const_vector_iterator::handle_type
viennacl::backend::mem_handle handle_type
Definition: vector.hpp:115
viennacl::implicit_vector_base::context
viennacl::context context() const
Definition: vector_def.hpp:46
viennacl::const_vector_iterator::operator++
self_type operator++(void)
Definition: vector.hpp:148
viennacl::vector::vector
vector(NumericT *ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, size_type start=0, size_type stride=1)
Definition: vector.hpp:971
v1
viennacl::vector< float > v1
Definition: global_variables.cpp:60
viennacl::const_vector_iterator::difference_type
vcl_ptrdiff_t difference_type
Definition: vector.hpp:114
viennacl::vector_iterator::operator+
self_type operator+(difference_type diff) const
Definition: vector.hpp:236
viennacl::operator*=
viennacl::enable_if< viennacl::is_scalar< S1 >::value, matrix_base< NumericT > & >::type operator*=(matrix_base< NumericT > &m1, S1 const &gpu_val)
Scales a matrix by a GPU scalar value.
Definition: matrix.hpp:1522
viennacl::const_vector_iterator::operator!=
bool operator!=(self_type const &other) const
Definition: vector.hpp:152
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::const_vector_iterator::offset
size_type offset() const
Offset of the current element index with respect to the beginning of the buffer.
Definition: vector.hpp:170
viennacl::linalg::inner_prod_impl
void inner_prod_impl(vector_base< T > const &vec1, vector_base< T > const &vec2, scalar< T > &result)
Computes the inner product of two vectors - dispatcher interface.
Definition: vector_operations.hpp:387
viennacl::vector_iterator::vector_iterator
vector_iterator(handle_type const &elements, size_type index, size_type start=0, size_type stride=1)
Definition: vector.hpp:214
viennacl::linalg::convert
void convert(matrix_base< DestNumericT > &dest, matrix_base< SrcNumericT > const &src)
Definition: matrix_operations.hpp:54
viennacl::CUDA_MEMORY
Definition: forwards.h:350
viennacl::vector_base::begin
iterator begin()
Returns an iterator pointing to the beginning of the vector (STL like)
Definition: vector.hpp:841
viennacl::vector_iterator::handle
handle_type & handle()
Definition: vector.hpp:238
viennacl::vector::difference_type
base_type::difference_type difference_type
Definition: vector.hpp:957
viennacl::vector_tuple
Tuple class holding pointers to multiple vectors. Mainly used as a temporary object returned from vie...
Definition: forwards.h:269
viennacl::implicit_vector_base::size
vcl_size_t size() const
Definition: vector_def.hpp:47
viennacl::vector_iterator
A STL-type iterator for vector elements. Elements can be accessed and manipulated. VERY SLOW!!
Definition: forwards.h:242
viennacl::traits::start
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:44
viennacl::linalg::host_based::detail::flip_sign
NumericT flip_sign(NumericT val)
Definition: vector_operations.hpp:57
viennacl::linalg::vector_swap
void vector_swap(vector_base< T > &vec1, vector_base< T > &vec2)
Swaps the contents of two vectors, data is copied.
Definition: vector_operations.hpp:218
viennacl::vector_expression::rhs
rhs_reference_type rhs() const
Get right hand side operand.
Definition: vector.hpp:77
viennacl::op_add
A tag class representing addition.
Definition: forwards.h:88
viennacl::vector::resize
void resize(size_type new_size, bool preserve=true)
Resizes the allocated memory for the vector. Pads the memory to be a multiple of 'AlignmentV'.
Definition: vector.hpp:1046
viennacl::vector::resize
void resize(size_type new_size, viennacl::context ctx, bool preserve=true)
Definition: vector.hpp:1051
viennacl::vector_base< NumericT >
viennacl::vector_base::cpu_value_type
NumericT cpu_value_type
Definition: vector_def.hpp:110
viennacl::operator/
viennacl::enable_if< viennacl::is_any_scalar< S1 >::value, matrix_expression< const matrix_expression< const LHS, const RHS, OP >, const S1, op_div > >::type operator/(matrix_expression< const LHS, const RHS, OP > const &proxy, S1 const &val)
Operator overload for the division of a matrix expression by a scalar from the right, e.g. (beta * m1) / alpha. Here, beta * m1 is wrapped into a matrix_expression and then divided by alpha.
Definition: matrix.hpp:1603
viennacl::vector_base::operator=
self_type & operator=(const self_type &vec)
Assignment operator. Other vector needs to be of the same size, or this vector is not yet initialized...
Definition: vector.hpp:356
viennacl::vcl_size_t
std::size_t vcl_size_t
Definition: forwards.h:75
viennacl::tie
vector_tuple< ScalarT > tie(vector_base< ScalarT > const &v0, vector_base< ScalarT > const &v1)
Definition: vector.hpp:1155
viennacl::vector< NumericT >
viennacl::traits::active_handle_id
viennacl::memory_types active_handle_id(T const &obj)
Returns an ID for the currently active memory domain of an object.
Definition: handle.hpp:218
viennacl::result_of::cpu_value_type::type
T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type
Definition: result_of.hpp:271
viennacl::linalg::avbv
void avbv(vector_base< T > &vec1, vector_base< T > const &vec2, ScalarType1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, vector_base< T > const &vec3, ScalarType2 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: vector_operations.hpp:107
viennacl::vector_iterator::vector_iterator
vector_iterator(vector_base< NumericT > &vec, size_type index, size_type start=0, size_type stride=1)
Constructor.
Definition: vector.hpp:224
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2)
Definition: vector.hpp:1093
viennacl::vector_expression::alignment
Definition: vector.hpp:64
viennacl::vector_tuple::size
vcl_size_t size() const
Definition: vector.hpp:1142
viennacl::vector::fast_swap
self_type & fast_swap(self_type &other)
Swaps the handles of two vectors by swapping the OpenCL handles only, no data copy.
Definition: vector.hpp:1058
viennacl::MAIN_MEMORY
Definition: forwards.h:348
viennacl::vector_iterator::operator-
difference_type operator-(self_type const &other) const
Definition: vector.hpp:235
viennacl::const_vector_iterator::stride_
size_type stride_
Definition: vector.hpp:181
viennacl::operator+
viennacl::vector< NumericT > operator+(const vector_base< NumericT > &v1, const vector_expression< const matrix_base< NumericT >, const vector_base< NumericT >, op_prod > &proxy)
Implementation of the operation 'result = v1 + A * v2', where A is a matrix.
Definition: matrix_operations.hpp:1182
viennacl::backend::mem_handle::switch_active_handle_id
void switch_active_handle_id(memory_types new_id)
Switches the currently active handle. If no support for that backend is provided, an exception is thr...
Definition: mem_handle.hpp:121
viennacl::backend::memory_copy
void memory_copy(mem_handle const &src_buffer, mem_handle &dst_buffer, vcl_size_t src_offset, vcl_size_t dst_offset, vcl_size_t bytes_to_copy)
Copies 'bytes_to_copy' bytes from address 'src_buffer + src_offset' to memory starting at address 'ds...
Definition: memory.hpp:140
viennacl::op_prod
A tag class representing matrix-vector products and element-wise multiplications. ...
Definition: forwards.h:94
viennacl::vector_base::clear
void clear()
Resets all entries to zero. Does not change the size of the vector.
Definition: vector.hpp:875
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::vector_base::operator/=
self_type & operator/=(char val)
Scales a vector (or proxy) by a char (8-bit integer)
Definition: vector.hpp:685
viennacl::unit_vector
Represents a vector consisting of 1 at a given index and zeros otherwise.
Definition: vector_def.hpp:76
viennacl::vector_iterator::operator*
entry_proxy< NumericT > operator*(void)
Definition: vector.hpp:230
viennacl::vector::vector
vector(size_type vec_size, viennacl::context ctx)
Definition: vector.hpp:969
viennacl::tools::align_to_multiple
INT_TYPE align_to_multiple(INT_TYPE to_reach, INT_TYPE base)
Rounds an integer to the next multiple of another integer.
Definition: tools.hpp:133
v2
viennacl::vector< int > v2
Definition: global_variables.cpp:61
viennacl::vector_expression::size
size_type size() const
Returns the size of the result vector.
Definition: vector.hpp:80
viennacl::scalar_vector
Represents a vector consisting of scalars 's' only, i.e. v[i] = s for all i. To be used as an initial...
Definition: vector_def.hpp:87
viennacl::copy
void copy(std::vector< NumericT > &cpu_vec, circulant_matrix< NumericT, AlignmentV > &gpu_mat)
Copies a circulant matrix from the std::vector to the OpenCL device (either GPU or multi-core CPU) ...
Definition: circulant_matrix.hpp:150
viennacl::const_vector_iterator::operator+
self_type operator+(difference_type diff) const
Definition: vector.hpp:166
viennacl::vector_base::size
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector_def.hpp:118
viennacl::linalg::av
void av(vector_base< T > &vec1, vector_base< T > const &vec2, ScalarType1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha)
Definition: vector_operations.hpp:78
ScalarType
float ScalarType
Definition: fft_1d.cpp:42
viennacl::tools::shared_ptr::reset
void reset()
Definition: shared_ptr.hpp:123
viennacl::copy
void copy(vector< NumericT, AlignmentV_SRC > const &gpu_src_vec, vector< NumericT, AlignmentV_DEST > &gpu_dest_vec)
Transfer from a ViennaCL vector to another ViennaCL vector. Convenience wrapper for viennacl::linalg:...
Definition: vector.hpp:1600
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType &v0, VectorType &v1)
Definition: vector.hpp:1085
viennacl::backend::mem_handle
Main abstraction class for multiple memory domains. Represents a buffer in either main RAM...
Definition: mem_handle.hpp:89
viennacl::vector_tuple::const_at
VectorType const & const_at(vcl_size_t i) const
Definition: vector.hpp:1146
viennacl::op_trans
A tag class representing transposed matrices.
Definition: forwards.h:220
viennacl::vector_iterator::handle
handle_type const & handle() const
Definition: vector.hpp:239
viennacl::vector::vector
vector(size_type vec_size)
An explicit constructor for the vector, allocating the given amount of memory (plus a padding specifi...
Definition: vector.hpp:967
viennacl::vector_iterator::size_type
base_type::size_type size_type
Definition: vector.hpp:211
viennacl::backend::mem_handle::raw_size
vcl_size_t raw_size() const
Returns the number of bytes of the currently active buffer.
Definition: mem_handle.hpp:230
viennacl::const_vector_iterator::start_
size_type start_
Definition: vector.hpp:180
viennacl::backend::memory_create
void memory_create(mem_handle &handle, vcl_size_t size_in_bytes, viennacl::context const &ctx, const void *host_ptr=NULL)
Creates an array of the specified size. If the second argument is provided, the buffer is initialized...
Definition: memory.hpp:87
viennacl::linalg::vector_assign
void vector_assign(vector_base< T > &vec1, const T &alpha, bool up_to_internal_size=false)
Assign a constant value to a vector (-range/-slice)
Definition: vector_operations.hpp:187
vector_def.hpp
Forward declarations of the implicit_vector_base, vector_base class.
viennacl::vector_expression::size_type
vcl_size_t size_type
Extracts the vector type from the two operands.
Definition: vector.hpp:68
handle.hpp
Extracts the underlying OpenCL handle from a vector, a matrix, an expression etc. ...
viennacl::linalg::prod_impl
void prod_impl(const matrix_base< NumericT > &mat, const vector_base< NumericT > &vec, vector_base< NumericT > &result)
Carries out matrix-vector multiplication.
Definition: matrix_operations.hpp:438
viennacl::vector_base::internal_size
size_type internal_size() const
Returns the internal length of the vector, which is given by size() plus the extra memory due to padd...
Definition: vector_def.hpp:120
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::vector_base::end
iterator end()
Returns an iterator pointing to the end of the vector (STL like)
Definition: vector.hpp:848
viennacl::memory_types
memory_types
Definition: forwards.h:345
viennacl::entry_proxy
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
Definition: forwards.h:233
viennacl::const_vector_iterator::size_type
vcl_size_t size_type
Definition: vector.hpp:113
diff
ScalarType diff(ScalarType &s1, viennacl::scalar< ScalarType > &s2)
Definition: blas3_solve.cpp:50
viennacl::vector::vector
vector()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:961
viennacl::async_copy
void async_copy(const const_vector_iterator< NumericT, AlignmentV > &gpu_begin, const const_vector_iterator< NumericT, AlignmentV > &gpu_end, CPU_ITERATOR cpu_begin)
Asynchronous version of fast_copy(), copying data from device to host. The host iterator cpu_begin ne...
Definition: vector.hpp:1284
scalar.hpp
Implementation of the ViennaCL scalar class.
result_of.hpp
A collection of compile time type deductions.
viennacl::const_vector_iterator::operator++
self_type operator++(int)
Definition: vector.hpp:149
op_assign
Definition: self_assign.cpp:132
viennacl::vector_base::operator*=
self_type & operator*=(char val)
Scales a vector (or proxy) by a char (8-bit integer)
Definition: vector.hpp:629
viennacl::vector_iterator::difference_type
base_type::difference_type difference_type
Definition: vector.hpp:212
viennacl::vector_base::handle
const handle_type & handle() const
Returns the memory handle.
Definition: vector_def.hpp:128
viennacl::vector::vector
vector(zero_vector< NumericT > const &v)
Creates the vector from the supplied zero vector.
Definition: vector.hpp:1016
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2, VectorType &v3)
Definition: vector.hpp:1115
memory.hpp
Main interface routines for memory management.
viennacl::vector_base::fast_swap
self_type & fast_swap(self_type &other)
Swaps the handles of two vectors by swapping the OpenCL handles only, no data copy.
Definition: vector.hpp:881
viennacl::backend::mem_handle::ram_handle
ram_handle_type & ram_handle()
Returns the handle to a buffer in CPU RAM. NULL is returned if no such buffer has been allocated...
Definition: mem_handle.hpp:99
viennacl::vector_tuple::vector_tuple
vector_tuple(std::vector< VectorType * > const &vecs)
Definition: vector.hpp:1133
viennacl::const_vector_iterator::stride
size_type stride() const
Index increment in the underlying buffer when incrementing the iterator to the next element...
Definition: vector.hpp:173
viennacl::vector_iterator::handle_type
base_type::handle_type handle_type
Definition: vector.hpp:210
viennacl::const_vector_iterator::const_vector_iterator
const_vector_iterator(handle_type const &elements, size_type index, size_type start=0, size_type stride=1)
Constructor for vector-like treatment of arbitrary buffers.
Definition: vector.hpp:136
viennacl::vcl_ptrdiff_t
std::ptrdiff_t vcl_ptrdiff_t
Definition: forwards.h:76
viennacl::vector_base::size_type
SizeT size_type
Definition: vector_def.hpp:112
viennacl::vector::switch_memory_context
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:1064
viennacl::backend::mem_handle::get_active_handle_id
memory_types get_active_handle_id() const
Returns an ID for the currently active memory buffer. Other memory buffers might contain old or no da...
Definition: mem_handle.hpp:118
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)