MCPcopy Create free account
hub / github.com/ARM-software/ComputeLibrary / mutate

Method mutate

src/graph/mutators/DepthConcatSubTensorMutator.cpp:50–114  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

48}
49
50void DepthConcatSubTensorMutator::mutate(Graph &g)
51{
52 // Early exit if no Concatenation layers exist in graph
53 if (g.nodes(NodeType::ConcatenateLayer).empty())
54 {
55 return;
56 }
57
58 // Perform topological sort
59 std::vector<NodeID> topological_sorted_node_ids = dfs(g);
60
61 // Should be in reverse order of execution
62 for (auto &node_id : arm_compute::utils::iterable::reverse_iterate(topological_sorted_node_ids))
63 {
64 INode *node = g.node(node_id);
65 if (node != nullptr && node->type() == NodeType::ConcatenateLayer && node->output(0) != nullptr)
66 {
67 // Get output tensor
68 auto output_tensor = node->output(0);
69
70 // Check concatenation axis (Sub-tensor optimization is supported for concatenation axis >=2)
71 auto *concat_node = arm_compute::utils::cast::polymorphic_downcast<ConcatenateLayerNode *>(node);
72 if (output_tensor == nullptr ||
73 get_dimension_idx(output_tensor->desc().layout, concat_node->concatenation_axis()) < 2)
74 {
75 continue;
76 }
77
78 // Check that all tensor have the same target, valid inputs and same quantization info
79 bool is_valid =
80 std::all_of(node->input_edges().cbegin(), node->input_edges().cend(),
81 [&](const EdgeID &eid)
82 {
83 return (g.edge(eid) != nullptr) && (g.edge(eid)->tensor() != nullptr) &&
84 (g.edge(eid)->tensor()->desc().target == output_tensor->desc().target) &&
85 (g.edge(eid)->tensor()->desc().quant_info == output_tensor->desc().quant_info);
86 });
87
88 // Create subtensors
89 if (is_valid && is_target_supported(output_tensor->desc().target))
90 {
91 ARM_COMPUTE_LOG_GRAPH_VERBOSE("Using sub-tensors for the node with ID : "
92 << node->id() << " and name : " << node->name() << std::endl);
93 // Create sub-tensor handles
94 unsigned depth = 0;
95 for (unsigned int i = 0; i < node->input_edges().size(); ++i)
96 {
97 auto input_tensor = node->input(i);
98 const auto input_shape = input_tensor->desc().shape;
99
100 backends::IDeviceBackend &backend =
101 backends::BackendRegistry::get().get_backend(input_tensor->desc().target);
102 std::unique_ptr<ITensorHandle> handle =
103 backend.create_subtensor(output_tensor->handle(), input_shape, Coordinates(0, 0, depth), false);
104 input_tensor->set_handle(std::move(handle));
105
106 depth += input_shape.z();
107 }

Callers

nothing calls this directly

Calls 15

dfsFunction · 0.85
reverse_iterateFunction · 0.85
get_dimension_idxFunction · 0.85
is_target_supportedFunction · 0.85
nodeMethod · 0.80
outputMethod · 0.80
concatenation_axisMethod · 0.80
edgeMethod · 0.80
inputMethod · 0.80
handleMethod · 0.80
set_handleMethod · 0.80
set_enabledMethod · 0.80

Tested by

no test coverage detected