diff --git a/src/plugins/intel_gpu/src/graph/impls/onednn/convolution_onednn.hpp b/src/plugins/intel_gpu/src/graph/impls/onednn/convolution_onednn.hpp index 8fed54a135d6eb..b01ed90ec95a0e 100644 --- a/src/plugins/intel_gpu/src/graph/impls/onednn/convolution_onednn.hpp +++ b/src/plugins/intel_gpu/src/graph/impls/onednn/convolution_onednn.hpp @@ -47,6 +47,13 @@ static std::shared_ptr get_convolutio auto weights_md = onednn::layout_to_memory_desc(weights_layout, dnnl::memory::format_tag::any); auto output_md = onednn::layout_to_memory_desc(output_layout, tag_in_out); + OPENVINO_ASSERT(!input_md.is_zero(), + "[GPU] The input memory descriptor of onednn convolution should not have zero dim."); + OPENVINO_ASSERT(!weights_md.is_zero(), + "[GPU] The weights memory descriptor of onednn convolution should not have zero dim."); + OPENVINO_ASSERT(!output_md.is_zero(), + "[GPU] The output memory descriptor of onednn convolution should not have zero dim."); + // adjust_conv_dilation_pad(dilation, stride, pad_l, pad_r, input_md, output_md, weights_md, grouped_weights); for (size_t i = 0; i < dilation.size(); i++) { dilation[i]--; diff --git a/src/plugins/intel_gpu/src/graph/layout_optimizer.cpp b/src/plugins/intel_gpu/src/graph/layout_optimizer.cpp index 7a10ca4df9f74b..864aded889b54c 100644 --- a/src/plugins/intel_gpu/src/graph/layout_optimizer.cpp +++ b/src/plugins/intel_gpu/src/graph/layout_optimizer.cpp @@ -1948,6 +1948,10 @@ void layout_optimizer::select_preferred_formats_for_onednn(program_node& node, d src_fmt = onednn::find_data_format(prim_desc.dst_desc()); } + // WA: Avoid b_fs_yx_fsv2 because Onednn tag aBcd2b is not declared. + if (src_fmt == format::b_fs_yx_fsv2) + src_fmt = format::byxf; + // WA: shallow convolution needs to set input format by bfyx. // onednn recommended byxf for input format. It will insert reorder before shallow conv. if (node.is_type() && node.get_input_layouts()[0].feature() == 3) { @@ -1980,6 +1984,9 @@ void layout_optimizer::select_preferred_formats_for_onednn(program_node& node, d node.set_preferred_input_fmt(idx, src_fmt); auto dst_fmt = onednn::find_data_format(prim_desc.dst_desc()); + // WA: Avoid b_fs_yx_fsv2 because Onednn tag aBcd2b is not declared. + if (dst_fmt == format::b_fs_yx_fsv2) + dst_fmt = format::byxf; // Errata: Best impl for shallow input conv with zero-point ops is ocl:xe_lp. if (node.is_type() && src_fmt == format::bfyx) { auto& conv = node.as(); diff --git a/src/plugins/intel_gpu/tests/unit/passes/select_preferred_formats_test.cpp b/src/plugins/intel_gpu/tests/unit/passes/select_preferred_formats_test.cpp index 2def3c9b978137..81ee021e86add8 100644 --- a/src/plugins/intel_gpu/tests/unit/passes/select_preferred_formats_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/passes/select_preferred_formats_test.cpp @@ -66,3 +66,50 @@ TEST(test_select_preferred_formats, setting_target_conv_format) { } } } + +TEST(test_select_preferred_formats, fsv2_fallback_to_byxf) { + auto& engine = get_test_engine(); + auto input = engine.allocate_memory({ data_types::f32, format::bfyx, { 1, 2, 96, 3002 } }); + auto weights = engine.allocate_memory({ data_types::f16, format::bfzyx, { 2, 32, 3, 3, 1 } }); + + // find_data_format() returns b_fs_yx_fsv2 for convolution input in the below topology. + // The b_fs_yx_fsv2 should fallback to byxf in current WA. + topology topology; + topology.add(data("weights", weights)); + topology.add(input_layout("input", input->get_layout())); + topology.add(reorder("reorder", input_info("input"), format::bfyx, data_types::f16)); + topology.add(convolution("conv1", input_info("reorder"), "weights", "", 2, {1, 1}, {1, 1}, {2, 1}, {0, 1}, true)); + + ExecutionConfig config = get_test_default_config(engine); + config.set_property(ov::intel_gpu::allow_new_shape_infer(true)); + ov::intel_gpu::ImplementationDesc impl = { format::b_fs_yx_fsv16, std::string(""), impl_types::onednn }; + config.set_property(ov::intel_gpu::force_implementations(ov::intel_gpu::ImplForcingMap{ {"conv1", impl} })); + + layout_optimizer lo(true); + auto prog = program::build_program(engine, topology, config, false, true); + + // It initializes output_layout. + // It's necessary because this test runs select_preferred_formats pass alone. + prog->get_node("conv1").get_output_layouts(false); + program_wrapper::apply_opt_pass(*prog, lo); + + ASSERT_NE(prog, nullptr); + + auto itr = prog->get_processing_order().begin(); + while (itr != prog->get_processing_order().end()) { + auto node_ptr = *itr++; + if (!node_ptr->is_type()) + continue; + + auto& node = node_ptr->as(); + auto input_fmt = node.get_preferred_input_fmt(0); + auto output_fmt = node.get_preferred_output_fmt(0); + if (engine.get_device_info().supports_immad) { + ASSERT_EQ(input_fmt, format::byxf); + ASSERT_EQ(output_fmt, format::b_fs_yx_fsv16); + } else { + ASSERT_EQ(input_fmt, format::any); + ASSERT_EQ(output_fmt, format::any); + } + } +} \ No newline at end of file