stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,76 @@
//---------------------------------------------------------------------------//
// 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_UTILITY_DIM_HPP
#define BOOST_COMPUTE_UTILITY_DIM_HPP
#include <boost/compute/config.hpp>
#include <boost/compute/utility/extents.hpp>
namespace boost {
namespace compute {
#ifndef BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
/// The variadic \c dim() function provides a concise syntax for creating
/// \ref extents objects.
///
/// For example,
/// \code
/// extents<2> region = dim(640, 480); // region == (640, 480)
/// \endcode
///
/// \see \ref extents "extents<N>"
template<class... Args>
inline extents<sizeof...(Args)> dim(Args... args)
{
return extents<sizeof...(Args)>({ static_cast<size_t>(args)... });
}
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1800)
// for some inexplicable reason passing one parameter to 'dim' variadic template
// generates compile error on msvc 2013 update 4
template<class T>
inline extents<1> dim(T arg)
{
return extents<1>(static_cast<size_t>(arg));
}
#endif // BOOST_WORKAROUND(BOOST_MSVC, <= 1800)
#else
// dim() function definitions for non-c++11 compilers
#define BOOST_COMPUTE_DETAIL_ASSIGN_DIM(z, n, var) \
var[n] = BOOST_PP_CAT(e, n);
#define BOOST_COMPUTE_DETAIL_DEFINE_DIM(z, n, var) \
inline extents<n> dim(BOOST_PP_ENUM_PARAMS(n, size_t e)) \
{ \
extents<n> exts; \
BOOST_PP_REPEAT(n, BOOST_COMPUTE_DETAIL_ASSIGN_DIM, exts) \
return exts; \
}
BOOST_PP_REPEAT(BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_DETAIL_DEFINE_DIM, ~)
#undef BOOST_COMPUTE_DETAIL_ASSIGN_DIM
#undef BOOST_COMPUTE_DETAIL_DEFINE_DIM
#endif // BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
/// \internal_
template<size_t N>
inline extents<N> dim()
{
return extents<N>();
}
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_UTILITY_DIM_HPP
@@ -0,0 +1,164 @@
//---------------------------------------------------------------------------//
// 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_UTILITY_EXTENTS_HPP
#define BOOST_COMPUTE_UTILITY_EXTENTS_HPP
#include <functional>
#include <numeric>
#include <boost/compute/config.hpp>
#ifndef BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#include <boost/array.hpp>
namespace boost {
namespace compute {
/// The extents class contains an array of n-dimensional extents.
///
/// \see dim()
template<size_t N>
class extents
{
public:
typedef size_t size_type;
static const size_type static_size = N;
typedef boost::array<size_t, N> array_type;
typedef typename array_type::iterator iterator;
typedef typename array_type::const_iterator const_iterator;
/// Creates an extents object with each component set to zero.
///
/// For example:
/// \code
/// extents<3> exts(); // (0, 0, 0)
/// \endcode
extents()
{
m_extents.fill(0);
}
/// Creates an extents object with each component set to \p value.
///
/// For example:
/// \code
/// extents<3> exts(1); // (1, 1, 1)
/// \endcode
explicit extents(size_t value)
{
m_extents.fill(value);
}
#ifndef BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST
/// Creates an extents object with \p values.
extents(std::initializer_list<size_t> values)
{
BOOST_ASSERT(values.size() == N);
std::copy(values.begin(), values.end(), m_extents.begin());
}
#endif // BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST
/// Returns the size (i.e. dimensionality) of the extents array.
size_type size() const
{
return N;
}
/// Returns the linear size of the extents. This is equivalent to the
/// product of each extent in each dimension.
size_type linear() const
{
return std::accumulate(
m_extents.begin(), m_extents.end(), 1, std::multiplies<size_type>()
);
}
/// Returns a pointer to the extents data array.
///
/// This is useful for passing the extents data to OpenCL APIs which
/// expect an array of \c size_t.
size_t* data()
{
return m_extents.data();
}
/// \overload
const size_t* data() const
{
return m_extents.data();
}
iterator begin()
{
return m_extents.begin();
}
const_iterator begin() const
{
return m_extents.begin();
}
const_iterator cbegin() const
{
return m_extents.cbegin();
}
iterator end()
{
return m_extents.end();
}
const_iterator end() const
{
return m_extents.end();
}
const_iterator cend() const
{
return m_extents.cend();
}
/// Returns a reference to the extent at \p index.
size_t& operator[](size_t index)
{
return m_extents[index];
}
/// \overload
const size_t& operator[](size_t index) const
{
return m_extents[index];
}
/// Returns \c true if the extents in \c *this are the same as \p other.
bool operator==(const extents &other) const
{
return m_extents == other.m_extents;
}
/// Returns \c true if the extents in \c *this are not the same as \p other.
bool operator!=(const extents &other) const
{
return m_extents != other.m_extents;
}
private:
array_type m_extents;
};
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_UTILITY_EXTENTS_HPP
@@ -0,0 +1,71 @@
//---------------------------------------------------------------------------//
// 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://kylelutz.github.com/compute for more information.
//---------------------------------------------------------------------------//
#ifndef BOOST_COMPUTE_UTILITY_INVOKE_HPP
#define BOOST_COMPUTE_UTILITY_INVOKE_HPP
#include <boost/preprocessor/enum.hpp>
#include <boost/preprocessor/repetition.hpp>
#include <boost/compute/config.hpp>
#include <boost/compute/command_queue.hpp>
#include <boost/compute/detail/meta_kernel.hpp>
#include <boost/compute/container/detail/scalar.hpp>
#include <boost/compute/type_traits/result_of.hpp>
namespace boost {
namespace compute {
#define BOOST_COMPUTE_DETAIL_INVOKE_ARG(z, n, unused) \
BOOST_PP_COMMA_IF(n) k.var<BOOST_PP_CAT(T, n)>("arg" BOOST_PP_STRINGIZE(n))
#define BOOST_COMPUTE_DETAIL_INVOKE_ADD_ARG(z, n, unused) \
k.add_set_arg("arg" BOOST_PP_STRINGIZE(n), BOOST_PP_CAT(arg, n));
#define BOOST_COMPUTE_DETAIL_DEFINE_INVOKE(z, n, unused) \
template<class Function, BOOST_PP_ENUM_PARAMS(n, class T)> \
inline typename result_of<Function(BOOST_PP_ENUM_PARAMS(n, T))>::type \
invoke(const Function& function, command_queue& queue, BOOST_PP_ENUM_BINARY_PARAMS(n, const T, &arg)) \
{ \
typedef typename result_of<Function(BOOST_PP_ENUM_PARAMS(n, T))>::type result_type; \
detail::meta_kernel k("invoke"); \
detail::scalar<result_type> result(queue.get_context()); \
const size_t result_arg = k.add_arg<result_type *>(memory_object::global_memory, "result"); \
BOOST_PP_REPEAT(n, BOOST_COMPUTE_DETAIL_INVOKE_ADD_ARG, ~) \
k << "*result = " << function( \
BOOST_PP_REPEAT(n, BOOST_COMPUTE_DETAIL_INVOKE_ARG, ~) \
) << ";"; \
k.set_arg(result_arg, result.get_buffer()); \
k.exec(queue); \
return result.read(queue); \
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_DETAIL_DEFINE_INVOKE, ~)
#undef BOOST_COMPUTE_DETAIL_INVOKE_ARG
#undef BOOST_COMPUTE_DETAIL_INVOKE_ADD_ARG
#undef BOOST_COMPUTE_DETAIL_DEFINE_INVOKE
#ifdef BOOST_COMPUTE_DOXYGEN_INVOKED
/// Invokes \p function with \p args on \p queue.
///
/// For example, to invoke the builtin abs() function:
/// \code
/// int result = invoke(abs<int>(), queue, -10); // returns 10
/// \endcode
template<class Function, class... Args>
inline typename result_of<Function(Args...)>::type
invoke(const Function& function, command_queue& queue, const Args&... args);
#endif // BOOST_COMPUTE_DOXYGEN_INVOKED
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_UTILITY_INVOKE_HPP
@@ -0,0 +1,172 @@
//---------------------------------------------------------------------------//
// 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_UTILITY_PROGRAM_CACHE_HPP
#define BOOST_COMPUTE_UTILITY_PROGRAM_CACHE_HPP
#include <string>
#include <utility>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/noncopyable.hpp>
#include <boost/compute/context.hpp>
#include <boost/compute/program.hpp>
#include <boost/compute/detail/lru_cache.hpp>
#include <boost/compute/detail/global_static.hpp>
namespace boost {
namespace compute {
/// The program_cache class stores \ref program objects in a LRU cache.
///
/// This class can be used to help mitigate the overhead of OpenCL's run-time
/// kernel compilation model. Commonly used programs can be stored persistently
/// in the cache and only compiled once on their first use.
///
/// Program objects are stored and retreived based on a user-defined cache key
/// along with the options used to build the program (if any).
///
/// For example, to insert a program into the cache:
/// \code
/// cache.insert("foo", foo_program);
/// \endcode
///
/// And to retreive the program later:
/// \code
/// boost::optional<program> p = cache.get("foo");
/// if(p){
/// // program found in cache
/// }
/// \endcode
///
/// \see program
class program_cache : boost::noncopyable
{
public:
/// Creates a new program cache with space for \p capacity number of
/// program objects.
program_cache(size_t capacity)
: m_cache(capacity)
{
}
/// Destroys the program cache.
~program_cache()
{
}
/// Returns the number of program objects currently stored in the cache.
size_t size() const
{
return m_cache.size();
}
/// Returns the total capacity of the cache.
size_t capacity() const
{
return m_cache.capacity();
}
/// Clears the program cache.
void clear()
{
m_cache.clear();
}
/// Returns the program object with \p key. Returns a null optional if no
/// program with \p key exists in the cache.
boost::optional<program> get(const std::string &key)
{
return m_cache.get(std::make_pair(key, std::string()));
}
/// Returns the program object with \p key and \p options. Returns a null
/// optional if no program with \p key and \p options exists in the cache.
boost::optional<program> get(const std::string &key, const std::string &options)
{
return m_cache.get(std::make_pair(key, options));
}
/// Inserts \p program into the cache with \p key.
void insert(const std::string &key, const program &program)
{
insert(key, std::string(), program);
}
/// Inserts \p program into the cache with \p key and \p options.
void insert(const std::string &key, const std::string &options, const program &program)
{
m_cache.insert(std::make_pair(key, options), program);
}
/// Loads the program with \p key from the cache if it exists. Otherwise
/// builds a new program with \p source and \p options, stores it in the
/// cache, and returns it.
///
/// This is a convenience function to simplify the common pattern of
/// attempting to load a program from the cache and, if not present,
/// building the program from source and storing it in the cache.
///
/// Equivalent to:
/// \code
/// boost::optional<program> p = get(key, options);
/// if(!p){
/// p = program::create_with_source(source, context);
/// p->build(options);
/// insert(key, options, *p);
/// }
/// return *p;
/// \endcode
program get_or_build(const std::string &key,
const std::string &options,
const std::string &source,
const context &context)
{
boost::optional<program> p = get(key, options);
if(!p){
p = program::build_with_source(source, context, options);
insert(key, options, *p);
}
return *p;
}
/// Returns the global program cache for \p context.
///
/// This global cache is used internally by Boost.Compute to store compiled
/// program objects used by its algorithms. All Boost.Compute programs are
/// stored with a cache key beginning with \c "__boost". User programs
/// should avoid using the same prefix in order to prevent collisions.
static boost::shared_ptr<program_cache> get_global_cache(const context &context)
{
typedef detail::lru_cache<cl_context, boost::shared_ptr<program_cache> > cache_map;
BOOST_COMPUTE_DETAIL_GLOBAL_STATIC(cache_map, caches, (8));
boost::optional<boost::shared_ptr<program_cache> > cache = caches.get(context.get());
if(!cache){
cache = boost::make_shared<program_cache>(64);
caches.insert(context.get(), *cache);
}
return *cache;
}
private:
detail::lru_cache<std::pair<std::string, std::string>, program> m_cache;
};
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_UTILITY_PROGRAM_CACHE_HPP
@@ -0,0 +1,39 @@
//---------------------------------------------------------------------------//
// 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_UTILITY_SOURCE_HPP
#define BOOST_COMPUTE_UTILITY_SOURCE_HPP
/// Stringizes OpenCL source code.
///
/// For example, to create a simple kernel which squares each input value:
/// \code
/// const char source[] = BOOST_COMPUTE_STRINGIZE_SOURCE(
/// __kernel void square(const float *input, float *output)
/// {
/// const uint i = get_global_id(0);
/// const float x = input[i];
/// output[i] = x * x;
/// }
/// );
///
/// // create and build square program
/// program square_program = program::build_with_source(source, context);
///
/// // create square kernel
/// kernel square_kernel(square_program, "square");
/// \endcode
#ifdef BOOST_COMPUTE_DOXYGEN_INVOKED
#define BOOST_COMPUTE_STRINGIZE_SOURCE(source)
#else
#define BOOST_COMPUTE_STRINGIZE_SOURCE(...) #__VA_ARGS__
#endif
#endif // BOOST_COMPUTE_UTILITY_SOURCE_HPP
@@ -0,0 +1,217 @@
//---------------------------------------------------------------------------//
// 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_UTILITY_WAIT_LIST_HPP
#define BOOST_COMPUTE_UTILITY_WAIT_LIST_HPP
#include <vector>
#include <boost/compute/config.hpp>
#ifndef BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#include <boost/compute/event.hpp>
namespace boost {
namespace compute {
template<class T> class future;
/// \class wait_list
/// \brief Stores a list of events.
///
/// The wait_list class stores a set of event objects and can be used to
/// specify dependencies for OpenCL operations or to wait on the host until
/// all of the events have completed.
///
/// This class also provides convenience functions for interacting with
/// OpenCL APIs which typically accept event dependencies as a \c cl_event*
/// pointer and a \c cl_uint size. For example:
/// \code
/// wait_list events = ...;
///
/// clEnqueueNDRangeKernel(..., events.get_event_ptr(), events.size(), ...);
/// \endcode
///
/// \see event, \ref future "future<T>"
class wait_list
{
public:
typedef std::vector<event>::iterator iterator;
typedef std::vector<event>::const_iterator const_iterator;
/// Creates an empty wait-list.
wait_list()
{
}
/// Creates a wait-list containing \p event.
wait_list(const event &event)
{
insert(event);
}
/// Creates a new wait-list as a copy of \p other.
wait_list(const wait_list &other)
: m_events(other.m_events)
{
}
#ifndef BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST
/// Creates a wait-list from \p events
wait_list(std::initializer_list<event> events)
: m_events(events)
{
}
#endif // BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST
/// Copies the events in the wait-list from \p other.
wait_list& operator=(const wait_list &other)
{
if(this != &other){
m_events = other.m_events;
}
return *this;
}
#ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
/// Move-constructs a new wait list object from \p other.
wait_list(wait_list&& other)
: m_events(std::move(other.m_events))
{
}
/// Move-assigns the wait list from \p other to \c *this.
wait_list& operator=(wait_list&& other)
{
m_events = std::move(other.m_events);
return *this;
}
#endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
/// Destroys the wait-list.
~wait_list()
{
}
/// Returns \c true if the wait-list is empty.
bool empty() const
{
return m_events.empty();
}
/// Returns the number of events in the wait-list.
uint_ size() const
{
return static_cast<uint_>(m_events.size());
}
/// Removes all of the events from the wait-list.
void clear()
{
m_events.clear();
}
/// Returns a cl_event pointer to the first event in the wait-list.
/// Returns \c 0 if the wait-list is empty.
///
/// This can be used to pass the wait-list to OpenCL functions which
/// expect a \c cl_event pointer to refer to a list of events.
const cl_event* get_event_ptr() const
{
if(empty()){
return 0;
}
return reinterpret_cast<const cl_event *>(&m_events[0]);
}
/// Reserves a minimum length of storage for the wait list object.
void reserve(size_t new_capacity) {
m_events.reserve(new_capacity);
}
/// Inserts \p event into the wait-list.
void insert(const event &event)
{
m_events.push_back(event);
}
/// Inserts the event from \p future into the wait-list.
template<class T>
void insert(const future<T> &future)
{
insert(future.get_event());
}
/// Blocks until all of the events in the wait-list have completed.
///
/// Does nothing if the wait-list is empty.
void wait() const
{
if(!empty()){
BOOST_COMPUTE_ASSERT_CL_SUCCESS(
clWaitForEvents(size(), get_event_ptr())
);
}
}
/// Returns a reference to the event at specified location \p pos.
const event& operator[](size_t pos) const {
return m_events[pos];
}
/// Returns a reference to the event at specified location \p pos.
event& operator[](size_t pos) {
return m_events[pos];
}
/// Returns an iterator to the first element of the wait-list.
iterator begin() {
return m_events.begin();
}
/// Returns an iterator to the first element of the wait-list.
const_iterator begin() const {
return m_events.begin();
}
/// Returns an iterator to the first element of the wait-list.
const_iterator cbegin() const {
return m_events.begin();
}
/// Returns an iterator to the element following the last element of the wait-list.
iterator end() {
return m_events.end();
}
/// Returns an iterator to the element following the last element of the wait-list.
const_iterator end() const {
return m_events.end();
}
/// Returns an iterator to the element following the last element of the wait-list.
const_iterator cend() const {
return m_events.end();
}
private:
std::vector<event> m_events;
};
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_UTILITY_WAIT_LIST_HPP