Commit 8b7f042d authored by Louis Feng's avatar Louis Feng

refactor and clean up.

parent dd5bd9ad
...@@ -2386,37 +2386,27 @@ namespace ngraph ...@@ -2386,37 +2386,27 @@ namespace ngraph
template <> template <>
void CPU_Emitter::EMITTER_DECL(ngraph::op::ConvolutionBias) void CPU_Emitter::EMITTER_DECL(ngraph::op::ConvolutionBias)
{ {
auto convolution = static_cast<const ngraph::op::Convolution*>(node); auto convolution = static_cast<const ngraph::op::ConvolutionBias*>(node);
const TensorViewWrapper& data = args[0]; const TensorViewWrapper& data = args[0];
const TensorViewWrapper& weights = args[1]; const TensorViewWrapper& weights = args[1];
const TensorViewWrapper& bias = args[2]; const TensorViewWrapper& bias = args[2];
const TensorViewWrapper& result = out[0]; const TensorViewWrapper& result = out[0];
const vector<size_t>& data_shape = data.get_shape();
const vector<size_t>& weights_shape = weights.get_shape();
const vector<size_t>& bias_shape = bias.get_shape();
const vector<size_t>& result_shape = result.get_shape();
if (runtime::cpu::mkldnn_utils::use_mkldnn_kernel(node)) using namespace runtime::cpu::mkldnn_utils;
if (mkldnn_utils::use_mkldnn_kernel(node))
{ {
auto data_format = auto data_format = mkldnn_utils::get_input_mkldnn_format(node, 0);
runtime::cpu::mkldnn_utils::get_input_mkldnn_format(node, 0); auto weights_format = mkldnn_utils::get_input_mkldnn_format(node, 1);
auto weights_format = auto bias_format = mkldnn_utils::get_input_mkldnn_format(node, 2);
runtime::cpu::mkldnn_utils::get_input_mkldnn_format(node, 1); auto result_format = mkldnn_utils::get_output_mkldnn_format(node, 0);
auto bias_format =
runtime::cpu::mkldnn_utils::get_input_mkldnn_format(node, 2);
auto result_format =
runtime::cpu::mkldnn_utils::get_output_mkldnn_format(node, 0);
auto& mkldnn_emitter = external_function->get_mkldnn_emitter(); auto& mkldnn_emitter = external_function->get_mkldnn_emitter();
auto data_desc = mkldnn_emitter->build_memory_descriptor( auto data_desc = mkldnn_emitter->build_memory_descriptor(data, data_format);
data, data_format); auto weights_desc = mkldnn_emitter->build_memory_descriptor(weights, weights_format);
auto weights_desc = mkldnn_emitter->build_memory_descriptor( auto bias_desc = mkldnn_emitter->build_memory_descriptor(bias, bias_format);
weights, weights_format); auto result_desc = mkldnn_emitter->build_memory_descriptor(result, result_format);
auto bias_desc = mkldnn_emitter->build_memory_descriptor(
bias, bias_format);
auto result_desc = mkldnn_emitter->build_memory_descriptor(
result, result_format);
// For dilation, MKLDNN wants to know how many elements to insert between, not how far // For dilation, MKLDNN wants to know how many elements to insert between, not how far
// apart to space the elements like nGraph. So we have to subtract 1 from each pos. // apart to space the elements like nGraph. So we have to subtract 1 from each pos.
...@@ -2463,33 +2453,28 @@ namespace ngraph ...@@ -2463,33 +2453,28 @@ namespace ngraph
const TensorViewWrapper& delta = args[1]; const TensorViewWrapper& delta = args[1];
const TensorViewWrapper& weights_delta = out[0]; const TensorViewWrapper& weights_delta = out[0];
const TensorViewWrapper& bias_delta = out[1]; const TensorViewWrapper& bias_delta = out[1];
const vector<size_t>& data_shape = data.get_shape();
const vector<size_t>& delta_shape = delta.get_shape();
const vector<size_t>& weights_delta_shape = weights_delta.get_shape();
const vector<size_t>& bias_delta_shape = bias_delta.get_shape();
if (runtime::cpu::mkldnn_utils::use_mkldnn_kernel(node)) using namespace runtime::cpu::mkldnn_utils;
if (mkldnn_utils::use_mkldnn_kernel(node))
{ {
const string& elem_type =
runtime::cpu::mkldnn_utils::get_mkldnn_data_type_string(
data.get_element_type());
Strides window_dilation_strides_adjusted; Strides window_dilation_strides_adjusted;
for (size_t s : convolution->get_window_dilation_strides_forward()) for (size_t s : convolution->get_window_dilation_strides_forward())
{ {
window_dilation_strides_adjusted.push_back(s - 1); window_dilation_strides_adjusted.push_back(s - 1);
} }
auto data_format = runtime::cpu::mkldnn_utils::get_input_mkldnn_format(node, 0); auto data_format = mkldnn_utils::get_input_mkldnn_format(node, 0);
auto delta_format = runtime::cpu::mkldnn_utils::get_input_mkldnn_format(node, 1); auto delta_format = mkldnn_utils::get_input_mkldnn_format(node, 1);
auto weights_delta_format = runtime::cpu::mkldnn_utils::get_output_mkldnn_format(node, 0); auto weights_delta_format = mkldnn_utils::get_output_mkldnn_format(node, 0);
auto bias_delta_format = runtime::cpu::mkldnn_utils::get_output_mkldnn_format(node, 1); auto bias_delta_format = mkldnn_utils::get_output_mkldnn_format(node, 1);
auto& mkldnn_emitter = external_function->get_mkldnn_emitter(); auto& mkldnn_emitter = external_function->get_mkldnn_emitter();
auto data_desc = mkldnn_emitter->build_memory_descriptor(data, data_format); auto data_desc = mkldnn_emitter->build_memory_descriptor(data, data_format);
auto delta_desc = mkldnn_emitter->build_memory_descriptor(delta, delta_format); auto delta_desc = mkldnn_emitter->build_memory_descriptor(delta, delta_format);
auto weights_delta_desc = mkldnn_emitter->build_memory_descriptor(weights_delta, weights_delta_format); auto weights_delta_desc = mkldnn_emitter->build_memory_descriptor(weights_delta, weights_delta_format);
auto bias_delta_desc = mkldnn_emitter->build_memory_descriptor(bias_delta, bias_delta_format); auto bias_delta_desc = mkldnn_emitter->build_memory_descriptor(bias_delta, bias_delta_format);
size_t conv_index = mkldnn_emitter->build_convolution_backward_filters_bias( size_t conv_index = mkldnn_emitter->build_convolution_backward_filters_bias(
data_desc, data_desc,
delta_desc, delta_desc,
......
...@@ -225,11 +225,9 @@ static const runtime::cpu::OpMap dispatcher{ ...@@ -225,11 +225,9 @@ static const runtime::cpu::OpMap dispatcher{
{TI(ngraph::op::ConvolutionBackpropData), {TI(ngraph::op::ConvolutionBackpropData),
&runtime::cpu::CPU_Emitter::emit<op::ConvolutionBackpropData>}, &runtime::cpu::CPU_Emitter::emit<op::ConvolutionBackpropData>},
{TI(ngraph::op::ConvolutionBias), &runtime::cpu::CPU_Emitter::emit<op::ConvolutionBias>}, {TI(ngraph::op::ConvolutionBias), &runtime::cpu::CPU_Emitter::emit<op::ConvolutionBias>},
// conv+bias backprop for data share the same implementation as ConvolutionBackpropData
{TI(ngraph::op::ConvolutionBiasBackpropFiltersBias), {TI(ngraph::op::ConvolutionBiasBackpropFiltersBias),
&runtime::cpu::CPU_Emitter::emit<op::ConvolutionBiasBackpropFiltersBias>}, &runtime::cpu::CPU_Emitter::emit<op::ConvolutionBiasBackpropFiltersBias>},
// conv+bias backprop for data share the same implementation as conv backprop data
{TI(ngraph::op::ConvolutionBiasBackpropData),
&runtime::cpu::CPU_Emitter::emit<op::ConvolutionBackpropData>},
{TI(ngraph::runtime::cpu::op::ConvertLayout), {TI(ngraph::runtime::cpu::op::ConvertLayout),
&runtime::cpu::CPU_Emitter::emit<runtime::cpu::op::ConvertLayout>}, &runtime::cpu::CPU_Emitter::emit<runtime::cpu::op::ConvertLayout>},
{TI(ngraph::op::Not), &runtime::cpu::CPU_Emitter::emit<op::Not>}, {TI(ngraph::op::Not), &runtime::cpu::CPU_Emitter::emit<op::Not>},
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <numeric> #include <numeric>
#include "ngraph/ops/convolution.hpp"
#include "ngraph/runtime/cpu/ops/conv_bias.hpp" #include "ngraph/runtime/cpu/ops/conv_bias.hpp"
#include "ngraph/ops/get_output_element.hpp" #include "ngraph/ops/get_output_element.hpp"
#include "ngraph/util.hpp" #include "ngraph/util.hpp"
...@@ -88,7 +89,7 @@ void op::ConvolutionBias::generate_adjoints(autodiff::Adjoints& adjoints, ...@@ -88,7 +89,7 @@ void op::ConvolutionBias::generate_adjoints(autodiff::Adjoints& adjoints,
const auto bias_shape = bias->get_shape(); const auto bias_shape = bias->get_shape();
adjoints.add_delta(data, adjoints.add_delta(data,
std::make_shared<op::ConvolutionBiasBackpropData>(data_shape, std::make_shared<op::ConvolutionBackpropData>(data_shape,
filter, filter,
delta, delta,
m_window_movement_strides, m_window_movement_strides,
...@@ -113,107 +114,6 @@ void op::ConvolutionBias::generate_adjoints(autodiff::Adjoints& adjoints, ...@@ -113,107 +114,6 @@ void op::ConvolutionBias::generate_adjoints(autodiff::Adjoints& adjoints,
adjoints.add_delta(bias, bias_delta); adjoints.add_delta(bias, bias_delta);
} }
op::ConvolutionBiasBackpropData::ConvolutionBiasBackpropData(const Shape& data_batch_shape,
const std::shared_ptr<Node>& filters,
const std::shared_ptr<Node>& output_delta,
const Strides& window_movement_strides_forward,
const Strides& window_dilation_strides_forward,
const CoordinateDiff& padding_below_forward,
const CoordinateDiff& padding_above_forward,
const Strides& data_dilation_strides_forward)
: RequiresTensorViewArgs("ConvolutionBackpropData", {filters, output_delta})
, m_data_batch_shape(data_batch_shape)
, m_window_movement_strides_forward(window_movement_strides_forward)
, m_window_dilation_strides_forward(window_dilation_strides_forward)
, m_padding_below_forward(padding_below_forward)
, m_padding_above_forward(padding_above_forward)
, m_data_dilation_strides_forward(data_dilation_strides_forward)
{
auto& filters_shape = get_input_shape(0);
auto& filters_et = get_input_element_type(0);
auto& output_delta_shape = get_input_shape(0);
auto& output_delta_et = get_input_element_type(1);
//
// Make sure filter and output delta element types match.
//
if (filters_et != output_delta_et)
{
throw ngraph_error(
"Convolution data batch backprop filter and output delta element types do not match");
}
// Forward Backward
// Window movement strides q p_x
// Window dilation strides p_f p_f
// Padding below a_x (S_F - 1)p_f - a_x
// Padding above b_x (S_f - 1)p_f + ((a_x + (S_x - 1)p_x + b_x - (S_f - 1)p_f) % q) - b_x
// Data dilation strides p_x q
for (size_t i = 0; i < data_batch_shape.size() - 2; i++)
{
m_window_movement_strides_backward.push_back(data_dilation_strides_forward[i]);
m_window_dilation_strides_backward.push_back(window_dilation_strides_forward[i]);
m_padding_below_backward.push_back((filters_shape[i + 2] - 1) *
window_dilation_strides_forward[i] -
padding_below_forward[i]);
m_padding_above_backward.push_back(
(filters_shape[i + 2] - 1) * window_dilation_strides_forward[i] +
((padding_below_forward[i] +
(data_batch_shape[i + 2] - 1) * data_dilation_strides_forward[i] +
padding_above_forward[i] -
(filters_shape[i + 2] - 1) * window_dilation_strides_forward[i]) %
window_movement_strides_forward[i]) -
padding_above_forward[i]);
m_data_dilation_strides_backward.push_back(window_movement_strides_forward[i]);
}
// Shape inferred_convolution_output_shape =
// infer_convolution_output_shape(output_delta_shape,
// filters_shape,
// m_window_movement_strides_backward,
// m_window_dilation_strides_backward,
// m_padding_below_backward,
// m_padding_above_backward,
// m_data_dilation_strides_backward,
// 0,
// 1,
// 0,
// 1,
// 0,
// 1,
// "In ConvolutionBiasBackpropData: ");
//
// // Not sure if this can ever actually happen (i.e., I think it will trip on something else
// // inside infer_convolution_output_shape before we get here) but it seems worth checking.
// if (inferred_convolution_output_shape != data_batch_shape)
// {
// throw ngraph_error(
// "Convolution data batch backprop inferred output shape does not match "
// "specified data batch shape");
// }
set_value_type_checked(filters_et, data_batch_shape);
}
std::shared_ptr<Node> op::ConvolutionBiasBackpropData::copy_with_new_args(
const NodeVector& new_args) const
{
if (new_args.size() != 2)
{
throw ngraph_error("Incorrect number of new arguments");
}
return std::make_shared<ConvolutionBiasBackpropData>(m_data_batch_shape,
new_args.at(0),
new_args.at(1),
m_window_movement_strides_forward,
m_window_dilation_strides_forward,
m_padding_below_forward,
m_padding_above_forward,
m_data_dilation_strides_forward);
}
op::ConvolutionBiasBackpropFiltersBias::ConvolutionBiasBackpropFiltersBias( op::ConvolutionBiasBackpropFiltersBias::ConvolutionBiasBackpropFiltersBias(
const std::shared_ptr<Node>& data_batch, const std::shared_ptr<Node>& data_batch,
const Shape& filters_shape, const Shape& filters_shape,
......
...@@ -60,100 +60,6 @@ namespace ngraph ...@@ -60,100 +60,6 @@ namespace ngraph
const Strides& data_dilation_strides); const Strides& data_dilation_strides);
}; };
/// \brief Data batch backprop for batched convolution + bias operation.
class ConvolutionBiasBackpropData : public util::RequiresTensorViewArgs
{
public:
/// \brief Constructs a batched-convolution data batch-backprop operation.
///
/// \param data_batch_shape The shape of the data batch from forward-prop.
/// \param filters The node producing the filters from forward-prop.
/// \param output_delta The node producing output delta.
/// \param window_movement_strides_forward The window movement strides from forward-prop.
/// \param window_dilation_strides_forward The window dilation strides from forward-prop.
/// \param padding_below_forward The padding-below sizes from forward-prop.
/// \param padding_above_forward The padding-above sizes from forward-prop.
/// \param data_dilation_strides_forward The data dilation strides from forward-prop.
ConvolutionBiasBackpropData(const Shape& data_batch_shape,
const std::shared_ptr<Node>& filters,
const std::shared_ptr<Node>& output_delta,
const Strides& window_movement_strides_forward,
const Strides& window_dilation_strides_forward,
const CoordinateDiff& padding_below_forward,
const CoordinateDiff& padding_above_forward,
const Strides& data_dilation_strides_forward);
virtual std::shared_ptr<Node> copy_with_new_args(const NodeVector& new_args) const override;
/// \return The data batch shape.
const Shape& get_data_batch_shape() const { return m_data_batch_shape; }
/// \return The window movement strides from the forward prop.
const Strides& get_window_movement_strides_forward() const
{
return m_window_movement_strides_forward;
}
/// \return The window dilation strides from the forward prop.
const Strides& get_window_dilation_strides_forward() const
{
return m_window_dilation_strides_forward;
}
/// \return The padding-below sizes (possibly negative) from the forward prop.
const CoordinateDiff& get_padding_below_forward() const
{
return m_padding_below_forward;
}
/// \return The padding-above sizes (possibly negative) from the forward prop.
const CoordinateDiff& get_padding_above_forward() const
{
return m_padding_above_forward;
}
/// \return The input data dilation strides from the forward prop.
const Strides& get_data_dilation_strides_forward() const
{
return m_data_dilation_strides_forward;
}
/// \return The window movement strides for the backward prop.
const Strides& get_window_movement_strides_backward() const
{
return m_window_movement_strides_backward;
}
/// \return The window dilation strides for the backward prop.
const Strides& get_window_dilation_strides_backward() const
{
return m_window_dilation_strides_backward;
}
/// \return The padding-below sizes (possibly negative) for the backward prop.
const CoordinateDiff& get_padding_below_backward() const
{
return m_padding_below_backward;
}
/// \return The padding-above sizes (possibly negative) for the backward prop.
const CoordinateDiff& get_padding_above_backward() const
{
return m_padding_above_backward;
}
/// \return The input data dilation strides for the backward prop.
const Strides& get_data_dilation_strides_backward() const
{
return m_data_dilation_strides_backward;
}
protected:
Shape m_data_batch_shape;
Strides m_window_movement_strides_forward;
Strides m_window_dilation_strides_forward;
CoordinateDiff m_padding_below_forward;
CoordinateDiff m_padding_above_forward;
Strides m_data_dilation_strides_forward;
Strides m_window_movement_strides_backward;
Strides m_window_dilation_strides_backward;
CoordinateDiff m_padding_below_backward;
CoordinateDiff m_padding_above_backward;
Strides m_data_dilation_strides_backward;
};
/// \brief Filters and bias backprop for batched convolution operation. /// \brief Filters and bias backprop for batched convolution operation.
class ConvolutionBiasBackpropFiltersBias : public util::RequiresTensorViewArgs class ConvolutionBiasBackpropFiltersBias : public util::RequiresTensorViewArgs
{ {
......
...@@ -185,7 +185,7 @@ namespace ngraph ...@@ -185,7 +185,7 @@ namespace ngraph
auto convolution = static_cast<op::ConvolutionBiasBackpropFiltersBias*>(node); auto convolution = static_cast<op::ConvolutionBiasBackpropFiltersBias*>(node);
auto data_shape = node->get_input_shape(0); auto data_shape = node->get_input_shape(0);
auto delta_shape = node->get_input_shape(0); auto delta_shape = node->get_input_shape(1);
auto data_rank = data_shape.size(); auto data_rank = data_shape.size();
auto delta_rank = delta_shape.size(); auto delta_rank = delta_shape.size();
...@@ -195,10 +195,8 @@ namespace ngraph ...@@ -195,10 +195,8 @@ namespace ngraph
data_dilated = data_dilated || (s != 1); data_dilated = data_dilated || (s != 1);
} }
std::cout << "testing ConvolutionBiasBackpropFiltersBias" << std::endl; if (!data_dilated && data_rank == 4 && delta_rank == 4 && node->get_input_element_type(0) == element::f32)
if (!data_dilated && data_rank == 4 && node->get_input_element_type(0) == element::f32)
{ {
std::cout << "assigned ConvolutionBiasBackpropFiltersBias" << std::endl;
auto op_annotations = auto op_annotations =
std::make_shared<ngraph::runtime::cpu::CPUOpAnnotations>(); std::make_shared<ngraph::runtime::cpu::CPUOpAnnotations>();
op_annotations->set_mkldnn_op(true); op_annotations->set_mkldnn_op(true);
......
...@@ -52,5 +52,5 @@ private: ...@@ -52,5 +52,5 @@ private:
void construct_fprop_bn(); void construct_fprop_bn();
void construct_zero_padded_reshaped_conv(); void construct_zero_padded_reshaped_conv();
void construct_zero_padded_conv(); void construct_zero_padded_conv();
construct_conv_bias(); void construct_conv_bias();
}; };
...@@ -25,13 +25,13 @@ ...@@ -25,13 +25,13 @@
#include "ngraph/log.hpp" #include "ngraph/log.hpp"
#include "ngraph/ngraph.hpp" #include "ngraph/ngraph.hpp"
#include "ngraph/ops/batch_norm.hpp" #include "ngraph/ops/batch_norm.hpp"
#include "ngraph/ops/parameter.hpp"
#include "ngraph/ops/sum.hpp" #include "ngraph/ops/sum.hpp"
#include "ngraph/pass/graph_rewrite.hpp" #include "ngraph/pass/graph_rewrite.hpp"
#include "ngraph/pass/manager.hpp" #include "ngraph/pass/manager.hpp"
#include "ngraph/pattern/matcher.hpp" #include "ngraph/pattern/matcher.hpp"
#include "ngraph/pattern/op/any.hpp" #include "ngraph/pattern/op/any.hpp"
#include "ngraph/pattern/op/label.hpp" #include "ngraph/pattern/op/label.hpp"
//
#include "ngraph/file_util.hpp" #include "ngraph/file_util.hpp"
#include "ngraph/pass/reshape_elimination.hpp" #include "ngraph/pass/reshape_elimination.hpp"
#include "ngraph/pass/visualize_tree.hpp" #include "ngraph/pass/visualize_tree.hpp"
...@@ -589,190 +589,165 @@ TEST(cpu_fusion, fuse_conv_bias) ...@@ -589,190 +589,165 @@ TEST(cpu_fusion, fuse_conv_bias)
ASSERT_GT(cb, 0); ASSERT_GT(cb, 0);
} }
TEST(cpu_fusion, conv_bias_fprop_n1c1h3w3) struct ConvolutionBiasTestData
{ {
const int n = 1; size_t n{0};
const int c = 1; size_t c{0};
const int filter = 1; size_t filter{0};
const int kernel_size = 3; size_t kernel_size{0};
const int w = 3; size_t w{0};
const int h = w; size_t h{0};
shared_ptr<runtime::TensorView> data_val;
auto data_shape = Shape{n, c, h, w}; shared_ptr<runtime::TensorView> weights_val;
auto data = make_shared<op::Parameter>(element::f32, data_shape); shared_ptr<runtime::TensorView> bias_val;
auto weights_shape = Shape{filter, c, kernel_size, kernel_size}; shared_ptr<runtime::TensorView> result_val;
auto weights = make_shared<op::Parameter>(element::f32, weights_shape); shared_ptr<runtime::TensorView> delta_val;
auto bias_shape = Shape{filter}; shared_ptr<runtime::TensorView> d_data_val;
auto bias = make_shared<op::Parameter>(element::f32, bias_shape); shared_ptr<runtime::TensorView> d_weights_val;
auto convolution= make_shared<op::Convolution>(data, weights); shared_ptr<runtime::TensorView> d_bias_val;
auto convolution_bias = make_shared<op::ConvolutionBias>(convolution, bias); vector<float> expected_result_val;
auto result_shape = Shape{1,1,1,1}; vector<float> expected_d_data_val;
vector<float> expected_d_weights_val;
auto f = make_shared<Function>(convolution_bias, op::ParameterVector{data, weights, bias}); vector<float> expected_d_bias_val;
auto manager = runtime::Manager::get("CPU");
auto external = manager->compile(f); Shape data_shape;
auto backend = manager->allocate_backend(); Shape weights_shape;
auto cf = backend->make_call_frame(external); Shape bias_shape;
Shape result_shape;
shared_ptr<op::Parameter> data;
shared_ptr<op::Parameter> weights;
shared_ptr<op::Parameter> bias;
shared_ptr<op::Parameter> delta;
void generate_fwd_n1c1h3w3(shared_ptr<runtime::Backend> backend) {
n = 1;
c = 1;
filter = 1;
kernel_size = 3;
w = 3;
h = w;
data_shape = Shape{n, c, h, w};
data = make_shared<op::Parameter>(element::f32, data_shape);
weights_shape = Shape{filter, c, kernel_size, kernel_size};
weights = make_shared<op::Parameter>(element::f32, weights_shape);
bias_shape = Shape{filter};
bias = make_shared<op::Parameter>(element::f32, bias_shape);
result_shape = Shape{n,filter,1,1};
data_val = backend->make_primary_tensor_view(element::f32, data_shape);
copy_data(data_val, vector<float>{-0.67765152f, 0.10073948f, 0.57595438f,
-0.3469252f, -0.22134334f, -1.80471897f,
-0.80642909f, 1.22033095f, 2.23235631f});
weights_val = backend->make_primary_tensor_view(element::f32, weights_shape);
copy_data(weights_val, vector<float>{0.20070229f, -0.54968649f, -0.19819015f,
-0.38577855f, 1.37109005f, -0.23789984f,
0.14867957f, -0.49851316f, -0.84815776f});
bias_val = backend->make_primary_tensor_view(element::f32, bias_shape);
copy_data(bias_val, vector<float>{0.07811152f});
result_val = backend->make_primary_tensor_view(element::f32, result_shape);
copy_data(result_val, vector<float>{0});
expected_result_val = vector<float>{-2.58936238f};
}
// Create some tensors for input/output void generate_bwd_n1c1h3w3(shared_ptr<runtime::Backend> backend) {
auto _data = backend->make_primary_tensor_view(element::f32, data_shape); generate_fwd_n1c1h3w3(backend);
copy_data(_data, vector<float>{-0.67765152, 0.10073948, 0.57595438,
-0.3469252, -0.22134334, -1.80471897, delta = make_shared<op::Parameter>(element::f32, result_shape);
-0.80642909, 1.22033095, 2.23235631});
auto _weights = backend->make_primary_tensor_view(element::f32, weights_shape); delta_val = backend->make_primary_tensor_view(element::f32, result_shape);
copy_data(_weights, vector<float>{0.20070229, -0.54968649, -0.19819015, copy_data(delta_val, vector<float>{-2.58936238f});
-0.38577855, 1.37109005, -0.23789984,
0.14867957, -0.49851316, -0.84815776}); d_data_val = backend->make_primary_tensor_view(element::f32, data_shape);
auto _bias = backend->make_primary_tensor_view(element::f32, bias_shape); copy_data(d_data_val, vector<float>{0,0,0,
copy_data(_bias, vector<float>{0.07811152}); 0,0,0,
auto result = backend->make_primary_tensor_view(element::f32, result_shape); 0,0,0});
vector<float> expected_result{-2.58936238}; d_weights_val = backend->make_primary_tensor_view(element::f32, weights_shape);
cf->call({_data, _weights, _bias}, {result}); copy_data(d_weights_val, vector<float>{0,0,0,
auto result_vec = read_vector<float>(result); 0,0,0,
for (size_t i = 0; i < result_vec.size(); ++i) { 0,0,0});
std::cout << result_vec[i] << " ";
d_bias_val = backend->make_primary_tensor_view(element::f32, bias_shape);
copy_data(d_bias_val, vector<float>{0});
expected_d_data_val = vector<float>{-0.51969099f, 1.42333758f, 0.5131861f,
0.99892044f, -3.5502491f, 0.61600888f,
-0.3849853f, 1.29083121f, 2.19618773f};
expected_d_weights_val = vector<float>{1.7546854f, -0.26085103f, -1.49135458f,
0.89831507f, 0.57313812f, 4.67307138f,
2.08813715f, -3.15987897f, -5.7803793f};
expected_d_bias_val = vector<float>{-2.58936238f};
} }
std::cout << std::endl; };
EXPECT_TRUE(test::all_close(expected_result, read_vector<float>(result)));
}
TEST(cpu_fusion, conv_bias_fprop) TEST(cpu_fusion, conv_bias_fprop_n1c1h3w3)
{ {
const int n = 1;
const int c = 1;
const int filter = 1;
const int kernel_size = 3;
const int w = 3;
const int h = w;
auto data_shape = Shape{n, c, h, w};
auto data = make_shared<op::Parameter>(element::f32, data_shape);
auto weights_shape = Shape{filter, c, kernel_size, kernel_size};
auto weights = make_shared<op::Parameter>(element::f32, weights_shape);
auto bias_shape = Shape{filter};
auto bias = make_shared<op::Parameter>(element::f32, bias_shape);
auto convolution= make_shared<op::Convolution>(data, weights);
auto convolution_bias = make_shared<op::ConvolutionBias>(convolution, bias);
auto result_shape = Shape{1,1,1,1};
auto f = make_shared<Function>(convolution_bias, op::ParameterVector{data, weights, bias});
auto manager = runtime::Manager::get("CPU"); auto manager = runtime::Manager::get("CPU");
auto external = manager->compile(f);
auto backend = manager->allocate_backend(); auto backend = manager->allocate_backend();
ConvolutionBiasTestData conv_test;
conv_test.generate_fwd_n1c1h3w3(backend);
auto convolution = make_shared<op::Convolution>(conv_test.data, conv_test.weights);
auto convolution_bias = make_shared<op::ConvolutionBias>(convolution, conv_test.bias);
auto f = make_shared<Function>(convolution_bias, op::ParameterVector{conv_test.data, conv_test.weights, conv_test.bias});
auto external = manager->compile(f);
auto cf = backend->make_call_frame(external); auto cf = backend->make_call_frame(external);
// Create some tensors for input/output cf->call({conv_test.data_val, conv_test.weights_val, conv_test.bias_val}, {conv_test.result_val});
auto _data = backend->make_primary_tensor_view(element::f32, data_shape); auto result_vec = read_vector<float>(conv_test.result_val);
copy_data(_data, vector<float>{-0.67765152, 0.10073948, 0.57595438,
-0.3469252, -0.22134334, -1.80471897,
-0.80642909, 1.22033095, 2.23235631});
auto _weights = backend->make_primary_tensor_view(element::f32, weights_shape);
copy_data(_weights, vector<float>{0.20070229, -0.54968649, -0.19819015,
-0.38577855, 1.37109005, -0.23789984,
0.14867957, -0.49851316, -0.84815776});
auto _bias = backend->make_primary_tensor_view(element::f32, bias_shape);
copy_data(_bias, vector<float>{0.07811152});
auto result = backend->make_primary_tensor_view(element::f32, result_shape);
vector<float> expected_result{-2.58936238};
cf->call({_data, _weights, _bias}, {result});
auto result_vec = read_vector<float>(result);
for (size_t i = 0; i < result_vec.size(); ++i) { for (size_t i = 0; i < result_vec.size(); ++i) {
std::cout << result_vec[i] << " "; std::cout << result_vec[i] << " ";
} }
std::cout << std::endl; std::cout << std::endl;
EXPECT_TRUE(test::all_close(expected_result, read_vector<float>(result))); EXPECT_TRUE(test::all_close(conv_test.expected_result_val, read_vector<float>(conv_test.result_val)));
} }
TEST(cpu_fusion, conv_bias_bprop_n1c1h3w3) TEST(cpu_fusion, conv_bias_bprop_n1c1h3w3)
{ {
const int n = 1;
const int c = 1;
const int filter = 1;
const int kernel_size = 3;
const int w = 3;
const int h = w;
auto data_shape = Shape{n, c, h, w};
auto data = make_shared<op::Parameter>(element::f32, data_shape);
auto weights_shape = Shape{filter, c, kernel_size, kernel_size};
auto weights = make_shared<op::Parameter>(element::f32, weights_shape);
auto bias_shape = Shape{filter};
auto bias = make_shared<op::Parameter>(element::f32, bias_shape);
auto convolution= make_shared<op::Convolution>(data, weights);
auto convolution_bias = make_shared<op::ConvolutionBias>(convolution, bias);
auto delta_shape = Shape{1,1,1,1};
auto delta = std::make_shared<op::Parameter>(element::f32, delta_shape);
auto f = make_shared<Function>(convolution_bias, op::ParameterVector{data, weights, bias});
auto manager = runtime::Manager::get("CPU"); auto manager = runtime::Manager::get("CPU");
auto backend = manager->allocate_backend(); auto backend = manager->allocate_backend();
auto d_data = convolution_bias->backprop_node(data, delta); ConvolutionBiasTestData conv_test;
auto d_weights = convolution_bias->backprop_node(weights, delta); conv_test.generate_bwd_n1c1h3w3(backend);
auto d_bias = convolution_bias->backprop_node(bias, delta);
auto convolution = make_shared<op::Convolution>(conv_test.data, conv_test.weights);
auto convolution_bias = make_shared<op::ConvolutionBias>(convolution, conv_test.bias);
auto f = make_shared<Function>(convolution_bias, op::ParameterVector{conv_test.data, conv_test.weights, conv_test.bias});
auto d_data = convolution_bias->backprop_node(conv_test.data, conv_test.delta);
auto d_weights = convolution_bias->backprop_node(conv_test.weights, conv_test.delta);
auto d_bias = convolution_bias->backprop_node(conv_test.bias, conv_test.delta);
auto df = make_shared<Function>(NodeVector{d_data, d_weights, d_bias}, auto df = make_shared<Function>(NodeVector{d_data, d_weights, d_bias},
op::ParameterVector{data, weights, bias, delta}); op::ParameterVector{conv_test.data, conv_test.weights, conv_test.bias, conv_test.delta});
auto external = manager->compile(df); auto external = manager->compile(df);
auto cf = backend->make_call_frame(external); auto cf = backend->make_call_frame(external);
// Create some tensors for input/output cf->call({conv_test.data_val, conv_test.weights_val, conv_test.bias_val, conv_test.delta_val}, {conv_test.d_data_val, conv_test.d_weights_val, conv_test.d_bias_val});
auto _data = backend->make_primary_tensor_view(element::f32, data_shape); auto result_vec = read_vector<float>(conv_test.d_data_val);
copy_data(_data, vector<float>{-0.67765152, 0.10073948, 0.57595438,
-0.3469252, -0.22134334, -1.80471897,
-0.80642909, 1.22033095, 2.23235631});
auto _weights = backend->make_primary_tensor_view(element::f32, weights_shape);
copy_data(_weights, vector<float>{0.20070229, -0.54968649, -0.19819015,
-0.38577855, 1.37109005, -0.23789984,
0.14867957, -0.49851316, -0.84815776});
auto _bias = backend->make_primary_tensor_view(element::f32, bias_shape);
copy_data(_bias, vector<float>{0.07811152});
auto _delta = backend->make_primary_tensor_view(element::f32, delta_shape);
copy_data(_delta, vector<float>{-2.58936238});
// results
auto _d_data = backend->make_primary_tensor_view(element::f32, data_shape);
copy_data(_d_data, vector<float>{0,0,0,
0,0,0,
0,0,0});
auto _d_weights = backend->make_primary_tensor_view(element::f32, weights_shape);
copy_data(_d_weights, vector<float>{0,0,0,
0,0,0,
0,0,0});
auto _d_bias = backend->make_primary_tensor_view(element::f32, bias_shape);
copy_data(_d_bias, vector<float>{0});
vector<float> expected_d_data{-0.51969099, 1.42333758, 0.5131861,
0.99892044, -3.5502491, 0.61600888,
-0.3849853, 1.29083121, 2.19618773};
vector<float> expected_d_weights{1.7546854, -0.26085103, -1.49135458,
0.89831507, 0.57313812, 4.67307138,
2.08813715, -3.15987897, -5.7803793};
vector<float> expected_d_bias{-2.58936238};
cf->call({_data, _weights, _bias, _delta}, {_d_data, _d_weights, _d_bias});
auto result_vec = read_vector<float>(_d_data);
for (size_t i = 0; i < result_vec.size(); ++i) { for (size_t i = 0; i < result_vec.size(); ++i) {
std::cout << result_vec[i] << " "; std::cout << result_vec[i] << " ";
} }
std::cout << std::endl; std::cout << std::endl;
result_vec = read_vector<float>(_d_weights); result_vec = read_vector<float>(conv_test.d_weights_val);
for (size_t i = 0; i < result_vec.size(); ++i) { for (size_t i = 0; i < result_vec.size(); ++i) {
std::cout << result_vec[i] << " "; std::cout << result_vec[i] << " ";
} }
std::cout << std::endl; std::cout << std::endl;
result_vec = read_vector<float>(_d_bias); result_vec = read_vector<float>(conv_test.d_bias_val);
for (size_t i = 0; i < result_vec.size(); ++i) { for (size_t i = 0; i < result_vec.size(); ++i) {
std::cout << result_vec[i] << " "; std::cout << result_vec[i] << " ";
} }
std::cout << std::endl; std::cout << std::endl;
EXPECT_TRUE(test::all_close(expected_d_data, read_vector<float>(_d_data))); EXPECT_TRUE(test::all_close(conv_test.expected_d_data_val, read_vector<float>(conv_test.d_data_val)));
EXPECT_TRUE(test::all_close(expected_d_weights, read_vector<float>(_d_weights))); EXPECT_TRUE(test::all_close(conv_test.expected_d_weights_val, read_vector<float>(conv_test.d_weights_val)));
EXPECT_TRUE(test::all_close(expected_d_bias, read_vector<float>(_d_bias))); EXPECT_TRUE(test::all_close(conv_test.expected_d_bias_val, read_vector<float>(conv_test.d_bias_val)));
} }
\ No newline at end of file
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