Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into remove-obsolete-i…
Browse files Browse the repository at this point in the history
…tt-profiling
  • Loading branch information
ilya-lavrenov committed Jan 27, 2021
2 parents b06494d + f88840d commit 9234687
Show file tree
Hide file tree
Showing 7 changed files with 422 additions and 57 deletions.
5 changes: 3 additions & 2 deletions inference-engine/src/gna_plugin/backend/am_intel_dnn.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2018-2020 Intel Corporation
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

Expand Down Expand Up @@ -201,7 +201,8 @@ void GNAPluginNS::backend::AMIntelDNN::InitConvolutional1DComponentPrivate(intel
}

if (comp.num_rows_in * comp.num_columns_in % 8 != 0) {
THROW_GNA_EXCEPTION << "Number of inputs to Convolutional1DComponent is not multiply by 8";
THROW_GNA_EXCEPTION << "Number of inputs to Convolutional1DComponent (" << comp.num_rows_in * comp.num_columns_in <<
") is not a multiply by 8";
}
if (comp.op.conv1D.num_filters < GNALimitations::convMinFiltersNum ||
comp.op.conv1D.num_filters > GNALimitations::convMaxFiltersNum ||
Expand Down
39 changes: 31 additions & 8 deletions inference-engine/src/gna_plugin/gna_graph_compiler.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2018-2020 Intel Corporation
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

Expand Down Expand Up @@ -356,7 +356,7 @@ void GNAGraphCompiler::finalizeConvolution1DPrimitive(InferenceEngine::CNNLayerP
uint32_t num_filters = convolution._out_depth;
uint32_t num_filter_coefficients = single_conv_kernel_size + num_conv_kernel_padding;
uint32_t num_filter_rows = num_filter_coefficients / num_feature_map_columns;
uint32_t num_columns_in = num_inputs;
uint32_t num_columns_in = num_inputs + num_input_padding;

uint32_t num_columns_out = (((num_inputs - num_filter_coefficients) / num_feature_map_columns) + 1) * convolution._out_depth;
uint32_t num_columns_out_unpadded = (((num_inputs - single_conv_kernel_size) / num_feature_map_columns) + 1) * convolution._out_depth;
Expand Down Expand Up @@ -841,15 +841,20 @@ void GNAGraphCompiler::PoolingPrimitive(InferenceEngine::CNNLayerPtr layer) {

IE_ASSERT(!layer->insData.empty());
IE_ASSERT(!layer->outData.empty());
printPoolingLayer(pooling);

auto inputs = layer->insData.begin()->lock();
auto outputs = *layer->outData.begin();

uint32_t w_dim_in = FROM_IR_DIM(inputs, 1);
uint32_t h_dim_in = FROM_IR_DIM(inputs, 2);
uint32_t c_dim_in = FROM_IR_DIM(inputs, 3);
uint32_t w_dim_out = FROM_IR_DIM(outputs, 1);
uint32_t h_dim_out = FROM_IR_DIM(outputs, 2);
uint32_t c_dim_out = FROM_IR_DIM(outputs, 3);
auto in_order = getFromIRDimsOrderNCHW(inputs->getLayout());
uint32_t w_dim_in = FROM_IR_DIM(inputs, in_order[3]);
uint32_t h_dim_in = FROM_IR_DIM(inputs, in_order[2]);
uint32_t c_dim_in = FROM_IR_DIM(inputs, in_order[1]);

auto out_order = getFromIRDimsOrderNCHW(outputs->getLayout());
uint32_t w_dim_out = FROM_IR_DIM(outputs, out_order[3]);
uint32_t h_dim_out = FROM_IR_DIM(outputs, out_order[2]);
uint32_t c_dim_out = FROM_IR_DIM(outputs, out_order[1]);

if (w_dim_in == 1) { // swap dimensions if needed to support swapped 1D case
swap(h_dim_in, w_dim_in);
Expand Down Expand Up @@ -2410,6 +2415,24 @@ void GNAGraphCompiler::printConvolutionLayer(const InferenceEngine::ConvolutionL
printTensorDesc("Output", layer.outData.front()->getTensorDesc());
}

void GNAGraphCompiler::printPoolingLayer(const InferenceEngine::PoolingLayer& layer) {
const char x = 'x';

gnalog() << "PoolingLayer '"
<< layer.name
<< "' Kernel: "
<< layer._kernel_x << x << layer._kernel_y
<< " Padding: "
<< layer._padding_x << x << layer._padding_y
<< " Stride: "
<< layer._stride_x << x << layer._stride_y
<< " Auto Padding: '"
<< layer._auto_pad << "'";
gnalog() << "\n";
printTensorDesc("Input", layer.input()->getTensorDesc());
printTensorDesc("Output", layer.outData.front()->getTensorDesc());
}

std::vector<uint8_t>
GNAGraphCompiler::transposeMatrix(uint8_t* ptr_matrix, size_t element_size, uint32_t num_rows, uint32_t num_cols) {
std::vector<uint8_t> temp_buffer(num_rows * num_cols * element_size);
Expand Down
3 changes: 2 additions & 1 deletion inference-engine/src/gna_plugin/gna_graph_compiler.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2018-2020 Intel Corporation
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

Expand Down Expand Up @@ -48,6 +48,7 @@ class GNAGraphCompiler {

static void printTensorDesc(const std::string& name, const InferenceEngine::TensorDesc& desc);
static void printConvolutionLayer(const InferenceEngine::ConvolutionLayer& layer);
static void printPoolingLayer(const InferenceEngine::PoolingLayer& layer);
static void assertConvolutionLayoutProper(const InferenceEngine::DataPtr&);
std::vector<uint8_t> static transposeMatrix(uint8_t* ptr_matrix, size_t element_size, uint32_t num_rows, uint32_t num_cols);
std::vector<std::size_t> static getFromIRDimsOrderNCHW(InferenceEngine::Layout layout);
Expand Down
120 changes: 77 additions & 43 deletions inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2018-2020 Intel Corporation
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

Expand Down Expand Up @@ -628,7 +628,8 @@ void ReversePermutationsPass::run() {
}

void RemovePermutationsNHWCToNCHWPass::run() {
std::list<CNNLayerPtr> permutationsToRemove;
std::set<CNNLayerPtr> permutations_to_remove;
std::list<std::pair<CNNLayerPtr, CNNLayerPtr>> nhwc_layout_patterns;
for (auto& l : *pLayers) {
if (!LayerInfo(l).isConvolution()) {
continue;
Expand All @@ -641,15 +642,31 @@ void RemovePermutationsNHWCToNCHWPass::run() {
if (getInputTo(l->outData.front()).empty()) {
continue;
}

if (!CNNNetHasPrevLayer(l.get())) {
continue;
}

auto next = getInputTo(l->outData.front()).begin()->second;
auto prev = CNNNetPrevLayer(l);
while (!LayerInfo(next).isPermute() && !LayerInfo(next).isNonFunctional() && !LayerInfo(next).isOutput() &&
next->outData.size() == 1) {
auto input_to = getInputTo(next->outData.front());
if (input_to.size() != 1) break;
next = input_to.begin()->second;
}

// The next layer must be NCHW to NHWC permute
if (!LayerInfo(next).isPermute() || next->input()->getLayout() != Layout::NCHW ||
next->GetParamAsInts("order") != GetPermuteOrder(Layout::NCHW, Layout::NHWC)) {
continue;
}

auto parent = CNNNetPrevLayer(l);
auto prev = parent;
while (!LayerInfo(prev).isPermute() && !LayerInfo(prev).isNonFunctional() &&
!LayerInfo(prev).isInput() && CNNNetHasPrevLayer(prev.get())) {
prev = CNNNetPrevLayer(prev);
}
// The previous layer must be NHWC to NCHW permute or have 1D data
if (LayerInfo(prev).isPermute()) {
if (prev->outData[0]->getLayout() != Layout::NCHW ||
Expand All @@ -658,62 +675,79 @@ void RemovePermutationsNHWCToNCHWPass::run() {
}

if (getPassManager()->getPolicy().NHWCToNCHWPolicy == Policy::NHWCToNCHW::REMOVE_ALL) {
permutationsToRemove.push_back(prev);
permutations_to_remove.insert(prev);
}
} else {
if (prev->outData.size() != 1 || getInputTo(prev->outData[0]).size() != 1) {
if (parent->outData.size() != 1 || getInputTo(parent->outData[0]).size() != 1) {
continue;
}
auto prev_dims = prev->outData[0]->getDims();
auto parent_dims = parent->outData[0]->getDims();
// Check if the previous layer has all dimensions except one to be equal to 1
if (std::count_if(std::begin(prev_dims), std::end(prev_dims), [](size_t dim) { return dim != 1; }) > 1) {
if (std::count_if(std::begin(parent_dims), std::end(parent_dims), [](size_t dim) { return dim != 1; }) > 1) {
continue;
}
}
permutationsToRemove.push_back(next);
permutations_to_remove.insert(next);
nhwc_layout_patterns.push_back({prev, next});

auto* convolution = dynamic_cast<ConvolutionLayer*>(l.get());
if (!convolution) {
THROW_GNA_EXCEPTION << "Invalid type of convolution layer";
}
if (convolution->_kernel_y != 1) {
THROW_GNA_LAYER_EXCEPTION(l) << "this case is not implemented yet";
}
auto in_channels = convolution->input()->getDims()[1];
convolution->_kernel_y = in_channels;
}

for (auto&& toRemove : permutationsToRemove) {
gnalog() << toRemove->type << " layer '" << toRemove->name << "' will be removed" << '\n';

if (!getInputTo(toRemove->outData.front()).empty()) {
auto next = getInputTo(toRemove->outData.front()).begin()->second;
IE_ASSERT(next != nullptr);

if (LayerInfo(next).isConvolution()) {
next->input()->setDims(toRemove->input()->getDims());
next->input()->setLayout(Layout::NHWC);
auto layerBeforePermute = CNNNetPrevLayer(toRemove);
DataPtr output = nullptr;
for (auto before_output : layerBeforePermute->outData) {
if (areEqualDatas(toRemove->input(), before_output)) {
output = before_output;
output->setLayout(Layout::NHWC);
break;
}
}
if (output == nullptr) {
THROW_GNA_EXCEPTION << "Could not find correct data link between " << toRemove->name << " and " << layerBeforePermute->name;
}
for (const auto& layers : nhwc_layout_patterns) {
auto pattern_start = layers.first;
auto pattern_end = layers.second;

auto setNHWCOrder = [](InferenceEngine::DataPtr data) {
if (data->getLayout() == Layout::NHWC) return;
auto dims = data->getDims();
auto order = GetPermuteOrder(Layout::NCHW, Layout::NHWC);
InferenceEngine::SizeVector new_dims;
for (int i = 0; i < dims.size(); ++i) {
new_dims.push_back(dims[order[i]]);
}
data->setDims(new_dims);
data->setLayout(Layout::NHWC);
};

auto* convolution = dynamic_cast<ConvolutionLayer*>(next.get());
if (!convolution) {
THROW_GNA_EXCEPTION << "There needs to be a convolution between permutations for RemovePermutationsNHWCToNCHWPass!";
}
auto current_layer = getInputTo(pattern_start->outData[0]).begin()->second;
setNHWCOrder(current_layer->input());
while (current_layer != pattern_end) {
setNHWCOrder(current_layer->outData[0]);
current_layer = getInputTo(current_layer->outData[0]).begin()->second;
}

if (convolution->_kernel_y != 1) {
THROW_GNA_LAYER_EXCEPTION(next) << "this case is not implemented yet";
if (LayerInfo(pattern_start).isPermute() && !getInputTo(pattern_start->outData.front()).empty()) {
auto layer_before_permute = CNNNetPrevLayer(pattern_start);
DataPtr output = nullptr;
for (auto before_output : layer_before_permute->outData) {
if (areEqualDatas(pattern_start->input(), before_output)) {
output = before_output;
output->setLayout(Layout::NHWC);
break;
}
auto in_channels = next->input()->getDims()[3];
convolution->_kernel_y = in_channels;
}
if (output == nullptr) {
THROW_GNA_EXCEPTION << "Could not find correct data link between " << pattern_start->name << " and " << layer_before_permute->name;
}
}
auto prev = CNNNetPrevLayer(toRemove);
if (LayerInfo(prev).isConvolution()) {
prev->outData[0]->setDims(toRemove->outData[0]->getDims());
prev->outData[0]->setLayout(Layout::NHWC);

if (!pattern_end->outData.empty() && !getInputTo(pattern_end->outData.front()).empty()) {
auto layer_after_permute = getInputTo(pattern_end->outData.front()).begin()->second;
layer_after_permute->input()->setLayout(Layout::NHWC);
}
CNNNetworkRemoveLayer(toRemove, false);
}

for (auto&& to_remove : permutations_to_remove) {
gnalog() << to_remove->type << " layer '" << to_remove->name << "' will be removed" << '\n';
CNNNetworkRemoveLayer(to_remove, false);
}
}

Expand Down
3 changes: 2 additions & 1 deletion inference-engine/src/legacy_api/src/cnn_network_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@ StatusCode CNNNetworkImpl::serialize(const std::string& xmlPath, const std::stri
noexcept {
try {
#ifdef ENABLE_V7_SERIALIZE
Serialization::Serialize(xmlPath, binPath, CNNNetwork(shared_from_this()));
Serialization::Serialize(xmlPath, binPath, CNNNetwork(
std::const_pointer_cast<ICNNNetwork>(shared_from_this())));
return OK;
#endif
} catch (const InferenceEngineException& e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Serialization {
* @param network network to be serialized
*/
void Serialize(const std::string& xmlPath, const std::string& binPath,
const InferenceEngine::ICNNNetwork& network);
const InferenceEngine::CNNNetwork& network);

} // namespace Serialization
} // namespace InferenceEngine
Loading

0 comments on commit 9234687

Please sign in to comment.