#include "primitive_cache.hpp"
#include "c_types_map.hpp"
#include "cache_utils.hpp"
#include "kernel_cache.hpp"
#include "primitive.hpp"
#include "primitive_desc_iface.hpp"
#include "primitive_iface.hpp"
#include "z_magic.hpp"
namespace dnnl {
namespace impl {
struct primitive_cache_t {
using key_t = primitive_hashing::key_t;
using result_t = primitive_cache_iface_t::result_t;
using create_func_t = result_t (&)(void *);
primitive_cache_t(int capacity) : cache_(capacity) {};
~primitive_cache_t() = default;
status_t set_capacity(int capacity) {
return cache_.set_capacity(capacity);
}
int get_capacity() const { return cache_.get_capacity(); }
int get_size() const { return cache_.get_size(); }
std::shared_ptr<primitive_desc_t> get_pd(const key_t &key) {
result_t result = cache_.get(key);
return result.value != nullptr ? result.value->pd() : nullptr;
}
result_t get_or_create(const key_t &key, create_func_t create,
void *create_context, bool force_create) {
return cache_.get_or_create(key, create, create_context, force_create);
}
private:
static void update_key(const key_t &key, const primitive_t &p) {
const primitive_desc_t *pd = p.pd().get();
key.op_desc_ = pd->op_desc();
key.attr_ = pd->attr();
}
friend size_t DNNL_API set_primitive_cache_capacity_without_clearing(
size_t capacity);
void set_capacity_without_clearing(int capacity) {
cache_.set_capacity_without_clearing(capacity);
}
utils::lru_cache_t<key_t, primitive_t, result_t, update_key> cache_;
};
primitive_cache_t &global_primitive_cache() {
#ifndef DNNL_DISABLE_PRIMITIVE_CACHE
static const int capacity
= getenv_int_user("PRIMITIVE_CACHE_CAPACITY", 1024);
#else
static const int capacity = 0;
#endif
static primitive_cache_t cache(capacity);
return cache;
}
primitive_cache_iface_t primitive_cache() {
return global_primitive_cache();
}
status_t get_primitive_cache_size(int *size) {
if (size == nullptr) return dnnl::impl::status::invalid_arguments;
*size = 0;
#ifndef DNNL_DISABLE_PRIMITIVE_CACHE
*size = global_primitive_cache().get_size();
#endif
return dnnl::impl::status::success;
}
bool is_pd_in_cache(const primitive_desc_iface_t *pd_iface) {
const auto *pd = pd_iface->impl().get();
const auto *engine = pd_iface->engine();
primitive_hashing::key_t key(pd, engine);
return bool(global_primitive_cache().get_pd(key));
}
bool is_primitive_in_cache(const primitive_iface_t *p_iface) {
return is_pd_in_cache(p_iface->pd());
}
size_t set_primitive_cache_capacity_without_clearing(size_t capacity) {
size_t old_capacity = global_primitive_cache().get_capacity();
global_primitive_cache().set_capacity_without_clearing((int)capacity);
return old_capacity;
}
status_t primitive_cache_iface_t::set_capacity(int capacity) {
return cache_.set_capacity(capacity);
}
int primitive_cache_iface_t::get_capacity() const {
return cache_.get_capacity();
}
int primitive_cache_iface_t::get_size() const {
return cache_.get_size();
}
std::shared_ptr<primitive_desc_t> primitive_cache_iface_t::get_pd(
const key_t &key) {
return cache_.get_pd(key);
}
primitive_cache_iface_t::result_t primitive_cache_iface_t::get_or_create(
const key_t &key, create_func_t create, void *create_context,
bool force_create) {
auto r = cache_.get_or_create(key, create, create_context, force_create);
return {std::move(r.value), r.status};
}
status_t set_primitive_cache_capacity(
int primitive_capacity, int kernel_capacity) {
if (primitive_capacity < 0 || kernel_capacity < 0)
return status::invalid_arguments;
#ifndef DNNL_DISABLE_PRIMITIVE_CACHE
auto status = global_primitive_cache().set_capacity(primitive_capacity);
CHECK(status);
return kernel_cache::get().set_capacity(kernel_capacity);
#endif
return status::success;
}
} }
dnnl::impl::status_t dnnl_get_primitive_cache_capacity(int *capacity) {
if (capacity == nullptr) return dnnl::impl::status::invalid_arguments;
*capacity = 0;
#ifndef DNNL_DISABLE_PRIMITIVE_CACHE
*capacity = dnnl::impl::global_primitive_cache().get_capacity();
assert(*capacity == dnnl::impl::kernel_cache::get().get_capacity());
#endif
return dnnl::impl::status::success;
}
dnnl::impl::status_t dnnl_set_primitive_cache_capacity(int capacity) {
return dnnl::impl::set_primitive_cache_capacity(capacity, capacity);
}