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

Method Run

tensorflow/lite/toco/graph_transformations/remove_trivial_binary.cc:49–134  ·  view source on GitHub ↗

A binary operator is called trivial when exactly one of its operands is a constant and is such that the binary operation is equivalent to the identity operation on its other input. For example, an Add operator is trivial if one of its operands is constant 0, a Mul operator is trivial if one of its operands is constant 1, etc.

Source from the content-addressed store, hash-verified

47// one of its operands is constant 0, a Mul operator is trivial
48// if one of its operands is constant 1, etc.
49::tensorflow::Status RemoveTrivialBinaryOperator::Run(Model* model,
50 std::size_t op_index,
51 bool* modified) {
52 *modified = false;
53 const auto binary_it = model->operators.begin() + op_index;
54 auto* binary_op = binary_it->get();
55 if (binary_op->type != OperatorType::kAdd &&
56 binary_op->type != OperatorType::kMul &&
57 binary_op->type != OperatorType::kSub &&
58 binary_op->type != OperatorType::kDiv) {
59 return ::tensorflow::Status::OK();
60 }
61
62 CHECK_EQ(binary_op->inputs.size(), 2);
63
64 // This graph transformation is only concerned with the case
65 // when one input is constant and the other is not constant.
66 const bool is_input_constant[2] = {
67 IsConstantParameterArray(*model, binary_op->inputs[0]),
68 IsConstantParameterArray(*model, binary_op->inputs[1]),
69 };
70 if (!is_input_constant[0] && !is_input_constant[1]) {
71 // Neither input is constant, so nothing we can resolve here.
72 return ::tensorflow::Status::OK();
73 }
74 if (is_input_constant[0] && is_input_constant[1]) {
75 // Both inputs are constants. That's a job for constants
76 // propagation, not for us to handle here.
77 return ::tensorflow::Status::OK();
78 }
79 const int index_of_constant_input = is_input_constant[0] ? 0 : 1;
80 const int index_of_variable_input = is_input_constant[0] ? 1 : 0;
81 CHECK(is_input_constant[index_of_constant_input]);
82 CHECK(!is_input_constant[index_of_variable_input]);
83
84 // If this was a broadcasting op we can't remove it as we need the broadcast.
85 // It's possible we could replace it with a cheaper op, though.
86 const auto& input_array_0 = model->GetArray(binary_op->inputs[0]);
87 const auto& input_array_1 = model->GetArray(binary_op->inputs[1]);
88 if (!input_array_0.has_shape() || !input_array_1.has_shape()) {
89 // Both input shapes must be known.
90 return ::tensorflow::Status::OK();
91 }
92 if (input_array_0.shape().dimensions_count() ==
93 input_array_1.shape().dimensions_count() &&
94 input_array_0.shape() != input_array_1.shape()) {
95 AddMessageF(
96 "Preserving %s even though it's trivial as we need to broadcast "
97 "(lhs %s, rhs %s)",
98 LogName(*binary_op), ShapeToString(input_array_0.shape()),
99 ShapeToString(input_array_1.shape()));
100 return ::tensorflow::Status::OK();
101 }
102
103 // Now check if the constant operand makes this binary
104 // operator trivial.
105 const auto& constant_input_array =
106 model->GetArray(binary_op->inputs[index_of_constant_input]);

Callers

nothing calls this directly

Calls 11

IsConstantParameterArrayFunction · 0.85
LogNameFunction · 0.85
has_shapeMethod · 0.80
dimensions_countMethod · 0.80
ShapeToStringFunction · 0.50
beginMethod · 0.45
getMethod · 0.45
sizeMethod · 0.45
shapeMethod · 0.45

Tested by

no test coverage detected