| 181 | ClWinogradConv2d::~ClWinogradConv2d() = default; |
| 182 | |
| 183 | void ClWinogradConv2d::configure(const ClCompileContext &compile_context, |
| 184 | ITensorInfo *src, |
| 185 | ITensorInfo *weights, |
| 186 | ITensorInfo *biases, |
| 187 | ITensorInfo *dst, |
| 188 | const PadStrideInfo &conv_info, |
| 189 | const ActivationLayerInfo &act_info, |
| 190 | bool enable_fast_math) |
| 191 | { |
| 192 | ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(src, weights, biases, dst, conv_info, act_info, enable_fast_math)); |
| 193 | ARM_COMPUTE_LOG_PARAMS(src, weights, biases, dst, conv_info, act_info, enable_fast_math); |
| 194 | |
| 195 | // Get indices for the width and height |
| 196 | const size_t idx_width = get_data_layout_dimension_index(src->data_layout(), DataLayoutDimension::WIDTH); |
| 197 | const size_t idx_height = get_data_layout_dimension_index(src->data_layout(), DataLayoutDimension::HEIGHT); |
| 198 | |
| 199 | // Input shape, kernel size and output tile |
| 200 | const Size2D input_dims = Size2D(src->tensor_shape()[idx_width], src->tensor_shape()[idx_height]); |
| 201 | const Size2D kernel_size = Size2D(weights->tensor_shape()[idx_width], weights->tensor_shape()[idx_height]); |
| 202 | const Size2D output_tile = winograd_output_tile(input_dims, kernel_size, src->data_layout()); |
| 203 | |
| 204 | // Check if the Winograd configuration requires fast math |
| 205 | if (!enable_fast_math) |
| 206 | { |
| 207 | ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(src, 1, |
| 208 | DataType::F32); //disable winograd for fp16 if fast math is false. |
| 209 | ARM_COMPUTE_ERROR_ON_MSG(check_support_fast_math(output_tile, kernel_size), |
| 210 | "This Winograd configuration requires enable_fast_math=true"); |
| 211 | } |
| 212 | const WinogradInfo winograd_info = |
| 213 | WinogradInfo(output_tile, kernel_size, input_dims, conv_info, src->data_layout()); |
| 214 | |
| 215 | _is_prepared = false; |
| 216 | |
| 217 | // Configure input transform |
| 218 | _input_transform->configure(compile_context, src, &_input0, winograd_info); |
| 219 | _border_handler.configure(compile_context, src, _input_transform->border_size(), BorderMode::CONSTANT, |
| 220 | PixelValue()); |
| 221 | |
| 222 | // Configure filter transform |
| 223 | _filter_transform->configure(compile_context, weights, &_input1, winograd_info); |
| 224 | |
| 225 | // Configure batched matrix multiply |
| 226 | _batched_mm.configure(compile_context, &_input0, &_input1, nullptr, &_batched_mm_output, 1.0f, 0.0f, |
| 227 | GEMMInfo(false, false, true /* Reshape weights only for the first run*/, 0, false, false, |
| 228 | GEMMLowpOutputStageInfo(), (src->data_type() == DataType::F16))); |
| 229 | |
| 230 | // Configure output transform |
| 231 | _output_transform->set_target(CLScheduler::get().target()); |
| 232 | _output_transform->configure(compile_context, &_batched_mm_output, biases, dst, winograd_info, act_info); |
| 233 | |
| 234 | _aux_mem = _batched_mm.workspace(); |
| 235 | const MemoryLifetime wino_wei_lifetm = |
| 236 | std::any_of(std::begin(_aux_mem), std::end(_aux_mem), |
| 237 | [](const auto &r) { return (r.lifetime == MemoryLifetime::Persistent) && (r.size > 0); }) |
| 238 | ? MemoryLifetime::Prepare |
| 239 | : MemoryLifetime::Persistent; |
| 240 | _aux_mem.push_back(MemoryInfo(offset_int_vec(2), MemoryLifetime::Temporary, _input0.total_size())); |
nothing calls this directly
no test coverage detected