diff --git a/src/plugins/intel_gpu/src/graph/graph_optimizer/add_required_reorders.cpp b/src/plugins/intel_gpu/src/graph/graph_optimizer/add_required_reorders.cpp index 5f39d55342b..a11964c3878 100644 --- a/src/plugins/intel_gpu/src/graph/graph_optimizer/add_required_reorders.cpp +++ b/src/plugins/intel_gpu/src/graph/graph_optimizer/add_required_reorders.cpp @@ -27,11 +27,14 @@ If not than required reorder is added to the network. /* Add a reorder in between node and usr */ -void add_required_reorders::add_reorder(program& p, program_node* node, program_node* usr) { +void add_required_reorders::add_reorder(program& p, program_node* node, program_node* usr, bool keep_original_dt) { layout reorder_layout = node->get_output_layout(); reorder_layout.format = usr->get_output_layout().format; reorder_layout.data_type = usr->get_output_layout().data_type; + if (keep_original_dt) + reorder_layout.data_type = node->get_output_layout().data_type; + auto new_reorder = std::make_shared(node->id() + "_reorder_" + usr->id(), node->id(), reorder_layout); auto& new_reorder_node = p.get_or_create(new_reorder); new_reorder_node.set_output_layout(reorder_layout, false); @@ -376,8 +379,16 @@ void add_required_reorders::run(program& p) { continue; } - if (usr->get_output_layout() != node.first->get_output_layout()) - add_reorder(p, node.first, usr); + if (usr->get_output_layout() != node.first->get_output_layout()) { + // Preserve original data type to prevent Convolution input data type from changing + // in the following sequence: Node(U8, unsupported format) -> Conv(FP16, bfyx). + // Without this condition, inserted reorder will change Conv's input to FP16, instead of + // expected U8 format. + bool keep_original_dt = false; + if (usr->is_type()) + keep_original_dt = true; + add_reorder(p, node.first, usr, keep_original_dt); + } } } } diff --git a/src/plugins/intel_gpu/src/graph/include/pass_manager.h b/src/plugins/intel_gpu/src/graph/include/pass_manager.h index 2ea466764d5..de9ec170096 100644 --- a/src/plugins/intel_gpu/src/graph/include/pass_manager.h +++ b/src/plugins/intel_gpu/src/graph/include/pass_manager.h @@ -57,7 +57,7 @@ public: private: void run(program& p) override; - void add_reorder(program& p, program_node* node, program_node* usr); + void add_reorder(program& p, program_node* node, program_node* usr, bool keep_original_dt = false); }; class add_reshape_to_primitives : public base_pass { diff --git a/src/plugins/intel_gpu/tests/unit/passes/add_required_reorders_test.cpp b/src/plugins/intel_gpu/tests/unit/passes/add_required_reorders_test.cpp index 75a955155ed..cb65717800d 100644 --- a/src/plugins/intel_gpu/tests/unit/passes/add_required_reorders_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/passes/add_required_reorders_test.cpp @@ -116,6 +116,37 @@ TEST(add_required_reorders, eltwise_input_reorder) { ASSERT_EQ(eltwise_node.get_output_layout().format, format::bfzyx); } +TEST(add_required_reorders, prevent_input_dt_changing_for_convs) { + auto& engine = get_test_engine(); + + int input_b = 1, input_f = 16, input_y = 3, input_x = 3; + int output_b = input_b, output_f = 16, output_y = 6, output_x = 6; + + auto input_mem = engine.allocate_memory({ {input_b, input_f, input_y, input_x}, data_types::u8, format::bs_fs_yx_bsv16_fsv32 }); + auto input2_mem = engine.allocate_memory({ {input_b, input_f, input_y, input_x}, data_types::u8, format::bs_fs_yx_bsv16_fsv32 }); + auto weights_mem = engine.allocate_memory({ {16, 16, 1, 1}, data_types::i8, format::bfyx }); + + auto input = input_layout("input", input_mem->get_layout()); + auto input_const = data("input_const", input2_mem); + auto weights = data("weights", weights_mem); + auto eltwise1 = eltwise("eltwise1", input_info("input"), input_info("input_const"), eltwise_mode::sum); + auto conv1 = convolution("conv1", input_info("eltwise1"), "weights", "", 1, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 2, 2 }, false); + auto output_reorder = reorder("reorder", input_info("conv1"), { data_types::f32, format::bfyx, { output_b, output_f, output_y, output_x } }); + + topology topology_test(input, input_const, eltwise1, weights, conv1, output_reorder); + + ExecutionConfig config_test = get_test_default_config(engine); + ov::intel_gpu::ImplementationDesc conv1_impl_test = { format::bfyx, "", impl_types::ocl }; + config_test.set_property(ov::intel_gpu::force_implementations(ov::intel_gpu::ImplForcingMap{ { "conv1", conv1_impl_test } })); + + auto prog = program::build_program(engine, topology_test, config_test, false, true); + program_wrapper::apply_opt_pass(*prog); + + ASSERT_NE(prog, nullptr); + ASSERT_TRUE(prog->has_node("conv1")); + ASSERT_EQ(prog->get_node("conv1").get_input_layout(0).data_type, data_types::u8); +} + TEST(add_required_reorders, skip_adding_reorder_batch_axis_padding) { auto& engine = get_test_engine();