MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / ConvertOp

Function ConvertOp

tensorflow/compiler/mlir/lite/flatbuffer_import.cc:548–631  ·  view source on GitHub ↗

TODO(krzysd) Handle function calls

Source from the content-addressed store, hash-verified

546
547// TODO(krzysd) Handle function calls
548StatusOr<Operation*> ConvertOp(
549 const tflite::OperatorT& op, const std::vector<Value>& vals_map,
550 Value optional_arg_marker, const std::vector<std::string>& op_names,
551 const std::vector<std::string>& func_names,
552 const std::vector<std::unique_ptr<tflite::TensorT>>& tensors, Location loc,
553 OpBuilder builder) {
554 llvm::SmallVector<Value, 4> operands;
555 llvm::SmallVector<mlir::Type, 2> outputTypes;
556
557 if (op.outputs.empty()) {
558 auto err = errors::InvalidArgument("operator with no outputs");
559 return emitError(loc, err.ToString()), err;
560 }
561
562 const bool is_basic_lstm = IsBasicLSTMOp(op.builtin_options);
563 const std::string& op_name =
564 is_basic_lstm ? "tfl.basic_lstm" : op_names.at(op.opcode_index);
565 OperationState op_state(loc, op_name);
566
567 for (auto input_num : op.inputs) {
568 if (input_num == -1) {
569 assert(optional_arg_marker != nullptr);
570 op_state.addOperands({optional_arg_marker});
571 } else {
572 op_state.addOperands({vals_map.at(input_num)});
573 }
574 }
575
576 for (auto output_num : op.outputs) {
577 auto& tensor = *tensors.at(output_num);
578 auto type_or_err = GetTensorType(tensor, builder);
579 if (!type_or_err.ok()) {
580 return emitError(loc, type_or_err.status().ToString()),
581 type_or_err.status();
582 }
583 auto type = type_or_err.ConsumeValueOrDie();
584
585 if (op_name == "tfl.quantize") {
586 // Special case for quantize: return type must also be in qtype attribute
587 op_state.addAttribute("qtype", mlir::TypeAttr::get(type));
588 } else if (op_name == "tfl.reshape" && type.hasStaticShape() &&
589 op_state.operands.size() == 1) {
590 // Special case for reshape: the second op is optional in the old
591 // converter and kernel, so we create the second operand, which is
592 // required by the new converter, from the result shape.
593 auto shape_type =
594 RankedTensorType::get({type.getRank()}, builder.getIntegerType(32));
595 mlir::SmallVector<mlir::Attribute, 4> shape;
596 shape.reserve(type.getRank());
597 for (auto s : type.getShape()) {
598 shape.push_back(builder.getI32IntegerAttr(static_cast<int32_t>(s)));
599 }
600 auto output_shape = DenseElementsAttr::get(shape_type, shape);
601 auto shape_op = builder.create<tfl::ConstOp>(loc, output_shape);
602 op_state.addOperands({shape_op});
603 }
604
605 op_state.addTypes({type});

Callers 1

ConvertSubgraphFunction · 0.85

Calls 15

InvalidArgumentFunction · 0.85
IsBasicLSTMOpFunction · 0.85
IsCustomOpFunction · 0.85
ConsumeValueOrDieMethod · 0.80
createOperationMethod · 0.80
GetTensorTypeFunction · 0.70
getFunction · 0.50
emptyMethod · 0.45
ToStringMethod · 0.45
atMethod · 0.45
okMethod · 0.45

Tested by

no test coverage detected