summaryrefslogtreecommitdiff
path: root/boost/compute/utility/program_cache.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/compute/utility/program_cache.hpp')
-rw-r--r--boost/compute/utility/program_cache.hpp172
1 files changed, 172 insertions, 0 deletions
diff --git a/boost/compute/utility/program_cache.hpp b/boost/compute/utility/program_cache.hpp
new file mode 100644
index 0000000000..c80e1a3b1e
--- /dev/null
+++ b/boost/compute/utility/program_cache.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