#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 {
class program_cache : boost::noncopyable
{
public:
program_cache(size_t capacity)
: m_cache(capacity)
{
}
~program_cache()
{
}
size_t size() const
{
return m_cache.size();
}
size_t capacity() const
{
return m_cache.capacity();
}
void clear()
{
m_cache.clear();
}
boost::optional<program> get(const std::string &key)
{
return m_cache.get(std::make_pair(key, std::string()));
}
boost::optional<program> get(const std::string &key, const std::string &options)
{
return m_cache.get(std::make_pair(key, options));
}
void insert(const std::string &key, const program &program)
{
insert(key, std::string(), program);
}
void insert(const std::string &key, const std::string &options, const program &program)
{
m_cache.insert(std::make_pair(key, options), program);
}
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;
}
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;
};
} }
#endif