1 /* 2 * Copyright (c) 2017-2021 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 #include "arm_compute/runtime/CL/functions/CLL2NormalizeLayer.h" 25 26 #include "arm_compute/core/CL/ICLTensor.h" 27 #include "arm_compute/core/Error.h" 28 #include "arm_compute/core/PixelValue.h" 29 #include "arm_compute/core/TensorInfo.h" 30 #include "arm_compute/core/Validate.h" 31 #include "arm_compute/runtime/CL/CLScheduler.h" 32 #include "src/core/CL/kernels/CLFillBorderKernel.h" 33 #include "src/core/CL/kernels/CLL2NormalizeLayerKernel.h" 34 #include "src/core/CL/kernels/CLReductionOperationKernel.h" 35 36 #include "src/common/utils/Log.h" 37 38 namespace arm_compute 39 { 40 namespace 41 { 42 constexpr int max_input_tensor_dim = 3; 43 } // namespace 44 CLL2NormalizeLayer(std::shared_ptr<IMemoryManager> memory_manager)45 CLL2NormalizeLayer::CLL2NormalizeLayer(std::shared_ptr<IMemoryManager> memory_manager) 46 : _memory_group(std::move(memory_manager)), 47 _reduce_func(), 48 _normalize_kernel(std::make_unique<CLL2NormalizeLayerKernel>()), 49 _sumsq() 50 { 51 } 52 53 CLL2NormalizeLayer::~CLL2NormalizeLayer() = default; 54 configure(ICLTensor * input,ICLTensor * output,int axis,float epsilon)55 void CLL2NormalizeLayer::configure(ICLTensor *input, ICLTensor *output, int axis, float epsilon) 56 { 57 configure(CLKernelLibrary::get().get_compile_context(), input, output, axis, epsilon); 58 } 59 configure(const CLCompileContext & compile_context,ICLTensor * input,ICLTensor * output,int axis,float epsilon)60 void CLL2NormalizeLayer::configure(const CLCompileContext &compile_context, ICLTensor *input, ICLTensor *output, int axis, float epsilon) 61 { 62 ARM_COMPUTE_LOG_PARAMS(input, output, axis, epsilon); 63 64 // Reset auxiliary tensor 65 _sumsq.allocator()->init(TensorInfo()); 66 67 // Manage intermediate buffers 68 _memory_group.manage(&_sumsq); 69 70 // Configure kernels 71 const uint32_t actual_axis = wrap_around(axis, max_input_tensor_dim); 72 _reduce_func.configure(compile_context, input, &_sumsq, actual_axis, ReductionOperation::SUM_SQUARE); 73 _normalize_kernel->configure(compile_context, input, &_sumsq, output, axis, epsilon); 74 75 // Allocate intermediate tensor 76 _sumsq.allocator()->allocate(); 77 } 78 validate(const ITensorInfo * input,const ITensorInfo * output,int axis,float epsilon)79 Status CLL2NormalizeLayer::validate(const ITensorInfo *input, const ITensorInfo *output, int axis, float epsilon) 80 { 81 TensorShape shape(input->tensor_shape()); 82 83 // Create intermediate tensor info 84 TensorInfo sum_sq; 85 sum_sq.set_data_type(input->data_type()); 86 sum_sq.set_tensor_shape(shape); 87 88 const uint32_t actual_axis = wrap_around(axis, max_input_tensor_dim); 89 ARM_COMPUTE_RETURN_ON_ERROR(CLReductionOperation::validate(input, &sum_sq, actual_axis, ReductionOperation::SUM_SQUARE)); 90 91 // Reduce shape on axis 92 shape.set(actual_axis, 1); 93 sum_sq.set_tensor_shape(shape); 94 95 ARM_COMPUTE_RETURN_ON_ERROR(CLL2NormalizeLayerKernel::validate(input, &sum_sq, output, axis, epsilon)); 96 97 return Status{}; 98 } 99 run()100 void CLL2NormalizeLayer::run() 101 { 102 MemoryGroupResourceScope scope_mg(_memory_group); 103 104 _reduce_func.run(); 105 CLScheduler::get().enqueue(*_normalize_kernel, true); 106 } 107 } // namespace arm_compute 108