/usr/include/boost/compute/container
Edit: /usr/include/boost/compute/container/valarray.hpp (16704B)
//---------------------------------------------------------------------------//
// Copyright (c) 2013 Kyle Lutz
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// See http://boostorg.github.com/compute for more information.
//---------------------------------------------------------------------------//
#ifndef BOOST_COMPUTE_CONTAINER_VALARRAY_HPP
#define BOOST_COMPUTE_CONTAINER_VALARRAY_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost {
namespace compute {
template
class valarray
{
public:
explicit valarray(const context &context = system::default_context())
: m_buffer(context, 0)
{
}
explicit valarray(size_t size,
const context &context = system::default_context())
: m_buffer(context, size * sizeof(T))
{
}
valarray(const T &value,
size_t size,
const context &context = system::default_context())
: m_buffer(context, size * sizeof(T))
{
fill(begin(), end(), value);
}
valarray(const T *values,
size_t size,
const context &context = system::default_context())
: m_buffer(context, size * sizeof(T))
{
copy(values, values + size, begin());
}
valarray(const valarray &other)
: m_buffer(other.m_buffer.get_context(), other.size() * sizeof(T))
{
copy(other.begin(), other.end(), begin());
}
valarray(const std::valarray &valarray,
const context &context = system::default_context())
: m_buffer(context, valarray.size() * sizeof(T))
{
copy(&valarray[0], &valarray[valarray.size()], begin());
}
valarray& operator=(const valarray &other)
{
if(this != &other){
// change to other's OpenCL context
m_buffer = buffer(other.m_buffer.get_context(), other.size() * sizeof(T));
copy(other.begin(), other.end(), begin());
}
return *this;
}
valarray& operator=(const std::valarray &valarray)
{
m_buffer = buffer(m_buffer.get_context(), valarray.size() * sizeof(T));
copy(&valarray[0], &valarray[valarray.size()], begin());
return *this;
}
valarray& operator*=(const T&);
valarray& operator/=(const T&);
valarray& operator%=(const T& val);
valarray operator+() const
{
// This operator can be used with any type.
valarray result(size());
copy(begin(), end(), result.begin());
return result;
}
valarray operator-() const
{
BOOST_STATIC_ASSERT_MSG(
is_fundamental::value,
"This operator can be used with all OpenCL built-in scalar"
" and vector types"
);
valarray result(size());
BOOST_COMPUTE_FUNCTION(T, unary_minus, (T x),
{
return -x;
});
transform(begin(), end(), result.begin(), unary_minus);
return result;
}
valarray operator~() const
{
BOOST_STATIC_ASSERT_MSG(
is_fundamental::value &&
!is_floating_point::type>::value,
"This operator can be used with all OpenCL built-in scalar"
" and vector types except the built-in scalar and vector float types"
);
valarray result(size());
BOOST_COMPUTE_FUNCTION(T, bitwise_not, (T x),
{
return ~x;
});
transform(begin(), end(), result.begin(), bitwise_not);
return result;
}
/// In OpenCL there cannot be memory buffer with bool type, for
/// this reason return type is valarray instead of valarray.
/// 1 means true, 0 means false.
valarray operator!() const
{
BOOST_STATIC_ASSERT_MSG(
is_fundamental::value,
"This operator can be used with all OpenCL built-in scalar"
" and vector types"
);
valarray result(size());
BOOST_COMPUTE_FUNCTION(char, logical_not, (T x),
{
return !x;
});
transform(begin(), end(), &result[0], logical_not);
return result;
}
valarray& operator+=(const T&);
valarray& operator-=(const T&);
valarray& operator^=(const T&);
valarray& operator&=(const T&);
valarray& operator|=(const T&);
valarray& operator<<=(const T&);
valarray& operator>>=(const T&);
valarray& operator*=(const valarray&);
valarray& operator/=(const valarray&);
valarray& operator%=(const valarray&);
valarray& operator+=(const valarray&);
valarray& operator-=(const valarray&);
valarray& operator^=(const valarray&);
valarray& operator&=(const valarray&);
valarray& operator|=(const valarray&);
valarray& operator<<=(const valarray&);
valarray& operator>>=(const valarray&);
~valarray()
{
}
size_t size() const
{
return m_buffer.size() / sizeof(T);
}
void resize(size_t size, T value = T())
{
m_buffer = buffer(m_buffer.get_context(), size * sizeof(T));
fill(begin(), end(), value);
}
detail::buffer_value operator[](size_t index)
{
return *(begin() + static_cast(index));
}
const detail::buffer_value operator[](size_t index) const
{
return *(begin() + static_cast(index));
}
T (min)() const
{
return *(boost::compute::min_element(begin(), end()));
}
T (max)() const
{
return *(boost::compute::max_element(begin(), end()));
}
T sum() const
{
return boost::compute::accumulate(begin(), end(), T(0));
}
template
valarray apply(UnaryFunction function) const
{
valarray result(size());
transform(begin(), end(), result.begin(), function);
return result;
}
const buffer& get_buffer() const
{
return m_buffer;
}
private:
buffer_iterator begin() const
{
return buffer_iterator(m_buffer, 0);
}
buffer_iterator end() const
{
return buffer_iterator(m_buffer, size());
}
private:
buffer m_buffer;
};
/// \internal_
#define BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name, assert) \
template \
inline valarray& \
valarray::operator op##=(const T& val) \
{ \
assert \
transform(begin(), end(), begin(), \
::boost::compute::bind(op_name(), placeholders::_1, val)); \
return *this; \
} \
\
template \
inline valarray& \
valarray::operator op##=(const valarray &rhs) \
{ \
assert \
transform(begin(), end(), rhs.begin(), begin(), op_name()); \
return *this; \
}
/// \internal_
#define BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(op, op_name) \
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name, \
BOOST_STATIC_ASSERT_MSG( \
is_fundamental::value, \
"This operator can be used with all OpenCL built-in scalar" \
" and vector types" \
); \
)
/// \internal_
/// For some operators class T can't be floating point type.
/// See OpenCL specification, operators chapter.
#define BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(op, op_name) \
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name, \
BOOST_STATIC_ASSERT_MSG( \
is_fundamental::value && \
!is_floating_point::type>::value, \
"This operator can be used with all OpenCL built-in scalar" \
" and vector types except the built-in scalar and vector float types" \
); \
)
// defining operators
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(+, plus)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(-, minus)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(*, multiplies)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(/, divides)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(^, bit_xor)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(&, bit_and)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(|, bit_or)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(<<, shift_left)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(>>, shift_right)
// The remainder (%) operates on
// integer scalar and integer vector data types only.
// See OpenCL specification.
BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT(%, modulus,
BOOST_STATIC_ASSERT_MSG(
is_integral::type>::value,
"This operator can be used only with OpenCL built-in integer types"
);
)
#undef BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY
#undef BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP
#undef BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT
/// \internal_
/// Macro for defining binary operators for valarray
#define BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR(op, op_name, assert) \
template \
valarray operator op (const valarray& lhs, const valarray& rhs) \
{ \
assert \
valarray result(lhs.size()); \
transform(buffer_iterator(lhs.get_buffer(), 0), \
buffer_iterator(lhs.get_buffer(), lhs.size()), \
buffer_iterator(rhs.get_buffer(), 0), \
buffer_iterator(result.get_buffer(), 0), \
op_name()); \
return result; \
} \
\
template \
valarray operator op (const T& val, const valarray& rhs) \
{ \
assert \
valarray result(rhs.size()); \
transform(buffer_iterator(rhs.get_buffer(), 0), \
buffer_iterator(rhs.get_buffer(), rhs.size()), \
buffer_iterator(result.get_buffer(), 0), \
::boost::compute::bind(op_name(), val, placeholders::_1)); \
return result; \
} \
\
template \
valarray operator op (const valarray& lhs, const T& val) \
{ \
assert \
valarray result(lhs.size()); \
transform(buffer_iterator(lhs.get_buffer(), 0), \
buffer_iterator(lhs.get_buffer(), lhs.size()), \
buffer_iterator(result.get_buffer(), 0), \
::boost::compute::bind(op_name(), placeholders::_1, val)); \
return result; \
}
/// \internal_
#define BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(op, op_name) \
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR(op, op_name, \
BOOST_STATIC_ASSERT_MSG( \
is_fundamental::value, \
"This operator can be used with all OpenCL built-in scalar" \
" and vector types" \
); \
)
/// \internal_
/// For some operators class T can't be floating point type.
/// See OpenCL specification, operators chapter.
#define BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(op, op_name) \
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR(op, op_name, \
BOOST_STATIC_ASSERT_MSG( \
is_fundamental::value && \
!is_floating_point::type>::value, \
"This operator can be used with all OpenCL built-in scalar" \
" and vector types except the built-in scalar and vector float types" \
); \
)
// defining binary operators for valarray
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(+, plus)
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(-, minus)
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(*, multiplies)
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(/, divides)
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(^, bit_xor)
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(&, bit_and)
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(|, bit_or)
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(<<, shift_left)
BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(>>, shift_right)
#undef BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY
#undef BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP
#undef BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR
/// \internal_
/// Macro for defining valarray comparison operators.
/// For return type valarray is used instead of valarray because
/// in OpenCL there cannot be memory buffer with bool type.
///
/// Note it's also used for defining binary logical operators (==, &&)
#define BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(op, op_name) \
template \
valarray operator op (const valarray& lhs, const valarray& rhs) \
{ \
BOOST_STATIC_ASSERT_MSG( \
is_fundamental::value, \
"This operator can be used with all OpenCL built-in scalar" \
" and vector types" \
); \
valarray result(lhs.size()); \
transform(buffer_iterator(lhs.get_buffer(), 0), \
buffer_iterator(lhs.get_buffer(), lhs.size()), \
buffer_iterator(rhs.get_buffer(), 0), \
buffer_iterator(result.get_buffer(), 0), \
op_name()); \
return result; \
} \
\
template \
valarray operator op (const T& val, const valarray& rhs) \
{ \
BOOST_STATIC_ASSERT_MSG( \
is_fundamental::value, \
"This operator can be used with all OpenCL built-in scalar" \
" and vector types" \
); \
valarray result(rhs.size()); \
transform(buffer_iterator(rhs.get_buffer(), 0), \
buffer_iterator(rhs.get_buffer(), rhs.size()), \
buffer_iterator(result.get_buffer(), 0), \
::boost::compute::bind(op_name(), val, placeholders::_1)); \
return result; \
} \
\
template \
valarray operator op (const valarray& lhs, const T& val) \
{ \
BOOST_STATIC_ASSERT_MSG( \
is_fundamental::value, \
"This operator can be used with all OpenCL built-in scalar" \
" and vector types" \
); \
valarray result(lhs.size()); \
transform(buffer_iterator(lhs.get_buffer(), 0), \
buffer_iterator(lhs.get_buffer(), lhs.size()), \
buffer_iterator(result.get_buffer(), 0), \
::boost::compute::bind(op_name(), placeholders::_1, val)); \
return result; \
}
BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(==, equal_to)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(!=, not_equal_to)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(>, greater)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(<, less)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(>=, greater_equal)
BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(<=, less_equal)
/// \internal_
/// Macro for defining binary logical operators for valarray.
///
/// For return type valarray is used instead of valarray because
/// in OpenCL there cannot be memory buffer with bool type.
/// 1 means true, 0 means false.
#define BOOST_COMPUTE_DEFINE_VALARRAY_LOGICAL_OPERATOR(op, op_name) \
BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(op, op_name)
BOOST_COMPUTE_DEFINE_VALARRAY_LOGICAL_OPERATOR(&&, logical_and)
BOOST_COMPUTE_DEFINE_VALARRAY_LOGICAL_OPERATOR(||, logical_or)
#undef BOOST_COMPUTE_DEFINE_VALARRAY_LOGICAL_OPERATOR
#undef BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_CONTAINER_VALARRAY_HPP