Skip to content

Commit

Permalink
[GPU] Implement fake_convert
Browse files Browse the repository at this point in the history
* add func test for fake convert
  • Loading branch information
ahnyoung-paul committed Dec 13, 2024
1 parent 69256c8 commit e575c22
Show file tree
Hide file tree
Showing 13 changed files with 534 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/core/include/openvino/op/fake_convert.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ class OPENVINO_API FakeConvert : public Op {
std::string get_destination_type() const;
const ov::element::Type& get_destination_element_type() const;

void set_destination_type(ov::element::Type destination_type) {
m_destination_type = destination_type;
}

private:
void validate_destination_type() const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ REGISTER_FACTORY(v13, ScaledDotProductAttention);
REGISTER_FACTORY(v13, BitwiseAnd);
REGISTER_FACTORY(v13, BitwiseOr);
REGISTER_FACTORY(v13, BitwiseXor);
REGISTER_FACTORY(v13, FakeConvert);

// ------------------------------ Supported v15 ops ----------------------------- //
REGISTER_FACTORY(v15, ROIAlignRotated);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once
#include "primitive.hpp"
#include <vector>

namespace cldnn {

/// @brief Returns shape of input primitive.
struct fake_convert : public primitive_base<fake_convert> {
CLDNN_DECLARE_PRIMITIVE(fake_convert)

fake_convert() : primitive_base("", {}) {}

/// @brief Constructs fake_convert primitive.
/// @param id This primitive id.
/// @param input Input primitive id.
/// @param output_data_type type of output values. can be i32 and i64.
fake_convert(const primitive_id& id,
const input_info& input,
const input_info& scale,
const input_info& shift,
std::string destination_type = "f8e4m3")
: primitive_base(id, {input, scale, shift}, 1), destination_type(destination_type) {}

fake_convert(const primitive_id& id,
const input_info& input,
const input_info& scale,
std::string destination_type = "f8e4m3")
: primitive_base(id, {input, scale}, 1), destination_type(destination_type) {}

std::string destination_type;

size_t hash() const override {
size_t seed = primitive::hash();
seed = hash_combine(seed, destination_type);
return seed;
}

bool operator==(const primitive& rhs) const override {
if (!compare_common_params(rhs))
return false;
auto rhs_casted = downcast<const fake_convert>(rhs);
return (destination_type == rhs_casted.destination_type);
}

void save(BinaryOutputBuffer& ob) const override {
primitive_base<fake_convert>::save(ob);
ob << destination_type;
}

void load(BinaryInputBuffer& ib) override {
primitive_base<fake_convert>::load(ib);
ib >> destination_type;
}
};
} // namespace cldnn
70 changes: 70 additions & 0 deletions src/plugins/intel_gpu/src/graph/fake_convert.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "fake_convert_inst.h"
#include "fake_convert_shape_inference.hpp"

#include "primitive_type_base.h"
#include "intel_gpu/runtime/error_handler.hpp"
#include "json_object.h"
#include <string>

namespace cldnn {
GPU_DEFINE_PRIMITIVE_TYPE_ID(fake_convert)

layout fake_convert_inst::calc_output_layout(fake_convert_node const& node, kernel_impl_params const& impl_param) {
return calc_output_layouts<ov::PartialShape>(node, impl_param)[0];
}

template<typename ShapeType>
std::vector<layout> fake_convert_inst::calc_output_layouts(fake_convert_node const& node, kernel_impl_params const& impl_param) {
auto desc = impl_param.typed_desc<fake_convert>();
auto input_layout = impl_param.get_input_layout(0);
auto scale_layout = impl_param.get_input_layout(1);
auto output_type = input_layout.data_type;
auto output_format = input_layout.format;

ov::op::v13::FakeConvert op;

std::vector<ShapeType> input_shapes = {
input_layout.get<ShapeType>(),
scale_layout.get<ShapeType>()
};
if (impl_param.input_layouts.size() == 3) {
auto shift_layout = impl_param.get_input_layout(2);
input_shapes.push_back(shift_layout.get<ShapeType>());
}
std::vector<ShapeType> output_shapes = ov::op::v13::shape_infer(&op, input_shapes);

return { layout{output_shapes[0], output_type, output_format} };
}

template std::vector<layout> fake_convert_inst::calc_output_layouts<ov::PartialShape>(fake_convert_node const& node, const kernel_impl_params& impl_param);

std::string fake_convert_inst::to_string(fake_convert_node const& node) {
auto desc = node.get_primitive();
auto node_info = node.desc_to_json();
auto& input = node.input();
auto& scale = node.scale();

std::stringstream primitive_description;

json_composite fake_convert_info;
fake_convert_info.add("input id", input.id());
fake_convert_info.add("scale id", scale.id());
if (node.has_shift()) {
fake_convert_info.add("shift id", node.shift().id());
}
fake_convert_info.add("destination_type", node.get_destination_type());

node_info->add("fake_convert info", fake_convert_info);
node_info->dump(primitive_description);

return primitive_description.str();
}

fake_convert_inst::typed_primitive_inst(network& network, fake_convert_node const& node)
: parent(network, node) {}

} // namespace cldnn
134 changes: 134 additions & 0 deletions src/plugins/intel_gpu/src/graph/impls/cpu/fake_convert.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "impls/cpu/cpu_impl_helpers.hpp"
#include "register.hpp"
#include "fake_convert_inst.h"
#include "impls/registry/implementation_map.hpp"

#include "openvino/op/fake_convert.hpp"

namespace cldnn {
namespace cpu {

struct fake_convert_impl : public typed_primitive_impl<fake_convert> {
using parent = typed_primitive_impl<fake_convert>;
using parent::parent;

std::string destination_type;

std::shared_ptr<ov::op::v13::FakeConvert> op;

DECLARE_OBJECT_TYPE_SERIALIZATION(cldnn::cpu::fake_convert_impl)

std::unique_ptr<primitive_impl> clone() const override {
return make_unique<fake_convert_impl>(*this);
}

fake_convert_impl() : parent("fake_convert_cpu_impl") {}

explicit fake_convert_impl(const fake_convert_node& outer) {
set_node_params(outer);
}

void set_node_params(const program_node& arg) override {
OPENVINO_ASSERT(arg.is_type<fake_convert>(), "[GPU] Incorrect program_node type");
const auto& node = arg.as<fake_convert>();
destination_type = node.get_destination_type();
}

void save(BinaryOutputBuffer& ob) const override {
parent::save(ob);
ob << destination_type;
}

void load(BinaryInputBuffer& ib) override {
parent::load(ib);
ib >> destination_type;
}

event::ptr execute_impl(const std::vector<event::ptr>& events, fake_convert_inst& instance) override {
OV_ITT_SCOPED_TASK(ov::intel_gpu::itt::domains::intel_gpu_plugin, "fake_convert::execute_impl");
auto& stream = instance.get_network().get_stream();

const bool pass_through_events = (stream.get_queue_type() == QueueTypes::out_of_order) && instance.all_dependencies_cpu_impl();

if (!pass_through_events) {
stream.wait_for_events(events);
}

auto params = instance.get_impl_params();

ov::TensorVector input_host_tensors;
ov::TensorVector output_host_tensors;

if (!op) {
op = std::make_shared<ov::op::v13::FakeConvert>();
op->set_destination_type(ov::element::Type(destination_type));
}

std::vector<memory::ptr> input_mem_ptrs;
for (size_t i = 0; i < instance.dependencies().size(); i++)
input_mem_ptrs.push_back(instance.dep_memory_ptr(i));

auto output_mem_ptr = instance.output_memory_ptr();

cldnn::mem_lock<uint8_t, mem_lock_type::read> output_lock(output_mem_ptr, stream);

for (size_t i = 0; i < input_mem_ptrs.size(); i++)
input_host_tensors.push_back(make_tensor(params->input_layouts[i], input_mem_ptrs[i]->lock(stream, mem_lock_type::read)));

output_host_tensors.push_back(make_tensor(params->output_layouts[0], output_lock.data()));

OPENVINO_ASSERT(op->evaluate(output_host_tensors, input_host_tensors),
"[GPU] Couldn't execute fake_convert primitive with id ", instance.id());

if (pass_through_events) {
return stream.group_events(events);
}

return make_output_event(stream, instance.is_output());
}

void init_kernels(const kernels_cache& , const kernel_impl_params&) override {}

void update(primitive_inst& inst, const kernel_impl_params& impl_param) override {}

public:
static std::unique_ptr<primitive_impl> create(const fake_convert_node& arg, const kernel_impl_params& impl_param) {
return make_unique<fake_convert_impl>();
}
};


namespace detail {

attach_fake_convert_impl::attach_fake_convert_impl() {
auto formats = {
format::bfyx,
format::bfzyx,
format::bfwzyx,
format::bfuwzyx,
format::bfvuwzyx,
};

auto types = {
data_types::f32,
data_types::f16,
data_types::i32,
data_types::i64,
data_types::i8,
data_types::u8,
};

implementation_map<fake_convert>::add(impl_types::cpu, shape_types::static_shape, fake_convert_impl::create, types, formats);
implementation_map<fake_convert>::add(impl_types::cpu, shape_types::dynamic_shape, fake_convert_impl::create, types, formats);
}

} // namespace detail
} // namespace cpu
} // namespace cldnn

BIND_BINARY_BUFFER_WITH_TYPE(cldnn::cpu::fake_convert_impl)
BIND_BINARY_BUFFER_WITH_TYPE(cldnn::fake_convert)
1 change: 1 addition & 0 deletions src/plugins/intel_gpu/src/graph/impls/cpu/register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void register_implementations() {
REGISTER_CPU(tile);
REGISTER_CPU(select);
REGISTER_CPU(reduce);
REGISTER_CPU(fake_convert);
}

} // namespace cpu
Expand Down
1 change: 1 addition & 0 deletions src/plugins/intel_gpu/src/graph/impls/cpu/register.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ REGISTER_CPU(broadcast);
REGISTER_CPU(tile);
REGISTER_CPU(select);
REGISTER_CPU(reduce);
REGISTER_CPU(fake_convert);

#undef REGISTER_CPU

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "registry.hpp"
#include "intel_gpu/primitives/fake_convert.hpp"
#include "primitive_inst.h"

namespace ov {
namespace intel_gpu {

using namespace cldnn;

const std::vector<std::shared_ptr<cldnn::ImplementationManager>>& Registry<fake_convert>::get_implementations() {
static const std::vector<std::shared_ptr<ImplementationManager>> impls = {
OV_GPU_GET_INSTANCE_CPU(fake_convert, shape_types::static_shape)
OV_GPU_GET_INSTANCE_CPU(fake_convert, shape_types::dynamic_shape)
};

return impls;
}

} // namespace intel_gpu
} // namespace ov
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ REGISTER_IMPLS(scatter_elements_update);
REGISTER_IMPLS(shape_of);
REGISTER_IMPLS(strided_slice);
REGISTER_IMPLS(tile);
REGISTER_IMPLS(fake_convert);

REGISTER_DEFAULT_IMPLS(assign, CPU_S, CPU_D);
REGISTER_DEFAULT_IMPLS(read_value, CPU_S, CPU_D);
Expand Down
55 changes: 55 additions & 0 deletions src/plugins/intel_gpu/src/graph/include/fake_convert_inst.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once
#include "intel_gpu/primitives/fake_convert.hpp"
#include "primitive_inst.h"

#include <memory>
#include <string>

namespace cldnn {

template <>
struct typed_program_node<fake_convert> : public typed_program_node_base<fake_convert> {
using parent = typed_program_node_base<fake_convert>;
typed_program_node(const std::shared_ptr<fake_convert> prim, program& prog)
: parent(prim, prog), destination_type(prim->destination_type) {
support_padding_all(true);
}

public:
using parent::parent;

program_node& input() const { return get_dependency(0); }
program_node& scale() const { return get_dependency(1); }
program_node& shift() const { return get_dependency(2); }
bool has_shift() const { return (get_dependencies().size() == 3); }

std::string get_destination_type() const { return destination_type; }

std::vector<size_t> get_shape_infer_dependencies() const override { return {}; }

private:
std::string destination_type;
};

using fake_convert_node = typed_program_node<fake_convert>;

template <>
class typed_primitive_inst<fake_convert> : public typed_primitive_inst_base<fake_convert> {
using parent = typed_primitive_inst_base<fake_convert>;
using parent::parent;

public:
template<typename ShapeType>
static std::vector<layout> calc_output_layouts(fake_convert_node const& /*node*/, const kernel_impl_params& impl_param);
static layout calc_output_layout(fake_convert_node const& node, kernel_impl_params const& impl_param);
static std::string to_string(fake_convert_node const& node);

typed_primitive_inst(network& network, fake_convert_node const& node);
};

using fake_convert_inst = typed_primitive_inst<fake_convert>;
} // namespace cldnn
Loading

0 comments on commit e575c22

Please sign in to comment.