#ifndef GRAPH_UTILS_PM_PBUILDER_HPP
#define GRAPH_UTILS_PM_PBUILDER_HPP
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <unordered_set>
#include "graph/interface/c_types_map.hpp"
namespace dnnl {
namespace impl {
namespace graph {
namespace utils {
namespace pm {
class pb_op_t;
class pb_node_t;
class pb_graph_t;
#define VARIADIC_INPUT_NUM 64
using iport_t = size_t;
using oport_t = size_t;
using producer_t = std::pair<pb_node_t *, oport_t>;
using consumer_t = std::pair<pb_node_t *, iport_t>;
using consumers_t = std::vector<std::shared_ptr<consumer_t>>;
using in_edge_t = std::pair<iport_t, std::shared_ptr<producer_t>>;
using in_edges_t = std::vector<std::shared_ptr<in_edge_t>>;
using port_map = std::pair<oport_t, iport_t>;
using decision_function = std::function<bool(op_t *)>;
enum class pb_node_kind {
PB_NODE_KIND_OP,
PB_NODE_KIND_ALTERNATION,
PB_NODE_KIND_REPETITION,
};
class pb_node_t {
public:
virtual ~pb_node_t() = default;
std::shared_ptr<producer_t> get_producer(iport_t p_port);
std::shared_ptr<consumers_t> get_consumers(oport_t p_port);
std::vector<std::pair<iport_t, producer_t>> get_inputs();
std::vector<std::pair<oport_t, consumers_t>> get_outputs();
size_t get_num_decision_functions();
decision_function get_decision_function(size_t index);
pb_node_kind get_node_kind() { return node_kind_; }
virtual std::string get_name() { return debug_string_; }
virtual void set_name(std::string &&name) {
debug_string_ = std::move(name);
}
const std::unordered_set<pb_op_t *> &get_contained_ops() { return p_ops_; }
protected:
friend class pb_graph_t;
pb_node_t() = default;
bool set_producer(iport_t p_port, std::shared_ptr<producer_t> p_producer);
bool add_consumer(
oport_t p_port, const std::shared_ptr<consumer_t> &p_consumer);
std::vector<std::shared_ptr<producer_t>> ins_;
std::vector<std::shared_ptr<consumers_t>> outs_;
std::vector<decision_function> decision_functions_;
std::string debug_string_;
pb_node_kind node_kind_;
std::unordered_set<pb_op_t *> p_ops_;
};
std::shared_ptr<consumer_t> consumer(pb_node_t *p_node, iport_t i_t);
std::shared_ptr<consumer_t> producer(pb_node_t *p_node, oport_t o_t);
std::shared_ptr<in_edge_t> in_edge(iport_t i_t, pb_node_t *p_node, oport_t o_t);
decision_function kind(dnnl::impl::graph::op_kind_t okind);
decision_function one_of_kind(
const std::vector<dnnl::impl::graph::op_kind_t> &okind);
class pb_op_t : public pb_node_t {
public:
pb_op_t() = delete;
bool append_decision_function(const decision_function &p_fn);
void allow_external_outputs() { accept_external_outputs_ = true; }
bool is_allowing_external_outputs() const {
return accept_external_outputs_;
}
void allow_internal_inputs() { accept_internal_inputs_ = true; }
bool is_allowing_internal_inputs() const { return accept_internal_inputs_; }
protected:
friend class pb_graph_t;
pb_op_t(const decision_function &p_fn);
bool accept_external_outputs_ = false;
bool accept_internal_inputs_ = false;
};
class alternation_t : public pb_node_t {
public:
alternation_t() = delete;
std::vector<pb_graph_t *> get_alternatives();
size_t get_min_op_num() const { return min_op_num_; }
protected:
friend class pb_graph_t;
alternation_t(std::vector<std::shared_ptr<pb_graph_t>> p_nodes);
std::vector<std::shared_ptr<pb_graph_t>> alternatives_;
size_t min_op_num_;
};
class repetition_t : public pb_node_t {
public:
repetition_t() = delete;
pb_graph_t *get_body();
port_map get_port_map(); size_t get_min_rep() const { return min_rep_; }
size_t get_max_rep() const { return max_rep_; }
size_t get_min_op_num() const { return min_op_num_; }
protected:
friend class pb_graph_t;
repetition_t(std::shared_ptr<pb_graph_t> p_node, port_map p_map,
size_t min_rep, size_t max_rep);
repetition_t(std::shared_ptr<pb_graph_t> p_node);
std::shared_ptr<pb_graph_t> body_;
port_map port_map_;
size_t min_rep_;
size_t max_rep_;
size_t min_op_num_;
};
class pb_graph_t : public pb_node_t {
public:
pb_graph_t();
pb_op_t *append_op(
dnnl::impl::graph::op_kind_t p_kind, const in_edges_t &p_in_edges);
pb_op_t *append_op(dnnl::impl::graph::op_kind_t p_kind);
pb_op_t *append_alternation(
const std::vector<dnnl::impl::graph::op_kind_t> &p_kind,
const in_edges_t &p_in_edges);
pb_op_t *append_alternation(
const std::vector<dnnl::impl::graph::op_kind_t> &p_kind);
alternation_t *append_alternation(
const std::vector<std::shared_ptr<pb_graph_t>> &p_nodes,
const in_edges_t &p_in_edges);
alternation_t *append_alternation(
const std::vector<std::shared_ptr<pb_graph_t>> &p_nodes);
repetition_t *append_repetition(const std::shared_ptr<pb_graph_t> &p_node,
const port_map &p_map, size_t min_rep, size_t max_rep,
const in_edges_t &p_in_edges);
repetition_t *append_repetition(const std::shared_ptr<pb_graph_t> &p_node,
const port_map &p_map, size_t min_rep, size_t max_rep);
repetition_t *append_optional(const std::shared_ptr<pb_graph_t> &p_node,
const in_edges_t &p_in_edges);
repetition_t *append_optional(const std::shared_ptr<pb_graph_t> &p_node);
std::vector<std::pair<iport_t, consumers_t>> get_inner_consumers();
std::vector<std::pair<oport_t, producer_t>> get_inner_producers();
std::shared_ptr<consumers_t> get_inner_consumer(iport_t);
std::shared_ptr<producer_t> get_inner_producer(oport_t);
bool create_input_port(iport_t, pb_node_t *, iport_t);
bool create_output_port(oport_t, pb_node_t *, oport_t);
std::vector<pb_node_t *> get_nodes();
size_t get_min_op_num() const { return min_op_num_; }
protected:
pb_op_t *append_op(const decision_function &type_checker,
const in_edges_t &p_in_edges, std::string name = "");
pb_op_t *append_op(
const decision_function &type_checker, std::string name = "");
bool set_edge(const std::shared_ptr<consumer_t> &,
const std::shared_ptr<producer_t> &);
bool connect_edges(pb_node_t *p_node, const in_edges_t &p_in_edges);
bool create_input_port(iport_t, const std::shared_ptr<consumer_t> &);
bool create_output_port(oport_t, std::shared_ptr<producer_t>);
std::vector<std::shared_ptr<pb_node_t>> nodes_;
std::unordered_set<oport_t> output_ports_;
std::vector<std::shared_ptr<consumers_t>> inner_consumers_ {nullptr};
std::vector<std::shared_ptr<producer_t>> inner_producers_ {nullptr};
size_t min_op_num_;
};
} } } } } #endif