stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,499 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
|
||||
//
|
||||
// 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 <cstddef>
|
||||
#include <valarray>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/compute/buffer.hpp>
|
||||
#include <boost/compute/algorithm/copy.hpp>
|
||||
#include <boost/compute/algorithm/fill.hpp>
|
||||
#include <boost/compute/algorithm/max_element.hpp>
|
||||
#include <boost/compute/algorithm/min_element.hpp>
|
||||
#include <boost/compute/algorithm/transform.hpp>
|
||||
#include <boost/compute/algorithm/accumulate.hpp>
|
||||
#include <boost/compute/detail/buffer_value.hpp>
|
||||
#include <boost/compute/functional.hpp>
|
||||
#include <boost/compute/functional/bind.hpp>
|
||||
#include <boost/compute/iterator/buffer_iterator.hpp>
|
||||
#include <boost/compute/type_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
|
||||
template<class T>
|
||||
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<T> &other)
|
||||
: m_buffer(other.m_buffer.get_context(), other.size() * sizeof(T))
|
||||
{
|
||||
}
|
||||
|
||||
valarray(const std::valarray<T> &valarray,
|
||||
const context &context = system::default_context())
|
||||
: m_buffer(context, valarray.size() * sizeof(T))
|
||||
{
|
||||
copy(&valarray[0], &valarray[valarray.size()], begin());
|
||||
}
|
||||
|
||||
valarray<T>& operator=(const valarray<T> &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<T>& operator=(const std::valarray<T> &valarray)
|
||||
{
|
||||
m_buffer = buffer(m_buffer.get_context(), valarray.size() * sizeof(T));
|
||||
copy(&valarray[0], &valarray[valarray.size()], begin());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
valarray<T>& operator*=(const T&);
|
||||
|
||||
valarray<T>& operator/=(const T&);
|
||||
|
||||
valarray<T>& operator%=(const T& val);
|
||||
|
||||
valarray<T> operator+() const
|
||||
{
|
||||
// This operator can be used with any type.
|
||||
valarray<T> result(size());
|
||||
copy(begin(), end(), result.begin());
|
||||
return result;
|
||||
}
|
||||
|
||||
valarray<T> operator-() const
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
is_fundamental<T>::value,
|
||||
"This operator can be used with all OpenCL built-in scalar"
|
||||
" and vector types"
|
||||
);
|
||||
valarray<T> result(size());
|
||||
BOOST_COMPUTE_FUNCTION(T, unary_minus, (T x),
|
||||
{
|
||||
return -x;
|
||||
});
|
||||
transform(begin(), end(), result.begin(), unary_minus);
|
||||
return result;
|
||||
}
|
||||
|
||||
valarray<T> operator~() const
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
is_fundamental<T>::value &&
|
||||
!is_floating_point<typename scalar_type<T>::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<T> 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<char> instead of valarray<bool>.
|
||||
/// 1 means true, 0 means false.
|
||||
valarray<char> operator!() const
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
is_fundamental<T>::value,
|
||||
"This operator can be used with all OpenCL built-in scalar"
|
||||
" and vector types"
|
||||
);
|
||||
valarray<char> result(size());
|
||||
BOOST_COMPUTE_FUNCTION(char, logical_not, (T x),
|
||||
{
|
||||
return !x;
|
||||
});
|
||||
transform(begin(), end(), &result[0], logical_not);
|
||||
return result;
|
||||
}
|
||||
|
||||
valarray<T>& operator+=(const T&);
|
||||
|
||||
valarray<T>& operator-=(const T&);
|
||||
|
||||
valarray<T>& operator^=(const T&);
|
||||
|
||||
valarray<T>& operator&=(const T&);
|
||||
|
||||
valarray<T>& operator|=(const T&);
|
||||
|
||||
valarray<T>& operator<<=(const T&);
|
||||
|
||||
valarray<T>& operator>>=(const T&);
|
||||
|
||||
valarray<T>& operator*=(const valarray<T>&);
|
||||
|
||||
valarray<T>& operator/=(const valarray<T>&);
|
||||
|
||||
valarray<T>& operator%=(const valarray<T>&);
|
||||
|
||||
valarray<T>& operator+=(const valarray<T>&);
|
||||
|
||||
valarray<T>& operator-=(const valarray<T>&);
|
||||
|
||||
valarray<T>& operator^=(const valarray<T>&);
|
||||
|
||||
valarray<T>& operator&=(const valarray<T>&);
|
||||
|
||||
valarray<T>& operator|=(const valarray<T>&);
|
||||
|
||||
valarray<T>& operator<<=(const valarray<T>&);
|
||||
|
||||
valarray<T>& operator>>=(const valarray<T>&);
|
||||
|
||||
~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<T> operator[](size_t index)
|
||||
{
|
||||
return *(begin() + static_cast<ptrdiff_t>(index));
|
||||
}
|
||||
|
||||
const detail::buffer_value<T> operator[](size_t index) const
|
||||
{
|
||||
return *(begin() + static_cast<ptrdiff_t>(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<class UnaryFunction>
|
||||
valarray<T> apply(UnaryFunction function) const
|
||||
{
|
||||
valarray<T> result(size());
|
||||
transform(begin(), end(), result.begin(), function);
|
||||
return result;
|
||||
}
|
||||
|
||||
const buffer& get_buffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
buffer_iterator<T> begin() const
|
||||
{
|
||||
return buffer_iterator<T>(m_buffer, 0);
|
||||
}
|
||||
|
||||
buffer_iterator<T> end() const
|
||||
{
|
||||
return buffer_iterator<T>(m_buffer, size());
|
||||
}
|
||||
|
||||
private:
|
||||
buffer m_buffer;
|
||||
};
|
||||
|
||||
/// \internal_
|
||||
#define BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name, assert) \
|
||||
template<class T> \
|
||||
inline valarray<T>& \
|
||||
valarray<T>::operator op##=(const T& val) \
|
||||
{ \
|
||||
assert \
|
||||
transform(begin(), end(), begin(), \
|
||||
::boost::compute::bind(op_name<T>(), placeholders::_1, val)); \
|
||||
return *this; \
|
||||
} \
|
||||
\
|
||||
template<class T> \
|
||||
inline valarray<T>& \
|
||||
valarray<T>::operator op##=(const valarray<T> &rhs) \
|
||||
{ \
|
||||
assert \
|
||||
transform(begin(), end(), rhs.begin(), begin(), op_name<T>()); \
|
||||
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<T>::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<T>::value && \
|
||||
!is_floating_point<typename scalar_type<T>::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<typename scalar_type<T>::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<class T> \
|
||||
valarray<T> operator op (const valarray<T>& lhs, const valarray<T>& rhs) \
|
||||
{ \
|
||||
assert \
|
||||
valarray<T> result(lhs.size()); \
|
||||
transform(buffer_iterator<T>(lhs.get_buffer(), 0), \
|
||||
buffer_iterator<T>(lhs.get_buffer(), lhs.size()), \
|
||||
buffer_iterator<T>(rhs.get_buffer(), 0), \
|
||||
buffer_iterator<T>(result.get_buffer(), 0), \
|
||||
op_name<T>()); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
template<class T> \
|
||||
valarray<T> operator op (const T& val, const valarray<T>& rhs) \
|
||||
{ \
|
||||
assert \
|
||||
valarray<T> result(rhs.size()); \
|
||||
transform(buffer_iterator<T>(rhs.get_buffer(), 0), \
|
||||
buffer_iterator<T>(rhs.get_buffer(), rhs.size()), \
|
||||
buffer_iterator<T>(result.get_buffer(), 0), \
|
||||
::boost::compute::bind(op_name<T>(), val, placeholders::_1)); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
template<class T> \
|
||||
valarray<T> operator op (const valarray<T>& lhs, const T& val) \
|
||||
{ \
|
||||
assert \
|
||||
valarray<T> result(lhs.size()); \
|
||||
transform(buffer_iterator<T>(lhs.get_buffer(), 0), \
|
||||
buffer_iterator<T>(lhs.get_buffer(), lhs.size()), \
|
||||
buffer_iterator<T>(result.get_buffer(), 0), \
|
||||
::boost::compute::bind(op_name<T>(), 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<T>::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<T>::value && \
|
||||
!is_floating_point<typename scalar_type<T>::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<char> is used instead of valarray<bool> 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<class T> \
|
||||
valarray<char> operator op (const valarray<T>& lhs, const valarray<T>& rhs) \
|
||||
{ \
|
||||
BOOST_STATIC_ASSERT_MSG( \
|
||||
is_fundamental<T>::value, \
|
||||
"This operator can be used with all OpenCL built-in scalar" \
|
||||
" and vector types" \
|
||||
); \
|
||||
valarray<char> result(lhs.size()); \
|
||||
transform(buffer_iterator<T>(lhs.get_buffer(), 0), \
|
||||
buffer_iterator<T>(lhs.get_buffer(), lhs.size()), \
|
||||
buffer_iterator<T>(rhs.get_buffer(), 0), \
|
||||
buffer_iterator<char>(result.get_buffer(), 0), \
|
||||
op_name<T>()); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
template<class T> \
|
||||
valarray<char> operator op (const T& val, const valarray<T>& rhs) \
|
||||
{ \
|
||||
BOOST_STATIC_ASSERT_MSG( \
|
||||
is_fundamental<T>::value, \
|
||||
"This operator can be used with all OpenCL built-in scalar" \
|
||||
" and vector types" \
|
||||
); \
|
||||
valarray<char> result(rhs.size()); \
|
||||
transform(buffer_iterator<T>(rhs.get_buffer(), 0), \
|
||||
buffer_iterator<T>(rhs.get_buffer(), rhs.size()), \
|
||||
buffer_iterator<char>(result.get_buffer(), 0), \
|
||||
::boost::compute::bind(op_name<T>(), val, placeholders::_1)); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
template<class T> \
|
||||
valarray<char> operator op (const valarray<T>& lhs, const T& val) \
|
||||
{ \
|
||||
BOOST_STATIC_ASSERT_MSG( \
|
||||
is_fundamental<T>::value, \
|
||||
"This operator can be used with all OpenCL built-in scalar" \
|
||||
" and vector types" \
|
||||
); \
|
||||
valarray<char> result(lhs.size()); \
|
||||
transform(buffer_iterator<T>(lhs.get_buffer(), 0), \
|
||||
buffer_iterator<T>(lhs.get_buffer(), lhs.size()), \
|
||||
buffer_iterator<char>(result.get_buffer(), 0), \
|
||||
::boost::compute::bind(op_name<T>(), 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<char> is used instead of valarray<bool> 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
|
||||
Reference in New Issue
Block a user