49 auto nodefinder = std::make_unique<luci::IndexNodeFinder>();
50 auto tensoroutputs = std::make_unique<luci::IndexTensorOutputs>();
54 const auto operators = reader.
operators();
55 const auto tensors = reader.
tensors();
56 assert(!tensors.null());
57 auto circle_metadata = std::make_unique<luci::CircleImportMetadata>(reader);
61 for (uint32_t i = 0; i < operators.size(); ++i)
63 const auto op = operators[i];
64 assert(op !=
nullptr);
65 const auto outputs =
luci::wrap(op->outputs());
67 for (uint32_t j = 0; j < outputs.size(); ++j)
69 auto tidx = outputs[j];
70 tensoroutputs->enroll(tidx);
77 for (
const auto input : reader.
inputs())
80 assert(input_node !=
nullptr);
82 assert(tensor !=
nullptr);
85 if (
tensor->shape() ==
nullptr)
91 nodefinder->enroll(input, input_node);
94 tensoroutputs->enroll(input);
97 auto graph_input =
graph->inputs()->create();
108 assert(tensor_shape_signature.size() == 0 ||
109 tensor_shape_signature.size() == tensor_shape.size());
112 auto input_shape = std::make_unique<loco::TensorShape>();
113 const auto &input_dims = tensor_shape;
114 input_shape->
rank(input_dims.size());
115 for (uint32_t r = 0;
r < input_dims.size(); ++
r)
117 if (tensor_shape_signature.size() > 0 && tensor_shape_signature.at(r) == -1)
118 input_shape->dim(r).unset();
120 input_shape->dim(r).set(input_dims[r]);
122 graph_input->shape(std::move(input_shape));
128 if (not const_builder)
129 throw oops::UserExn(
"Not supported",
"tensor with buffer builder");
131 for (uint32_t i = 0; i < tensors.size(); ++i)
133 auto *const_node = const_builder->build(i, &gb_context);
134 if (const_node !=
nullptr)
135 nodefinder->enroll(i, const_node);
140 for (uint32_t i = 0; i < tensors.size(); ++i)
143 if (variable_node !=
nullptr)
144 nodefinder->enroll(i, variable_node);
151 auto origin_table = circle_metadata->origin_table();
152 for (uint32_t i = 0; i < operators.size(); ++i)
154 const auto op = operators[i];
155 assert(op !=
nullptr);
156 circle::BuiltinOperator builtincode = reader.
builtin_code(op);
158 if (
const auto *builder = source.
lookup(builtincode))
161 circle::OperatorT oper_t;
162 op->UnPackTo(&oper_t);
165 if (!builder->validate(args))
170 auto built_op = builder->build(oper_t, &gb_context);
172 if (origin_table.find(i) != origin_table.end())
173 add_origin(built_op, origin_table.at(i));
184 for (
auto output : reader.outputs())
187 assert(tensor !=
nullptr);
190 assert(output_node !=
nullptr);
191 auto output_from = nodefinder->node(output);
192 if (output_from !=
nullptr)
200 assert(output_dummy !=
nullptr);
204 if (
tensor->shape() ==
nullptr)
213 auto graph_output =
graph->outputs()->create();
215 assert(tname.length() > 0);
216 graph_output->name(tname);
225 assert(tensor_shape_signature.size() == 0 ||
226 tensor_shape_signature.size() == tensor_shape.size());
229 auto output_shape = std::make_unique<loco::TensorShape>();
230 const auto &output_dims = tensor_shape;
232 for (uint32_t r = 0;
r < output_dims.size(); ++
r)
234 if (tensor_shape_signature.size() > 0 && tensor_shape_signature.at(r) == -1)
243 graph_output->dtype(dtype);
246 ext_buffer = gb_context.ext_buffer();
255 INFO(l) <<
"[luci] GraphValidate error " << d.node() <<
"(" << d.index() <<
")" << std::endl;
269std::unique_ptr<Module> Importer::importModule(
const circle::Model *model)
const
275 auto module = make_module();
279 if (_source !=
nullptr)
282 source_ptr = _source;
286 if (!reader.parse(model, _file_data, _file_size))
289 for (uint32_t g = 0; g < reader.num_subgraph(); ++g)
293 if (!reader.select_subgraph(g))
296 graph->name(reader.name());
299 bool graph_ext_buffer =
false;
300 convert_graph(*source_ptr, reader, graph.get(), graph_ext_buffer);
303 VERBOSE(l, 3) <<
"--- graph dump begin -------------------------------------------";
304 VERBOSE(l, 3) <<
"Name: " << graph->name();
306 VERBOSE(l, 3) <<
"--- graph dump end ---------------------------------------------";
308 assert(
loco::valid(graph.get(), std::make_unique<ValidateCollector>()));
310 module->add(std::move(graph));
312 if (graph_ext_buffer)
313 module->ext_buffer(true);
316 post_import_graph(
module.get(), reader);
319 auto circle_metadata = std::make_unique<luci::CircleImportMetadata>(reader);
320 if (circle_metadata->source_table().size() > 0)
323 module->source_table(circle_metadata->source_table());
329 std::map<uint32_t, std::string> table;
334 auto circle_node = loco::must_cast<luci::CircleNode *>(node);
340 assert(table.find(
get_node_id(circle_node)) == table.end());
341 table.insert({
get_node_id(circle_node), circle_node->name()});
344 module->source_table(table);
348 if (circle_metadata->execution_plan_table().size() > 0)
350 auto execution_plan_table = circle_metadata->execution_plan_table();
351 auto node_position = 0;
356 if (execution_plan_table.count(node_position) == 0)
359 auto node_plan = execution_plan_table[node_position];
360 assert(node_plan.size() > 0);
365 node_plan[0], std::vector<uint32_t>(node_plan.begin() + 1, node_plan.end())));
374std::unique_ptr<Module> Importer::importModule(
const uint8_t *
data,
size_t size)
382 const circle::Model *circle_model = circle::GetModel(_file_data);
383 if (circle_model ==
nullptr)
386 return importModule(circle_model);
The details of each error.
uint32_t rank(void) const
Temporary DummyNode used with dangle CircleNode.
CircleNode for Output of the Graph.
loco::Node * from(void) const
void index(const loco::GraphOutputIndex &index)
Loads Circle file and provides helpers to access attributes.
CircleOperators operators() const
CircleTensors tensors() const
circle::BuiltinOperator builtin_code(const circle::Operator *op) const
std::string opcode_name(const circle::Operator *op) const
Virtual CircleVariable in Circle for 'variable' Tensor.
Class to store context to build loco graph IR from TensorFlow.
static GraphBuilderRegistry & get()
const luci_interpreter::RuntimeShape output_shape
#define VERBOSE(name, lv)
const T * data(const std::vector< T, Alloc > &v)
std::vector< loco::Node * > postorder_traversal(const std::vector< loco::Node * > &roots)
Generate postorder traversal sequence starting from "roots".
std::set< Node * > all_nodes(Graph *)
Enumerate all the nodes in a given graph.
bool valid(Graph *g, std::unique_ptr< ErrorListener > &&l=nullptr)
Validate a loco graph.
std::vector< Node * > output_nodes(Graph *)
std::unique_ptr< Graph > make_graph(void)
CircleNodeID get_node_id(const luci::CircleNode *circle_node)
loco::DataType luci_datatype(circle::TensorType type)
FormattedGraph fmt(loco::Graph *g)
const char * tensor_name(const circle::Tensor *tensor)
void copy_tensor_attributes(const circle::Tensor *tensor, CircleNode *node)
Copy common tensor attributes such as name, type, etc. to node.
CircleVariable * create_circlevariable(GraphBuilderContext *context, int32_t tensor_index)
VectorWrapper< T > wrap(const flatbuffers::Vector< T > *vec)
void set_node_id(luci::CircleNode *circle_node, CircleNodeID id)
bool has_node_id(const luci::CircleNode *circle_node)
std::shared_ptr< CircleNodeOrigin > single_origin(uint32_t id, const std::string &name)
CircleOutput * output_node(loco::Graph *g, const loco::GraphOutputIndex &index)
Find a CircleOutput node with a given output index.
CircleInput * input_node(loco::Graph *g, const loco::GraphInputIndex &index)
Find a Pull node with a given input index.
void add_execution_plan(luci::CircleNode *circle_node, const luci::CircleNodeExecutionPlan &execution_plan)
Error listener (with default implementation)
void notify(const ErrorDetail< ErrorCategory::MissingArgument > &) override
NodeName name(void) const
ShapeStatus shape_status(void) const
virtual const GraphBuilderBase * lookup(const circle::BuiltinOperator &op) const =0
Returns registered GraphBuilder pointer for operator (nullptr if not present)