|
| 1 | +// Copyright (C) 2024 Intel Corporation |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | +// |
| 4 | + |
| 5 | +#include "impls/cpu/cpu_impl_helpers.hpp" |
| 6 | +#include "register.hpp" |
| 7 | +#include "resample_inst.h" |
| 8 | +#include "impls/registry/implementation_map.hpp" |
| 9 | + |
| 10 | +#include "openvino/op/interpolate.hpp" |
| 11 | + |
| 12 | +#include <algorithm> |
| 13 | +#include <string> |
| 14 | +#include <vector> |
| 15 | +#include <utility> |
| 16 | + |
| 17 | +namespace cldnn { |
| 18 | +namespace cpu { |
| 19 | + |
| 20 | +namespace { |
| 21 | + |
| 22 | + |
| 23 | + |
| 24 | +} // namespace |
| 25 | + |
| 26 | +struct resample_impl : public typed_primitive_impl<resample> { |
| 27 | + using parent = typed_primitive_impl<resample>; |
| 28 | + using parent::parent; |
| 29 | + |
| 30 | + using InterpolateMode = ov::op::v4::Interpolate::InterpolateMode; |
| 31 | + using CoordinateTransformMode = ov::op::v4::Interpolate::CoordinateTransformMode; |
| 32 | + using Nearest_mode = ov::op::v4::Interpolate::NearestMode; |
| 33 | + using InterpolateAttrs = ov::op::v4::Interpolate::InterpolateAttrs; |
| 34 | + using ShapeCalcMode = ov::op::v4::Interpolate::ShapeCalcMode; |
| 35 | + |
| 36 | + std::shared_ptr<ov::op::Op> op; |
| 37 | + |
| 38 | + std::vector<int64_t> sizes; |
| 39 | + std::vector<float> scales; |
| 40 | + std::vector<int64_t> axes; |
| 41 | + std::vector<size_t> pads_begin; |
| 42 | + std::vector<size_t> pads_end; |
| 43 | + InterpolateMode operation_type = InterpolateMode::LINEAR; |
| 44 | + ShapeCalcMode shape_calc_mode = ShapeCalcMode::SIZES; |
| 45 | + int32_t antialias = 0; |
| 46 | + float cube_coeff = -0.75f; |
| 47 | + CoordinateTransformMode coord_trans_mode = CoordinateTransformMode::HALF_PIXEL; |
| 48 | + Nearest_mode round_mode = Nearest_mode::ROUND_PREFER_FLOOR; |
| 49 | + |
| 50 | + DECLARE_OBJECT_TYPE_SERIALIZATION(cldnn::cpu::resample_impl) |
| 51 | + |
| 52 | + std::unique_ptr<primitive_impl> clone() const override { |
| 53 | + return make_unique<resample_impl>(*this); |
| 54 | + } |
| 55 | + |
| 56 | + resample_impl() : parent("resample_cpu_impl") {} |
| 57 | + |
| 58 | + explicit resample_impl(const resample_node& outer) { |
| 59 | + set_node_params(outer); |
| 60 | + } |
| 61 | + |
| 62 | + void set_node_params(const program_node& arg) override { |
| 63 | + OPENVINO_ASSERT(arg.is_type<resample>(), "[GPU] Incorrect program_node type"); |
| 64 | + const auto& node = arg.as<resample>(); |
| 65 | + |
| 66 | + sizes = node.get_primitive()->sizes; |
| 67 | + scales = node.get_primitive()->scales; |
| 68 | + axes = node.get_primitive()->axes; |
| 69 | + |
| 70 | + pads_begin = node.get_primitive()->pads_begin; |
| 71 | + pads_end = node.get_primitive()->pads_end; |
| 72 | + operation_type = node.get_primitive()->operation_type; |
| 73 | + shape_calc_mode = node.get_primitive()->shape_calc_mode; |
| 74 | + antialias = node.get_primitive()->antialias; |
| 75 | + cube_coeff = node.get_primitive()->cube_coeff; |
| 76 | + coord_trans_mode = node.get_primitive()->coord_trans_mode; |
| 77 | + round_mode = node.get_primitive()->round_mode; |
| 78 | + } |
| 79 | + |
| 80 | + // void save(BinaryOutputBuffer& ob) const override { |
| 81 | + // parent::save(ob); |
| 82 | + // ob << make_data(&mode, sizeof(eltwise_mode)); |
| 83 | + // ob << coefficients; |
| 84 | + // } |
| 85 | + |
| 86 | + // void load(BinaryInputBuffer& ib) override { |
| 87 | + // parent::load(ib); |
| 88 | + // ib >> make_data(&mode, sizeof(eltwise_mode)); |
| 89 | + // ib >> coefficients; |
| 90 | + // } |
| 91 | + |
| 92 | + event::ptr execute_impl(const std::vector<event::ptr>& events, resample_inst& instance) override { |
| 93 | + OV_ITT_SCOPED_TASK(ov::intel_gpu::itt::domains::intel_gpu_plugin, "resample::execute_impl"); |
| 94 | + auto& stream = instance.get_network().get_stream(); |
| 95 | + |
| 96 | + const bool pass_through_events = (stream.get_queue_type() == QueueTypes::out_of_order) && instance.all_dependencies_cpu_impl(); |
| 97 | + |
| 98 | + if (!pass_through_events) { |
| 99 | + stream.wait_for_events(events); |
| 100 | + } |
| 101 | + |
| 102 | + auto params = instance.get_impl_params(); |
| 103 | + |
| 104 | + // Set input tensors |
| 105 | + ov::TensorVector input_host_tensors; |
| 106 | + auto input_mem_ptr = instance.input_memory_ptr(); |
| 107 | + cldnn::mem_lock<uint8_t, mem_lock_type::read> input_lock(input_mem_ptr, stream); |
| 108 | + |
| 109 | + for (size_t i = 0; i < params->input_layouts.size(); i++) { |
| 110 | + auto input_tensor = make_tensor(params->input_layouts[0], input_lock.data()); |
| 111 | + input_host_tensors.push_back(input_tensor); |
| 112 | + } |
| 113 | + |
| 114 | + if (input_host_tensors.size() == 1) { |
| 115 | + auto target_shape_sizes = params->output_layouts[0].get_tensor().sizes(); |
| 116 | + std::vector<int64_t> target_shape_ps; |
| 117 | + for (size_t i = 0; i < axes.size(); i++) |
| 118 | + target_shape_ps.push_back(target_shape_sizes[i]); |
| 119 | + |
| 120 | + auto target_shape_tensor = ov::Tensor(ov::element::i32, {target_shape_ps.size()}, target_shape_ps.data()); |
| 121 | + input_host_tensors.push_back(target_shape_tensor); |
| 122 | + |
| 123 | + if (shape_calc_mode == ov::op::util::InterpolateBase::ShapeCalcMode::SIZES) { |
| 124 | + auto new_scales = scales; |
| 125 | + auto input_shape_sizes = params->input_layouts[0].get_tensor().sizes(); |
| 126 | + for (size_t i = 0; i < sizes.size(); i++) |
| 127 | + new_scales[i] = sizes[i] / input_shape_sizes[i]; |
| 128 | + |
| 129 | + auto scales_tensor = ov::Tensor(ov::element::f32, {new_scales.size()}, new_scales.data()); |
| 130 | + input_host_tensors.push_back(scales_tensor); |
| 131 | + shape_calc_mode = ov::op::util::InterpolateBase::ShapeCalcMode::SCALES; |
| 132 | + } else if (shape_calc_mode == ov::op::util::InterpolateBase::ShapeCalcMode::SCALES) { |
| 133 | + auto scales_tensor = ov::Tensor(ov::element::f32, {scales.size()}, scales.data()); |
| 134 | + input_host_tensors.push_back(scales_tensor); |
| 135 | + } else { |
| 136 | + OPENVINO_ASSERT(false, "[GPU] Not supported Interpolate ShapeCalcMode", instance.id()); |
| 137 | + } |
| 138 | + |
| 139 | + auto axes_tensor = ov::Tensor(ov::element::i64, {axes.size()}, axes.data()); |
| 140 | + input_host_tensors.push_back(axes_tensor); |
| 141 | + } |
| 142 | + |
| 143 | + // set output tensors |
| 144 | + ov::TensorVector output_host_tensors; |
| 145 | + auto output_mem_ptr = instance.output_memory_ptr(); |
| 146 | + cldnn::mem_lock<uint8_t, mem_lock_type::write> output_lock(output_mem_ptr, stream); |
| 147 | + |
| 148 | + auto output_tensor = make_tensor(params->output_layouts[0], output_lock.data()); |
| 149 | + output_host_tensors.push_back(output_tensor); |
| 150 | + |
| 151 | + // Set Attrs |
| 152 | + InterpolateAttrs attrs; |
| 153 | + attrs.mode = operation_type; |
| 154 | + attrs.shape_calculation_mode = shape_calc_mode; |
| 155 | + attrs.pads_begin = pads_begin; |
| 156 | + attrs.pads_end = pads_end; |
| 157 | + attrs.coordinate_transformation_mode = coord_trans_mode; |
| 158 | + attrs.nearest_mode = round_mode; |
| 159 | + attrs.antialias = antialias; |
| 160 | + attrs.cube_coeff = cube_coeff; |
| 161 | + |
| 162 | + if (!op) { |
| 163 | + auto interp = std::make_shared<ov::op::v4::Interpolate>(); |
| 164 | + interp->set_attrs(attrs); |
| 165 | + op = interp; |
| 166 | + } |
| 167 | + |
| 168 | + OPENVINO_ASSERT(op->evaluate(output_host_tensors, input_host_tensors), |
| 169 | + "[GPU] Couldn't execute resample primitive with id ", instance.id()); |
| 170 | + |
| 171 | + if (pass_through_events) { |
| 172 | + return stream.group_events(events); |
| 173 | + } |
| 174 | + |
| 175 | + return make_output_event(stream, instance.is_output()); |
| 176 | + } |
| 177 | + |
| 178 | + void init_kernels(const kernels_cache& , const kernel_impl_params&) override {} |
| 179 | + |
| 180 | + void update(primitive_inst& inst, const kernel_impl_params& impl_param) override {} |
| 181 | + |
| 182 | +public: |
| 183 | + static std::unique_ptr<primitive_impl> create(const resample_node& arg, const kernel_impl_params& impl_param) { |
| 184 | + return make_unique<resample_impl>(); |
| 185 | + } |
| 186 | +}; |
| 187 | + |
| 188 | + |
| 189 | +namespace detail { |
| 190 | + |
| 191 | +attach_resample_impl::attach_resample_impl() { |
| 192 | + auto formats = { |
| 193 | + format::bfyx, |
| 194 | + }; |
| 195 | + |
| 196 | + auto types = { |
| 197 | + data_types::f32, |
| 198 | + }; |
| 199 | + |
| 200 | + implementation_map<resample>::add(impl_types::cpu, shape_types::static_shape, resample_impl::create, types, formats); |
| 201 | + implementation_map<resample>::add(impl_types::cpu, shape_types::dynamic_shape, resample_impl::create, types, formats); |
| 202 | +} |
| 203 | + |
| 204 | +} // namespace detail |
| 205 | +} // namespace cpu |
| 206 | +} // namespace cldnn |
| 207 | + |
| 208 | +BIND_BINARY_BUFFER_WITH_TYPE(cldnn::cpu::resample_impl) |
0 commit comments