| 221 | } |
| 222 | |
| 223 | void InPlaceOperationMutator::mutate(Graph &g) |
| 224 | { |
| 225 | std::set<NodeType> in_place_nodes = {NodeType::ActivationLayer, |
| 226 | NodeType::BatchNormalizationLayer, |
| 227 | NodeType::EltwiseLayer, |
| 228 | NodeType::UnaryEltwiseLayer, |
| 229 | NodeType::DepthwiseConvolutionLayer, |
| 230 | NodeType::FusedDepthwiseConvolutionBatchNormalizationLayer, |
| 231 | NodeType::PrintLayer}; |
| 232 | |
| 233 | // Not interested in the order of nodes |
| 234 | for (auto &node : g.nodes()) |
| 235 | { |
| 236 | if (node && in_place_nodes.find(node->type()) != std::end(in_place_nodes)) |
| 237 | { |
| 238 | // Get input edge |
| 239 | Edge *input_edge = node->input_edge(0); |
| 240 | |
| 241 | // Check if parent has a single output if yes then force in place calculation else not |
| 242 | if ((input_edge != nullptr) && output_edges_are_separate_tensors(g, input_edge)) |
| 243 | { |
| 244 | if (node->type() == NodeType::EltwiseLayer) |
| 245 | { |
| 246 | try_in_place_elementwise(node); |
| 247 | } |
| 248 | else if (node->type() == NodeType::FusedDepthwiseConvolutionBatchNormalizationLayer || |
| 249 | node->type() == NodeType::DepthwiseConvolutionLayer) |
| 250 | { |
| 251 | try_in_place_depthwiseconv(node); |
| 252 | } |
| 253 | else |
| 254 | { |
| 255 | // Get current and new output tensors |
| 256 | auto current_output_tensor = node->output(0); |
| 257 | auto new_output_tensor = input_edge->tensor(); |
| 258 | |
| 259 | ARM_COMPUTE_ERROR_ON(current_output_tensor == nullptr || new_output_tensor == nullptr); |
| 260 | |
| 261 | // Prevent in-place operation if there is an accessor bound to the in-place tensor or quantization info are different |
| 262 | if (new_output_tensor->accessor() != nullptr || |
| 263 | current_output_tensor->desc().quant_info != new_output_tensor->desc().quant_info) |
| 264 | { |
| 265 | ARM_COMPUTE_LOG_GRAPH_VERBOSE("Prevented in-place operation as there is an accessor bound to " |
| 266 | "the input tensor or the quantization info are different.\n"); |
| 267 | } |
| 268 | else |
| 269 | { |
| 270 | set_new_output_and_inherit_accessor(node, current_output_tensor, new_output_tensor); |
| 271 | } |
| 272 | } |
| 273 | } |
| 274 | } |
| 275 | } |
| 276 | } |
| 277 | } // namespace graph |
| 278 | } // namespace arm_compute |
nothing calls this directly
no test coverage detected