stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_ASSERT_CL_SUCCESS_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_ASSERT_CL_SUCCESS_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG)
|
||||
#define BOOST_COMPUTE_ASSERT_CL_SUCCESS(function) \
|
||||
function
|
||||
#else
|
||||
#define BOOST_COMPUTE_ASSERT_CL_SUCCESS(function) \
|
||||
BOOST_ASSERT(function == CL_SUCCESS)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_ASSERT_CL_SUCCESS_HPP
|
||||
@@ -0,0 +1,178 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_BUFFER_VALUE_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_BUFFER_VALUE_HPP
|
||||
|
||||
#include <boost/compute/context.hpp>
|
||||
#include <boost/compute/command_queue.hpp>
|
||||
#include <boost/compute/detail/device_ptr.hpp>
|
||||
#include <boost/compute/detail/read_write_single_value.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
class buffer_value
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
buffer_value()
|
||||
{
|
||||
}
|
||||
|
||||
buffer_value(const value_type &value)
|
||||
: m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
// creates a reference for the value in buffer at index (in bytes).
|
||||
buffer_value(const buffer &buffer, size_t index)
|
||||
: m_buffer(buffer.get(), false),
|
||||
m_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
buffer_value(const buffer_value<T> &other)
|
||||
: m_buffer(other.m_buffer.get(), false),
|
||||
m_index(other.m_index)
|
||||
{
|
||||
}
|
||||
|
||||
~buffer_value()
|
||||
{
|
||||
// set buffer to null so that its reference count will
|
||||
// not be decremented when its destructor is called
|
||||
m_buffer.get() = 0;
|
||||
}
|
||||
|
||||
operator value_type() const
|
||||
{
|
||||
if(m_buffer.get()){
|
||||
const context &context = m_buffer.get_context();
|
||||
const device &device = context.get_device();
|
||||
command_queue queue(context, device);
|
||||
|
||||
return detail::read_single_value<T>(m_buffer, m_index / sizeof(T), queue);
|
||||
}
|
||||
else {
|
||||
return m_value;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_value<T> operator-() const
|
||||
{
|
||||
return -T(*this);
|
||||
}
|
||||
|
||||
bool operator<(const T &value) const
|
||||
{
|
||||
return T(*this) < value;
|
||||
}
|
||||
|
||||
bool operator>(const T &value) const
|
||||
{
|
||||
return T(*this) > value;
|
||||
}
|
||||
|
||||
bool operator<=(const T &value) const
|
||||
{
|
||||
return T(*this) <= value;
|
||||
}
|
||||
|
||||
bool operator>=(const T &value) const
|
||||
{
|
||||
return T(*this) <= value;
|
||||
}
|
||||
|
||||
bool operator==(const T &value) const
|
||||
{
|
||||
return T(*this) == value;
|
||||
}
|
||||
|
||||
bool operator==(const buffer_value<T> &other) const
|
||||
{
|
||||
if(m_buffer.get() != other.m_buffer.get()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(m_buffer.get()){
|
||||
return m_index == other.m_index;
|
||||
}
|
||||
else {
|
||||
return m_value == other.m_value;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator!=(const T &value) const
|
||||
{
|
||||
return T(*this) != value;
|
||||
}
|
||||
|
||||
buffer_value<T>& operator=(const T &value)
|
||||
{
|
||||
if(m_buffer.get()){
|
||||
const context &context = m_buffer.get_context();
|
||||
command_queue queue(context, context.get_device());
|
||||
|
||||
detail::write_single_value<T>(value, m_buffer, m_index / sizeof(T), queue);
|
||||
|
||||
return *this;
|
||||
}
|
||||
else {
|
||||
m_value = value;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_value<T>& operator=(const buffer_value<T> &value)
|
||||
{
|
||||
return operator=(T(value));
|
||||
}
|
||||
|
||||
detail::device_ptr<T> operator&() const
|
||||
{
|
||||
return detail::device_ptr<T>(m_buffer, m_index);
|
||||
}
|
||||
|
||||
buffer_value<T>& operator++()
|
||||
{
|
||||
if(m_buffer.get()){
|
||||
T value = T(*this);
|
||||
value++;
|
||||
*this = value;
|
||||
}
|
||||
else {
|
||||
m_value++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
buffer_value<T> operator++(int)
|
||||
{
|
||||
buffer_value<T> result(*this);
|
||||
++(*this);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
const buffer m_buffer;
|
||||
size_t m_index;
|
||||
value_type m_value;
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_BUFFER_VALUE_HPP
|
||||
@@ -0,0 +1,215 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DEVICE_PTR_HPP
|
||||
#define BOOST_COMPUTE_DEVICE_PTR_HPP
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/compute/buffer.hpp>
|
||||
#include <boost/compute/config.hpp>
|
||||
#include <boost/compute/detail/is_buffer_iterator.hpp>
|
||||
#include <boost/compute/detail/read_write_single_value.hpp>
|
||||
#include <boost/compute/type_traits/is_device_iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
template<class T, class IndexExpr>
|
||||
struct device_ptr_index_expr
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
device_ptr_index_expr(const buffer &buffer,
|
||||
uint_ index,
|
||||
const IndexExpr &expr)
|
||||
: m_buffer(buffer),
|
||||
m_index(index),
|
||||
m_expr(expr)
|
||||
{
|
||||
}
|
||||
|
||||
operator T() const
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(boost::is_integral<IndexExpr>::value,
|
||||
"Index expression must be integral");
|
||||
|
||||
BOOST_ASSERT(m_buffer.get());
|
||||
|
||||
const context &context = m_buffer.get_context();
|
||||
const device &device = context.get_device();
|
||||
command_queue queue(context, device);
|
||||
|
||||
return detail::read_single_value<T>(m_buffer, m_expr, queue);
|
||||
}
|
||||
|
||||
const buffer &m_buffer;
|
||||
uint_ m_index;
|
||||
IndexExpr m_expr;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class device_ptr
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
|
||||
device_ptr()
|
||||
: m_index(0)
|
||||
{
|
||||
}
|
||||
|
||||
device_ptr(const buffer &buffer, size_t index = 0)
|
||||
: m_buffer(buffer.get(), false),
|
||||
m_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
device_ptr(const device_ptr<T> &other)
|
||||
: m_buffer(other.m_buffer.get(), false),
|
||||
m_index(other.m_index)
|
||||
{
|
||||
}
|
||||
|
||||
device_ptr<T>& operator=(const device_ptr<T> &other)
|
||||
{
|
||||
if(this != &other){
|
||||
m_buffer.get() = other.m_buffer.get();
|
||||
m_index = other.m_index;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
|
||||
device_ptr(device_ptr<T>&& other) BOOST_NOEXCEPT
|
||||
: m_buffer(other.m_buffer.get(), false),
|
||||
m_index(other.m_index)
|
||||
{
|
||||
other.m_buffer.get() = 0;
|
||||
}
|
||||
|
||||
device_ptr<T>& operator=(device_ptr<T>&& other) BOOST_NOEXCEPT
|
||||
{
|
||||
m_buffer.get() = other.m_buffer.get();
|
||||
m_index = other.m_index;
|
||||
|
||||
other.m_buffer.get() = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
|
||||
|
||||
~device_ptr()
|
||||
{
|
||||
// set buffer to null so that its reference count will
|
||||
// not be decremented when its destructor is called
|
||||
m_buffer.get() = 0;
|
||||
}
|
||||
|
||||
size_type get_index() const
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
const buffer& get_buffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
template<class OT>
|
||||
device_ptr<OT> cast() const
|
||||
{
|
||||
return device_ptr<OT>(m_buffer, m_index);
|
||||
}
|
||||
|
||||
device_ptr<T> operator+(difference_type n) const
|
||||
{
|
||||
return device_ptr<T>(m_buffer, m_index + n);
|
||||
}
|
||||
|
||||
device_ptr<T> operator+(const device_ptr<T> &other) const
|
||||
{
|
||||
return device_ptr<T>(m_buffer, m_index + other.m_index);
|
||||
}
|
||||
|
||||
device_ptr<T>& operator+=(difference_type n)
|
||||
{
|
||||
m_index += static_cast<size_t>(n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
difference_type operator-(const device_ptr<T> &other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index - other.m_index);
|
||||
}
|
||||
|
||||
device_ptr<T>& operator-=(difference_type n)
|
||||
{
|
||||
m_index -= n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const device_ptr<T> &other) const
|
||||
{
|
||||
return m_buffer.get() == other.m_buffer.get() &&
|
||||
m_index == other.m_index;
|
||||
}
|
||||
|
||||
bool operator!=(const device_ptr<T> &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template<class Expr>
|
||||
detail::device_ptr_index_expr<T, Expr>
|
||||
operator[](const Expr &expr) const
|
||||
{
|
||||
BOOST_ASSERT(m_buffer.get());
|
||||
|
||||
return detail::device_ptr_index_expr<T, Expr>(m_buffer,
|
||||
uint_(m_index),
|
||||
expr);
|
||||
}
|
||||
|
||||
private:
|
||||
const buffer m_buffer;
|
||||
size_t m_index;
|
||||
};
|
||||
|
||||
// is_buffer_iterator specialization for device_ptr
|
||||
template<class Iterator>
|
||||
struct is_buffer_iterator<
|
||||
Iterator,
|
||||
typename boost::enable_if<
|
||||
boost::is_same<
|
||||
device_ptr<typename Iterator::value_type>,
|
||||
typename boost::remove_const<Iterator>::type
|
||||
>
|
||||
>::type
|
||||
> : public boost::true_type {};
|
||||
|
||||
} // end detail namespace
|
||||
|
||||
// is_device_iterator specialization for device_ptr
|
||||
template<class T>
|
||||
struct is_device_iterator<detail::device_ptr<T> > : boost::true_type {};
|
||||
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DEVICE_PTR_HPP
|
||||
@@ -0,0 +1,112 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2016 Jakub Szuppe <j.szuppe@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_DETAIL_DIAGNOSTIC_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_DIAGNOSTIC_HPP
|
||||
|
||||
// Macros for suppressing warnings for GCC version 4.6 or later. Usage:
|
||||
//
|
||||
// BOOST_COMPUTE_BOOST_COMPUTE_GCC_DIAG_OFF(sign-compare);
|
||||
// if(a < b){
|
||||
// BOOST_COMPUTE_BOOST_COMPUTE_GCC_DIAG_ON(sign-compare);
|
||||
//
|
||||
// Source: https://svn.boost.org/trac/boost/wiki/Guidelines/WarningsGuidelines
|
||||
#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
|
||||
#define BOOST_COMPUTE_GCC_DIAG_STR(s) #s
|
||||
#define BOOST_COMPUTE_GCC_DIAG_JOINSTR(x,y) BOOST_COMPUTE_GCC_DIAG_STR(x ## y)
|
||||
# define BOOST_COMPUTE_GCC_DIAG_DO_PRAGMA(x) _Pragma (#x)
|
||||
# define BOOST_COMPUTE_GCC_DIAG_PRAGMA(x) BOOST_COMPUTE_GCC_DIAG_DO_PRAGMA(GCC diagnostic x)
|
||||
# if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
|
||||
# define BOOST_COMPUTE_GCC_DIAG_OFF(x) BOOST_COMPUTE_GCC_DIAG_PRAGMA(push) \
|
||||
BOOST_COMPUTE_GCC_DIAG_PRAGMA(ignored BOOST_COMPUTE_GCC_DIAG_JOINSTR(-W,x))
|
||||
# define BOOST_COMPUTE_GCC_DIAG_ON(x) BOOST_COMPUTE_GCC_DIAG_PRAGMA(pop)
|
||||
# else
|
||||
# define BOOST_COMPUTE_GCC_DIAG_OFF(x) \
|
||||
BOOST_COMPUTE_GCC_DIAG_PRAGMA(ignored BOOST_COMPUTE_GCC_DIAG_JOINSTR(-W,x))
|
||||
# define BOOST_COMPUTE_GCC_DIAG_ON(x) \
|
||||
BOOST_COMPUTE_GCC_DIAG_PRAGMA(warning BOOST_COMPUTE_GCC_DIAG_JOINSTR(-W,x))
|
||||
# endif
|
||||
#else // Ensure these macros do nothing for other compilers.
|
||||
# define BOOST_COMPUTE_GCC_DIAG_OFF(x)
|
||||
# define BOOST_COMPUTE_GCC_DIAG_ON(x)
|
||||
#endif
|
||||
|
||||
// Macros for suppressing warnings for Clang.
|
||||
//
|
||||
// BOOST_COMPUTE_BOOST_COMPUTE_CLANG_DIAG_OFF(sign-compare);
|
||||
// if(a < b){
|
||||
// BOOST_COMPUTE_BOOST_COMPUTE_CLANG_DIAG_ON(sign-compare);
|
||||
//
|
||||
// Source: https://svn.boost.org/trac/boost/wiki/Guidelines/WarningsGuidelines
|
||||
#ifdef __clang__
|
||||
# define BOOST_COMPUTE_CLANG_DIAG_STR(s) # s
|
||||
// stringize s to "no-sign-compare"
|
||||
# define BOOST_COMPUTE_CLANG_DIAG_JOINSTR(x,y) BOOST_COMPUTE_CLANG_DIAG_STR(x ## y)
|
||||
// join -W with no-unused-variable to "-Wno-sign-compare"
|
||||
# define BOOST_COMPUTE_CLANG_DIAG_DO_PRAGMA(x) _Pragma (#x)
|
||||
// _Pragma is unary operator #pragma ("")
|
||||
# define BOOST_COMPUTE_CLANG_DIAG_PRAGMA(x) \
|
||||
BOOST_COMPUTE_CLANG_DIAG_DO_PRAGMA(clang diagnostic x)
|
||||
# define BOOST_COMPUTE_CLANG_DIAG_OFF(x) BOOST_COMPUTE_CLANG_DIAG_PRAGMA(push) \
|
||||
BOOST_COMPUTE_CLANG_DIAG_PRAGMA(ignored BOOST_COMPUTE_CLANG_DIAG_JOINSTR(-W,x))
|
||||
// For example: #pragma clang diagnostic ignored "-Wno-sign-compare"
|
||||
# define BOOST_COMPUTE_CLANG_DIAG_ON(x) BOOST_COMPUTE_CLANG_DIAG_PRAGMA(pop)
|
||||
// For example: #pragma clang diagnostic warning "-Wno-sign-compare"
|
||||
#else // Ensure these macros do nothing for other compilers.
|
||||
# define BOOST_COMPUTE_CLANG_DIAG_OFF(x)
|
||||
# define BOOST_COMPUTE_CLANG_DIAG_ON(x)
|
||||
# define BOOST_COMPUTE_CLANG_DIAG_PRAGMA(x)
|
||||
#endif
|
||||
|
||||
// Macros for suppressing warnings for MSVC. Usage:
|
||||
//
|
||||
// BOOST_COMPUTE_BOOST_COMPUTE_MSVC_DIAG_OFF(4018); //sign-compare
|
||||
// if(a < b){
|
||||
// BOOST_COMPUTE_BOOST_COMPUTE_MSVC_DIAG_ON(4018);
|
||||
//
|
||||
#if defined(_MSC_VER)
|
||||
# define BOOST_COMPUTE_MSVC_DIAG_DO_PRAGMA(x) __pragma(x)
|
||||
# define BOOST_COMPUTE_MSVC_DIAG_PRAGMA(x) \
|
||||
BOOST_COMPUTE_MSVC_DIAG_DO_PRAGMA(warning(x))
|
||||
# define BOOST_COMPUTE_MSVC_DIAG_OFF(x) BOOST_COMPUTE_MSVC_DIAG_PRAGMA(push) \
|
||||
BOOST_COMPUTE_MSVC_DIAG_PRAGMA(disable: x)
|
||||
# define BOOST_COMPUTE_MSVC_DIAG_ON(x) BOOST_COMPUTE_MSVC_DIAG_PRAGMA(pop)
|
||||
#else // Ensure these macros do nothing for other compilers.
|
||||
# define BOOST_COMPUTE_MSVC_DIAG_OFF(x)
|
||||
# define BOOST_COMPUTE_MSVC_DIAG_ON(x)
|
||||
#endif
|
||||
|
||||
// Macros for suppressing warnings for GCC, Clang and MSVC. Usage:
|
||||
//
|
||||
// BOOST_COMPUTE_DIAG_OFF(sign-compare, sign-compare, 4018);
|
||||
// if(a < b){
|
||||
// BOOST_COMPUTE_DIAG_ON(sign-compare, sign-compare, 4018);
|
||||
//
|
||||
#if defined(_MSC_VER) // MSVC
|
||||
# define BOOST_COMPUTE_DIAG_OFF(gcc, clang, msvc) BOOST_COMPUTE_MSVC_DIAG_OFF(msvc)
|
||||
# define BOOST_COMPUTE_DIAG_ON(gcc, clang, msvc) BOOST_COMPUTE_MSVC_DIAG_ON(msvc)
|
||||
#elif defined(__clang__) // Clang
|
||||
# define BOOST_COMPUTE_DIAG_OFF(gcc, clang, msvc) BOOST_COMPUTE_CLANG_DIAG_OFF(clang)
|
||||
# define BOOST_COMPUTE_DIAG_ON(gcc, clang, msvc) BOOST_COMPUTE_CLANG_DIAG_ON(clang)
|
||||
#elif defined(__GNUC__) // GCC/G++
|
||||
# define BOOST_COMPUTE_DIAG_OFF(gcc, clang, msvc) BOOST_COMPUTE_GCC_DIAG_OFF(gcc)
|
||||
# define BOOST_COMPUTE_DIAG_ON(gcc, clang, msvc) BOOST_COMPUTE_GCC_DIAG_ON(gcc)
|
||||
#else // Ensure these macros do nothing for other compilers.
|
||||
# define BOOST_COMPUTE_DIAG_OFF(gcc, clang, msvc)
|
||||
# define BOOST_COMPUTE_DIAG_ON(gcc, clang, msvc)
|
||||
#endif
|
||||
|
||||
#define BOOST_COMPUTE_DISABLE_DEPRECATED_DECLARATIONS() \
|
||||
BOOST_COMPUTE_DIAG_OFF(deprecated-declarations, deprecated-declarations, 4996)
|
||||
#define BOOST_COMPUTE_ENABLE_DEPRECATED_DECLARATIONS() \
|
||||
BOOST_COMPUTE_DIAG_ON(deprecated-declarations, deprecated-declarations, 4996);
|
||||
|
||||
|
||||
#endif /* BOOST_COMPUTE_DETAIL_DIAGNOSTIC_HPP */
|
||||
@@ -0,0 +1,50 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_DURATION_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_DURATION_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifndef BOOST_COMPUTE_NO_HDR_CHRONO
|
||||
#include <chrono>
|
||||
#endif
|
||||
|
||||
#include <boost/chrono/duration.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
#ifndef BOOST_COMPUTE_NO_HDR_CHRONO
|
||||
template<class Rep, class Period>
|
||||
inline std::chrono::duration<Rep, Period>
|
||||
make_duration_from_nanoseconds(std::chrono::duration<Rep, Period>, size_t nanoseconds)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::duration<Rep, Period> >(
|
||||
std::chrono::nanoseconds(nanoseconds)
|
||||
);
|
||||
}
|
||||
#endif // BOOST_COMPUTE_NO_HDR_CHRONO
|
||||
|
||||
template<class Rep, class Period>
|
||||
inline boost::chrono::duration<Rep, Period>
|
||||
make_duration_from_nanoseconds(boost::chrono::duration<Rep, Period>, size_t nanoseconds)
|
||||
{
|
||||
return boost::chrono::duration_cast<boost::chrono::duration<Rep, Period> >(
|
||||
boost::chrono::nanoseconds(nanoseconds)
|
||||
);
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_DURATION_HPP
|
||||
@@ -0,0 +1,216 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_GET_OBJECT_INFO_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_GET_OBJECT_INFO_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/preprocessor/tuple/elem.hpp>
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/compute/cl.hpp>
|
||||
#include <boost/compute/exception/opencl_error.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
template<class Function, class Object, class AuxInfo>
|
||||
struct bound_info_function
|
||||
{
|
||||
bound_info_function(Function function, Object object, AuxInfo aux_info)
|
||||
: m_function(function),
|
||||
m_object(object),
|
||||
m_aux_info(aux_info)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Info>
|
||||
cl_int operator()(Info info, size_t size, void *value, size_t *size_ret) const
|
||||
{
|
||||
return m_function(m_object, m_aux_info, info, size, value, size_ret);
|
||||
}
|
||||
|
||||
Function m_function;
|
||||
Object m_object;
|
||||
AuxInfo m_aux_info;
|
||||
};
|
||||
|
||||
template<class Function, class Object>
|
||||
struct bound_info_function<Function, Object, void>
|
||||
{
|
||||
bound_info_function(Function function, Object object)
|
||||
: m_function(function),
|
||||
m_object(object)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Info>
|
||||
cl_int operator()(Info info, size_t size, void *value, size_t *size_ret) const
|
||||
{
|
||||
return m_function(m_object, info, size, value, size_ret);
|
||||
}
|
||||
|
||||
Function m_function;
|
||||
Object m_object;
|
||||
};
|
||||
|
||||
template<class Function, class Object>
|
||||
inline bound_info_function<Function, Object, void>
|
||||
bind_info_function(Function f, Object o)
|
||||
{
|
||||
return bound_info_function<Function, Object, void>(f, o);
|
||||
}
|
||||
|
||||
template<class Function, class Object, class AuxInfo>
|
||||
inline bound_info_function<Function, Object, AuxInfo>
|
||||
bind_info_function(Function f, Object o, AuxInfo j)
|
||||
{
|
||||
return bound_info_function<Function, Object, AuxInfo>(f, o, j);
|
||||
}
|
||||
|
||||
// default implementation
|
||||
template<class T>
|
||||
struct get_object_info_impl
|
||||
{
|
||||
template<class Function, class Info>
|
||||
T operator()(Function function, Info info) const
|
||||
{
|
||||
T value;
|
||||
|
||||
cl_int ret = function(info, sizeof(T), &value, 0);
|
||||
if(ret != CL_SUCCESS){
|
||||
BOOST_THROW_EXCEPTION(opencl_error(ret));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
// specialization for bool
|
||||
template<>
|
||||
struct get_object_info_impl<bool>
|
||||
{
|
||||
template<class Function, class Info>
|
||||
bool operator()(Function function, Info info) const
|
||||
{
|
||||
cl_bool value;
|
||||
|
||||
cl_int ret = function(info, sizeof(cl_bool), &value, 0);
|
||||
if(ret != CL_SUCCESS){
|
||||
BOOST_THROW_EXCEPTION(opencl_error(ret));
|
||||
}
|
||||
|
||||
return value == CL_TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
// specialization for std::string
|
||||
template<>
|
||||
struct get_object_info_impl<std::string>
|
||||
{
|
||||
template<class Function, class Info>
|
||||
std::string operator()(Function function, Info info) const
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
cl_int ret = function(info, 0, 0, &size);
|
||||
if(ret != CL_SUCCESS){
|
||||
BOOST_THROW_EXCEPTION(opencl_error(ret));
|
||||
}
|
||||
|
||||
if(size == 0){
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string value(size - 1, 0);
|
||||
|
||||
ret = function(info, size, &value[0], 0);
|
||||
if(ret != CL_SUCCESS){
|
||||
BOOST_THROW_EXCEPTION(opencl_error(ret));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
// specialization for std::vector<T>
|
||||
template<class T>
|
||||
struct get_object_info_impl<std::vector<T> >
|
||||
{
|
||||
template<class Function, class Info>
|
||||
std::vector<T> operator()(Function function, Info info) const
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
cl_int ret = function(info, 0, 0, &size);
|
||||
if(ret != CL_SUCCESS){
|
||||
BOOST_THROW_EXCEPTION(opencl_error(ret));
|
||||
}
|
||||
|
||||
std::vector<T> vector(size / sizeof(T));
|
||||
ret = function(info, size, &vector[0], 0);
|
||||
if(ret != CL_SUCCESS){
|
||||
BOOST_THROW_EXCEPTION(opencl_error(ret));
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
};
|
||||
|
||||
// returns the value (of type T) from the given clGet*Info() function call.
|
||||
template<class T, class Function, class Object, class Info>
|
||||
inline T get_object_info(Function f, Object o, Info i)
|
||||
{
|
||||
return get_object_info_impl<T>()(bind_info_function(f, o), i);
|
||||
}
|
||||
|
||||
template<class T, class Function, class Object, class Info, class AuxInfo>
|
||||
inline T get_object_info(Function f, Object o, Info i, AuxInfo j)
|
||||
{
|
||||
return get_object_info_impl<T>()(bind_info_function(f, o, j), i);
|
||||
}
|
||||
|
||||
// returns the value type for the clGet*Info() call on Object with Enum.
|
||||
template<class Object, int Enum>
|
||||
struct get_object_info_type;
|
||||
|
||||
// defines the object::get_info<Enum>() specialization
|
||||
#define BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATION(object_type, result_type, value) \
|
||||
namespace detail { \
|
||||
template<> struct get_object_info_type<object_type, value> { typedef result_type type; }; \
|
||||
} \
|
||||
template<> inline result_type object_type::get_info<value>() const \
|
||||
{ \
|
||||
return get_info<result_type>(value); \
|
||||
}
|
||||
|
||||
// used by BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS()
|
||||
#define BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_IMPL(r, data, elem) \
|
||||
BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATION( \
|
||||
data, BOOST_PP_TUPLE_ELEM(2, 0, elem), BOOST_PP_TUPLE_ELEM(2, 1, elem) \
|
||||
)
|
||||
|
||||
// defines the object::get_info<Enum>() specialization for each
|
||||
// (result_type, value) tuple in seq for object_type.
|
||||
#define BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(object_type, seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH( \
|
||||
BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_IMPL, object_type, seq \
|
||||
)
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_GET_OBJECT_INFO_HPP
|
||||
@@ -0,0 +1,36 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_GETENV_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_GETENV_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
inline const char* getenv(const char *env_var)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4996)
|
||||
#endif
|
||||
return std::getenv(env_var);
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_GETENV_HPP
|
||||
@@ -0,0 +1,37 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_GLOBAL_STATIC_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_GLOBAL_STATIC_HPP
|
||||
|
||||
#include <boost/compute/config.hpp>
|
||||
|
||||
#ifdef BOOST_COMPUTE_THREAD_SAFE
|
||||
# ifdef BOOST_COMPUTE_HAVE_THREAD_LOCAL
|
||||
// use c++11 thread local storage
|
||||
# define BOOST_COMPUTE_DETAIL_GLOBAL_STATIC(type, name, ctor) \
|
||||
thread_local type name ctor;
|
||||
# else
|
||||
// use thread_specific_ptr from boost.thread
|
||||
# include <boost/thread/tss.hpp>
|
||||
# define BOOST_COMPUTE_DETAIL_GLOBAL_STATIC(type, name, ctor) \
|
||||
static ::boost::thread_specific_ptr< type > BOOST_PP_CAT(name, _tls_ptr_); \
|
||||
if(!BOOST_PP_CAT(name, _tls_ptr_).get()){ \
|
||||
BOOST_PP_CAT(name, _tls_ptr_).reset(new type ctor); \
|
||||
} \
|
||||
static type &name = *BOOST_PP_CAT(name, _tls_ptr_);
|
||||
# endif
|
||||
#else
|
||||
// no thread-safety, just use static
|
||||
# define BOOST_COMPUTE_DETAIL_GLOBAL_STATIC(type, name, ctor) \
|
||||
static type name ctor;
|
||||
#endif
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_GLOBAL_STATIC_HPP
|
||||
@@ -0,0 +1,30 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_IS_BUFFER_ITERATOR_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_IS_BUFFER_ITERATOR_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// default = false
|
||||
template<class Iterator, class Enable = void>
|
||||
struct is_buffer_iterator : public boost::false_type {};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_IS_BUFFER_ITERATOR_HPP
|
||||
@@ -0,0 +1,118 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_IS_CONTIGUOUS_ITERATOR_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_IS_CONTIGUOUS_ITERATOR_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <valarray>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// default = false
|
||||
template<class Iterator, class Enable = void>
|
||||
struct _is_contiguous_iterator : public boost::false_type {};
|
||||
|
||||
// std::vector<T>::iterator = true
|
||||
template<class Iterator>
|
||||
struct _is_contiguous_iterator<
|
||||
Iterator,
|
||||
typename boost::enable_if<
|
||||
typename boost::is_same<
|
||||
Iterator,
|
||||
typename std::vector<typename Iterator::value_type>::iterator
|
||||
>::type
|
||||
>::type
|
||||
> : public boost::true_type {};
|
||||
|
||||
// std::vector<T>::const_iterator = true
|
||||
template<class Iterator>
|
||||
struct _is_contiguous_iterator<
|
||||
Iterator,
|
||||
typename boost::enable_if<
|
||||
typename boost::is_same<
|
||||
Iterator,
|
||||
typename std::vector<typename Iterator::value_type>::const_iterator
|
||||
>::type
|
||||
>::type
|
||||
> : public boost::true_type {};
|
||||
|
||||
// std::valarray<T>::iterator = true
|
||||
template<class Iterator>
|
||||
struct _is_contiguous_iterator<
|
||||
Iterator,
|
||||
typename boost::enable_if<
|
||||
typename boost::is_same<
|
||||
Iterator,
|
||||
typename std::valarray<typename Iterator::value_type>::iterator
|
||||
>::type
|
||||
>::type
|
||||
> : public boost::true_type {};
|
||||
|
||||
// std::valarray<T>::const_iterator = true
|
||||
template<class Iterator>
|
||||
struct _is_contiguous_iterator<
|
||||
Iterator,
|
||||
typename boost::enable_if<
|
||||
typename boost::is_same<
|
||||
Iterator,
|
||||
typename std::valarray<typename Iterator::value_type>::const_iterator
|
||||
>::type
|
||||
>::type
|
||||
> : public boost::true_type {};
|
||||
|
||||
// T* = true
|
||||
template<class Iterator>
|
||||
struct _is_contiguous_iterator<
|
||||
Iterator,
|
||||
typename boost::enable_if<
|
||||
boost::is_pointer<Iterator>
|
||||
>::type
|
||||
> : public boost::true_type {};
|
||||
|
||||
// the is_contiguous_iterator meta-function returns true if Iterator points
|
||||
// to a range of contiguous values. examples of contiguous iterators are
|
||||
// std::vector<>::iterator and float*. examples of non-contiguous iterators
|
||||
// are std::set<>::iterator and std::insert_iterator<>.
|
||||
//
|
||||
// the implementation consists of two phases. the first checks that value_type
|
||||
// for the iterator is not void. this must be done as for many containers void
|
||||
// is not a valid value_type (ex. std::vector<void>::iterator is not valid).
|
||||
// after ensuring a non-void value_type, the _is_contiguous_iterator function
|
||||
// is invoked. it has specializations retuning true for all (known) contiguous
|
||||
// iterators types and a default value of false.
|
||||
template<class Iterator, class Enable = void>
|
||||
struct is_contiguous_iterator :
|
||||
public _is_contiguous_iterator<
|
||||
typename boost::remove_cv<Iterator>::type
|
||||
> {};
|
||||
|
||||
// value_type of void = false
|
||||
template<class Iterator>
|
||||
struct is_contiguous_iterator<
|
||||
Iterator,
|
||||
typename boost::enable_if<
|
||||
typename boost::is_void<
|
||||
typename Iterator::value_type
|
||||
>::type
|
||||
>::type
|
||||
> : public boost::false_type {};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_IS_CONTIGUOUS_ITERATOR_HPP
|
||||
@@ -0,0 +1,53 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_ITERATOR_PLUS_DISTANCE_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_ITERATOR_PLUS_DISTANCE_HPP
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
template<class Iterator, class Distance, class Tag>
|
||||
inline Iterator iterator_plus_distance(Iterator i, Distance n, Tag)
|
||||
{
|
||||
while(n--){ i++; }
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
template<class Iterator, class Distance>
|
||||
inline Iterator iterator_plus_distance(Iterator i,
|
||||
Distance n,
|
||||
std::random_access_iterator_tag)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<Iterator>::difference_type difference_type;
|
||||
|
||||
return i + static_cast<difference_type>(n);
|
||||
}
|
||||
|
||||
// similar to std::advance() except returns the advanced iterator and
|
||||
// also works with iterators that don't define difference_type
|
||||
template<class Iterator, class Distance>
|
||||
inline Iterator iterator_plus_distance(Iterator i, Distance n)
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::iterator_category tag;
|
||||
|
||||
return iterator_plus_distance(i, n, tag());
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_ITERATOR_PLUS_DISTANCE_HPP
|
||||
@@ -0,0 +1,44 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_ITERATOR_RANGE_SIZE_H
|
||||
#define BOOST_COMPUTE_DETAIL_ITERATOR_RANGE_SIZE_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// This is a convenience function which returns the size of a range
|
||||
// bounded by two iterators. This function has two differences from
|
||||
// the std::distance() function: 1) the return type (size_t) is
|
||||
// unsigned, and 2) the return value is always positive.
|
||||
template<class Iterator>
|
||||
inline size_t iterator_range_size(Iterator first, Iterator last)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<Iterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
difference_type difference = std::distance(first, last);
|
||||
|
||||
return static_cast<size_t>(
|
||||
(std::max)(difference, static_cast<difference_type>(0))
|
||||
);
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_ITERATOR_RANGE_SIZE_H
|
||||
@@ -0,0 +1,35 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_ITERATOR_TRAITS_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_ITERATOR_TRAITS_HPP
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/compute/detail/is_contiguous_iterator.hpp>
|
||||
#include <boost/compute/type_traits/is_device_iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
template<class Iterator>
|
||||
struct iterator_traits : public std::iterator_traits<Iterator>
|
||||
{
|
||||
static const bool is_contiguous = is_contiguous_iterator<Iterator>::value;
|
||||
static const bool is_on_device = is_device_iterator<Iterator>::value;
|
||||
static const bool is_on_host = !is_on_device;
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_ITERATOR_TRAITS_HPP
|
||||
@@ -0,0 +1,53 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_LITERAL_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_LITERAL_HPP
|
||||
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/compute/types/fundamental.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
std::string make_literal(T x)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << std::setprecision(
|
||||
#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
|
||||
std::numeric_limits<T>::max_digits10
|
||||
#else
|
||||
// We don't have max_digits10, so add 3 other digits (this is what is required for
|
||||
// float, and is one more than required for double).
|
||||
3 + std::numeric_limits<T>::digits10
|
||||
#endif
|
||||
)
|
||||
<< std::scientific
|
||||
<< x;
|
||||
|
||||
if(boost::is_same<T, float>::value || boost::is_same<T, float_>::value){
|
||||
s << "f";
|
||||
}
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_LITERAL_HPP
|
||||
@@ -0,0 +1,139 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_LRU_CACHE_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_LRU_CACHE_HPP
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// a cache which evicts the least recently used item when it is full
|
||||
template<class Key, class Value>
|
||||
class lru_cache
|
||||
{
|
||||
public:
|
||||
typedef Key key_type;
|
||||
typedef Value value_type;
|
||||
typedef std::list<key_type> list_type;
|
||||
typedef std::map<
|
||||
key_type,
|
||||
std::pair<value_type, typename list_type::iterator>
|
||||
> map_type;
|
||||
|
||||
lru_cache(size_t capacity)
|
||||
: m_capacity(capacity)
|
||||
{
|
||||
}
|
||||
|
||||
~lru_cache()
|
||||
{
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_map.size();
|
||||
}
|
||||
|
||||
size_t capacity() const
|
||||
{
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return m_map.empty();
|
||||
}
|
||||
|
||||
bool contains(const key_type &key)
|
||||
{
|
||||
return m_map.find(key) != m_map.end();
|
||||
}
|
||||
|
||||
void insert(const key_type &key, const value_type &value)
|
||||
{
|
||||
typename map_type::iterator i = m_map.find(key);
|
||||
if(i == m_map.end()){
|
||||
// insert item into the cache, but first check if it is full
|
||||
if(size() >= m_capacity){
|
||||
// cache is full, evict the least recently used item
|
||||
evict();
|
||||
}
|
||||
|
||||
// insert the new item
|
||||
m_list.push_front(key);
|
||||
m_map[key] = std::make_pair(value, m_list.begin());
|
||||
}
|
||||
}
|
||||
|
||||
boost::optional<value_type> get(const key_type &key)
|
||||
{
|
||||
// lookup value in the cache
|
||||
typename map_type::iterator i = m_map.find(key);
|
||||
if(i == m_map.end()){
|
||||
// value not in cache
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
// return the value, but first update its place in the most
|
||||
// recently used list
|
||||
typename list_type::iterator j = i->second.second;
|
||||
if(j != m_list.begin()){
|
||||
// move item to the front of the most recently used list
|
||||
m_list.erase(j);
|
||||
m_list.push_front(key);
|
||||
|
||||
// update iterator in map
|
||||
j = m_list.begin();
|
||||
const value_type &value = i->second.first;
|
||||
m_map[key] = std::make_pair(value, j);
|
||||
|
||||
// return the value
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
// the item is already at the front of the most recently
|
||||
// used list so just return it
|
||||
return i->second.first;
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_map.clear();
|
||||
m_list.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
void evict()
|
||||
{
|
||||
// evict item from the end of most recently used list
|
||||
typename list_type::iterator i = --m_list.end();
|
||||
m_map.erase(*i);
|
||||
m_list.erase(i);
|
||||
}
|
||||
|
||||
private:
|
||||
map_type m_map;
|
||||
list_type m_list;
|
||||
size_t m_capacity;
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_LRU_CACHE_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_MPL_VECTOR_TO_TUPLE_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_MPL_VECTOR_TO_TUPLE_HPP
|
||||
|
||||
#include <boost/mpl/copy.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/fusion/include/mpl.hpp>
|
||||
#include <boost/fusion/adapted/boost_tuple.hpp>
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
|
||||
#include <boost/compute/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
template<class Vector, size_t N>
|
||||
struct mpl_vector_to_tuple_impl;
|
||||
|
||||
#define BOOST_COMPUTE_PRINT_ELEM(z, n, unused) \
|
||||
typename mpl::at_c<Vector, n>::type
|
||||
|
||||
#define BOOST_COMPUTE_VEC2TUP(z, n, unused) \
|
||||
template<class Vector> \
|
||||
struct mpl_vector_to_tuple_impl<Vector, n> \
|
||||
{ \
|
||||
typedef typename \
|
||||
boost::tuple< \
|
||||
BOOST_PP_ENUM(n, BOOST_COMPUTE_PRINT_ELEM, ~) \
|
||||
> type; \
|
||||
};
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_VEC2TUP, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_VEC2TUP
|
||||
#undef BOOST_COMPUTE_PRINT_ELEM
|
||||
|
||||
// meta-function which converts a mpl::vector to a boost::tuple
|
||||
template<class Vector>
|
||||
struct mpl_vector_to_tuple
|
||||
{
|
||||
typedef typename
|
||||
mpl_vector_to_tuple_impl<
|
||||
Vector,
|
||||
mpl::size<Vector>::value
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_MPL_VECTOR_TO_TUPLE_HPP
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_NVIDIA_COMPUTE_CAPABILITY_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_NVIDIA_COMPUTE_CAPABILITY_HPP
|
||||
|
||||
#include <boost/compute/device.hpp>
|
||||
|
||||
#ifdef BOOST_COMPUTE_HAVE_HDR_CL_EXT
|
||||
#include <CL/cl_ext.h>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
|
||||
#define BOOST_COMPUTE_CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
|
||||
#else
|
||||
#define BOOST_COMPUTE_CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000
|
||||
#endif
|
||||
|
||||
#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV
|
||||
#define BOOST_COMPUTE_CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV
|
||||
#else
|
||||
#define BOOST_COMPUTE_CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001
|
||||
#endif
|
||||
|
||||
inline void get_nvidia_compute_capability(const device &device, int &major, int &minor)
|
||||
{
|
||||
if(!device.supports_extension("cl_nv_device_attribute_query")){
|
||||
major = minor = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
major = device.get_info<uint_>(BOOST_COMPUTE_CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV);
|
||||
minor = device.get_info<uint_>(BOOST_COMPUTE_CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV);
|
||||
}
|
||||
|
||||
inline bool check_nvidia_compute_capability(const device &device, int major, int minor)
|
||||
{
|
||||
int actual_major, actual_minor;
|
||||
get_nvidia_compute_capability(device, actual_major, actual_minor);
|
||||
|
||||
return actual_major > major ||
|
||||
(actual_major == major && actual_minor >= minor);
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_NVIDIA_COMPUTE_CAPABILITY_HPP
|
||||
@@ -0,0 +1,215 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2015 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_DETAIL_PARAMETER_CACHE_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_PARAMETER_CACHE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <boost/compute/config.hpp>
|
||||
#include <boost/compute/device.hpp>
|
||||
#include <boost/compute/detail/global_static.hpp>
|
||||
#include <boost/compute/version.hpp>
|
||||
|
||||
#ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/compute/detail/path.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#endif // BOOST_COMPUTE_USE_OFFLINE_CACHE
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
class parameter_cache : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
parameter_cache(const device &device)
|
||||
: m_dirty(false),
|
||||
m_device_name(device.name())
|
||||
{
|
||||
#ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE
|
||||
// get offline cache file name (e.g. /home/user/.boost_compute/tune/device.json)
|
||||
m_file_name = make_file_name();
|
||||
|
||||
// load parameters from offline cache file (if it exists)
|
||||
if(boost::filesystem::exists(m_file_name)){
|
||||
read_from_disk();
|
||||
}
|
||||
#endif // BOOST_COMPUTE_USE_OFFLINE_CACHE
|
||||
}
|
||||
|
||||
~parameter_cache()
|
||||
{
|
||||
#ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE
|
||||
write_to_disk();
|
||||
#endif // BOOST_COMPUTE_USE_OFFLINE_CACHE
|
||||
}
|
||||
|
||||
void set(const std::string &object, const std::string ¶meter, uint_ value)
|
||||
{
|
||||
m_cache[std::make_pair(object, parameter)] = value;
|
||||
|
||||
// set the dirty flag to true. this will cause the updated parameters
|
||||
// to be stored to disk.
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
uint_ get(const std::string &object, const std::string ¶meter, uint_ default_value)
|
||||
{
|
||||
std::map<std::pair<std::string, std::string>, uint_>::iterator
|
||||
iter = m_cache.find(std::make_pair(object, parameter));
|
||||
if(iter != m_cache.end()){
|
||||
return iter->second;
|
||||
}
|
||||
else {
|
||||
return default_value;
|
||||
}
|
||||
}
|
||||
|
||||
static boost::shared_ptr<parameter_cache> get_global_cache(const device &device)
|
||||
{
|
||||
// device name -> parameter cache
|
||||
typedef std::map<std::string, boost::shared_ptr<parameter_cache> > cache_map;
|
||||
|
||||
BOOST_COMPUTE_DETAIL_GLOBAL_STATIC(cache_map, caches, ((std::less<std::string>())));
|
||||
|
||||
cache_map::iterator iter = caches.find(device.name());
|
||||
if(iter == caches.end()){
|
||||
boost::shared_ptr<parameter_cache> cache =
|
||||
boost::make_shared<parameter_cache>(device);
|
||||
|
||||
caches.insert(iter, std::make_pair(device.name(), cache));
|
||||
|
||||
return cache;
|
||||
}
|
||||
else {
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE
|
||||
// returns a string containing a cannoical device name
|
||||
static std::string cannonical_device_name(std::string name)
|
||||
{
|
||||
boost::algorithm::trim(name);
|
||||
std::replace(name.begin(), name.end(), ' ', '_');
|
||||
std::replace(name.begin(), name.end(), '(', '_');
|
||||
std::replace(name.begin(), name.end(), ')', '_');
|
||||
return name;
|
||||
}
|
||||
|
||||
// returns the boost.compute version string
|
||||
static std::string version_string()
|
||||
{
|
||||
char buf[32];
|
||||
std::snprintf(buf, sizeof(buf), "%d.%d.%d", BOOST_COMPUTE_VERSION_MAJOR,
|
||||
BOOST_COMPUTE_VERSION_MINOR,
|
||||
BOOST_COMPUTE_VERSION_PATCH);
|
||||
return buf;
|
||||
}
|
||||
|
||||
// returns the file path for the cached parameters
|
||||
std::string make_file_name() const
|
||||
{
|
||||
return detail::parameter_cache_path(true) + cannonical_device_name(m_device_name) + ".json";
|
||||
}
|
||||
|
||||
// store current parameters to disk
|
||||
void write_to_disk()
|
||||
{
|
||||
BOOST_ASSERT(!m_file_name.empty());
|
||||
|
||||
if(m_dirty){
|
||||
// save current parameters to disk
|
||||
boost::property_tree::ptree pt;
|
||||
pt.put("header.device", m_device_name);
|
||||
pt.put("header.version", version_string());
|
||||
typedef std::map<std::pair<std::string, std::string>, uint_> map_type;
|
||||
for(map_type::const_iterator iter = m_cache.begin(); iter != m_cache.end(); ++iter){
|
||||
const std::pair<std::string, std::string> &key = iter->first;
|
||||
pt.add(key.first + "." + key.second, iter->second);
|
||||
}
|
||||
write_json(m_file_name, pt);
|
||||
|
||||
m_dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
// load stored parameters from disk
|
||||
void read_from_disk()
|
||||
{
|
||||
BOOST_ASSERT(!m_file_name.empty());
|
||||
|
||||
m_cache.clear();
|
||||
|
||||
boost::property_tree::ptree pt;
|
||||
try {
|
||||
read_json(m_file_name, pt);
|
||||
}
|
||||
catch(boost::property_tree::json_parser::json_parser_error&){
|
||||
// no saved cache file, ignore
|
||||
return;
|
||||
}
|
||||
|
||||
std::string stored_device;
|
||||
try {
|
||||
stored_device = pt.get<std::string>("header.device");
|
||||
}
|
||||
catch(boost::property_tree::ptree_bad_path&){
|
||||
return;
|
||||
}
|
||||
|
||||
std::string stored_version;
|
||||
try {
|
||||
stored_version = pt.get<std::string>("header.version");
|
||||
}
|
||||
catch(boost::property_tree::ptree_bad_path&){
|
||||
return;
|
||||
}
|
||||
|
||||
if(stored_device == m_device_name && stored_version == version_string()){
|
||||
typedef boost::property_tree::ptree::const_iterator pt_iter;
|
||||
for(pt_iter iter = pt.begin(); iter != pt.end(); ++iter){
|
||||
if(iter->first == "header"){
|
||||
// skip header
|
||||
continue;
|
||||
}
|
||||
|
||||
boost::property_tree::ptree child_pt = pt.get_child(iter->first);
|
||||
for(pt_iter child_iter = child_pt.begin(); child_iter != child_pt.end(); ++child_iter){
|
||||
set(iter->first, child_iter->first, boost::lexical_cast<uint_>(child_iter->second.data()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_dirty = false;
|
||||
}
|
||||
#endif // BOOST_COMPUTE_USE_OFFLINE_CACHE
|
||||
|
||||
private:
|
||||
bool m_dirty;
|
||||
std::string m_device_name;
|
||||
std::string m_file_name;
|
||||
std::map<std::pair<std::string, std::string>, uint_> m_cache;
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_PARAMETER_CACHE_HPP
|
||||
@@ -0,0 +1,73 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_PATH_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_PATH_HPP
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/compute/detail/getenv.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// Path delimiter symbol for the current OS.
|
||||
static const std::string& path_delim()
|
||||
{
|
||||
static const std::string delim =
|
||||
boost::filesystem::path("/").make_preferred().string();
|
||||
return delim;
|
||||
}
|
||||
|
||||
// Path to appdata folder.
|
||||
inline const std::string& appdata_path()
|
||||
{
|
||||
#ifdef WIN32
|
||||
static const std::string appdata = detail::getenv("APPDATA")
|
||||
+ path_delim() + "boost_compute";
|
||||
#else
|
||||
static const std::string appdata = detail::getenv("HOME")
|
||||
+ path_delim() + ".boost_compute";
|
||||
#endif
|
||||
return appdata;
|
||||
}
|
||||
|
||||
// Path to cached binaries.
|
||||
inline std::string program_binary_path(const std::string &hash, bool create = false)
|
||||
{
|
||||
std::string dir = detail::appdata_path() + path_delim()
|
||||
+ hash.substr(0, 2) + path_delim()
|
||||
+ hash.substr(2);
|
||||
|
||||
if(create && !boost::filesystem::exists(dir)){
|
||||
boost::filesystem::create_directories(dir);
|
||||
}
|
||||
|
||||
return dir + path_delim();
|
||||
}
|
||||
|
||||
// Path to parameter caches.
|
||||
inline std::string parameter_cache_path(bool create = false)
|
||||
{
|
||||
const static std::string dir = appdata_path() + path_delim() + "tune";
|
||||
|
||||
if(create && !boost::filesystem::exists(dir)){
|
||||
boost::filesystem::create_directories(dir);
|
||||
}
|
||||
|
||||
return dir + path_delim();
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_PATH_HPP
|
||||
@@ -0,0 +1,82 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_PRINT_RANGE_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_PRINT_RANGE_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/compute/algorithm/copy.hpp>
|
||||
#include <boost/compute/container/vector.hpp>
|
||||
#include <boost/compute/detail/is_buffer_iterator.hpp>
|
||||
#include <boost/compute/detail/iterator_range_size.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
template<class InputIterator>
|
||||
inline void print_range(InputIterator first,
|
||||
InputIterator last,
|
||||
command_queue &queue,
|
||||
typename boost::enable_if<
|
||||
is_buffer_iterator<InputIterator>
|
||||
>::type* = 0)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<InputIterator>::value_type
|
||||
value_type;
|
||||
|
||||
const size_t size = iterator_range_size(first, last);
|
||||
|
||||
// copy values to temporary vector on the host
|
||||
std::vector<value_type> tmp(size);
|
||||
::boost::compute::copy(first, last, tmp.begin(), queue);
|
||||
|
||||
// print values
|
||||
std::cout << "[ ";
|
||||
for(size_t i = 0; i < size; i++){
|
||||
std::cout << tmp[i];
|
||||
if(i != size - 1){
|
||||
std::cout << ", ";
|
||||
}
|
||||
}
|
||||
std::cout << " ]" << std::endl;
|
||||
}
|
||||
|
||||
template<class InputIterator>
|
||||
inline void print_range(InputIterator first,
|
||||
InputIterator last,
|
||||
command_queue &queue,
|
||||
typename boost::enable_if_c<
|
||||
!is_buffer_iterator<InputIterator>::value
|
||||
>::type* = 0)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<InputIterator>::value_type
|
||||
value_type;
|
||||
|
||||
const context &context = queue.get_context();
|
||||
const size_t size = iterator_range_size(first, last);
|
||||
|
||||
// copy values to temporary vector on the device
|
||||
::boost::compute::vector<value_type> tmp(size, context);
|
||||
::boost::compute::copy(first, last, tmp.begin(), queue);
|
||||
|
||||
print_range(tmp.begin(), tmp.end(), queue);
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_PRINT_RANGE_HPP
|
||||
@@ -0,0 +1,77 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_DETAIL_READ_WRITE_SINGLE_VALUE_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_READ_WRITE_SINGLE_VALUE_HPP
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/compute/buffer.hpp>
|
||||
#include <boost/compute/exception.hpp>
|
||||
#include <boost/compute/command_queue.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// reads and returns a single value at index in the buffer
|
||||
template<class T>
|
||||
inline T read_single_value(const buffer &buffer,
|
||||
size_t index,
|
||||
command_queue &queue)
|
||||
{
|
||||
BOOST_ASSERT(index < buffer.size() / sizeof(T));
|
||||
BOOST_ASSERT(buffer.get_context() == queue.get_context());
|
||||
|
||||
T value;
|
||||
queue.enqueue_read_buffer(buffer,
|
||||
sizeof(T) * index,
|
||||
sizeof(T),
|
||||
&value);
|
||||
return value;
|
||||
}
|
||||
|
||||
// reads and returns a the first value in the buffer
|
||||
template<class T>
|
||||
inline T read_single_value(const buffer &buffer, command_queue &queue)
|
||||
{
|
||||
return read_single_value<T>(buffer, 0, queue);
|
||||
}
|
||||
|
||||
// writes a single value at index to the buffer
|
||||
template<class T>
|
||||
inline void write_single_value(const T &value,
|
||||
const buffer &buffer,
|
||||
size_t index,
|
||||
command_queue &queue)
|
||||
{
|
||||
BOOST_ASSERT(index < buffer.size() / sizeof(T));
|
||||
BOOST_ASSERT(buffer.get_context() == queue.get_context());
|
||||
|
||||
queue.enqueue_write_buffer(buffer,
|
||||
index * sizeof(T),
|
||||
sizeof(T),
|
||||
&value);
|
||||
}
|
||||
|
||||
// writes value to the first location in buffer
|
||||
template<class T>
|
||||
inline void write_single_value(const T &value,
|
||||
const buffer &buffer,
|
||||
command_queue &queue)
|
||||
{
|
||||
write_single_value<T>(value, buffer, 0, queue);
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_READ_WRITE_SINGLE_VALUE_HPP
|
||||
@@ -0,0 +1,53 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_SHA1_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_SHA1_HPP
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <boost/uuid/sha1.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// Accumulates SHA1 hash of the passed strings.
|
||||
class sha1 {
|
||||
public:
|
||||
sha1(const std::string &s = "") {
|
||||
if (!s.empty()) this->process(s);
|
||||
}
|
||||
|
||||
sha1& process(const std::string &s) {
|
||||
h.process_bytes(s.c_str(), s.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator std::string() {
|
||||
unsigned int digest[5];
|
||||
h.get_digest(digest);
|
||||
|
||||
std::ostringstream buf;
|
||||
for(int i = 0; i < 5; ++i)
|
||||
buf << std::hex << std::setfill('0') << std::setw(8) << digest[i];
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
private:
|
||||
boost::uuids::detail::sha1 h;
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_SHA1_HPP
|
||||
@@ -0,0 +1,35 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_VARIDAIC_MACROS_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_VARIDAIC_MACROS_HPP
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/config/config.hpp>
|
||||
#include <boost/preprocessor/tuple/to_seq.hpp>
|
||||
|
||||
#if BOOST_PP_VARIADICS == 1
|
||||
# include <boost/preprocessor/variadic/size.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_PP_VARIADIC_SIZE
|
||||
# define BOOST_COMPUTE_PP_VARIADIC_SIZE BOOST_PP_VARIADIC_SIZE
|
||||
#else
|
||||
# define BOOST_COMPUTE_PP_VARIADIC_SIZE(...) BOOST_COMPUTE_PP_VARIADIC_SIZE_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
|
||||
# define BOOST_COMPUTE_PP_VARIADIC_SIZE_I(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, size, ...) size
|
||||
#endif
|
||||
|
||||
#define BOOST_COMPUTE_PP_TUPLE_SIZE(tuple) \
|
||||
BOOST_COMPUTE_PP_VARIADIC_SIZE tuple
|
||||
|
||||
#define BOOST_COMPUTE_PP_TUPLE_TO_SEQ(tuple) \
|
||||
BOOST_PP_TUPLE_TO_SEQ(BOOST_COMPUTE_PP_TUPLE_SIZE(tuple), tuple)
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_VARIDAIC_MACROS_HPP
|
||||
@@ -0,0 +1,50 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_VENDOR_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_VENDOR_HPP
|
||||
|
||||
#include <boost/compute/device.hpp>
|
||||
#include <boost/compute/platform.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// returns true if the device is an nvidia gpu
|
||||
inline bool is_nvidia_device(const device &device)
|
||||
{
|
||||
std::string nvidia("NVIDIA");
|
||||
return device.vendor().compare(0, nvidia.size(), nvidia) == 0;
|
||||
}
|
||||
|
||||
// returns true if the device is an amd cpu or gpu
|
||||
inline bool is_amd_device(const device &device)
|
||||
{
|
||||
return device.platform().vendor() == "Advanced Micro Devices, Inc.";
|
||||
}
|
||||
|
||||
// returns true if the platform is Apple OpenCL platform
|
||||
inline bool is_apple_platform(const platform &platform)
|
||||
{
|
||||
return platform.name() == "Apple";
|
||||
}
|
||||
|
||||
// returns true if the device is from Apple OpenCL Platform
|
||||
inline bool is_apple_platform_device(const device &device)
|
||||
{
|
||||
return is_apple_platform(device.platform());
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_VENDOR_HPP
|
||||
@@ -0,0 +1,37 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_DETAIL_WORK_SIZE_HPP
|
||||
#define BOOST_COMPUTE_DETAIL_WORK_SIZE_HPP
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// Given a total number of values (count), a number of values to
|
||||
// process per thread (vtp), and a number of threads to execute per
|
||||
// block (tpb), this function returns the global work size to be
|
||||
// passed to clEnqueueNDRangeKernel() for a 1D algorithm.
|
||||
inline size_t calculate_work_size(size_t count, size_t vpt, size_t tpb)
|
||||
{
|
||||
size_t work_size = static_cast<size_t>(std::ceil(float(count) / vpt));
|
||||
if(work_size % tpb != 0){
|
||||
work_size += tpb - work_size % tpb;
|
||||
}
|
||||
return work_size;
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_DETAIL_WORK_SIZE_HPP
|
||||
Reference in New Issue
Block a user