Compute Library
 22.11
ClKernelGraph.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifdef ENABLE_EXPERIMENTAL_DYNAMIC_FUSION
26 
27 #include "src/core/CL/CLValidate.h"
30 
31 #include "support/Cast.h"
32 
33 namespace arm_compute
34 {
35 namespace experimental
36 {
37 namespace dynamic_fusion
38 {
40 {
41  const auto input = _tensors.get_const_tensor(TensorType::ACL_SRC_0);
42  const auto weight = _tensors.get_const_tensor(TensorType::ACL_SRC_1);
43  const auto bias = _tensors.get_const_tensor(TensorType::ACL_SRC_2);
44  const auto dst = _tensors.get_const_tensor(TensorType::ACL_DST_0);
46  ArgumentID input_id;
47  add_tensor(bp, input->desc, input_id, input->id);
48  ArgumentID weight_id;
49  add_tensor(bp, weight->desc, weight_id, weight->id);
50  ArgumentID bias_id = g_arg_placeholder;
51  if(bias != nullptr)
52  {
53  add_tensor(bp, bias->desc, bias_id, bias->id);
54  }
55  ArgumentID dst_id;
56  add_tensor(bp, dst->desc, dst_id, dst->id);
57 
58  add_kcomp_direct_conv2d(bp, desc, input_id, weight_id, bias_id, dst_id);
59  return Status{};
60 }
62 {
63  // 1. Check validity
64  ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src, weights, dst);
65  // Matching data type
68  if(biases != nullptr)
69  {
71  }
72 
73  // Matching data layout
76  if(biases != nullptr)
77  {
79  }
80 
81  // All tensor infos are initialized
85  if(biases != nullptr)
86  {
88  }
89  // Device requirements are met
91  // weights shape is correct
92  const DataLayout data_layout = src->data_layout();
93  const int channel_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::CHANNEL);
94  ARM_COMPUTE_RETURN_ERROR_ON_MSG(weights->dimension(channel_idx) != src->dimension(channel_idx), "Weights feature map dimension should match the respective src's one");
95  ARM_COMPUTE_RETURN_ERROR_ON_MSG(weights->num_dimensions() > 4, "Weights can be at most 4 dimensional");
96 
97  // dst shape is correct
98  PadStrideInfo legacy_pad_stride(conv2d_desc.conv2d.stride.x(), conv2d_desc.conv2d.stride.y(), conv2d_desc.conv2d.pad.left, conv2d_desc.conv2d.pad.right, conv2d_desc.conv2d.pad.top,
99  conv2d_desc.conv2d.pad.bottom, DimensionRoundingType{});
101  misc::shape_calculator::compute_deep_convolution_shape(*src, *weights, legacy_pad_stride));
102 
103  // biases shape is correct
104  if(biases != nullptr)
105  {
106  ARM_COMPUTE_RETURN_ERROR_ON_MSG(biases->dimension(0) != weights->dimension(3),
107  "Biases size and number of dst feature maps should match");
109  "Biases should be one dimensional");
110  }
111 
112  // 2. Check support level
113  // Data type
115  // Data layout
117 
118  return Status{};
119 }
120 
122 {
123  const auto converted = *utils::cast::polymorphic_downcast<const ClDirectConv2dKernel *>(&other);
124  return config() == other.config() && tensors() == other.tensors() && desc == converted.desc;
125 }
126 
128 {
129  const auto lhs = _tensors.get_const_tensor(TensorType::ACL_SRC_0);
130  const auto rhs = _tensors.get_const_tensor(TensorType::ACL_SRC_1);
131  const auto dst = _tensors.get_const_tensor(TensorType::ACL_DST_0);
133  ArgumentID lhs_id;
134  add_tensor(bp, lhs->desc, lhs_id, lhs->id);
135  ArgumentID rhs_id;
136  add_tensor(bp, rhs->desc, rhs_id, rhs->id);
137  ArgumentID dst_id;
138  add_tensor(bp, dst->desc, dst_id, dst->id);
139 
140  add_kcomp_eltwise_op(bp, desc, lhs_id, rhs_id, dst_id);
141  return Status{};
142 }
143 
145 {
146  // 1. Check validity
148 
149  // Matching data type
152 
153  // Matching data layout
156 
157  // All tensor infos are initialized
161 
162  // Device requirements are met
164 
165  const bool in_place = (lhs == dst) || (rhs == dst);
166  const bool src0_in_place = in_place && (lhs == dst);
167 
168  // dst shape is correct
169  const TensorShape out_shape = TensorShape::broadcast_shape(lhs->tensor_shape(), rhs->tensor_shape());
170  ARM_COMPUTE_RETURN_ERROR_ON_MSG(out_shape.total_size() == 0, "Inputs are not broadcast compatible");
171  ARM_COMPUTE_RETURN_ERROR_ON_MSG(detail::have_different_dimensions(out_shape, dst->tensor_shape(), 0), "Wrong shape for dst");
172  if(in_place)
173  {
174  ARM_COMPUTE_RETURN_ERROR_ON_MSG(detail::have_different_dimensions(out_shape, src0_in_place ? lhs->tensor_shape() : rhs->tensor_shape(), 0),
175  "Wrong shape for dst, cannot do in_place calculation");
176  }
177 
178  // 2. Check support level
179 
180  // Data type
182 
183  // Data layout
185 
186  return Status{};
187 }
188 
190 {
191  const auto converted = *utils::cast::polymorphic_downcast<const ClElementwiseKernel *>(&other);
192  return config() == other.config() && tensors() == other.tensors() && desc == converted.desc;
193 }
194 
196 {
197  const auto src = _tensors.get_const_tensor(TensorType::ACL_SRC_0);
198  const auto dst = _tensors.get_const_tensor(TensorType::ACL_DST_0);
200  ArgumentID src_id;
201  add_tensor(bp, src->desc, src_id, src->id);
202  ArgumentID dst_id;
203  add_tensor(bp, dst->desc, dst_id, dst->id);
204 
205  add_kcomp_floor(bp, desc, src_id, dst_id);
206  return Status{};
207 }
208 
210 {
211  // 1. Check validity
213 
214  // Matching data type
216 
217  // Matching data layout
219 
220  // All tensor infos are initialized
223 
224  // Device requirements are met
226 
227  // dst shape is correct
229 
230  // 2. Check support level
231 
232  // Data type
234 
235  // Data layout
237 
238  return Status{};
239 }
240 
241 bool ClFloorKernel::operator==(const ClKernel &other) const
242 {
243  const auto converted = *utils::cast::polymorphic_downcast<const ClFloorKernel *>(&other);
244  return config() == other.config() && tensors() == other.tensors() && desc == converted.desc;
245 }
246 
247 std::vector<const ClKernel *> traverse(const ClKernelGraph &graph)
248 {
249  std::vector<const ClKernel *> kernels;
250  const auto sorted = graph.graph.topological_sort();
251  for(const auto &pack : sorted.second)
252  {
253  kernels.push_back(graph.kernels.at(pack.op).get());
254  }
255  return kernels;
256 }
257 
258 std::vector<ClKernel *> traverse(ClKernelGraph &graph)
259 {
260  std::vector<ClKernel *> kernels;
261  const auto sorted = graph.graph.topological_sort();
262  for(const auto &pack : sorted.second)
263  {
264  kernels.push_back(graph.kernels.at(pack.op).get());
265  }
266  return kernels;
267 }
268 } // namespace dynamic_fusion
269 } // namespace experimental
270 } // namespace arm_compute
271 #endif /* ENABLE_EXPERIMENTAL_DYNAMIC_FUSION */
virtual size_t num_dimensions() const =0
The number of dimensions of the tensor (rank)
bool operator==(const ClKernel &other) const override
#define ARM_COMPUTE_RETURN_ERROR_ON_F16_UNSUPPORTED(tensor)
Definition: CLValidate.h:35
Shape of a tensor.
Definition: TensorShape.h:39
bool operator==(const ClKernel &other) const override
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN(t,...)
Definition: Validate.h:742
ITensorDescPack< ClKernelTensor > tensors() const
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...)
Definition: Validate.h:490
virtual size_t dimension(size_t index) const =0
Return the size of the requested dimension.
1 channel, 1 F32 per channel
DimensionRoundingType
Dimension rounding type when down-scaling on CNNs.
Definition: Types.h:550
static TensorShape broadcast_shape(const Shapes &... shapes)
If shapes are broadcast compatible, return the broadcasted shape.
Definition: TensorShape.h:211
bool operator==(const ClKernel &other) const override
size_t bottom
Padding across the height dimension on the bottom, in elements.
Definition: Types.h:796
size_t right
Padding across the width dimension on the right, in elements.
Definition: Types.h:794
Store the tensor&#39;s metadata.
Definition: ITensorInfo.h:40
static Status validate(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *dst, const ClDirectConv2dKernelDescriptor &conv2d_desc)
size_t x() const
Semantic accessor for width as x.
Definition: Size2D.h:75
Status class.
Definition: Error.h:52
std::pair< Status, std::vector< OpPack > > topological_sort() const
Sort the graph in a topological order.
std::vector< const ClKernel * > traverse(const ClKernelFusionGroup &group)
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:296
size_t left
Padding across the width dimension on the left, in elements.
Definition: Types.h:793
static Status validate(const ITensorInfo *src, const ITensorInfo *dst)
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(...)
Definition: Validate.h:284
SimpleTensor< float > src
Definition: DFT.cpp:155
Copyright (c) 2017-2022 Arm Limited.
Status generate(ClKernelBlueprint &bp) const override
1 channel, 1 F16 per channel
Intermediate representation of the final, complete kernel source.
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...)
Definition: Validate.h:159
size_t top
Padding across the height dimension on the top, in elements.
Definition: Types.h:795
Status add_kcomp_eltwise_op(ClKernelBlueprint &kernel_blueprint, const ClElementwiseKernelDescriptor &desc, ArgumentID src0_id, ArgumentID src1_id, ArgumentID &dst_id)
Component: Eltwise Operator.
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
size_t total_size() const
Collapses all dimensions to a single linear total size.
Definition: TensorShape.h:172
bool have_different_dimensions(const Dimensions< T > &dim1, const Dimensions< T > &dim2, unsigned int upper_dim)
Definition: Validate.h:47
Status add_kcomp_direct_conv2d(ClKernelBlueprint &kernel_blueprint, const ClDirectConv2dKernelDescriptor &direct_conv2d_desc, ArgumentID src_id, ArgumentID weight_id, ArgumentID bias_id, ArgumentID &dst_id)
Component: Direct Convolution.
Padding and stride information class.
Definition: Types.h:669
static Status validate(const ITensorInfo *lhs, const ITensorInfo *rhs, const ITensorInfo *dst)
Status add_kcomp_floor(ClKernelBlueprint &kernel_blueprint, const ClFloorKernelDescriptor &, ArgumentID src_id, ArgumentID &dst_id)
Component: Floor.
size_t y() const
Semantic accessor for height as y.
Definition: Size2D.h:84
Status generate(ClKernelBlueprint &bp) const override
Status generate(ClKernelBlueprint &bp) const override
OpTensor add_tensor(OperatorGraph &graph, ITensorInfo &info)
Associate a TensorInfo with a newly created OpTensor in the graph.
size_t get_data_layout_dimension_index(const DataLayout &data_layout, const DataLayoutDimension &data_layout_dimension)
Get the index of the given dimension.
Definition: Helpers.inl:193
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
Definition: Validate.h:541
Num samples, height, width, channels.
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Definition: Validate.h:788
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
If the condition is true, an error is returned.
Definition: Error.h:244
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:157
DataLayout
[DataLayout enum definition]
Definition: Types.h:113
TensorShape compute_deep_convolution_shape(const TensorShape &input_shape, DataLayout input_data_layout, const TensorShape &weights_shape, const PadStrideInfo &conv_info)
Calculate the deep convolution shape output shape of a tensor.
virtual DataLayout data_layout() const =0
Get the data layout of the tensor.
const int32_t * bias