]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/compute/include/boost/compute/detail/parameter_cache.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / compute / include / boost / compute / detail / parameter_cache.hpp
CommitLineData
7c673cae
FG
1//---------------------------------------------------------------------------//
2// Copyright (c) 2013-2015 Kyle Lutz <kyle.r.lutz@gmail.com>
3//
4// Distributed under the Boost Software License, Version 1.0
5// See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt
7//
8// See http://boostorg.github.com/compute for more information.
9//---------------------------------------------------------------------------//
10
11#ifndef BOOST_COMPUTE_DETAIL_PARAMETER_CACHE_HPP
12#define BOOST_COMPUTE_DETAIL_PARAMETER_CACHE_HPP
13
14#include <algorithm>
15#include <string>
16
17#include <boost/shared_ptr.hpp>
18#include <boost/make_shared.hpp>
19#include <boost/noncopyable.hpp>
20
21#include <boost/compute/config.hpp>
22#include <boost/compute/device.hpp>
23#include <boost/compute/detail/global_static.hpp>
24#include <boost/compute/version.hpp>
25
26#ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE
27#include <boost/algorithm/string/trim.hpp>
28#include <boost/compute/detail/path.hpp>
29#include <boost/property_tree/ptree.hpp>
30#include <boost/property_tree/json_parser.hpp>
31#endif // BOOST_COMPUTE_USE_OFFLINE_CACHE
32
33namespace boost {
34namespace compute {
35namespace detail {
36
37class parameter_cache : boost::noncopyable
38{
39public:
40 parameter_cache(const device &device)
41 : m_dirty(false),
42 m_device_name(device.name())
43 {
44 #ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE
45 // get offline cache file name (e.g. /home/user/.boost_compute/tune/device.json)
46 m_file_name = make_file_name();
47
48 // load parameters from offline cache file (if it exists)
49 if(boost::filesystem::exists(m_file_name)){
50 read_from_disk();
51 }
52 #endif // BOOST_COMPUTE_USE_OFFLINE_CACHE
53 }
54
55 ~parameter_cache()
56 {
57 #ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE
58 write_to_disk();
59 #endif // BOOST_COMPUTE_USE_OFFLINE_CACHE
60 }
61
62 void set(const std::string &object, const std::string &parameter, uint_ value)
63 {
64 m_cache[std::make_pair(object, parameter)] = value;
65
66 // set the dirty flag to true. this will cause the updated parameters
67 // to be stored to disk.
68 m_dirty = true;
69 }
70
71 uint_ get(const std::string &object, const std::string &parameter, uint_ default_value)
72 {
73 std::map<std::pair<std::string, std::string>, uint_>::iterator
74 iter = m_cache.find(std::make_pair(object, parameter));
75 if(iter != m_cache.end()){
76 return iter->second;
77 }
78 else {
79 return default_value;
80 }
81 }
82
83 static boost::shared_ptr<parameter_cache> get_global_cache(const device &device)
84 {
85 // device name -> parameter cache
86 typedef std::map<std::string, boost::shared_ptr<parameter_cache> > cache_map;
87
88 BOOST_COMPUTE_DETAIL_GLOBAL_STATIC(cache_map, caches, ((std::less<std::string>())));
89
90 cache_map::iterator iter = caches.find(device.name());
91 if(iter == caches.end()){
92 boost::shared_ptr<parameter_cache> cache =
93 boost::make_shared<parameter_cache>(device);
94
95 caches.insert(iter, std::make_pair(device.name(), cache));
96
97 return cache;
98 }
99 else {
100 return iter->second;
101 }
102 }
103
104private:
105#ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE
106 // returns a string containing a cannoical device name
107 static std::string cannonical_device_name(std::string name)
108 {
109 boost::algorithm::trim(name);
110 std::replace(name.begin(), name.end(), ' ', '_');
111 std::replace(name.begin(), name.end(), '(', '_');
112 std::replace(name.begin(), name.end(), ')', '_');
113 return name;
114 }
115
116 // returns the boost.compute version string
117 static std::string version_string()
118 {
119 char buf[32];
120 std::snprintf(buf, sizeof(buf), "%d.%d.%d", BOOST_COMPUTE_VERSION_MAJOR,
121 BOOST_COMPUTE_VERSION_MINOR,
122 BOOST_COMPUTE_VERSION_PATCH);
123 return buf;
124 }
125
126 // returns the file path for the cached parameters
127 std::string make_file_name() const
128 {
129 return detail::parameter_cache_path(true) + cannonical_device_name(m_device_name) + ".json";
130 }
131
132 // store current parameters to disk
133 void write_to_disk()
134 {
135 BOOST_ASSERT(!m_file_name.empty());
136
137 if(m_dirty){
138 // save current parameters to disk
139 boost::property_tree::ptree pt;
140 pt.put("header.device", m_device_name);
141 pt.put("header.version", version_string());
142 typedef std::map<std::pair<std::string, std::string>, uint_> map_type;
143 for(map_type::const_iterator iter = m_cache.begin(); iter != m_cache.end(); ++iter){
144 const std::pair<std::string, std::string> &key = iter->first;
145 pt.add(key.first + "." + key.second, iter->second);
146 }
147 write_json(m_file_name, pt);
148
149 m_dirty = false;
150 }
151 }
152
153 // load stored parameters from disk
154 void read_from_disk()
155 {
156 BOOST_ASSERT(!m_file_name.empty());
157
158 m_cache.clear();
159
160 boost::property_tree::ptree pt;
161 try {
162 read_json(m_file_name, pt);
163 }
164 catch(boost::property_tree::json_parser::json_parser_error&){
165 // no saved cache file, ignore
166 return;
167 }
168
169 std::string stored_device;
170 try {
171 stored_device = pt.get<std::string>("header.device");
172 }
173 catch(boost::property_tree::ptree_bad_path&){
174 return;
175 }
176
177 std::string stored_version;
178 try {
179 stored_version = pt.get<std::string>("header.version");
180 }
181 catch(boost::property_tree::ptree_bad_path&){
182 return;
183 }
184
185 if(stored_device == m_device_name && stored_version == version_string()){
186 typedef boost::property_tree::ptree::const_iterator pt_iter;
187 for(pt_iter iter = pt.begin(); iter != pt.end(); ++iter){
188 if(iter->first == "header"){
189 // skip header
190 continue;
191 }
192
193 boost::property_tree::ptree child_pt = pt.get_child(iter->first);
194 for(pt_iter child_iter = child_pt.begin(); child_iter != child_pt.end(); ++child_iter){
195 set(iter->first, child_iter->first, boost::lexical_cast<uint_>(child_iter->second.data()));
196 }
197 }
198 }
199
200 m_dirty = false;
201 }
202#endif // BOOST_COMPUTE_USE_OFFLINE_CACHE
203
204private:
205 bool m_dirty;
206 std::string m_device_name;
207 std::string m_file_name;
208 std::map<std::pair<std::string, std::string>, uint_> m_cache;
209};
210
211} // end detail namespace
212} // end compute namespace
213} // end boost namespace
214
215#endif // BOOST_COMPUTE_DETAIL_PARAMETER_CACHE_HPP