| 2234 | } |
| 2235 | |
| 2236 | bool ReshapeIsEquivalentToTranspose(const Model& model, |
| 2237 | const TensorFlowReshapeOperator* op, |
| 2238 | bool allow_extra_unary_dims) { |
| 2239 | CHECK(!op->shape.empty()); |
| 2240 | CHECK(model.HasArray(op->inputs[0])); |
| 2241 | CHECK(model.HasArray(op->outputs[0])); |
| 2242 | |
| 2243 | const auto& input_array = model.GetArray(op->inputs[0]); |
| 2244 | const auto& output_array = model.GetArray(op->outputs[0]); |
| 2245 | |
| 2246 | CHECK(input_array.has_shape()); |
| 2247 | CHECK(output_array.has_shape()); |
| 2248 | |
| 2249 | std::vector<int> in_shape = input_array.shape().dims(); |
| 2250 | std::vector<int> out_shape = output_array.shape().dims(); |
| 2251 | |
| 2252 | // If the reshape changes the number of dimensions so it cannot be interpreted |
| 2253 | // as a transpose. |
| 2254 | if (!allow_extra_unary_dims && in_shape.size() != out_shape.size()) { |
| 2255 | return false; |
| 2256 | } |
| 2257 | |
| 2258 | in_shape.erase(std::remove(in_shape.begin(), in_shape.end(), 1), |
| 2259 | in_shape.end()); |
| 2260 | out_shape.erase(std::remove(out_shape.begin(), out_shape.end(), 1), |
| 2261 | out_shape.end()); |
| 2262 | return in_shape == out_shape; |
| 2263 | } |
| 2264 | |
| 2265 | void CheckFinalDataTypesSatisfied(const Model& model) { |
| 2266 | for (const auto& array_entry : model.GetArrayMap()) { |