#ifndef COMMON_PRIMITIVE_DESC_ITERATOR_HPP
#define COMMON_PRIMITIVE_DESC_ITERATOR_HPP
#include "oneapi/dnnl/dnnl.h"
#include "c_types_map.hpp"
#include "engine.hpp"
#include "impl_list_item.hpp"
#include "primitive_attr.hpp"
#include "primitive_cache.hpp"
#include "primitive_hashing.hpp"
#include "type_helpers.hpp"
namespace dnnl {
namespace impl {
struct primitive_desc_t;
struct primitive_desc_iterator_t : public c_compatible {
primitive_desc_iterator_t(engine_t *engine, const op_desc_t *op_desc,
const primitive_attr_t *attr, const primitive_desc_t *hint_fwd_pd,
int skip_idx = -1)
: idx_(-1)
, engine_(engine)
, op_desc_(op_desc->clone())
, attr_(attr ? *attr : primitive_attr_t())
, hint_fwd_pd_(hint_fwd_pd)
, impl_list_(engine_->get_implementation_list(op_desc_.get()))
, last_idx_(0)
, skip_idx_(skip_idx)
, offset_(-1) {
while (impl_list_[last_idx_])
++last_idx_;
is_initialized_ = is_initialized_ && attr_.is_initialized();
}
engine_t *engine() const { return engine_; }
bool operator==(const primitive_desc_iterator_t &rhs) const {
return idx_ == rhs.idx_ && engine_ == rhs.engine_;
}
bool operator!=(const primitive_desc_iterator_t &rhs) const {
return !operator==(rhs);
}
primitive_desc_iterator_t end() const {
return primitive_desc_iterator_t(engine_, last_idx_);
}
primitive_desc_iterator_t &operator++() {
if (idx_ == last_idx_) return *this;
offset_++;
pd_.reset();
std::vector<dnnl::impl::memory_desc_t> hint_mds;
if (hint_fwd_pd_) hint_mds = hint_fwd_pd_->hint_mds(true );
primitive_hashing::key_t key(
engine_, op_desc_.get(), &attr_, offset_, hint_mds, skip_idx_);
pd_ = primitive_cache().get_pd(key);
if (pd_) { return *this; }
while (++idx_ != last_idx_) {
if (idx_ == skip_idx_) continue;
primitive_desc_t *candidate_pd = nullptr;
auto s = impl_list_[idx_](&candidate_pd, op_desc_.get(), &attr_,
engine_, hint_fwd_pd_, offset_, skip_idx_);
if (s == status::success) {
pd_.reset(candidate_pd);
break;
}
}
return *this;
}
const std::shared_ptr<primitive_desc_t> &operator*() const { return pd_; }
const primitive_attr_t &attr() const { return attr_; }
bool is_initialized() const { return is_initialized_; }
protected:
int idx_;
engine_t *engine_;
std::shared_ptr<primitive_desc_t> pd_;
std::unique_ptr<op_desc_t> op_desc_;
const primitive_attr_t attr_;
const primitive_desc_t *hint_fwd_pd_;
const impl_list_item_t *impl_list_;
int last_idx_;
int skip_idx_;
int offset_;
private:
primitive_desc_iterator_t(engine_t *engine, int last_idx)
: idx_(last_idx)
, engine_(engine)
, hint_fwd_pd_(nullptr)
, impl_list_(nullptr)
, last_idx_(last_idx)
, skip_idx_(-1)
, offset_(-1) {}
primitive_desc_iterator_t(primitive_desc_iterator_t &&other)
: idx_(other.idx_)
, engine_(other.engine_)
, pd_(std::move(other.pd_))
, op_desc_(std::move(other.op_desc_))
, attr_(other.attr_)
, hint_fwd_pd_(other.hint_fwd_pd_)
, impl_list_(other.impl_list_)
, skip_idx_(other.skip_idx_)
, offset_(other.offset_) {}
DNNL_DISALLOW_COPY_AND_ASSIGN(primitive_desc_iterator_t);
};
} }
#endif