#ifndef COMMON_PRIMITIVE_HPP
#define COMMON_PRIMITIVE_HPP
#include "common/c_types_map.hpp"
#include "common/cache_blob.hpp"
#include "common/cache_hit_types.hpp"
#include "common/primitive_desc.hpp"
#include "common/primitive_exec_types.hpp"
#include <cassert>
#include <type_traits>
namespace dnnl {
namespace impl {
struct resource_mapper_t;
struct primitive_t : public c_compatible {
using primitive_list_t = std::vector<const primitive_t *>;
primitive_t(const primitive_desc_t *pd) : pd_(pd->clone()) {}
virtual ~primitive_t() = default;
virtual status_t init(impl::engine_t *engine) { return status::success; }
status_t init(engine_t *engine, bool use_global_scratchpad,
const cache_blob_t &cache_blob) {
cache_blob_ = cache_blob;
CHECK(init(engine));
use_global_scratchpad_ = use_global_scratchpad;
cache_blob_ = cache_blob_t();
return status::success;
}
const std::shared_ptr<primitive_desc_t> &pd() const { return pd_; }
primitive_kind_t kind() const { return pd_->kind(); }
virtual status_t execute(const exec_ctx_t &ctx) const = 0;
virtual status_t get_cache_blob(
engine_t *engine, cache_blob_t &cache_blob) const {
assert(!"unexpected");
return status::runtime_error;
}
virtual status_t get_cache_blob_size(engine_t *engine, size_t *size) const {
assert(!"unexpected");
return status::runtime_error;
}
virtual status_t create_resource(
impl::engine_t *engine, resource_mapper_t &mapper) const {
return status::success;
}
bool use_global_scratchpad() const { return use_global_scratchpad_; }
cache_blob_t cache_blob() const { return cache_blob_; }
cache_state_t creation_cache_state() const {
return creation_cached_state_;
}
protected:
template <typename impl_type, typename pd_t>
static status_t create_primitive_common(
std::pair<std::shared_ptr<primitive_t>, cache_state_t> &primitive,
const pd_t *pd, engine_t *engine, bool use_global_scratchpad,
const cache_blob_t &cache_blob, bool force_create_from_blob) {
auto global_primitive_cache = primitive_cache();
primitive_hashing::key_t key(pd, engine);
struct create_context_t {
engine_t *engine;
const pd_t *pd;
const cache_blob_t &cache_blob;
bool use_global_scratchpad;
cache_state_t cache_status;
};
create_context_t context {
engine, pd, cache_blob, use_global_scratchpad,
force_create_from_blob ? cache_state_t::persistent_hit
: cache_state_t::primitive_hit};
primitive_cache_iface_t::create_func_ptr_t create = [](void *context) {
auto &c = *static_cast<create_context_t *>(context);
std::shared_ptr<primitive_t> p = std::make_shared<impl_type>(c.pd);
status_t status
= p->init(c.engine, c.use_global_scratchpad, c.cache_blob);
c.cache_status = p->creation_cache_state();
return primitive_cache_iface_t::result_t {std::move(p), status};
};
auto result = global_primitive_cache.get_or_create(
key, *create, &context, force_create_from_blob);
primitive = {std::move(result.value), context.cache_status};
return result.status;
}
std::shared_ptr<primitive_desc_t> pd_;
bool use_global_scratchpad_ = false;
cache_blob_t cache_blob_;
cache_state_t creation_cached_state_ = cache_state_t::miss;
private:
primitive_t() = delete;
DNNL_DISALLOW_COPY_AND_ASSIGN(primitive_t);
};
} }
#define ARG_PTR_TYPE(t) \
typename std::remove_cv<typename std::remove_pointer<t>::type>::type *
#define CTX_OUT_CLEAN_MEM(type, arg, status) \
static_cast<ARG_PTR_TYPE(type)>(ctx.host_ptr(arg, true, &(status)))
#define CTX_OUT_MEM_COMMON(type, arg, index) \
static_cast<ARG_PTR_TYPE(type)>(ctx.host_ptr(arg, false, nullptr, index))
#define CTX_OUT_MEm(type, arg) CTX_OUT_MEM_COMMON(type, arg, 0)
#define CTX_OUT_MEm0(type, arg) CTX_OUT_MEM_COMMON(type, arg, 0)
#define CTX_OUT_MEm1(type, arg) CTX_OUT_MEM_COMMON(type, arg, 1)
#define CTX_OUT_MEm2(type, arg) CTX_OUT_MEM_COMMON(type, arg, 2)
#define CTX_IN_MEM_COMMON(type, arg, index) \
static_cast<const ARG_PTR_TYPE(type)>( \
ctx.host_ptr(arg, false, nullptr, index))
#define CTX_IN_MEm(type, arg) CTX_IN_MEM_COMMON(type, arg, 0)
#define CTX_IN_MEm0(type, arg) CTX_IN_MEM_COMMON(type, arg, 0)
#define CTX_IN_MEm1(type, arg) CTX_IN_MEM_COMMON(type, arg, 1)
#define CTX_IN_MEm2(type, arg) CTX_IN_MEM_COMMON(type, arg, 2)
#define CTX_IN_MEM(type, arg, ...) CTX_IN_MEm##__VA_ARGS__(type, arg)
#define CTX_OUT_MEM(type, arg, ...) CTX_OUT_MEm##__VA_ARGS__(type, arg)
#endif