| 110 | namespace details { |
| 111 | |
| 112 | OperatorKey::OperatorKey( |
| 113 | const ::toco::OperatorSignature& op_signature, |
| 114 | const std::map<OperatorType, std::unique_ptr<BaseOperator>>& ops_by_type, |
| 115 | bool enable_select_tf_ops) { |
| 116 | // Get the op name (by Toco definition). |
| 117 | const ::toco::Operator& op = *op_signature.op; |
| 118 | string name = HelpfulOperatorTypeName(op); |
| 119 | |
| 120 | bool is_builtin = false; |
| 121 | const auto& builtin_ops = GetBuiltinOpsMap(); |
| 122 | if (ops_by_type.count(op.type) != 0) { |
| 123 | version_ = ops_by_type.at(op.type)->GetVersion(op_signature); |
| 124 | name = ops_by_type.at(op.type)->name(); |
| 125 | is_builtin = (builtin_ops.count(name) > 0); |
| 126 | } |
| 127 | |
| 128 | if (is_builtin) { |
| 129 | // For TFLite supported builtin ops, find out its BuiltinOperator enum used |
| 130 | // in FlatBuffer. |
| 131 | type_ = builtin_ops.at(name); |
| 132 | return; |
| 133 | } |
| 134 | // The logic below is all for custom ops or Flex ops. |
| 135 | is_custom_op_ = true; |
| 136 | type_ = BuiltinOperator_CUSTOM; |
| 137 | |
| 138 | if (op.type == OperatorType::kUnsupported) { |
| 139 | const TensorFlowUnsupportedOperator& unsupported_op = |
| 140 | static_cast<const TensorFlowUnsupportedOperator&>(op); |
| 141 | const auto tensorflow_op = unsupported_op.tensorflow_op; |
| 142 | |
| 143 | if (ShouldExportAsFlexOp(enable_select_tf_ops, |
| 144 | unsupported_op.tensorflow_op)) { |
| 145 | is_custom_op_ = false; |
| 146 | is_flex_op_ = true; |
| 147 | flex_tensorflow_op_ = tensorflow_op; |
| 148 | custom_code_ = |
| 149 | string(::tflite::kFlexCustomCodePrefix) + flex_tensorflow_op_; |
| 150 | } else { |
| 151 | custom_code_ = tensorflow_op; |
| 152 | } |
| 153 | } else if (enable_select_tf_ops && !op.tensorflow_node_def.empty()) { |
| 154 | // For Toco-supported/TFLite-unsupported ops, if the TensorFlow NodeDef |
| 155 | // is retained in the Toco Operator, we produce a Flex op if Flex mode |
| 156 | // is enabled. |
| 157 | is_custom_op_ = false; |
| 158 | is_flex_op_ = true; |
| 159 | flex_tensorflow_op_ = name; |
| 160 | custom_code_ = |
| 161 | string(::tflite::kFlexCustomCodePrefix) + flex_tensorflow_op_; |
| 162 | } else { |
| 163 | // If Flex is disabled or the original TensorFlow NodeDef isn't available, |
| 164 | // we produce a custom op. This gives developers a chance to implement |
| 165 | // custom ops. |
| 166 | custom_code_ = name; |
| 167 | } |
| 168 | |
| 169 | if (is_flex_op_) { |
nothing calls this directly
no test coverage detected