Commit 1c2e0a57 authored by Pruthvi's avatar Pruthvi Committed by Scott Cyphers

add method to conditional check for mkldnn version & use conv_auto (#2540)

* - add method to conditional check for mkl version
- use conv_auto if feature is available

* fix conditional check for mkl version

* fix typo

* - added funx to query mkldnn_version

* WIP debug

* -   added test case for conv winograd algorithm selection

* i) style fix

* - fix clang errors

* - fix clang error ( clang has issue around conditional operator)
- changes to mkldnn::utils conv_heuristics helper to return mkldnn:algorithm instead of bool value

* - add right checks based on the choosen conv algorithm in the unit test

* - utililty function to determine isa_type in unit test

* - address PR comments
- add unit test for conv_winograd and executes with CPU backend

* i) fix style ii) remove unit test

* Localize mkldnn_version() based decisions to mkldnn_utils
parent 48b14943
......@@ -243,10 +243,11 @@ mkldnn::memory::format MKLDNNEmitter::query_convolution_forward_weight_format(
mkldnn::memory::dims mkldnn_padding_below(padding_below.begin(), padding_below.end());
mkldnn::memory::dims mkldnn_padding_above(padding_above.begin(), padding_above.end());
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
mkldnn::engine cpu_engine(mkldnn::engine::cpu, 0);
mkldnn::convolution_forward::desc conv_desc_layout(
mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
input_data_desc,
weights_desc_any, // this needs to be in default format
result_desc,
......@@ -276,13 +277,13 @@ size_t MKLDNNEmitter::build_convolution_forward(const mkldnn::memory::desc& inpu
mkldnn::primitive_attr conv_attr;
conv_attr.set_post_ops(pops);
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
size_t conv_index = 0;
try
{
auto conv_prim = new mkldnn::convolution_forward(
{{mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
input_data_desc,
weights_desc,
result_desc,
......@@ -331,9 +332,10 @@ size_t
conv_attr.set_int_output_round_mode(mkldnn::round_mode::round_nearest);
/* Specify the scales array and corresponding mask */
conv_attr.set_output_scales(0, output_scale);
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
size_t conv_index = insert_primitive(new mkldnn::convolution_forward(
{{mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
input_data_desc,
weights_desc,
result_desc,
......@@ -375,9 +377,10 @@ size_t
conv_attr.set_int_output_round_mode(mkldnn::round_mode::round_nearest);
/* Specify the scales array and corresponding mask */
conv_attr.set_output_scales(0, output_scale);
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
size_t conv_index = insert_primitive(new mkldnn::convolution_forward(
{{mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
input_data_desc,
weights_desc,
bias_desc,
......@@ -415,12 +418,13 @@ size_t MKLDNNEmitter::build_convolution_forward(const mkldnn::memory::desc& inpu
mkldnn::primitive_attr conv_attr;
conv_attr.set_post_ops(pops);
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
size_t conv_index = -1;
try
{
conv_index = insert_primitive(new mkldnn::convolution_forward(
{{mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
input_data_desc,
weights_desc,
bias_desc,
......@@ -465,8 +469,9 @@ size_t MKLDNNEmitter::build_convolution_backward_weights_bias(
mkldnn::memory::dims dilation(ng_dilation_strides.begin(), ng_dilation_strides.end());
mkldnn::memory::dims padding_l(ng_padding_below.begin(), ng_padding_below.end());
mkldnn::memory::dims padding_r(ng_padding_above.begin(), ng_padding_above.end());
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
mkldnn::convolution_forward::primitive_desc fwd_pd{{mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
in_data_desc,
out_weights_delta_desc,
out_bias_delta_desc,
......@@ -478,19 +483,18 @@ size_t MKLDNNEmitter::build_convolution_backward_weights_bias(
mkldnn::padding_kind::zero},
executor::global_cpu_engine};
mkldnn::convolution_backward_weights::primitive_desc bwd_pd{
{mkldnn::algorithm::convolution_direct,
in_data_desc,
out_weights_delta_desc,
out_bias_delta_desc,
in_delta_desc,
strides,
dilation,
padding_l,
padding_r,
mkldnn::padding_kind::zero},
executor::global_cpu_engine,
fwd_pd};
mkldnn::convolution_backward_weights::primitive_desc bwd_pd{{convolution_algo,
in_data_desc,
out_weights_delta_desc,
out_bias_delta_desc,
in_delta_desc,
strides,
dilation,
padding_l,
padding_r,
mkldnn::padding_kind::zero},
executor::global_cpu_engine,
fwd_pd};
const size_t conv_index = insert_primitive(
new mkldnn::convolution_backward_weights(bwd_pd,
......@@ -544,8 +548,9 @@ size_t
size_t delta_index = build_memory_primitive(delta_desc);
size_t result_index = build_memory_primitive(result_desc);
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
size_t primitive_index = insert_primitive(new mkldnn::convolution_backward_weights(
{{mkldnn::algorithm::convolution_direct,
{{convolution_algo,
input_desc,
result_desc,
delta_desc,
......@@ -557,7 +562,7 @@ size_t
executor::global_cpu_engine,
// Forward primitive descriptor corresponding to this backward weights descriptor
{{mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
input_desc,
result_desc,
delta_desc,
......@@ -609,8 +614,9 @@ size_t MKLDNNEmitter::build_convolution_backward_data(const mkldnn::memory::desc
size_t delta_index = build_memory_primitive(delta_desc);
size_t result_index = build_memory_primitive(result_desc);
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
size_t primitive_index = insert_primitive(new mkldnn::convolution_backward_data(
{{mkldnn::algorithm::convolution_direct,
{{convolution_algo,
result_desc,
weights_desc,
delta_desc,
......@@ -622,7 +628,7 @@ size_t MKLDNNEmitter::build_convolution_backward_data(const mkldnn::memory::desc
executor::global_cpu_engine,
// Forward primitive descriptor corresponding to this backward data descriptor
{{mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
result_desc,
weights_desc,
delta_desc,
......
......@@ -1249,6 +1249,7 @@ namespace ngraph
// apart to space the elements like nGraph. So we have to subtract 1 from each pos.
Strides window_dilation_strides_adjusted;
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
for (size_t s : convolution->get_window_dilation_strides())
{
window_dilation_strides_adjusted.push_back(s - 1);
......@@ -1268,7 +1269,7 @@ namespace ngraph
auto bias_desc = mkldnn_utils::get_input_mkldnn_md(node, 2);
return mkldnn::convolution_forward::desc(
mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
data_desc,
weights_desc,
bias_desc,
......@@ -1283,7 +1284,7 @@ namespace ngraph
{
return mkldnn::convolution_forward::desc(
mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
data_desc,
weights_desc,
result_desc,
......@@ -1509,9 +1510,10 @@ namespace ngraph
}
auto delta_desc = mkldnn_utils::get_input_mkldnn_md(node, 1);
auto result_desc = mkldnn_utils::get_output_mkldnn_md(node, 0);
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
return mkldnn::convolution_backward_data::desc(
mkldnn::algorithm::convolution_direct,
convolution_algo,
result_desc,
weights_desc,
delta_desc,
......@@ -1539,13 +1541,13 @@ namespace ngraph
auto in_data_desc = mkldnn_utils::get_input_mkldnn_md(node, 0);
auto in_delta_desc = mkldnn_utils::get_input_mkldnn_md(node, 1);
auto out_weights_delta_desc = mkldnn_utils::get_output_mkldnn_md(node, 0);
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
if (has_bias<OP>())
{
auto out_bias_delta_desc = mkldnn_utils::get_output_mkldnn_md(node, 1);
return mkldnn::convolution_backward_weights::desc(
mkldnn::algorithm::convolution_direct,
convolution_algo,
in_data_desc,
out_weights_delta_desc,
out_bias_delta_desc,
......@@ -1559,7 +1561,7 @@ namespace ngraph
else
{
return mkldnn::convolution_backward_weights::desc(
mkldnn::algorithm::convolution_direct,
convolution_algo,
in_data_desc,
out_weights_delta_desc,
in_delta_desc,
......@@ -1585,6 +1587,7 @@ namespace ngraph
window_dilation_strides_adjusted.push_back(s - 1);
}
mkldnn::algorithm convolution_algo = mkldnn_utils::get_conv_algo();
if (std::is_same<OP, ngraph::op::ConvolutionBackpropData>())
{
auto weights_desc = mkldnn_utils::get_input_mkldnn_md(node, 0);
......@@ -1602,7 +1605,7 @@ namespace ngraph
return mkldnn::convolution_forward::desc(
mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
result_desc,
weights_desc,
delta_desc,
......@@ -1619,7 +1622,7 @@ namespace ngraph
auto out_weights_delta_desc = mkldnn_utils::get_output_mkldnn_md(node, 0);
return mkldnn::convolution_forward::desc(
mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
in_data_desc,
out_weights_delta_desc,
in_delta_desc,
......@@ -1638,7 +1641,7 @@ namespace ngraph
return mkldnn::convolution_forward::desc(
mkldnn::prop_kind::forward,
mkldnn::algorithm::convolution_direct,
convolution_algo,
in_data_desc,
out_weights_delta_desc,
out_bias_delta_desc,
......
......@@ -41,6 +41,20 @@ using namespace mkldnn;
using namespace ngraph;
using namespace std;
#if defined(MKLDNN_VERSION_MAJOR) && defined(MKLDNN_VERSION_MINOR) && defined(MKLDNN_VERSION_PATCH)
/** Intel(R) MKL-DNN Version type */
/* typedef struct {
int major;
int minor;
int patch;
const char *hash;
} mkldnn_version_t; */
static const mkldnn_version_t* get_mkldnn_version()
{
return mkldnn_version();
}
#endif
std::map<element::Type, const mkldnn::memory::data_type>&
runtime::cpu::mkldnn_utils::get_mkldnn_data_type_map()
{
......@@ -712,6 +726,18 @@ bool runtime::cpu::mkldnn_utils::can_use_mkldnn_batchnorm_fprop(const ngraph::No
}
}
mkldnn::algorithm runtime::cpu::mkldnn_utils::get_conv_algo()
{
#if defined(MKLDNN_VERSION_MAJOR) && defined(MKLDNN_VERSION_MINOR) && defined(MKLDNN_VERSION_PATCH)
auto mkldnn_version = get_mkldnn_version();
if (mkldnn_version->major >= 0 && mkldnn_version->minor >= 18 && mkldnn_version->patch >= 0)
{
return mkldnn::algorithm::convolution_auto;
}
#endif
return mkldnn::algorithm::convolution_direct;
}
bool runtime::cpu::mkldnn_utils::can_use_mkldnn_batchnorm_bprop(const ngraph::Node* node)
{
auto input_rank = node->get_input_shape(2).size();
......
......@@ -17,7 +17,6 @@
#pragma once
#include <mkldnn.hpp>
#include "ngraph/axis_vector.hpp"
#include "ngraph/node.hpp"
#include "ngraph/op/batch_norm.hpp"
......@@ -77,6 +76,14 @@ namespace ngraph
bool can_use_mkldnn_batchnorm_fprop(const ngraph::Node* node);
bool can_use_mkldnn_batchnorm_bprop(const ngraph::Node* node);
/*
Intel(R) MKL-DNN supports the Winograd algorithm for convolutions with the following sizes:
2D convolution (i.e. spatial depth d=1), kernel sizes kh=3,kw=3. strides sh=sw=1.
Inference - Based on convolution sizes, MKLDNN chooses between two different tile sizes F(2x2, 3x3) or
F(4x4, 3x3)(refer to Winograd paper for more informartion on tile sizes). Training - Uses F(4x4, 3x3) winograd.
*/
mkldnn::algorithm get_conv_algo();
bool use_mkldnn_kernel(const ngraph::Node* node);
void assign_mkldnn_kernel(Node* node);
......@@ -85,7 +92,6 @@ namespace ngraph
std::map<element::Type, const std::string>& get_mkldnn_data_type_string_map();
std::map<mkldnn::memory::format, const std::string>& get_mkldnn_format_string_map();
std::set<mkldnn::memory::format>& get_filter_formats();
template <typename T>
bool can_use_mkldnn_conv(ngraph::Node* node)
{
......
......@@ -391,6 +391,7 @@ namespace ngraph
const memory::desc result_desc(
mkldnn_result_shape, et_result, memory::format::any);
std::unique_ptr<convolution_forward::desc> fwd_desc{nullptr};
auto convolution_algo = mkldnn_utils::get_conv_algo();
if (use_bias)
{
memory::data_type et_bias =
......@@ -401,18 +402,17 @@ namespace ngraph
mkldnn_arg2_shape, et_bias, memory::format::any);
try
{
fwd_desc.reset(
new convolution_forward::desc(prop_kind::forward,
algorithm::convolution_direct,
input_data_desc,
weights_desc,
bias_desc, // with bias
result_desc,
mkldnn_filter_strides,
mkldnn_dilated_strides,
mkldnn_padding_below,
mkldnn_padding_above,
padding_kind::zero));
fwd_desc.reset(new convolution_forward::desc(prop_kind::forward,
convolution_algo,
input_data_desc,
weights_desc,
bias_desc, // with bias
result_desc,
mkldnn_filter_strides,
mkldnn_dilated_strides,
mkldnn_padding_below,
mkldnn_padding_above,
padding_kind::zero));
}
catch (const mkldnn::error& e)
{
......@@ -425,17 +425,16 @@ namespace ngraph
{
try
{
fwd_desc.reset(
new convolution_forward::desc(prop_kind::forward,
algorithm::convolution_direct,
input_data_desc,
weights_desc,
result_desc,
mkldnn_filter_strides,
mkldnn_dilated_strides,
mkldnn_padding_below,
mkldnn_padding_above,
padding_kind::zero));
fwd_desc.reset(new convolution_forward::desc(prop_kind::forward,
convolution_algo,
input_data_desc,
weights_desc,
result_desc,
mkldnn_filter_strides,
mkldnn_dilated_strides,
mkldnn_padding_below,
mkldnn_padding_above,
padding_kind::zero));
}
catch (const mkldnn::error& e)
{
......
......@@ -33,6 +33,8 @@
#include "ngraph/pass/manager.hpp"
#include "ngraph/pass/visualize_tree.hpp"
#include "ngraph/runtime/cpu/cpu_backend.hpp"
#include "ngraph/runtime/cpu/mkldnn_utils.hpp"
#include "ngraph/runtime/cpu/op/conv_bias.hpp"
#include "ngraph/runtime/cpu/op/convert_layout.hpp"
#include "ngraph/serializer.hpp"
#include "ngraph/util.hpp"
......@@ -945,3 +947,45 @@ TEST(cpu_test, rotated_pooling)
compare_backends(
make_f(false, false), make_f(false, false), "INTERPRETER", "CPU"); // 5D MaxPool
}
TEST(cpu_test, conv_test_winograd)
{
/* This test checks for the cpu specific graph pass handling for conv_winograd implementation.
On SKX with MKLDNN version >= v0.18.0, mkldnn_verbose should match the following
mkldnn_verbose,info,Intel(R) MKL-DNN v0.18.0 (Git Hash 863ff6e7042cec7d2e29897fe9f0872e0888b0fc),Intel(R) Advanced Vector Extensions 512 (Intel(R) AVX-512) with AVX512BW, AVX512VL, and AVX512DQ extensions
mkldnn_verbose,create,reorder,simple:any,undef,in:f32_nchw out:f32_OIhw16i16o,num:1,64x3x3x3,0.0129395
mkldnn_verbose,exec,reorder,simple:any,undef,in:f32_nchw out:f32_OIhw16i16o,num:1,64x3x3x3,0.414062
mkldnn_verbose,create,reorder,simple:any,undef,in:f32_nchw out:f32_nChw16c,num:1,64x3x224x224,0.0119629
mkldnn_verbose,exec,reorder,simple:any,undef,in:f32_nchw out:f32_nChw16c,num:1,64x3x224x224,19.302
mkldnn_verbose,create,convolution,jit_wino_4x3:avx512_core,forward_training,fsrc:nChw16c fwei:OIhw16i16o fbia:undef fdst:nChw16c,alg:convolution_winograd,mb64_ic3oc64_ih224oh224kh3sh1dh0ph1_iw224ow224kw3sw1dw0pw1,1.84106
mkldnn_verbose,exec,convolution,jit_wino_4x3:avx512_core,forward_training,fsrc:nChw16c fwei:OIhw16i16o fbia:undef fdst:nChw16c,alg:convolution_winograd,mb64_ic3oc64_ih224oh224kh3sh1dh0ph1_iw224ow224kw3sw1dw0pw1,46.6631
mkldnn_verbose,create,reorder,jit:uni,undef,in:f32_nChw16c out:f32_nchw,num:1,64x64x224x224,0.279053
mkldnn_verbose,exec,reorder,jit:uni,undef,in:f32_nChw16c out:f32_nchw,num:1,64x64x224x224,100.219
*/
auto make_function = []() -> std::shared_ptr<Function> {
auto input = make_shared<op::Parameter>(element::f32, Shape{64, 3, 224, 224});
auto filter = make_shared<op::Parameter>(element::f32, Shape{64, 3, 3, 3});
auto conv = make_shared<op::Convolution>(input,
filter,
Strides{1, 1},
Strides{1, 1},
CoordinateDiff{1, 1},
CoordinateDiff{1, 1},
Strides{1, 1});
return make_shared<Function>(conv, ParameterVector{input, filter});
};
auto backend = runtime::Backend::create("CPU");
auto cpu_f = make_function();
test::Uniform<float> rng(-100.0f, 100.0f);
vector<vector<float>> args;
for (shared_ptr<op::Parameter> param : cpu_f->get_parameters())
{
vector<float> tensor_val(shape_size(param->get_shape()));
rng.initialize(tensor_val);
args.push_back(tensor_val);
}
auto cpu_results = execute(cpu_f, args, "CPU");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment