Commit 15babf5e authored by Louis Feng's avatar Louis Feng Committed by Jai Menon

NGMX-275 MKLDNN convolution backprop (#485)

* Squashed commit of the following:

commit 5fdd89a8529743f05e84f837f64816f527506ff4
Merge: 9405cba3 90640854
Author: Louis Feng <louis.feng@intel.com>
Date:   Sun Feb 11 10:10:35 2018 -0800

    Merge branch 'master' into louisfeng/NGMX-275

commit 9405cba3c93b9ed7f61e2b7e28c47c5a1f95882a
Author: Louis Feng <louis.feng@intel.com>
Date:   Sun Feb 11 10:03:34 2018 -0800

    refactor with new policy.

commit ee3a1fb007fd9ba7a6b687391381900ad81fbce3
Author: Louis Feng <louis.feng@intel.com>
Date:   Sat Feb 10 23:49:16 2018 -0800

    added scoped emitter util.

commit 0ec93d0f3a62f7ada4aad1242a14ff34670c0512
Author: Louis Feng <louis.feng@intel.com>
Date:   Sat Feb 10 01:10:57 2018 -0800

    refactored common code.

commit 8acb3e10cb0328425a25688fe8f1d485c46a3892
Merge: 1835daf3 8d938e32
Author: Louis Feng <louis.feng@intel.com>
Date:   Fri Feb 9 21:59:55 2018 -0800

    Merge branch 'master' into louisfeng/NGMX-275

commit 1835daf3fe8bfcfa4dae41dc64249c15f0d2550c
Author: Louis Feng <louis.feng@intel.com>
Date:   Fri Feb 9 21:59:35 2018 -0800

    fixed errors.

commit 0eb5b34edc5c2035bf4bd929a467bfbdda231640
Merge: 35422d27 9918436d
Author: Louis Feng <louis.feng@intel.com>
Date:   Fri Feb 9 15:34:14 2018 -0800

    Merge branch 'louisfeng/fix-isnan' into louisfeng/NGMX-275

commit 35422d27b3ddd146bfb97c8bdf70919b411c24fc
Merge: 4ebde727 85a17aeb
Author: Louis Feng <louis.feng@intel.com>
Date:   Fri Feb 9 15:33:56 2018 -0800

    Merge branch 'master' into louisfeng/NGMX-275

commit 4ebde72731c5b82f67362249c6c29b8073c9ec85
Author: Louis Feng <louis.feng@intel.com>
Date:   Fri Feb 9 15:25:00 2018 -0800

    WIP.

commit 40f43c78285ee8003b84a16d1dba78c4a56a479e
Author: Louis Feng <louis.feng@intel.com>
Date:   Thu Feb 8 22:13:21 2018 -0800

    fixed dilation, passing all conv tests, fixed mxnet ngraph missing mkldnn namespace errors.

commit 34bc573f44a15bf39d4e547724c64a31093c2f4e
Author: Louis Feng <louis.feng@intel.com>
Date:   Wed Feb 7 23:42:27 2018 -0800

    fixed padding between ngraph and mkldnn.

commit df63ae6cd8694a6e63c0affa0a5747279ad5dfab
Author: Louis Feng <louis.feng@intel.com>
Date:   Wed Feb 7 23:34:41 2018 -0800

    fixed padding etc.

commit 62a7c8a89b6ddacd22f28c61389f7496482b87d2
Author: Louis Feng <louis.feng@intel.com>
Date:   Wed Feb 7 17:28:13 2018 -0800

    convolution backprop with mkldnn.

* minor changes.

* Fixed test case fail due to missing mkldnn head. Added new mkldnn ops to list of header include check.

* style format.

* rethrow ngraph execption and removed cerr message.

* refactor to keep changes within emitters.

* removed mkldnn util.
parent 5e773f81
......@@ -2036,8 +2036,87 @@ void runtime::cpu::CPU_Emitter::EmitConvolutionBackpropFilters(
auto arg0_shape = args[0].get_shape();
auto arg1_shape = args[1].get_shape();
auto result_shape = out[0].get_shape();
auto arg0_rank = arg0_shape.size();
auto arg1_rank = arg1_shape.size();
bool data_dilated = false;
for (size_t s : convolution->get_data_dilation_strides_forward())
{
data_dilated = data_dilated || (s != 1);
}
if (!data_dilated && arg0_rank == 4 && arg1_rank == 4 &&
args[0].get_element_type() == element::f32)
{
const string& elem_type = get_mkldnn_data_type(args[0].get_element_type().c_type_string());
Strides window_dilation_strides_adjusted;
writer << "kernel::convolution<" << out[0].get_type() << ">(" << args[0].get_name() << ",\n";
for (size_t s : convolution->get_window_dilation_strides_forward())
{
window_dilation_strides_adjusted.push_back(s - 1);
}
auto emit_memory_desc = [&writer](const std::string& var,
const std::string& shape,
const std::string& type,
const std::string& layout) {
writer << "memory::desc " << var << " = memory::desc({" << shape << "}, " << type
<< ", memory::format::" << layout << ");\n";
};
auto emit_memory =
[&writer](const std::string& var, const std::string& desc, const std::string& data) {
writer << "memory " << var << " = memory({" << desc << ", cpu_engine}, " << data
<< ");\n";
};
auto emit_memory_dims = [&writer](const std::string& var, const std::string& dims) {
writer << "memory::dims " << var << "{" << dims << "};\n";
};
writer << "{\n";
writer.indent++;
writer << "try {\n";
writer.indent++;
writer << "engine cpu_engine = engine(engine::cpu, 0);\n";
emit_memory_desc("data_desc", join(arg0_shape), elem_type, "nchw");
emit_memory_desc("delta_desc", join(arg1_shape), elem_type, "nchw");
emit_memory_desc("result_desc", join(result_shape), elem_type, "oihw");
emit_memory("data", "data_desc", args[0].get_name());
emit_memory("delta", "delta_desc", args[1].get_name());
emit_memory("result", "result_desc", out[0].get_name());
emit_memory_dims("dilates", join(window_dilation_strides_adjusted));
emit_memory_dims("strides", join(convolution->get_window_movement_strides_forward()));
emit_memory_dims("padding_l", join(convolution->get_padding_below_forward()));
emit_memory_dims("padding_r", join(convolution->get_padding_above_forward()));
writer << "convolution_backward_weights::desc bwd_weights_desc("
"algorithm::convolution_direct, "
"data_desc, result_desc, delta_desc, strides, dilates,"
"padding_l, padding_r, padding_kind::zero);\n"
"convolution_forward::primitive_desc fwd_pd({prop_kind::forward, "
"algorithm::convolution_direct, data_desc, "
"result_desc, delta_desc, strides, dilates, padding_l, padding_r, "
"padding_kind::zero}, cpu_engine);\n"
"convolution_backward_weights::primitive_desc bwd_weights_pd(bwd_weights_desc, "
"cpu_engine, fwd_pd);\n"
"convolution_backward_weights bwd_weights(bwd_weights_pd, data, delta, "
"result);\n"
"stream s = stream(stream::kind::eager);\n"
"s.submit({bwd_weights}).wait();\n";
writer.indent--;
writer << "} catch (const mkldnn::error& e) {\n";
writer.indent++;
writer << "throw ngraph::ngraph_error(\"MKLDNN ERROR (\" + std::to_string("
"e.status) + \"): \" + e.message);\n";
writer.indent--;
writer << "}\n";
writer.indent--;
writer << "}\n";
}
else
{
writer << "kernel::convolution<" << out[0].get_type() << ">(" << args[0].get_name()
<< ",\n";
writer << " " << args[1].get_name() << ",\n";
writer << " " << out[0].get_name() << ",\n";
writer << " {" << join(arg0_shape) << "},\n";
......@@ -2054,6 +2133,7 @@ void runtime::cpu::CPU_Emitter::EmitConvolutionBackpropFilters(
writer << " {"
<< join(convolution->get_data_dilation_strides_backward()) << "},\n";
writer << " 1, 0, 0, 1, 1, 0, false);\n";
}
}
void runtime::cpu::CPU_Emitter::EmitConvolutionBackpropData(
......@@ -2067,9 +2147,86 @@ void runtime::cpu::CPU_Emitter::EmitConvolutionBackpropData(
auto arg0_shape = args[0].get_shape();
auto arg1_shape = args[1].get_shape();
auto result_shape = out[0].get_shape();
auto arg0_rank = arg0_shape.size();
auto arg1_rank = arg1_shape.size();
bool data_dilated = false;
for (size_t s : convolution->get_data_dilation_strides_forward())
{
data_dilated = data_dilated || (s != 1);
}
if (!data_dilated && arg0_rank == 4 && arg1_rank == 4 &&
args[0].get_element_type() == element::f32)
{
const string& elem_type = get_mkldnn_data_type(args[0].get_element_type().c_type_string());
Strides window_dilation_strides_adjusted;
for (size_t s : convolution->get_window_dilation_strides_forward())
{
window_dilation_strides_adjusted.push_back(s - 1);
}
auto emit_memory_desc = [&writer](const std::string& var,
const std::string& shape,
const std::string& type,
const std::string& layout) {
writer << "memory::desc " << var << " = memory::desc({" << shape << "}, " << type
<< ", memory::format::" << layout << ");\n";
};
auto emit_memory =
[&writer](const std::string& var, const std::string& desc, const std::string& data) {
writer << "memory " << var << " = memory({" << desc << ", cpu_engine}, " << data
<< ");\n";
};
auto emit_memory_dims = [&writer](const std::string& var, const std::string& dims) {
writer << "memory::dims " << var << "{" << dims << "};\n";
};
writer << "{\n";
writer.indent++;
writer << "try {\n";
writer.indent++;
writer << "engine cpu_engine = engine(engine::cpu, 0);\n";
emit_memory_desc("weight_desc", join(arg0_shape), elem_type, "oihw");
emit_memory_desc("delta_desc", join(arg1_shape), elem_type, "nchw");
emit_memory_desc("result_desc", join(result_shape), elem_type, "nchw");
emit_memory("weight", "weight_desc", args[0].get_name());
emit_memory("delta", "delta_desc", args[1].get_name());
emit_memory("result", "result_desc", out[0].get_name());
emit_memory_dims("dilates", join(window_dilation_strides_adjusted));
emit_memory_dims("strides", join(convolution->get_window_movement_strides_forward()));
emit_memory_dims("padding_l", join(convolution->get_padding_below_forward()));
emit_memory_dims("padding_r", join(convolution->get_padding_above_forward()));
writer << "convolution_backward_data::desc bwd_data_desc(algorithm::convolution_direct, "
"result_desc, weight_desc, delta_desc, strides, dilates, "
"padding_l, padding_r, padding_kind::zero);\n"
"convolution_forward::primitive_desc fwd_pd({prop_kind::forward, "
"algorithm::convolution_direct, result_desc, weight_desc, delta_desc, "
"strides, dilates, padding_l, padding_r, padding_kind::zero}, cpu_engine);\n"
"convolution_backward_data::primitive_desc bwd_data_pd(bwd_data_desc, "
"cpu_engine, fwd_pd);\n"
"convolution_backward_data bwd_data(bwd_data_pd, delta, weight, result);\n"
"stream s = stream(stream::kind::eager);\n"
"s.submit({bwd_data}).wait();\n";
writer.indent--;
writer << "} catch (const mkldnn::error& e) {\n";
writer.indent++;
writer << "throw ngraph::ngraph_error(\"MKLDNN ERROR (\" + std::to_string("
"e.status) + \"): \" + e.message);\n";
writer.indent--;
writer << "}\n";
writer.indent--;
writer << "}\n";
}
else
{
// Note that args[1] and args[0] are switched here from the usual order.
writer << "kernel::convolution<" << out[0].get_type() << ">(" << args[1].get_name() << ",\n";
writer << "kernel::convolution<" << out[0].get_type() << ">(" << args[1].get_name()
<< ",\n";
writer << " " << args[0].get_name() << ",\n";
writer << " " << out[0].get_name() << ",\n";
writer << " {" << join(arg1_shape) << "},\n";
......@@ -2086,6 +2243,7 @@ void runtime::cpu::CPU_Emitter::EmitConvolutionBackpropData(
writer << " {"
<< join(convolution->get_data_dilation_strides_backward()) << "},\n";
writer << " 0, 1, 0, 1, 0, 1, true);\n";
}
}
void runtime::cpu::CPU_Emitter::EmitNot(codegen::CodeWriter& writer,
......
......@@ -242,6 +242,8 @@ void runtime::cpu::CPU_ExternalFunction::compile()
for (shared_ptr<Node> node : current_function->get_ordered_ops())
{
if (dynamic_cast<op::Convolution*>(node.get()) ||
dynamic_cast<op::ConvolutionBackpropData*>(node.get()) ||
dynamic_cast<op::ConvolutionBackpropFilters*>(node.get()) ||
dynamic_cast<op::AvgPool*>(node.get()) || dynamic_cast<op::MaxPool*>(node.get()) ||
dynamic_cast<op::AvgPoolBackprop*>(node.get()))
{
......@@ -259,6 +261,7 @@ void runtime::cpu::CPU_ExternalFunction::compile()
writer +=
R"(#include <Eigen/Dense>
#include "ngraph/except.hpp"
#include "ngraph/runtime/aligned_buffer.hpp"
#include "ngraph/runtime/cpu/cpu_eigen_utils.hpp"
#include "ngraph/runtime/cpu/cpu_kernels.hpp"
......
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