36#include <google/protobuf/io/coded_stream.h>
37#include <google/protobuf/io/zero_copy_stream_impl.h>
38#include <google/protobuf/text_format.h>
52bool load_text(std::istream *stream, tensorflow::GraphDef &graph_def)
54 google::protobuf::io::IstreamInputStream iis(stream);
56 return google::protobuf::TextFormat::Parse(&iis, &graph_def);
59bool load_binary(std::istream *stream, tensorflow::GraphDef &graph_def)
61 google::protobuf::io::IstreamInputStream iis(stream);
62 google::protobuf::io::CodedInputStream cis(&iis);
64 return graph_def.ParseFromCodedStream(&cis);
68 tensorflow::GraphDef &graph_def)
71 : load_binary(stream, graph_def);
79void set_unknown_rank(tensorflow::GraphDef &tf_graph_def)
81 for (
auto &n : *tf_graph_def.mutable_node())
83 if (n.op().compare(
"Placeholder"))
86 auto iter = n.attr().find(
"shape");
87 if (iter == n.attr().end())
89 tensorflow::AttrValue attr;
90 attr.mutable_shape()->set_unknown_rank(
true);
91 n.mutable_attr()->insert({
"shape", attr});
103 for (
auto &n : *tf_graph_def.mutable_node())
105 if (n.op().compare(
"Placeholder"))
108 auto node_shape = n.mutable_attr()->at(
"shape").mutable_shape();
109 auto sig_shape = signature.
shape(n.name() +
":0");
114 if (sig_shape ==
nullptr)
117 for (uint32_t i = 0; i < sig_shape->rank(); i++)
121 for (uint32_t d = 0; d <
node_shape->dim_size(); d++)
125 if (sig_shape ==
nullptr)
127 node_shape->mutable_dim(d)->set_size(sig_shape->dim(d));
133 if (sig_shape &&
node_shape->dim(d).size() != sig_shape->dim(d))
143 set_unknown_rank(tf_graph_def);
144 if (!set_input_shape(signature, tf_graph_def))
145 oops::UserExn(
"Info you provided may be wrong or not enough. Please check the info file.");
157 for (
const auto &custom_op : sig.customops())
159 std::unique_ptr<moco::tf::COpCallGraphBuilder> builder =
160 std::make_unique<moco::tf::COpCallGraphBuilder>(&sig);
161 registry.add(custom_op, std::move(builder));
197 std::ifstream ifs{modelfile, std::ios::in | std::ios::binary};
198 return load(signature, &ifs, type);
204 tensorflow::GraphDef tf_graph_def;
206 load_tf(stream, type, tf_graph_def);
208 transform_tf(signature, tf_graph_def);
210 auto graph =
import(signature, tf_graph_def);
212 return std::move(graph);
215std::unique_ptr<loco::Graph> Frontend::import(
const ModelSignature &signature,
216 tensorflow::GraphDef &tf_graph_def)
const
225 INFO(frontend) <<
">>";
226 INFO(frontend) <<
">> Import stage started";
227 INFO(frontend) <<
">>";
228 auto graph = importer.import(signature, tf_graph_def);
230 TFOptimizer tfoptimizier;
233 INFO(frontend) <<
">>";
234 INFO(frontend) <<
">> TF optimize stage started";
235 INFO(frontend) <<
">>";
236 tfoptimizier.optimize(graph.get());
241 for (uint32_t n = 0; n < graph->inputs()->
size(); ++n)
243 auto input = graph->inputs()->at(n);
245 assert(input_node !=
nullptr);
246 input->shape(std::make_unique<loco::TensorShape>(tensor_shape(input_node)));
249 for (uint32_t n = 0; n < graph->outputs()->
size(); ++n)
251 auto output = graph->outputs()->at(n);
253 assert(output_node !=
nullptr);
254 output->shape(std::make_unique<loco::TensorShape>(::tensor_shape(output_node)));
258 Canonicalizer canonicalizer;
260 INFO(frontend) <<
">>";
261 INFO(frontend) <<
">> Canonicalize stage started";
262 INFO(frontend) <<
">>";
263 canonicalizer.canonicalize(
graph.get());
268 INFO(frontend) <<
">>";
269 INFO(frontend) <<
">> Canonical optimize stage started";
270 INFO(frontend) <<
">>";
271 optimizer.optimize(
graph.get());
273 return std::move(graph);
enco::Bundle load(void) const override
Logical unit of computation.
Class to return graph builder for TF nodes.
static GraphBuilderRegistry & get()
std::unique_ptr< loco::Graph > load(const ModelSignature &, const char *, FileType) const
bool shape_known(const Node *node)
NodeShape shape_get(const Node *node)
TFPush * push_node(loco::Graph *g, const loco::GraphOutputIndex &index)
Find a TFPush node with a given output index.
loco::NodeShape node_shape(const loco::Node *node)
TFPlaceholder * placeholder_node(loco::Graph *g, const loco::GraphInputIndex &idx)
Class to store information to run a model. Normally this info comes from users via CLI params or conf...
void shape(const std::string &node_name, const angkor::TensorShape &shape)
Adds node name and its shape provided from user.