From f9a36f4af8bcdc6bf16c11c91eedc0f5ab51aff1 Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Fri, 13 Dec 2019 12:33:09 +0000 Subject: COMPMID-2819: Retain configuration step data layout to avoid side-effects. Configuring functions serially can lead to side-effects in tensor attributes. One of them is the data layout changing in case functions share same IO tensors. Retain DataLayout used during configuration. Change-Id: I17538ce08b86df6986f0fcf21fa6544fbd5bd74b Signed-off-by: Georgios Pinitas Reviewed-on: https://review.mlplatform.org/c/2470 Tested-by: Arm Jenkins Reviewed-by: Giorgio Arena --- arm_compute/core/CL/kernels/CLPoolingLayerKernel.h | 1 + arm_compute/core/CL/kernels/CLScaleKernel.h | 1 + .../core/NEON/kernels/NEPoolingLayerKernel.h | 1 + src/core/CL/kernels/CLPoolingLayerKernel.cpp | 28 +++++++++++----------- src/core/CL/kernels/CLScaleKernel.cpp | 16 ++++++------- src/core/NEON/kernels/NEPoolingLayerKernel.cpp | 15 ++++++------ 6 files changed, 33 insertions(+), 29 deletions(-) diff --git a/arm_compute/core/CL/kernels/CLPoolingLayerKernel.h b/arm_compute/core/CL/kernels/CLPoolingLayerKernel.h index db1a756229..68a99039d8 100644 --- a/arm_compute/core/CL/kernels/CLPoolingLayerKernel.h +++ b/arm_compute/core/CL/kernels/CLPoolingLayerKernel.h @@ -75,6 +75,7 @@ public: const ICLTensor *_input; ICLTensor *_output; PoolingLayerInfo _pool_info; + DataLayout _data_layout; BorderSize _border_size; unsigned int _num_elems_processed_per_iteration; }; diff --git a/arm_compute/core/CL/kernels/CLScaleKernel.h b/arm_compute/core/CL/kernels/CLScaleKernel.h index ff72af29fc..1ada3cde85 100644 --- a/arm_compute/core/CL/kernels/CLScaleKernel.h +++ b/arm_compute/core/CL/kernels/CLScaleKernel.h @@ -75,6 +75,7 @@ public: public: InterpolationPolicy _interpolationPolicy = InterpolationPolicy::BILINEAR; + DataLayout _data_layout = DataLayout::UNKNOWN; }; } // namespace arm_compute #endif /*__ARM_COMPUTE_CLSCALEKERNEL_H__ */ diff --git a/arm_compute/core/NEON/kernels/NEPoolingLayerKernel.h b/arm_compute/core/NEON/kernels/NEPoolingLayerKernel.h index 5f45a90cef..5b143250e9 100644 --- a/arm_compute/core/NEON/kernels/NEPoolingLayerKernel.h +++ b/arm_compute/core/NEON/kernels/NEPoolingLayerKernel.h @@ -194,6 +194,7 @@ private: const ITensor *_input; ITensor *_output; PoolingLayerInfo _pool_info; + DataLayout _data_layout; unsigned int _num_elems_processed_per_iteration; BorderSize _border_size; bool _is_square; diff --git a/src/core/CL/kernels/CLPoolingLayerKernel.cpp b/src/core/CL/kernels/CLPoolingLayerKernel.cpp index 8eaf5bf76f..032d451aad 100644 --- a/src/core/CL/kernels/CLPoolingLayerKernel.cpp +++ b/src/core/CL/kernels/CLPoolingLayerKernel.cpp @@ -172,7 +172,7 @@ std::tuple validate_and_configure_window(ITenso } // namespace CLPoolingLayerKernel::CLPoolingLayerKernel() - : _input(nullptr), _output(nullptr), _pool_info(), _border_size(0), _num_elems_processed_per_iteration(1) + : _input(nullptr), _output(nullptr), _pool_info(), _data_layout(DataLayout::UNKNOWN), _border_size(0), _num_elems_processed_per_iteration(1) { } @@ -185,13 +185,18 @@ void CLPoolingLayerKernel::configure(const ICLTensor *input, ICLTensor *output, { ARM_COMPUTE_ERROR_ON_NULLPTR(input, output); + // Set instance variables + _input = input; + _output = output; + _pool_info = pool_info; + _data_layout = input->info()->data_layout(); + int pool_stride_x = 0; int pool_stride_y = 0; const PoolingType pool_type = pool_info.pool_type(); - DataLayout data_layout = input->info()->data_layout(); - const int idx_width = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH); - const int idx_height = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT); - const int idx_channel = get_data_layout_dimension_index(data_layout, DataLayoutDimension::CHANNEL); + const int idx_width = get_data_layout_dimension_index(_data_layout, DataLayoutDimension::WIDTH); + const int idx_height = get_data_layout_dimension_index(_data_layout, DataLayoutDimension::HEIGHT); + const int idx_channel = get_data_layout_dimension_index(_data_layout, DataLayoutDimension::CHANNEL); const int pool_size_x = pool_info.is_global_pooling() ? input->info()->dimension(idx_width) : pool_info.pool_size().width; const int pool_size_y = pool_info.is_global_pooling() ? input->info()->dimension(idx_height) : pool_info.pool_size().height; const PadStrideInfo pad_stride_info = pool_info.pad_stride_info(); @@ -218,11 +223,6 @@ void CLPoolingLayerKernel::configure(const ICLTensor *input, ICLTensor *output, auto_init(input->info(), output->info(), pool_info); ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), pool_info)); - // Set instance variables - _input = input; - _output = output; - _pool_info = pool_info; - const DataType data_type = input->info()->data_type(); build_opts.add_option("-DDATA_TYPE=" + get_cl_type_from_data_type(data_type)); @@ -237,7 +237,7 @@ void CLPoolingLayerKernel::configure(const ICLTensor *input, ICLTensor *output, build_opts.add_option_if(data_type == DataType::F16, "-DFP16"); // Create kernel - switch(data_layout) + switch(_data_layout) { case DataLayout::NCHW: { @@ -286,7 +286,7 @@ void CLPoolingLayerKernel::configure(const ICLTensor *input, ICLTensor *output, ARM_COMPUTE_ERROR_THROW_ON(std::get<0>(win_config)); ICLKernel::configure_internal(std::get<1>(win_config)); - if(data_layout == DataLayout::NCHW) + if(_data_layout == DataLayout::NCHW) { CLPoolingConfig pooling_config = std::get<2>(win_config); _num_elems_processed_per_iteration = pooling_config.first; @@ -302,7 +302,7 @@ void CLPoolingLayerKernel::configure(const ICLTensor *input, ICLTensor *output, _config_id = "pooling_layer_"; _config_id += lower_string(string_from_data_type(data_type)); _config_id += "_"; - _config_id += lower_string(string_from_data_layout(data_layout)); + _config_id += lower_string(string_from_data_layout(_data_layout)); _config_id += "_"; _config_id += support::cpp11::to_string(output->info()->dimension(idx_width)); _config_id += "_"; @@ -333,7 +333,7 @@ void CLPoolingLayerKernel::run(const Window &window, cl::CommandQueue &queue) // Collapse window Window window_collapsed = window.collapse_if_possible(ICLKernel::window(), Window::DimZ); - switch(_input->info()->data_layout()) + switch(_data_layout) { case DataLayout::NCHW: { diff --git a/src/core/CL/kernels/CLScaleKernel.cpp b/src/core/CL/kernels/CLScaleKernel.cpp index 488313fd12..82c5c8a446 100644 --- a/src/core/CL/kernels/CLScaleKernel.cpp +++ b/src/core/CL/kernels/CLScaleKernel.cpp @@ -160,11 +160,12 @@ const ICLTensor *CLScaleKernel::output() const void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy) { + ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), policy)); + _input = input; _output = output; _interpolationPolicy = policy; - - ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), policy)); + _data_layout = input->info()->data_layout(); float wr = 0.f; float hr = 0.f; @@ -172,10 +173,9 @@ void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, Interpo const bool call_quantized_kernel = is_data_type_quantized_asymmetric(input->info()->data_type()) && policy == InterpolationPolicy::BILINEAR; - DataLayout data_layout = input->info()->data_layout(); - const int idx_width = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH); - const int idx_height = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT); - const bool is_nhwc = data_layout == DataLayout::NHWC; + const int idx_width = get_data_layout_dimension_index(_data_layout, DataLayoutDimension::WIDTH); + const int idx_height = get_data_layout_dimension_index(_data_layout, DataLayoutDimension::HEIGHT); + const bool is_nhwc = _data_layout == DataLayout::NHWC; // Compute the ratio between source width/height and destination width/height const unsigned int input_width = input->info()->dimension(idx_width); @@ -215,7 +215,7 @@ void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, Interpo std::transform(interpolation_name.begin(), interpolation_name.end(), interpolation_name.begin(), ::tolower); std::string kernel_name = "scale_" + interpolation_name; kernel_name += call_quantized_kernel ? "_quantized_" : "_"; - kernel_name += lower_string(string_from_data_layout(data_layout)); + kernel_name += lower_string(string_from_data_layout(_data_layout)); _kernel = static_cast(CLKernelLibrary::get().create_kernel(kernel_name, build_opts.options())); unsigned int idx = is_nhwc ? 2 * num_arguments_per_4D_tensor() : 2 * num_arguments_per_2D_tensor(); //Skip the input and output parameters @@ -249,7 +249,7 @@ void CLScaleKernel::run(const Window &window, cl::CommandQueue &queue) ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICLKernel::window(), window); - switch(_input->info()->data_layout()) + switch(_data_layout) { case DataLayout::NCHW: { diff --git a/src/core/NEON/kernels/NEPoolingLayerKernel.cpp b/src/core/NEON/kernels/NEPoolingLayerKernel.cpp index 5be6f5b6f0..14de4a19d8 100644 --- a/src/core/NEON/kernels/NEPoolingLayerKernel.cpp +++ b/src/core/NEON/kernels/NEPoolingLayerKernel.cpp @@ -321,7 +321,7 @@ std::pair validate_and_configure_window(ITensorInfo *input, ITen } // namespace NEPoolingLayerKernel::NEPoolingLayerKernel() - : _func(nullptr), _input(nullptr), _output(nullptr), _pool_info(), _num_elems_processed_per_iteration(0), _border_size(0), _is_square(false) + : _func(nullptr), _input(nullptr), _output(nullptr), _pool_info(), _data_layout(DataLayout::UNKNOWN), _num_elems_processed_per_iteration(0), _border_size(0), _is_square(false) { } @@ -364,14 +364,15 @@ void NEPoolingLayerKernel::configure(const ITensor *input, ITensor *output, cons ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), pool_info, pooled_w, pooled_h)); // Set instance variables - _input = input; - _output = output; - _pool_info = pool_info; - _is_square = (pool_size.x() == pool_size.y()); + _input = input; + _output = output; + _pool_info = pool_info; + _data_layout = input->info()->data_layout(); + _is_square = (pool_size.x() == pool_size.y()); // Get data type const DataType data_type = input->info()->data_type(); - const bool is_nchw = data_layout == DataLayout::NCHW; + const bool is_nchw = _data_layout == DataLayout::NCHW; if(data_type == DataType::QASYMM8) { @@ -1840,7 +1841,7 @@ void NEPoolingLayerKernel::run(const Window &window, const ThreadInfo &info) const bool exclude_padding = _pool_info.exclude_padding(); Window window_input(window); - if(_input->info()->data_layout() == DataLayout::NCHW) + if(_data_layout == DataLayout::NCHW) { // Set step for input in x and y direction for the input unsigned int window_x_inc = 0; -- cgit v1.2.1