blob: 4d6e7f81bb415dca2ef9837dddcd4d2c133aa799 [file] [log] [blame]
Jakub Sujak32741722022-11-25 16:43:18 +00001/*
Gunes Bayir0ee13af2024-02-07 15:34:45 +00002 * Copyright (c) 2022-2024 Arm Limited.
Jakub Sujak32741722022-11-25 16:43:18 +00003 *
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#include "arm_compute/dynamic_fusion/sketch/gpu/operators/GpuClamp.h"
25
26#include "arm_compute/core/experimental/Types.h"
27
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010028#include "src/common/utils/Log.h"
Jakub Sujak32741722022-11-25 16:43:18 +000029#include "src/core/helpers/AutoConfiguration.h"
30#include "src/dynamic_fusion/sketch/ArgumentPack.h"
Jakub Sujak32741722022-11-25 16:43:18 +000031#include "src/dynamic_fusion/sketch/gpu/components/cl/ClComponentActivation.h"
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010032#include "src/dynamic_fusion/sketch/gpu/GpuWorkloadSketchImpl.h"
Jakub Sujak32741722022-11-25 16:43:18 +000033
Jakub Sujak32741722022-11-25 16:43:18 +000034namespace arm_compute
35{
36namespace experimental
37{
38namespace dynamic_fusion
39{
40namespace
41{
Gunes Bayircc287732023-01-19 15:56:00 +000042Status is_supported_op_helper(const GpuWorkloadContext &context,
43 const ITensorInfo *src,
44 const ITensorInfo *dst,
45 const ClampAttributes &attributes)
Jakub Sujak32741722022-11-25 16:43:18 +000046{
47 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src, dst);
48 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(src, 1, DataType::F16, DataType::F32);
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010049 ARM_COMPUTE_RETURN_ERROR_ON_MSG(attributes.max_val() < attributes.min_val(),
50 "Maximum clamp value cannot be lower than minimum value");
Jakub Sujak32741722022-11-25 16:43:18 +000051
Gunes Bayircc287732023-01-19 15:56:00 +000052 TensorInfo dst_info_to_validate;
53 const ITensorInfo *dst_info_to_validate_ptr = &dst_info_to_validate;
54
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010055 if (dst != nullptr)
Gunes Bayircc287732023-01-19 15:56:00 +000056 {
57 dst_info_to_validate_ptr = dst;
58 }
59
Jakub Sujak32741722022-11-25 16:43:18 +000060 auto_init_if_empty(dst_info_to_validate, *src->clone());
61
62 // CLAMP operator is implemented as LU_BOUNDED_RELU with the alpha and beta variables swapped
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010063 const ClComponentActivation::Attributes act_info{ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU,
64 attributes.max_val(), attributes.min_val()};
Jakub Sujak32741722022-11-25 16:43:18 +000065
66 // Check components
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010067 if (context.gpu_language() == GpuLanguage::OpenCL)
Jakub Sujak32741722022-11-25 16:43:18 +000068 {
69 // Validate Activation Component
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010070 const auto properties =
71 IGpuKernelComponent::Properties().stage(UnitWorkloadStage{UnitWorkloadStage::Stage::Run});
Jakub Sujak32741722022-11-25 16:43:18 +000072
73 ArgumentPack<ITensorInfo> arguments;
74 arguments.add_const_tensor(ACL_SRC, src);
Gunes Bayircc287732023-01-19 15:56:00 +000075 arguments.add_const_tensor(ACL_DST, dst_info_to_validate_ptr);
Jakub Sujak32741722022-11-25 16:43:18 +000076 ARM_COMPUTE_RETURN_ON_ERROR(ClComponentActivation::validate(properties, arguments, act_info));
77 }
78 else
79 {
80 ARM_COMPUTE_RETURN_ERROR_MSG("Unimplemented Gpu language");
81 }
82 return Status{};
83}
84
Gunes Bayircc287732023-01-19 15:56:00 +000085constexpr GpuOperatorType operator_type = GpuOperatorType::Simple;
86} // namespace
87
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010088Status
89GpuClamp::is_supported_op(const GpuWorkloadContext &context, const ITensorInfo *src, const ClampAttributes &attributes)
Gunes Bayircc287732023-01-19 15:56:00 +000090{
91 return is_supported_op_helper(context, src, nullptr, attributes);
92}
93
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010094Status GpuClamp::validate_op(const GpuWorkloadSketch &sketch, const ITensorInfo *src, const ClampAttributes &attributes)
Jakub Sujak32741722022-11-25 16:43:18 +000095{
Gunes Bayircc287732023-01-19 15:56:00 +000096 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src);
Jakub Sujak32741722022-11-25 16:43:18 +000097
98 // Check if tensors have valid id, i.e. they are created from a sketch
Gunes Bayircc287732023-01-19 15:56:00 +000099 ARM_COMPUTE_RETURN_ERROR_ON(!src->has_valid_id());
100
101 // Refer to GpuConv2d::validate_op() for id-validness of this TensorInfo object
102 TensorInfo dst_info_to_validate;
Jakub Sujak32741722022-11-25 16:43:18 +0000103
104 // Auto initialize dst tensor info
Jakub Sujak32741722022-11-25 16:43:18 +0000105 auto_init_if_empty(dst_info_to_validate, *src->clone());
106
107 // Perform fusion test to check if the operator meets fusion constraints
108 ArgumentPack<ITensorInfo> tensors;
109 tensors.add_const_tensor(ACL_SRC, src);
110 tensors.add_const_tensor(ACL_DST, &dst_info_to_validate);
111 const auto op = sketch.implementation().operator_group().new_operator(operator_type, tensors);
112 ARM_COMPUTE_RETURN_ERROR_ON_MSG(!sketch.implementation().operator_group().try_add_operator(op),
113 "Operator fusion test failed. This operator cannot be fused into the workload");
114
115 // Check if configuration is supported
Gunes Bayircc287732023-01-19 15:56:00 +0000116 return is_supported_op_helper(*sketch.gpu_context(), src, &dst_info_to_validate, attributes);
Jakub Sujak32741722022-11-25 16:43:18 +0000117}
118
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100119ITensorInfo *GpuClamp::create_op(GpuWorkloadSketch &sketch, ITensorInfo *src, const ClampAttributes &attributes)
Jakub Sujak32741722022-11-25 16:43:18 +0000120{
Gunes Bayircc287732023-01-19 15:56:00 +0000121 ARM_COMPUTE_ERROR_ON_NULLPTR(src);
122 ARM_COMPUTE_LOG_PARAMS(src, attributes);
123 ARM_COMPUTE_ERROR_THROW_ON(GpuClamp::validate_op(sketch, src, attributes));
124
125 ITensorInfo *dst = sketch.implementation().create_virtual_tensor();
126 ARM_COMPUTE_ERROR_ON_NULLPTR(dst);
Jakub Sujak32741722022-11-25 16:43:18 +0000127
128 // Auto initialize dst tensor
129 auto_init_if_empty(*dst, *src->clone());
130
131 // Translate into components and add to component graph
132 GpuKernelComponentGraph &comp_graph = sketch.implementation().component_graph();
133
134 // CLAMP operator is implemented as LU_BOUNDED_RELU with the alpha and beta variables swapped
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100135 const ClComponentActivation::Attributes act_info{ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU,
136 attributes.max_val(), attributes.min_val()};
Jakub Sujak32741722022-11-25 16:43:18 +0000137
138 const auto *const sketch_ctx = sketch.implementation().context();
139
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100140 if (sketch_ctx->gpu_language() == GpuLanguage::OpenCL)
Jakub Sujak32741722022-11-25 16:43:18 +0000141 {
142 // Add Activation Component
143 auto properties = IGpuKernelComponent::Properties();
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100144 properties.stage(UnitWorkloadStage{UnitWorkloadStage::Stage::Run});
Jakub Sujak32741722022-11-25 16:43:18 +0000145
146 ArgumentPack<ITensorInfo> arguments;
147 arguments.add_const_tensor(ACL_SRC, src);
148 arguments.add_const_tensor(ACL_DST, dst);
149 comp_graph.add_new_component<ClComponentActivation>(properties, arguments, act_info);
150 }
151 else
152 {
153 ARM_COMPUTE_ERROR("Unimplemented Gpu language");
154 }
155
156 // Set up fusion test by adding to the Operator Group
157 // Note this has to be performed after all the components have been successfully added to the component graph
158
159 // Pack tensor infos
160 ArgumentPack<ITensorInfo> tensors;
161 tensors.add_const_tensor(ACL_SRC, src);
162 tensors.add_const_tensor(ACL_DST, dst);
163
164 const auto op = sketch.implementation().operator_group().new_operator(operator_type, tensors);
165 sketch.implementation().operator_group().add_operator(op);
Gunes Bayircc287732023-01-19 15:56:00 +0000166
167 return dst;
Jakub Sujak32741722022-11-25 16:43:18 +0000168}
169
170} // namespace dynamic_fusion
171} // namespace experimental
172} // namespace arm_compute