summaryrefslogtreecommitdiff
path: root/src/cache.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cache.hpp')
-rw-r--r--src/cache.hpp126
1 files changed, 67 insertions, 59 deletions
diff --git a/src/cache.hpp b/src/cache.hpp
index 9ecb0f1e..c3675f07 100644
--- a/src/cache.hpp
+++ b/src/cache.hpp
@@ -15,81 +15,89 @@
#define CLBLAST_CACHE_H_
#include <string>
-#include <vector>
#include <mutex>
+#include <map>
#include "utilities/utilities.hpp"
namespace clblast {
// =================================================================================================
-// The cache of compiled OpenCL binaries, along with some meta-data
-struct BinaryCache {
- std::string binary;
- std::string device_name;
- Precision precision;
- std::string routine_name_;
-
- // Finds out whether the properties match
- bool MatchInCache(const std::string &ref_device, const Precision &ref_precision,
- const std::string &ref_routine) {
- return (device_name == ref_device &&
- precision == ref_precision &&
- routine_name_ == ref_routine);
- }
-};
-
-// The actual cache, implemented as a vector of the above data-type, and its mutex
-static std::vector<BinaryCache> binary_cache_;
-static std::mutex binary_cache_mutex_;
+// The generic thread-safe cache. We assume that the Key may be a heavyweight struct that is not
+// normally used by the caller, while the Value is either lightweight or ref-counted.
+// Hence, searching by non-Key is supported (if there is a corresponding operator<()), and
+// on Store() the Key instance is moved from the caller (because it will likely be constructed
+// as temporary at the time of Store()).
+template <typename Key, typename Value>
+class Cache {
+public:
+ // Cached object is returned by-value to avoid racing with Invalidate().
+ // Due to lack of std::optional<>, in case of a cache miss we return a default-constructed
+ // Value and set the flag to false.
+ template <typename U>
+ Value Get(const U &key, bool *in_cache) const;
+
+ // We do not return references to just stored object to avoid racing with Invalidate().
+ // Caller is expected to store a temporary.
+ void Store(Key &&key, Value &&value);
+ void Invalidate();
+
+ static Cache<Key, Value> &Instance();
+
+private:
+#if __cplusplus >= 201402L
+ // The std::less<void> allows to search in cache by an object comparable with Key, without
+ // constructing a temporary Key
+ // (see http://en.cppreference.com/w/cpp/utility/functional/less_void,
+ // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3657.htm,
+ // http://stackoverflow.com/questions/10536788/avoiding-key-construction-for-stdmapfind)
+ std::map<Key, Value, std::less<void>> cache_;
+#else
+ std::vector<std::pair<Key, Value>> cache_;
+#endif
+ mutable std::mutex cache_mutex_;
+
+ static Cache<Key, Value> instance_;
+}; // class Cache
// =================================================================================================
-// The cache of compiled OpenCL programs, along with some meta-data
-struct ProgramCache {
- Program program;
- cl_context context;
- Precision precision;
- std::string routine_name_;
-
- // Finds out whether the properties match
- bool MatchInCache(const cl_context ref_context, const Precision &ref_precision,
- const std::string &ref_routine) {
- return (context == ref_context &&
- precision == ref_precision &&
- routine_name_ == ref_routine);
- }
-};
-
-// The actual cache, implemented as a vector of the above data-type, and its mutex
-static std::vector<ProgramCache> program_cache_;
-static std::mutex program_cache_mutex_;
+// The key struct for the cache of compiled OpenCL binaries
+// Order of fields: precision, routine_name, device_name (smaller fields first)
+typedef std::tuple<Precision, std::string, std::string> BinaryKey;
+typedef std::tuple<const Precision &, const std::string &, const std::string &> BinaryKeyRef;
+
+typedef Cache<BinaryKey, std::string> BinaryCache;
+
+extern template class Cache<BinaryKey, std::string>;
+extern template std::string BinaryCache::Get(const BinaryKeyRef &, bool *) const;
+
// =================================================================================================
-// Stores the compiled binary or program in the cache
-void StoreBinaryToCache(const std::string &binary, const std::string &device_name,
- const Precision &precision, const std::string &routine_name);
-void StoreProgramToCache(const Program &program, const Context &context,
- const Precision &precision, const std::string &routine_name);
-
-// Queries the cache and retrieves a matching binary or program. Assumes that the match is
-// available, throws otherwise.
-const std::string& GetBinaryFromCache(const std::string &device_name, const Precision &precision,
- const std::string &routine_name);
-const Program& GetProgramFromCache(const Context &context, const Precision &precision,
- const std::string &routine_name);
-
-// Queries the cache to see whether or not the compiled kernel is already there
-bool BinaryIsInCache(const std::string &device_name, const Precision &precision,
- const std::string &routine_name);
-bool ProgramIsInCache(const Context &context, const Precision &precision,
- const std::string &routine_name);
+// The key struct for the cache of compiled OpenCL programs (context-dependent)
+// Order of fields: context, precision, routine_name (smaller fields first)
+typedef std::tuple<cl_context, Precision, std::string> ProgramKey;
+typedef std::tuple<const cl_context &, const Precision &, const std::string &> ProgramKeyRef;
+
+typedef Cache<ProgramKey, Program> ProgramCache;
+
+extern template class Cache<ProgramKey, Program>;
+extern template Program ProgramCache::Get(const ProgramKeyRef &, bool *) const;
// =================================================================================================
-// Clears the cache of stored binaries
-void CacheClearAll();
+class Database;
+
+// The key struct for the cache of database maps.
+// Order of fields: precision, device_name, routines (smaller fields first)
+typedef std::tuple<Precision, std::string, std::vector<std::string>> DatabaseKey;
+typedef std::tuple<const Precision &, const std::string &, const std::vector<std::string> &> DatabaseKeyRef;
+
+typedef Cache<DatabaseKey, Database> DatabaseCache;
+
+extern template class Cache<DatabaseKey, Database>;
+extern template Database DatabaseCache::Get(const DatabaseKeyRef &, bool *) const;
// =================================================================================================
} // namespace clblast