[GNA] Fix offset and size computation for Crop (#13400)
Fix GetCropParams
Add test to reproduce crop isue from ticket
Use convolution in the test
Cleanup get dim getters using backoffset
This commit is contained in:
committed by
GitHub
parent
cc1dd0bf1a
commit
fdd047edb9
@@ -10,6 +10,7 @@
|
||||
#include "backend/gna_types.h"
|
||||
#include "quantization.hpp"
|
||||
#include "weights_converter.hpp"
|
||||
#include "gna_graph_tools.hpp"
|
||||
|
||||
|
||||
namespace GNAPluginNS {
|
||||
@@ -192,7 +193,7 @@ static size_t GetBiasSizeForLayer(InferenceEngine::WeightableLayer& wl) {
|
||||
return wl._biases->size();
|
||||
} else if (LayerInfo(wl).isConvolution()) {
|
||||
// calculating biases len using outdata dims: biases number should be equal to output channels number
|
||||
size_t size = InferenceEngine::GetDataDimSize(wl.outData.front(), InferenceEngine::DataDimName::C);
|
||||
size_t size = InferenceEngine::GetDataDimByName(wl.outData.front(), InferenceEngine::DataDimName::C);
|
||||
return size;
|
||||
} else {
|
||||
// calculating biases size using outData dimensions
|
||||
|
||||
@@ -1264,7 +1264,7 @@ class ScaleFactorPerLayer<InferenceEngine::WeightableLayer*> {
|
||||
double weights_reducer = 1.0;
|
||||
auto conv = dynamic_cast<InferenceEngine::ConvolutionLayer *>(wl);
|
||||
if (conv && !LayerInfo(conv).isConvolutionFilter()) {
|
||||
const auto inDepth = GetDataDimSize(conv->insData.front().lock(), InferenceEngine::DataDimName::C);
|
||||
const auto inDepth = InferenceEngine::GetDataDimByName(conv->insData.front().lock(), InferenceEngine::DataDimName::C);
|
||||
weights_reducer = GNAConvolutionLayer::getWeightsReducer(*conv);
|
||||
weights_reducer *= MAX_VAL_2B_FEAT * scaleRange * inDepth / std::numeric_limits<int32_t>::max();
|
||||
weights_reducer = std::max(1.0, weights_reducer);
|
||||
|
||||
@@ -312,15 +312,15 @@ void GNAGraphCompiler::ConvolutionPrimitive(InferenceEngine::CNNLayerPtr layer)
|
||||
const auto outputs = layer->outData.front();
|
||||
assertConvolutionLayoutProper(inputs);
|
||||
|
||||
const auto in_batch = GetDataDimSize(inputs, InferenceEngine::DataDimName::N);
|
||||
const auto in_channels = GetDataDimSize(inputs, InferenceEngine::DataDimName::C);
|
||||
auto in_height = GetDataDimSize(inputs, InferenceEngine::DataDimName::H);
|
||||
auto in_width = GetDataDimSize(inputs, InferenceEngine::DataDimName::W);
|
||||
const auto in_batch = InferenceEngine::GetDataDimByName(inputs, InferenceEngine::DataDimName::N);
|
||||
const auto in_channels = InferenceEngine::GetDataDimByName(inputs, InferenceEngine::DataDimName::C);
|
||||
auto in_height = InferenceEngine::GetDataDimByName(inputs, InferenceEngine::DataDimName::H);
|
||||
auto in_width = InferenceEngine::GetDataDimByName(inputs, InferenceEngine::DataDimName::W);
|
||||
|
||||
const auto out_batch = GetDataDimSize(outputs, InferenceEngine::DataDimName::N);
|
||||
const auto out_channels = GetDataDimSize(outputs, InferenceEngine::DataDimName::C);
|
||||
auto out_height = GetDataDimSize(outputs, InferenceEngine::DataDimName::H);
|
||||
auto out_width = GetDataDimSize(outputs, InferenceEngine::DataDimName::W);
|
||||
const auto out_batch = InferenceEngine::GetDataDimByName(outputs, InferenceEngine::DataDimName::N);
|
||||
const auto out_channels = InferenceEngine::GetDataDimByName(outputs, InferenceEngine::DataDimName::C);
|
||||
auto out_height = InferenceEngine::GetDataDimByName(outputs, InferenceEngine::DataDimName::H);
|
||||
auto out_width = InferenceEngine::GetDataDimByName(outputs, InferenceEngine::DataDimName::W);
|
||||
|
||||
if (in_height > 1 && in_width == 1) {
|
||||
std::swap(in_height, in_width);
|
||||
@@ -906,13 +906,13 @@ void GNAGraphCompiler::PoolingPrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
auto inputs = layer->insData.begin()->lock();
|
||||
auto outputs = *layer->outData.begin();
|
||||
|
||||
uint32_t w_dim_in = GetDataDimSize(inputs, InferenceEngine::DataDimName::W);
|
||||
uint32_t h_dim_in = GetDataDimSize(inputs, InferenceEngine::DataDimName::H);
|
||||
const uint32_t c_dim_in = GetDataDimSize(inputs, InferenceEngine::DataDimName::C);
|
||||
uint32_t w_dim_in = InferenceEngine::GetDataDimByName(inputs, InferenceEngine::DataDimName::W);
|
||||
uint32_t h_dim_in = InferenceEngine::GetDataDimByName(inputs, InferenceEngine::DataDimName::H);
|
||||
const uint32_t c_dim_in = InferenceEngine::GetDataDimByName(inputs, InferenceEngine::DataDimName::C);
|
||||
|
||||
uint32_t w_dim_out = GetDataDimSize(outputs, InferenceEngine::DataDimName::W);
|
||||
uint32_t h_dim_out = GetDataDimSize(outputs, InferenceEngine::DataDimName::H);
|
||||
const uint32_t c_dim_out = GetDataDimSize(outputs, InferenceEngine::DataDimName::C);
|
||||
uint32_t w_dim_out = InferenceEngine::GetDataDimByName(outputs, InferenceEngine::DataDimName::W);
|
||||
uint32_t h_dim_out = InferenceEngine::GetDataDimByName(outputs, InferenceEngine::DataDimName::H);
|
||||
const uint32_t c_dim_out = InferenceEngine::GetDataDimByName(outputs, InferenceEngine::DataDimName::C);
|
||||
|
||||
if (w_dim_in == 1) { // swap dimensions if needed to support swapped 1D case
|
||||
swap(h_dim_in, w_dim_in);
|
||||
@@ -1142,11 +1142,9 @@ void GNAGraphCompiler::CropPrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
IE_ASSERT(!layer->insData.empty());
|
||||
auto inputs = layer->insData.begin()->lock();
|
||||
|
||||
size_t cropOffset, cropOutputSize;
|
||||
std::vector<int32_t> axis;
|
||||
std::tie(cropOffset, cropOutputSize, axis) = GetCropParams(cropLayer);
|
||||
size_t cropOffsetBytes = cropOffset * cropLayer->precision.size();
|
||||
size_t cropOutputSizeBytes = cropOutputSize * cropLayer->precision.size();
|
||||
const auto crop_params = GetCropParams(cropLayer);
|
||||
size_t cropOffsetBytes = crop_params.start_offset * cropLayer->precision.size();
|
||||
size_t cropOutputSizeBytes = crop_params.crop_size * cropLayer->precision.size();
|
||||
|
||||
if (!LayerInfo(cropLayer).isCropAffined()) {
|
||||
// leave crop as it is
|
||||
@@ -1175,11 +1173,6 @@ void GNAGraphCompiler::CropPrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
IE_ASSERT(!layer->outData.empty());
|
||||
auto outputs = *layer->outData.begin();
|
||||
|
||||
// only 1D crops supported
|
||||
if (axis.size() != 1) {
|
||||
THROW_GNA_EXCEPTION << "only 1D crop layer supported: " << cropLayer->name;
|
||||
}
|
||||
|
||||
// TODO: add unit tests for 4d crops blobs
|
||||
uint32_t num_rows_in = InferenceEngine::details::product(begin(inputs->getDims()), end(inputs->getDims()));
|
||||
uint32_t num_columns_in = 1;
|
||||
@@ -1222,7 +1215,7 @@ void GNAGraphCompiler::CropPrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
connectInput(layer, ptr_inputs, num_data_bytes_in, 0, 0);
|
||||
connectOutput(layer, ptr_outputs, num_data_bytes_out);
|
||||
|
||||
FillWeightOfAligningFilter(layer, ptr_weights, cropOffset, (quantized == nullptr) ? false : true);
|
||||
FillWeightOfAligningFilter(layer, ptr_weights, crop_params.start_offset, (quantized == nullptr) ? false : true);
|
||||
|
||||
(quantized == nullptr) ?
|
||||
gnamem->getQueue(REGION_RO)->push_value(layer, ptr_biases, 0.0f, num_rows_out, 64) :
|
||||
@@ -1297,16 +1290,16 @@ void GNAGraphCompiler::EltwisePrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
|
||||
auto outputs = *layer->outData.begin();
|
||||
|
||||
auto in_4b_batch = GetDataDimSize(inputs4Bytes, InferenceEngine::DataDimName::N);
|
||||
auto in_4b_channels = GetDataDimSize(inputs4Bytes, InferenceEngine::DataDimName::C);
|
||||
auto in_4b_height = GetDataDimSize(inputs4Bytes, InferenceEngine::DataDimName::H);
|
||||
auto in_4b_width = GetDataDimSize(inputs4Bytes, InferenceEngine::DataDimName::W);
|
||||
auto in_4b_batch = InferenceEngine::GetDataDimByName(inputs4Bytes, InferenceEngine::DataDimName::N);
|
||||
auto in_4b_channels = InferenceEngine::GetDataDimByName(inputs4Bytes, InferenceEngine::DataDimName::C);
|
||||
auto in_4b_height = InferenceEngine::GetDataDimByName(inputs4Bytes, InferenceEngine::DataDimName::H);
|
||||
auto in_4b_width = InferenceEngine::GetDataDimByName(inputs4Bytes, InferenceEngine::DataDimName::W);
|
||||
auto in_4b_total_size = in_4b_batch * in_4b_channels * in_4b_height * in_4b_width;
|
||||
|
||||
auto in_2b_batch = GetDataDimSize(inputs2Bytes, InferenceEngine::DataDimName::N);
|
||||
auto in_2b_channels = GetDataDimSize(inputs2Bytes, InferenceEngine::DataDimName::C);
|
||||
auto in_2b_height = GetDataDimSize(inputs2Bytes, InferenceEngine::DataDimName::H);
|
||||
auto in_2b_width = GetDataDimSize(inputs2Bytes, InferenceEngine::DataDimName::W);
|
||||
auto in_2b_batch = InferenceEngine::GetDataDimByName(inputs2Bytes, InferenceEngine::DataDimName::N);
|
||||
auto in_2b_channels = InferenceEngine::GetDataDimByName(inputs2Bytes, InferenceEngine::DataDimName::C);
|
||||
auto in_2b_height = InferenceEngine::GetDataDimByName(inputs2Bytes, InferenceEngine::DataDimName::H);
|
||||
auto in_2b_width = InferenceEngine::GetDataDimByName(inputs2Bytes, InferenceEngine::DataDimName::W);
|
||||
auto in_2b_total_size = in_2b_batch * in_2b_channels * in_2b_height * in_2b_width;
|
||||
|
||||
if (in_2b_batch != in_4b_batch) {
|
||||
@@ -1428,9 +1421,11 @@ void GNAGraphCompiler::GemmPrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
auto batch_size = (in_dims.size() == 1) ? 1 : in_dims.front();
|
||||
uint32_t num_rows_in = InferenceEngine::details::product(in_dims) / batch_size;
|
||||
uint32_t num_columns_in = batch_size;
|
||||
uint32_t num_rows_out = GetDataDimSize(outputs, 1);
|
||||
const auto out_dims = outputs->getDims();
|
||||
const auto out_dims_size = ngraph::shape_size(out_dims);
|
||||
const auto bytes_per_output = outputs->getPrecision().size();
|
||||
uint32_t num_rows_out = InferenceEngine::GetDimFromBack(out_dims, 1);
|
||||
uint32_t num_padding = ALIGN(num_rows_in, noOfInputsDivisor) - num_rows_in;
|
||||
uint32_t num_padding_out = 0;
|
||||
|
||||
// Gemm gets two inputs
|
||||
void* ptr_input_1 = nullptr; // the first input
|
||||
@@ -1443,9 +1438,9 @@ void GNAGraphCompiler::GemmPrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
dnn->InitAffineComponent(currentComponent,
|
||||
num_rows_in + num_padding,
|
||||
num_columns_in,
|
||||
num_rows_out + num_padding_out,
|
||||
num_rows_out,
|
||||
inputPrecision.size(),
|
||||
outputs->getPrecision().size(),
|
||||
bytes_per_output,
|
||||
quantized == nullptr ? input_2->getPrecision().size() : 2,
|
||||
quantized == nullptr ? input_2->getPrecision().size() : 4,
|
||||
GetScaleFactor(layer, QuantizedDataType::weights),
|
||||
@@ -1456,8 +1451,7 @@ void GNAGraphCompiler::GemmPrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
ptr_biases,
|
||||
false);
|
||||
|
||||
size_t num_data_bytes_out = InferenceEngine::details::product(begin(outputs->getDims()), end(outputs->getDims()))
|
||||
* outputs->getPrecision().size();
|
||||
const auto num_data_bytes_out = out_dims_size * bytes_per_output;
|
||||
|
||||
size_t num_data_bytes_in_1 = InferenceEngine::details::product(begin(input_1->getDims()), end(input_1->getDims()))
|
||||
* input_1->getPrecision().size();
|
||||
@@ -1483,6 +1477,7 @@ void GNAGraphCompiler::AffinePrimitive(InferenceEngine::CNNLayerPtr layer, bool
|
||||
IE_ASSERT(!layer->outData.empty());
|
||||
auto inputs = layer->insData.begin()->lock();
|
||||
auto outputs = *layer->outData.begin();
|
||||
const auto out_dims = outputs->getDims();
|
||||
Precision inputPrecision;
|
||||
uint32_t noOfInputsDivisor = GNALimitations::noOfInputsDivisor;
|
||||
|
||||
@@ -1501,7 +1496,7 @@ void GNAGraphCompiler::AffinePrimitive(InferenceEngine::CNNLayerPtr layer, bool
|
||||
auto batch_size = (in_dims.size() == 1) ? 1 : in_dims.front();
|
||||
uint32_t num_rows_in = InferenceEngine::details::product(in_dims) / batch_size;
|
||||
uint32_t num_columns_in = batch_size;
|
||||
uint32_t num_rows_out = isDiag ? num_rows_in : GetDataDimSize(outputs, 1);
|
||||
uint32_t num_rows_out = isDiag ? num_rows_in : InferenceEngine::GetDimFromBack(out_dims, 1);
|
||||
uint32_t num_padding = ALIGN(num_rows_in, noOfInputsDivisor) - num_rows_in;
|
||||
uint32_t num_padding_out = isDiag ? num_padding : 0;
|
||||
|
||||
@@ -1697,8 +1692,8 @@ void GNAGraphCompiler::ConcatAlignFilterPrimitive(InferenceEngine::CNNLayerPtr l
|
||||
|
||||
const uint32_t noOfInputsDivisor = gnaFlags->input_low_precision ?
|
||||
GNALimitations::noOfInputsLowPrecDivisor : GNALimitations::noOfInputsDivisor;
|
||||
uint32_t num_columns_in = GetDataDimSize(inputs, 2);
|
||||
uint32_t num_rows_out = GetDataDimSize(outputs, 1);
|
||||
uint32_t num_columns_in = GetDimFromBack(inputs->getDims(), 2);
|
||||
uint32_t num_rows_out = GetDimFromBack(outputs->getDims(), 1);
|
||||
uint32_t num_rows_in = filterLayer->_weights->size() / num_rows_out;
|
||||
uint32_t num_padding = ALIGN(num_rows_in, noOfInputsDivisor) - num_rows_in;
|
||||
|
||||
@@ -1929,10 +1924,10 @@ void GNAGraphCompiler::PWLPrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
|
||||
auto orientation = kDnnInterleavedOrientation;
|
||||
|
||||
uint32_t w_dim_in = GetDataDimSize(inputs, DataDimName::W);
|
||||
uint32_t h_dim_in = GetDataDimSize(inputs, DataDimName::H);
|
||||
uint32_t c_dim_in = GetDataDimSize(inputs, DataDimName::C);
|
||||
uint32_t n_dim_in = GetDataDimSize(inputs, DataDimName::N);
|
||||
uint32_t w_dim_in = GetDataDimByName(inputs, DataDimName::W);
|
||||
uint32_t h_dim_in = GetDataDimByName(inputs, DataDimName::H);
|
||||
uint32_t c_dim_in = GetDataDimByName(inputs, DataDimName::C);
|
||||
uint32_t n_dim_in = GetDataDimByName(inputs, DataDimName::N);
|
||||
num_columns = n_dim_in;
|
||||
num_rows = w_dim_in * h_dim_in * c_dim_in;
|
||||
|
||||
|
||||
@@ -128,8 +128,10 @@ inline std::pair<InferenceEngine::CNNLayerPtr, InferenceEngine::CNNLayerPtr> Fin
|
||||
// Check if reshape is expected for this pattern:
|
||||
// the next layer has the both, height and width dimensions > 1
|
||||
IE_ASSERT(in_dims_size == 3 || in_dims_size == 4);
|
||||
size_t height = in_dims_size == 3 ? 1 : GetDataDimSize(next->insData[0].lock(), InferenceEngine::DataDimName::H);
|
||||
size_t width = GetDataDimSize(next->insData[0].lock(), InferenceEngine::DataDimName::W);
|
||||
size_t height = in_dims_size == 3 ? 1
|
||||
: InferenceEngine::GetDataDimByName(next->insData[0].lock(),
|
||||
InferenceEngine::DataDimName::H);
|
||||
size_t width = InferenceEngine::GetDataDimByName(next->insData[0].lock(), InferenceEngine::DataDimName::W);
|
||||
if (out_dims_size < 3 || height != 1 || width != 1) {
|
||||
return std::make_pair(nullptr, nullptr);
|
||||
}
|
||||
@@ -178,11 +180,12 @@ inline std::pair<InferenceEngine::CNNLayerPtr, InferenceEngine::CNNLayerPtr> Fin
|
||||
// Check if reshape is expected for this pattern:
|
||||
// the previous layer has number of channels > 1 and one of height/width dimensions is also > 1
|
||||
in_dims_size = parent->insData[0].lock()->getDims().size();
|
||||
out_dims_size = parent->outData[0]->getDims().size();
|
||||
const auto out_dims = parent->outData[0]->getDims();
|
||||
out_dims_size = out_dims.size();
|
||||
IE_ASSERT(out_dims_size == 3 || out_dims_size == 4);
|
||||
size_t channels = GetDataDimSize(parent->outData[0], static_cast<uint32_t>(out_dims_size - 1));
|
||||
size_t height = out_dims_size == 3 ? 1 : GetDataDimSize(parent->outData[0], InferenceEngine::DataDimName::H);
|
||||
size_t width = GetDataDimSize(parent->outData[0], static_cast<uint32_t>(InferenceEngine::DataDimName::W));
|
||||
size_t channels = InferenceEngine::GetDimFromFront(out_dims, 1);
|
||||
size_t height = out_dims_size == 3 ? 1 : InferenceEngine::GetDataDimByName(parent->outData[0], InferenceEngine::DataDimName::H);
|
||||
size_t width = InferenceEngine::GetDimFromBack(out_dims, 3);
|
||||
if (in_dims_size < 3 || channels != 1 && (height != 1 || width != 1)) {
|
||||
return std::make_pair(nullptr, nullptr);
|
||||
}
|
||||
@@ -259,9 +262,9 @@ inline std::vector<TranspositionInfo> FindTranspositionInfoFromPrevLayers(Infere
|
||||
std::function<std::vector<TranspositionInfo>(InferenceEngine::CNNLayerPtr)> findTranspositionInfoRecursive =
|
||||
[&findTranspositionInfoRecursive](InferenceEngine::CNNLayerPtr layer) -> std::vector<TranspositionInfo> {
|
||||
auto getTransposeInfoFromData = [](InferenceEngine::DataPtr data, bool transpose = true) {
|
||||
auto rows = InferenceEngine::GetDataDimSize(data, InferenceEngine::DataDimName::C);
|
||||
auto columns = InferenceEngine::GetDataDimSize(data, InferenceEngine::DataDimName::H) *
|
||||
InferenceEngine::GetDataDimSize(data, InferenceEngine::DataDimName::W);
|
||||
auto rows = InferenceEngine::GetDataDimByName(data, InferenceEngine::DataDimName::C);
|
||||
auto columns = InferenceEngine::GetDataDimByName(data, InferenceEngine::DataDimName::H) *
|
||||
InferenceEngine::GetDataDimByName(data, InferenceEngine::DataDimName::W);
|
||||
return std::vector<TranspositionInfo>{{transpose, rows, columns}};
|
||||
};
|
||||
if (LayerInfo(layer).isConvolution() || LayerInfo(layer).isPooling()) {
|
||||
@@ -355,9 +358,9 @@ inline std::vector<TranspositionInfo> FindTranspositionInfoFromNextLayers(Infere
|
||||
std::function<std::vector<TranspositionInfo>(InferenceEngine::CNNLayerPtr)> findTranspositionInfoRecursive =
|
||||
[&findTranspositionInfoRecursive](InferenceEngine::CNNLayerPtr layer) -> std::vector<TranspositionInfo> {
|
||||
if (LayerInfo(layer).isConvolution()) {
|
||||
auto rows = InferenceEngine::GetDataDimSize(layer->input(), InferenceEngine::DataDimName::C);
|
||||
auto columns = InferenceEngine::GetDataDimSize(layer->input(), InferenceEngine::DataDimName::H) *
|
||||
InferenceEngine::GetDataDimSize(layer->input(), InferenceEngine::DataDimName::W);
|
||||
auto rows = InferenceEngine::GetDataDimByName(layer->input(), InferenceEngine::DataDimName::C);
|
||||
auto columns = InferenceEngine::GetDataDimByName(layer->input(), InferenceEngine::DataDimName::H) *
|
||||
InferenceEngine::GetDataDimByName(layer->input(), InferenceEngine::DataDimName::W);
|
||||
return {{true, rows, columns}};
|
||||
}
|
||||
|
||||
|
||||
@@ -776,14 +776,25 @@ inline void CNNNetworkReconnectLayer(CNNLayerPtr old_prev_layer, CNNLayerPtr new
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t GetDimFromFront(const InferenceEngine::SizeVector& dims, uint32_t dim) {
|
||||
if (dim >= dims.size()) {
|
||||
return 1;
|
||||
}
|
||||
return static_cast<uint32_t>(dims[dim]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns a size of a specified data dimension depending on its back offset
|
||||
* @param data a pointer to the data
|
||||
* @brief returns a specified dimension depending on its back offset
|
||||
* @param dims vector of dimensions
|
||||
* @param backOffset back dimension offset
|
||||
*/
|
||||
inline uint32_t GetDataDimSize(InferenceEngine::DataPtr data, uint32_t backOffset) {
|
||||
auto dims = data->getDims();
|
||||
return (dims.size() > backOffset - 1) ? static_cast<uint32_t>(dims[dims.size() - backOffset]) : uint32_t(1);
|
||||
|
||||
inline uint32_t GetDimFromBack(const InferenceEngine::SizeVector& dims, const uint32_t backOffset) {
|
||||
if (backOffset > dims.size()) {
|
||||
return 1;
|
||||
}
|
||||
const auto indexFromFront = dims.size() - backOffset;
|
||||
return GetDimFromFront(dims, indexFromFront);
|
||||
}
|
||||
|
||||
enum class DataDimName {
|
||||
@@ -795,7 +806,7 @@ enum class DataDimName {
|
||||
* @param data a pointer to the data
|
||||
* @param dimName dimension name
|
||||
*/
|
||||
inline uint32_t GetDataDimSize(InferenceEngine::DataPtr data, DataDimName dimName) {
|
||||
inline uint32_t GetDataDimByName(InferenceEngine::DataPtr data, DataDimName dimName) {
|
||||
uint32_t dimIxInNCHW = static_cast<uint32_t>(dimName);
|
||||
IE_ASSERT(dimIxInNCHW <= 3);
|
||||
|
||||
@@ -819,7 +830,8 @@ inline uint32_t GetDataDimSize(InferenceEngine::DataPtr data, DataDimName dimNam
|
||||
default:
|
||||
THROW_GNA_EXCEPTION << data->getName() << " Unexpected layout " << data->getLayout();
|
||||
}
|
||||
return GetDataDimSize(data, backOffsets[dimIxInNCHW]);
|
||||
auto dims = data->getDims();
|
||||
return GetDimFromBack(dims, backOffsets[dimIxInNCHW]);
|
||||
}
|
||||
|
||||
} // namespace InferenceEngine
|
||||
|
||||
@@ -40,9 +40,11 @@ double getWeightsReducer(InferenceEngine::ConvolutionLayer& conv) {
|
||||
// for kernelSize in {7, 8} -> 1.2
|
||||
const std::vector< KRT > reducers{ {49, 3.0}, {36, 2.6}, {21, 2.3}, {14, 1.7}, {9, 1.3}, {7, 1.2} };
|
||||
auto reducer = 1.0;
|
||||
const auto inDepth = GetDataDimSize(conv.insData.front().lock(), InferenceEngine::DataDimName::C);
|
||||
const auto inHeight = GetDataDimSize(conv.insData.front().lock(), InferenceEngine::DataDimName::H);
|
||||
const auto inWidth = GetDataDimSize(conv.insData.front().lock(), InferenceEngine::DataDimName::W);
|
||||
const auto inDepth = InferenceEngine::GetDataDimByName(conv.insData.front().lock(), InferenceEngine::DataDimName::C);
|
||||
const auto inHeight =
|
||||
InferenceEngine::GetDataDimByName(conv.insData.front().lock(), InferenceEngine::DataDimName::H);
|
||||
const auto inWidth =
|
||||
InferenceEngine::GetDataDimByName(conv.insData.front().lock(), InferenceEngine::DataDimName::W);
|
||||
if (isConv2D(inHeight, inWidth, inDepth, conv._kernel_y, conv._kernel_x) &&
|
||||
!isMappableFrom2DTo1D(inHeight, inWidth, inDepth, conv._kernel_y, conv._kernel_x, conv._stride_y, conv._stride_x)) {
|
||||
const auto kernelSize = conv._kernel_x * conv._kernel_y;
|
||||
|
||||
58
src/plugins/intel_gna/src/layers/gna_crop_layer.cpp
Normal file
58
src/plugins/intel_gna/src/layers/gna_crop_layer.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "gna_crop_layer.hpp"
|
||||
#include "../gna_plugin_log.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace GNAPluginNS {
|
||||
|
||||
SimpleCrop get_crop_params(const std::vector<int32_t>& axis_in,
|
||||
const std::vector<int32_t>& offset_in,
|
||||
const std::vector<int32_t>& dim_in,
|
||||
const std::vector<size_t>& input_dims) {
|
||||
const auto total_size_to_crop = ov::shape_size(input_dims);
|
||||
|
||||
SimpleCrop ret{0, total_size_to_crop};
|
||||
|
||||
auto crop_axis_detected = false;
|
||||
auto cropped_dim_size = total_size_to_crop;
|
||||
for (int n = 0; n < axis_in.size(); n++) {
|
||||
const auto axis = axis_in[n];
|
||||
if (axis < 0 || axis >= input_dims.size()) {
|
||||
gnawarn() << "Crop axis outside of input shape size detected.\n";
|
||||
continue;
|
||||
}
|
||||
const auto input_dim = input_dims[axis];
|
||||
// Skip axis that is untouched
|
||||
if (offset_in[n] == 0 && dim_in[n] == input_dim) {
|
||||
continue;
|
||||
}
|
||||
if (crop_axis_detected) {
|
||||
THROW_GNA_EXCEPTION
|
||||
<< "Crop layer does not support the number of (non-trivial) cropped dimensions more than 1.";
|
||||
}
|
||||
crop_axis_detected = true;
|
||||
ret.crop_size = dim_in[n];
|
||||
ret.start_offset = offset_in[n];
|
||||
cropped_dim_size = input_dim;
|
||||
}
|
||||
|
||||
if (crop_axis_detected) {
|
||||
ret.start_offset *= (total_size_to_crop / cropped_dim_size);
|
||||
ret.crop_size *= (total_size_to_crop / cropped_dim_size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SimpleCrop GetCropParams(InferenceEngine::CropLayer* cropLayer) {
|
||||
auto input_dims = cropLayer->insData.begin()->lock()->getDims();
|
||||
|
||||
const auto out_val = get_crop_params(cropLayer->axis, cropLayer->offset, cropLayer->dim, input_dims);
|
||||
return out_val;
|
||||
}
|
||||
|
||||
} // namespace GNAPluginNS
|
||||
@@ -5,7 +5,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <legacy/ie_layers.h>
|
||||
#include "gna_graph_tools.hpp"
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace GNAPluginNS {
|
||||
class GNACropLayer {
|
||||
@@ -24,44 +25,20 @@ public:
|
||||
void *gna_ptr = nullptr;
|
||||
};
|
||||
|
||||
struct SimpleCrop {
|
||||
size_t start_offset;
|
||||
size_t crop_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief returns parameters extracted from Crop layer: elements offset, elements output size and axes
|
||||
* @param cropLayer pointer to a Crop layer
|
||||
*/
|
||||
inline std::tuple<size_t, size_t, std::vector<int32_t>> GetCropParams(InferenceEngine::CropLayer* cropLayer) {
|
||||
IE_ASSERT(!cropLayer->axis.empty());
|
||||
IE_ASSERT(cropLayer->axis.size() == cropLayer->dim.size());
|
||||
IE_ASSERT(cropLayer->axis.size() == cropLayer->offset.size());
|
||||
SimpleCrop get_crop_params(const std::vector<int32_t>& axis_in,
|
||||
const std::vector<int32_t>& offset_in,
|
||||
const std::vector<int32_t>& dim_in,
|
||||
const std::vector<size_t>& input_dims);
|
||||
|
||||
std::vector<int> axis, dim, offset;
|
||||
auto inputs = cropLayer->insData.begin()->lock();
|
||||
for (int n = 0; n < cropLayer->axis.size(); n++) {
|
||||
uint32_t input_dim = GetDataDimSize(inputs, inputs->getDims().size() - cropLayer->axis[n]);
|
||||
// Exclude crop layer components that do nothing
|
||||
if (cropLayer->offset[n] == 0 && cropLayer->dim[n] == input_dim) {
|
||||
continue;
|
||||
}
|
||||
axis.push_back(cropLayer->axis[n]);
|
||||
dim.push_back(cropLayer->dim[n]);
|
||||
offset.push_back(cropLayer->offset[n]);
|
||||
}
|
||||
|
||||
if (axis.size() != 1) {
|
||||
THROW_GNA_EXCEPTION <<
|
||||
"Crop layer does not support the number of (non-trivial) cropped dimensions more than 1, provided: "
|
||||
<< axis.size() << ".";
|
||||
}
|
||||
|
||||
size_t cropOffset = offset.front();
|
||||
size_t cropOutputSize = dim.front();
|
||||
|
||||
// fix for crop on tensor dim > 2D
|
||||
for (int n = axis[0]+1; n < cropLayer->dim.size(); n++) {
|
||||
cropOffset *= cropLayer->dim[n];
|
||||
cropOutputSize *= cropLayer->dim[n];
|
||||
}
|
||||
|
||||
return std::make_tuple(cropOffset, cropOutputSize, axis);
|
||||
}
|
||||
SimpleCrop GetCropParams(InferenceEngine::CropLayer* cropLayer);
|
||||
|
||||
} // namespace GNAPluginNS
|
||||
|
||||
@@ -344,9 +344,8 @@ class LayerInfo {
|
||||
bool isCropAffined() const noexcept {
|
||||
auto cropLayer = dynamic_cast<InferenceEngine::CropLayer *> (layer);
|
||||
if (cropLayer != nullptr && !cropLayer->offset.empty()) {
|
||||
size_t offset;
|
||||
std::tie(offset, std::ignore, std::ignore) = GetCropParams(cropLayer);
|
||||
return GNAPluginNS::GNALimitations::isCropAffinedOffset(offset);
|
||||
const auto crop_params = GetCropParams(cropLayer);
|
||||
return GNAPluginNS::GNALimitations::isCropAffinedOffset(crop_params.start_offset);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2414,8 +2414,9 @@ void TransposeWeightsFromNCHWToNHWCPass::run() {
|
||||
|
||||
// Transpose all constant inputs
|
||||
for (auto && input : constInputs) {
|
||||
auto rows = GetDataDimSize(input->outData[0], DataDimName::C);
|
||||
auto columns = GetDataDimSize(input->outData[0], DataDimName::H) * GetDataDimSize(input->outData[0], DataDimName::W);
|
||||
auto rows = GetDataDimByName(input->outData[0], DataDimName::C);
|
||||
auto columns = GetDataDimByName(input->outData[0], DataDimName::H) *
|
||||
GetDataDimByName(input->outData[0], DataDimName::W);
|
||||
|
||||
auto blob = convertToRWBlob(input->blobs["custom"]);
|
||||
input->blobs["custom"] = blob;
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <ie_core.hpp>
|
||||
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include "functional_test_utils/plugin_cache.hpp"
|
||||
#include "shared_test_classes/base/layer_test_utils.hpp"
|
||||
#include "functional_test_utils/blob_utils.hpp"
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
|
||||
#include "ngraph_functions/pass/convert_prc.hpp"
|
||||
|
||||
typedef std::tuple<
|
||||
InferenceEngine::Precision, // Network Precision
|
||||
std::string, // Target Device
|
||||
std::map<std::string, std::string>, // Configuration
|
||||
std::vector<size_t> // input shape
|
||||
> cccmParams;
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
class CropAfterConvolutionTest : public testing::WithParamInterface<cccmParams>,
|
||||
public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<cccmParams> obj) {
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetDevice;
|
||||
std::map<std::string, std::string> configuration;
|
||||
std::vector<size_t> cropInputShape;
|
||||
std::tie(netPrecision, targetDevice, configuration, cropInputShape) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
result << "targetDevice=" << targetDevice << "_";
|
||||
for (auto const& configItem : configuration) {
|
||||
result << "_configItem=" << configItem.first << "_" << configItem.second;
|
||||
}
|
||||
result << "_CIS=" << CommonTestUtils::vec2str(cropInputShape);
|
||||
return result.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::vector<size_t> inputShape;
|
||||
std::tie(netPrecision, targetDevice, configuration, inputShape) = this->GetParam();
|
||||
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
auto reshape_pattern_size = ngraph::Shape{inputShape.size()};
|
||||
auto reshape_pattern = ngraph::builder::makeConstant(ov::element::i64, reshape_pattern_size, inputShape);
|
||||
auto params = ngraph::builder::makeParams(ngPrc, {inputShape});
|
||||
auto input_reshape = std::make_shared<ngraph::opset9::Reshape>(params[0], reshape_pattern, false);
|
||||
|
||||
const std::vector<size_t> filterSize{1, 1};
|
||||
const std::vector<size_t> strides{1, 1};
|
||||
const std::vector<ptrdiff_t> padsBegin{0, 0};
|
||||
const std::vector<ptrdiff_t> padsEnd{0, 0};
|
||||
const std::vector<size_t> dilations{1, 1};
|
||||
const auto pad_type = ngraph::op::PadType::EXPLICIT;
|
||||
const size_t numOutChannels = 8;
|
||||
constexpr auto c_index_in_nchw = 1;
|
||||
constexpr auto h_index_in_nchw = 2;
|
||||
const auto weights_size = ngraph::shape_size(filterSize) * numOutChannels * inputShape[c_index_in_nchw];
|
||||
auto weights_values = CommonTestUtils::generate_float_numbers(weights_size, -0.2f, 0.2f);
|
||||
const auto weights2_size = ngraph::shape_size(filterSize) * numOutChannels * numOutChannels;
|
||||
auto weights2_values = CommonTestUtils::generate_float_numbers(weights2_size, -0.2f, 0.2f);
|
||||
|
||||
auto convolution_node = ngraph::builder::makeConvolution(input_reshape,
|
||||
ngPrc,
|
||||
filterSize,
|
||||
strides,
|
||||
padsBegin,
|
||||
padsEnd,
|
||||
dilations,
|
||||
pad_type,
|
||||
numOutChannels,
|
||||
false,
|
||||
weights_values);
|
||||
|
||||
const std::vector<int64_t> crop_begin{4};
|
||||
const std::vector<int64_t> crop_end{20};
|
||||
const std::vector<int64_t> crop_stride{1};
|
||||
const std::vector<int64_t> axes{h_index_in_nchw};
|
||||
auto split_node =
|
||||
ngraph::builder::makeSlice(convolution_node, crop_begin, crop_end, crop_stride, axes, ngPrc);
|
||||
|
||||
auto convolution_node2 = ngraph::builder::makeConvolution(split_node,
|
||||
ngPrc,
|
||||
filterSize,
|
||||
strides,
|
||||
padsBegin,
|
||||
padsEnd,
|
||||
dilations,
|
||||
pad_type,
|
||||
numOutChannels,
|
||||
false,
|
||||
weights2_values);
|
||||
ngraph::ResultVector results{std::make_shared<ngraph::opset9::Result>(convolution_node2)};
|
||||
function = std::make_shared<ngraph::Function>(results, params, "CropAfterConvolutionTest");
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(CropAfterConvolutionTest, CompareWithRefImpl) {
|
||||
Run();
|
||||
};
|
||||
|
||||
const std::vector<InferenceEngine::Precision> netPrecisions = {
|
||||
InferenceEngine::Precision::FP16,
|
||||
InferenceEngine::Precision::FP32,
|
||||
};
|
||||
|
||||
const std::vector<std::map<std::string, std::string>> configs = {
|
||||
{
|
||||
{"GNA_DEVICE_MODE", "GNA_SW_EXACT"}
|
||||
},
|
||||
{
|
||||
{"GNA_DEVICE_MODE", "GNA_SW_FP32"}
|
||||
}
|
||||
};
|
||||
|
||||
const std::vector<std::vector<size_t>> input_shapes {
|
||||
{1, 8, 32, 16},
|
||||
{1, 16, 32, 16},
|
||||
{1, 8, 128, 32},
|
||||
{1, 16, 32, 32},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_crop_after_conv, CropAfterConvolutionTest,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GNA),
|
||||
::testing::ValuesIn(configs),
|
||||
::testing::ValuesIn(input_shapes)),
|
||||
CropAfterConvolutionTest::getTestCaseName);
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -18,17 +18,16 @@ typedef std::tuple<
|
||||
std::vector<int>, // Axes
|
||||
std::vector<int>, // Offset
|
||||
size_t, // Offset in flatten data
|
||||
size_t, // Output size in flatten data
|
||||
std::vector<int> // Axes which arre not skipped
|
||||
size_t // Output size in flatten data
|
||||
> CropParams;
|
||||
|
||||
const std::vector<CropParams> crop_params_vector = {
|
||||
{{8, 16}, {1, 16}, {0, 1}, {1, 0}, 16, 16, {0}},
|
||||
{{5, 24}, {1, 24}, {0, 1}, {2, 0}, 48, 24, {0}},
|
||||
{{8, 16}, {2, 16}, {0, 1}, {1, 0}, 16, 32, {0}},
|
||||
{{1, 16}, {1, 8}, {0, 1}, {0, 5}, 5, 8, {1}},
|
||||
{{1, 8, 16}, {1, 1, 16}, {0, 1, 2}, {0, 1, 0}, 16, 16, {1}},
|
||||
{{1, 1, 8, 16}, {1, 1, 1, 16}, {0, 1, 2, 3}, {0, 0, 1, 0}, 16, 16, {2}}
|
||||
{{8, 16}, {1, 16}, {0, 1}, {1, 0}, 16, 16},
|
||||
{{5, 24}, {1, 24}, {0, 1}, {2, 0}, 48, 24},
|
||||
{{8, 16}, {2, 16}, {0, 1}, {1, 0}, 16, 32},
|
||||
{{1, 16}, {1, 8}, {0, 1}, {0, 5}, 5, 8 },
|
||||
{{1, 8, 16}, {1, 1, 16}, {0, 1, 2}, {0, 1, 0}, 16, 16},
|
||||
{{1, 1, 8, 16}, {1, 1, 1, 16}, {0, 1, 2, 3}, {0, 0, 1, 0}, 16, 16}
|
||||
};
|
||||
|
||||
TEST(GetCropParamsTest, testGetCropParams) {
|
||||
@@ -37,8 +36,7 @@ TEST(GetCropParamsTest, testGetCropParams) {
|
||||
std::vector<size_t> in_shape;
|
||||
std::vector<int> orig_out_shape, orig_axes, orig_offset;
|
||||
size_t result_offset, result_out_size;
|
||||
std::vector<int> result_axes;
|
||||
std::tie(in_shape, orig_out_shape, orig_axes, orig_offset, result_offset, result_out_size, result_axes) = crop_params;
|
||||
std::tie(in_shape, orig_out_shape, orig_axes, orig_offset, result_offset, result_out_size) = crop_params;
|
||||
|
||||
auto crop_layer = std::make_shared<InferenceEngine::CropLayer>(attrs);
|
||||
auto layout = in_shape.size() == 2 ? InferenceEngine::NC : (in_shape.size() == 3 ? InferenceEngine::CHW : InferenceEngine::NCHW);
|
||||
@@ -48,12 +46,9 @@ TEST(GetCropParamsTest, testGetCropParams) {
|
||||
crop_layer->dim = orig_out_shape;
|
||||
crop_layer->axis = orig_axes;
|
||||
crop_layer->offset = orig_offset;
|
||||
size_t offset, out_size;
|
||||
std::vector<int32_t> axis;
|
||||
std::tie(offset, out_size, axis) = GNAPluginNS::GetCropParams(crop_layer.get());
|
||||
ASSERT_EQ(offset, result_offset);
|
||||
ASSERT_EQ(out_size, result_out_size);
|
||||
ASSERT_EQ(axis, result_axes);
|
||||
const auto results = GNAPluginNS::GetCropParams(crop_layer.get());
|
||||
ASSERT_EQ(results.start_offset, result_offset);
|
||||
ASSERT_EQ(results.crop_size, result_out_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user