[GNA] Added support permute layer (#723)
* [GNA] Added GNA natively supported permute layer cases.
This commit is contained in:
parent
18004bdb5e
commit
0bf1f53356
@ -311,6 +311,65 @@ void GNAPluginNS::backend::AMIntelDNN::InitPiecewiseLinearComponentPrivate(intel
|
||||
}
|
||||
}
|
||||
|
||||
void GNAPluginNS::backend::AMIntelDNN::InitInterleaveComponentPrivate(intel_dnn_component_t &comp,
|
||||
uint32_t num_rows_in,
|
||||
uint32_t num_columns_in,
|
||||
uint32_t num_bytes_per_input,
|
||||
uint32_t num_bytes_per_output,
|
||||
float output_scale_factor,
|
||||
void *&ptr_inputs,
|
||||
void *&ptr_outputs,
|
||||
bool postInitMem) {
|
||||
comp.num_rows_in = num_rows_in;
|
||||
comp.num_columns_in = num_columns_in;
|
||||
comp.num_rows_out = num_columns_in;
|
||||
comp.num_columns_out = num_rows_in;
|
||||
comp.num_bytes_per_input = num_bytes_per_input;
|
||||
comp.num_bytes_per_output = num_bytes_per_output;
|
||||
comp.operation = kDnnInterleaveOp;
|
||||
comp.macro_operation = kDnnMacroOpNone;
|
||||
comp.orientation_in = kDnnNonInterleavedOrientation;
|
||||
comp.orientation_out = kDnnInterleavedOrientation;
|
||||
comp.output_scale_factor = output_scale_factor;
|
||||
comp.input_scale_factor = output_scale_factor;
|
||||
if (!postInitMem) {
|
||||
comp.ptr_inputs = ptr_inputs;
|
||||
comp.ptr_outputs = ptr_outputs;
|
||||
} else {
|
||||
ptr_inputs = &comp.ptr_inputs;
|
||||
ptr_outputs = &comp.ptr_outputs;
|
||||
}
|
||||
}
|
||||
|
||||
void GNAPluginNS::backend::AMIntelDNN::InitDeinterleaveComponentPrivate(intel_dnn_component_t &comp,
|
||||
uint32_t num_rows_in,
|
||||
uint32_t num_columns_in,
|
||||
uint32_t num_bytes_per_input,
|
||||
uint32_t num_bytes_per_output,
|
||||
float output_scale_factor,
|
||||
void *&ptr_inputs,
|
||||
void *&ptr_outputs,
|
||||
bool postInitMem) {
|
||||
comp.num_rows_in = num_rows_in;
|
||||
comp.num_columns_in = num_columns_in;
|
||||
comp.num_rows_out = num_columns_in;
|
||||
comp.num_columns_out = num_rows_in;
|
||||
comp.num_bytes_per_input = num_bytes_per_input;
|
||||
comp.num_bytes_per_output = num_bytes_per_output;
|
||||
comp.operation = kDnnDeinterleaveOp;
|
||||
comp.macro_operation = kDnnMacroOpNone;
|
||||
comp.orientation_in = kDnnInterleavedOrientation;
|
||||
comp.orientation_out = kDnnNonInterleavedOrientation;
|
||||
comp.output_scale_factor = output_scale_factor;
|
||||
comp.input_scale_factor = output_scale_factor;
|
||||
if (!postInitMem) {
|
||||
comp.ptr_inputs = ptr_inputs;
|
||||
comp.ptr_outputs = ptr_outputs;
|
||||
} else {
|
||||
ptr_inputs = &comp.ptr_inputs;
|
||||
ptr_outputs = &comp.ptr_outputs;
|
||||
}
|
||||
}
|
||||
|
||||
void GNAPluginNS::backend::AMIntelDNN::Propagate() {
|
||||
for (uint32_t i = 0; i < component.size(); i++) {
|
||||
|
@ -193,6 +193,46 @@ public:
|
||||
true);
|
||||
}
|
||||
|
||||
template<class A, class B>
|
||||
static void InitDeinterleaveComponent(intel_dnn_component_t &cmp,
|
||||
uint32_t num_rows_in,
|
||||
uint32_t num_columns_in,
|
||||
uint32_t num_bytes_per_input,
|
||||
uint32_t num_bytes_per_output,
|
||||
float output_scale_factor,
|
||||
A *&ptr_inputs,
|
||||
B *&ptr_outputs) {
|
||||
InitDeinterleaveComponentPrivate(cmp,
|
||||
num_rows_in,
|
||||
num_columns_in,
|
||||
num_bytes_per_input,
|
||||
num_bytes_per_output,
|
||||
output_scale_factor,
|
||||
(void *&) ptr_inputs,
|
||||
(void *&) ptr_outputs,
|
||||
true);
|
||||
}
|
||||
|
||||
template<class A, class B>
|
||||
static void InitInterleaveComponent(intel_dnn_component_t &cmp,
|
||||
uint32_t num_rows_in,
|
||||
uint32_t num_columns_in,
|
||||
uint32_t num_bytes_per_input,
|
||||
uint32_t num_bytes_per_output,
|
||||
float output_scale_factor,
|
||||
A *&ptr_inputs,
|
||||
B *&ptr_outputs) {
|
||||
InitInterleaveComponentPrivate(cmp,
|
||||
num_rows_in,
|
||||
num_columns_in,
|
||||
num_bytes_per_input,
|
||||
num_bytes_per_output,
|
||||
output_scale_factor,
|
||||
(void *&) ptr_inputs,
|
||||
(void *&) ptr_outputs,
|
||||
true);
|
||||
}
|
||||
|
||||
|
||||
template<class A, class B>
|
||||
static void InitCopyComponent(intel_dnn_component_t &cmp,
|
||||
@ -343,6 +383,26 @@ private:
|
||||
intel_pwl_segment_t *ptr_segments,
|
||||
bool postInitMem);
|
||||
|
||||
static void InitInterleaveComponentPrivate(intel_dnn_component_t &cmp,
|
||||
uint32_t num_rows_in,
|
||||
uint32_t num_columns_in,
|
||||
uint32_t num_bytes_per_input,
|
||||
uint32_t num_bytes_per_output,
|
||||
float output_scale_factor,
|
||||
void *&ptr_inputs,
|
||||
void *&ptr_outputs,
|
||||
bool postInitMem);
|
||||
|
||||
static void InitDeinterleaveComponentPrivate(intel_dnn_component_t &cmp,
|
||||
uint32_t num_rows_in,
|
||||
uint32_t num_columns_in,
|
||||
uint32_t num_bytes_per_input,
|
||||
uint32_t num_bytes_per_output,
|
||||
float output_scale_factor,
|
||||
void *&ptr_inputs,
|
||||
void *&ptr_outputs,
|
||||
bool postInitMem);
|
||||
|
||||
static void InitConvolutional1DComponentPrivate(intel_dnn_component_t &comp,
|
||||
uint32_t num_rows_in,
|
||||
uint32_t num_columns_in,
|
||||
|
@ -1412,30 +1412,76 @@ case name:\
|
||||
}
|
||||
|
||||
void GNAGraphCompiler::PermutePrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
if (LayerInfo(layer).isTrivialPermute()) {
|
||||
return;
|
||||
}
|
||||
auto layerOrder = layer->GetParamAsInts("order");
|
||||
auto quantized = InferenceEngine::getInjectedData<QuantizedLayerParams>(layer);
|
||||
auto inputs = layer->insData.begin()->lock();
|
||||
auto inputsOrder = inputs->getTensorDesc().getDims();
|
||||
auto outputs = layer->outData.front();
|
||||
|
||||
string dimMessage;
|
||||
if (layerOrder == vector<int>({0, 3, 2, 1})) {
|
||||
return; // supported case
|
||||
// squeeze order vector
|
||||
SizeVector squeezedInputOrder;
|
||||
for (auto input_shape : inputsOrder) {
|
||||
if (input_shape != 1) squeezedInputOrder.push_back(input_shape);
|
||||
}
|
||||
SizeVector squeezedOutputOrder;
|
||||
for (auto output_shape : layerOrder) {
|
||||
if (output_shape != 0) squeezedOutputOrder.push_back(output_shape);
|
||||
}
|
||||
|
||||
if (layerOrder == vector<int>({1, 0, 2})) {
|
||||
IE_ASSERT(!layer->insData.empty());
|
||||
auto inputs = layer->insData.begin()->lock();
|
||||
auto inputs_size = inputs->getTensorDesc().getDims().size();
|
||||
if (inputs_size != layerOrder.size()) {
|
||||
THROW_IE_EXCEPTION << "[GNA plugin] Invalid input tensor size for permute layer " <<
|
||||
layer->GetParamAsString("order");
|
||||
}
|
||||
auto permuteDim0 = FROM_IR_DIM(inputs, inputs_size);
|
||||
auto permuteDim1 = FROM_IR_DIM(inputs, inputs_size - 1);
|
||||
if (permuteDim0 == 1 || permuteDim1 == 1) {
|
||||
return; // supported case
|
||||
}
|
||||
dimMessage = " (with first dim = " + to_string(permuteDim0) + ", second dim = " + to_string(permuteDim1) + ")";
|
||||
void* ptr_inputs = nullptr;
|
||||
void* ptr_outputs = nullptr;
|
||||
|
||||
if (squeezedInputOrder.size() > 2) {
|
||||
THROW_GNA_LAYER_EXCEPTION(layer) << "unsupported permute (requested transpose is not 2D)";
|
||||
}
|
||||
THROW_IE_EXCEPTION << "[GNA plugin] Unsupported permute order: was " << layer->GetParamAsString("order") <<
|
||||
dimMessage << ", but only support 1,0,2 (with first or second dim = 1) and 0,3,2,1";
|
||||
|
||||
if (std::min(squeezedInputOrder[0], squeezedInputOrder[1]) > 8) {
|
||||
THROW_GNA_LAYER_EXCEPTION(layer) << "unsupported permute (minor dimension="
|
||||
<< std::min(squeezedInputOrder[0], squeezedInputOrder[1]) << " > 8)";
|
||||
}
|
||||
|
||||
// now this can be run on GNA
|
||||
if (squeezedInputOrder[0] < squeezedInputOrder[1]) { // interleave case
|
||||
if (ALIGN(squeezedInputOrder[1], 8) != squeezedInputOrder[1]) {
|
||||
THROW_GNA_LAYER_EXCEPTION(layer) << "unsupported permute (row size not a multiple of 8)";
|
||||
} else {
|
||||
auto& currentComponent = dnnComponents.addComponent(layer->name, "interleave");
|
||||
dnn->InitInterleaveComponent(currentComponent,
|
||||
squeezedInputOrder[0],
|
||||
squeezedInputOrder[1],
|
||||
inputs->getPrecision().size(),
|
||||
outputs->getPrecision().size(),
|
||||
(quantized == nullptr) ? 1.0f : quantized->_dst_quant.scale,
|
||||
ptr_inputs,
|
||||
ptr_outputs);
|
||||
}
|
||||
|
||||
} else { // deinterleave case
|
||||
if (ALIGN(squeezedInputOrder[0], 8) != squeezedInputOrder[0]) {
|
||||
THROW_GNA_LAYER_EXCEPTION(layer) << "[GNA plugin] unsupported permute (column size not a multiple of 8)";
|
||||
} else {
|
||||
auto& currentComponent = dnnComponents.addComponent(layer->name, "deinterleave");
|
||||
dnn->InitDeinterleaveComponent(currentComponent,
|
||||
squeezedInputOrder[0],
|
||||
squeezedInputOrder[1],
|
||||
inputs->getPrecision().size(),
|
||||
outputs->getPrecision().size(),
|
||||
quantized == nullptr ? 1 : quantized->_dst_quant.scale,
|
||||
ptr_inputs,
|
||||
ptr_outputs);
|
||||
}
|
||||
}
|
||||
|
||||
size_t num_data_bytes_out = ALIGN(InferenceEngine::details::product(
|
||||
begin(outputs->getDims()), end(outputs->getDims())), 8)
|
||||
* outputs->getPrecision().size();
|
||||
size_t num_data_bytes_in = squeezedInputOrder[0] * squeezedInputOrder[1] * inputs->getPrecision().size();
|
||||
|
||||
connectInput(layer, ptr_inputs, num_data_bytes_in);
|
||||
connectOutput(layer, ptr_outputs, num_data_bytes_out);
|
||||
}
|
||||
|
||||
void SKIP(GNAGraphCompiler*, CNNLayerPtr) {}
|
||||
@ -1795,9 +1841,14 @@ GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer,
|
||||
return connectInput(prevLayer, ptr, num_data_bytes_in, offset, 0);
|
||||
}
|
||||
|
||||
// permute layer resulted in trivial permute
|
||||
if (LayerInfo(prevLayer).isPermute()) {
|
||||
gnalog() << "Skipping permute layer: " << prevLayer->name << "\n";
|
||||
return {connectInput(prevLayer, ptr, num_data_bytes_in, offset, 0).input, true, prevLayer};
|
||||
if (!LayerInfo(prevLayer).isTrivialPermute()) {
|
||||
// we should have GNA primitive for it
|
||||
THROW_GNA_EXCEPTION << "missed gna primitive for permute: " << prevLayer->name;
|
||||
}
|
||||
gnalog() << "Skipping trivial permute layer: " << prevLayer->name << "\n";
|
||||
return connectInput(prevLayer, ptr, num_data_bytes_in, offset, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "details/caseless.hpp"
|
||||
#include "ie_algorithm.hpp"
|
||||
#include "gna-api.h"
|
||||
#include "gna_permute.hpp"
|
||||
|
||||
|
||||
namespace GNAPluginNS {
|
||||
@ -194,6 +195,42 @@ class LayerInfo {
|
||||
bool isPermute() const noexcept {
|
||||
return isOfType("permute");
|
||||
}
|
||||
// @brief this not only mathematically trivial, has some WA for kaldi case
|
||||
bool isTrivialPermute() {
|
||||
if (!isPermute()) return false;
|
||||
|
||||
auto layerOrder = layer->GetParamAsInts("order");
|
||||
|
||||
if (layerOrder == std::vector<int>({ 0, 3, 2, 1 })) {
|
||||
return true; // supported case
|
||||
}
|
||||
auto inputs = layer->insData.begin()->lock();
|
||||
auto inputsOrder = inputs->getTensorDesc().getDims();
|
||||
|
||||
// cases when all permutations happened either between 1 and X shape where no other dims in between
|
||||
auto permuteSequence = genPermutations(layerOrder.begin(), layerOrder.end());
|
||||
auto inputsOrderTransformed = inputsOrder;
|
||||
for (auto && permute : permuteSequence) {
|
||||
// check dims of permuted
|
||||
if (inputsOrderTransformed[permute.first] == 1 &&
|
||||
inputsOrderTransformed[permute.second] == 1) {
|
||||
return true;
|
||||
}
|
||||
if (inputsOrderTransformed[permute.first] != 1 &&
|
||||
inputsOrderTransformed[permute.second] != 1) {
|
||||
return false;
|
||||
}
|
||||
// check dims in between
|
||||
for (int j = permute.first + 1; j != permute.second; j++) {
|
||||
if (inputsOrderTransformed[j] != 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// apply permutation
|
||||
std::swap(inputsOrderTransformed[permute.first], inputsOrderTransformed[permute.second]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool isPooling() const noexcept {
|
||||
return isOfType("pooling");
|
||||
}
|
||||
|
105
inference-engine/src/gna_plugin/layers/gna_permute.hpp
Normal file
105
inference-engine/src/gna_plugin/layers/gna_permute.hpp
Normal file
@ -0,0 +1,105 @@
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include "gna_plugin_log.hpp"
|
||||
|
||||
namespace GNAPluginNS {
|
||||
template <class T>
|
||||
class PermuteSequence {
|
||||
public:
|
||||
using cnt_type = std::vector<std::pair<T, T>>;
|
||||
|
||||
private:
|
||||
std::vector<T> orderVec;
|
||||
cnt_type permutes;
|
||||
|
||||
public:
|
||||
explicit PermuteSequence(std::vector<T> && orderVecIn) : orderVec(std::move(orderVecIn)) {
|
||||
std::vector<bool> counter(orderVec.size());
|
||||
for (auto && x : this->orderVec) {
|
||||
if (x < 0) {
|
||||
THROW_GNA_EXCEPTION << "invalid order: element " << x << " should be >= 0";
|
||||
}
|
||||
if (x >= counter.size()) {
|
||||
THROW_GNA_EXCEPTION << "invalid order: element " << x << " should be < "<< counter.size();
|
||||
}
|
||||
if (counter[x]) {
|
||||
THROW_GNA_EXCEPTION << "invalid order: element " << x << " present more than once";
|
||||
}
|
||||
counter[x] = true;
|
||||
}
|
||||
|
||||
// generating permutation graph
|
||||
std::fill(counter.begin(), counter.end(), false);
|
||||
|
||||
// length of current cycle
|
||||
std::list<cnt_type> permuteCycles;
|
||||
int seqId = 0;
|
||||
bool newSeq = false;
|
||||
|
||||
for (int i = 0; i != orderVec.size();) {
|
||||
// we have this permutation on the list already
|
||||
if (counter[i]) {
|
||||
newSeq = false;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
counter[i] = true;
|
||||
// looks we found a permutation
|
||||
if (orderVec[i] != i) {
|
||||
if (!newSeq) {
|
||||
newSeq = true;
|
||||
permuteCycles.push_back({});
|
||||
}
|
||||
permuteCycles.back().push_back({i, orderVec[i]});
|
||||
counter[i] = true;
|
||||
i = orderVec[i];
|
||||
continue;
|
||||
}
|
||||
// this dims not permuted
|
||||
i++;
|
||||
}
|
||||
|
||||
for (auto && cycle : permuteCycles) {
|
||||
for (int i = 0; i + 1 < cycle.size(); i++) {
|
||||
permutes.push_back(cycle[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
const cnt_type & cnt() const noexcept {
|
||||
return permutes;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief generates permutations sequence in order to reach given order
|
||||
* @tparam Iterator
|
||||
* @return
|
||||
*/
|
||||
template <class Iterator>
|
||||
inline typename PermuteSequence<typename std::iterator_traits<Iterator>::value_type>::cnt_type genPermutations(
|
||||
Iterator beg, Iterator en) {
|
||||
static_assert(
|
||||
std::is_same<std::random_access_iterator_tag,
|
||||
typename std::iterator_traits<Iterator>::iterator_category>::value,
|
||||
"The genPermutations() function only accepts random access iterators or raw pointers to an array.\n");
|
||||
using value_type = typename std::iterator_traits<Iterator>::value_type;
|
||||
std::vector<value_type> v;
|
||||
for (; beg != en; beg++) {
|
||||
v.push_back(*beg);
|
||||
}
|
||||
auto permute = PermuteSequence<value_type> (std::move(v));
|
||||
return permute.cnt();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename PermuteSequence<T>::cnt_type genPermutations(const std::initializer_list<T> & lst) {
|
||||
return genPermutations(lst.begin(), lst.end());
|
||||
}
|
||||
} // namespace GNAPluginNS
|
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <vector>
|
||||
#include "subgraph_tests/reshape_permute_reshape.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
|
||||
namespace {
|
||||
std::vector<std::vector<std::vector<size_t>>> inputs{
|
||||
{{1, 4 , 160}, {0, 2, 1}},
|
||||
{{8, 16}, {1, 0}},
|
||||
{{1, 1, 4, 16}, {3, 1, 2, 0}},
|
||||
{{1, 8, 200}, {0, 2, 1}},
|
||||
{{1, 8, 16}, {2, 1, 0}},
|
||||
};
|
||||
|
||||
std::vector<InferenceEngine::Precision> netPrecisions = {InferenceEngine::Precision::FP32,
|
||||
InferenceEngine::Precision::FP16,
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(reshape_permute_reshape, ReshapePermuteReshape,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputs),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GNA)),
|
||||
ReshapePermuteReshape::getTestCaseName);
|
||||
} // namespace
|
@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "functional_test_utils/layer_test_utils.hpp"
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
typedef std::tuple<
|
||||
std::vector<std::vector<size_t>>, //input shapes and permute shapes
|
||||
InferenceEngine::Precision, //Network precision
|
||||
std::string //Device name
|
||||
> ReshapePermuteReshapeTuple;
|
||||
|
||||
class ReshapePermuteReshape : public testing::WithParamInterface<ReshapePermuteReshapeTuple>,
|
||||
public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<ReshapePermuteReshapeTuple> &obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
} // namespace LayerTestsDefinitions
|
@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <debug.h>
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include "functional_test_utils/precision_utils.hpp"
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
#include "subgraph_tests/reshape_permute_reshape.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
std::string ReshapePermuteReshape::getTestCaseName(const testing::TestParamInfo<ReshapePermuteReshapeTuple> &obj) {
|
||||
std::vector<std::vector<size_t >> input;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetName;
|
||||
std::tie(input, netPrecision, targetName) = obj.param;
|
||||
std::ostringstream results;
|
||||
|
||||
results << "IS=" << CommonTestUtils::vec2str(input[0]) << "_";
|
||||
results << "netPRC=" << netPrecision.name() << "_";
|
||||
results << "targetDevice=" << targetName << "_";
|
||||
return results.str();
|
||||
}
|
||||
|
||||
void ReshapePermuteReshape::SetUp() {
|
||||
std::vector<std::vector<size_t >> inputs;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(inputs, netPrecision, targetDevice) = this->GetParam();
|
||||
const std::size_t input_dim = InferenceEngine::details::product(inputs[0]);
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
std::vector<size_t> shape_input{1, input_dim};
|
||||
auto input = ngraph::builder::makeParams(ngPrc, {shape_input});
|
||||
auto reshape1_pattern = std::make_shared<ngraph::op::Constant>(ngraph::element::i64,
|
||||
ngraph::Shape{inputs[0].size()},
|
||||
inputs[0]);
|
||||
auto reshape1 = std::make_shared<ngraph::op::v1::Reshape>(input[0], reshape1_pattern, false);
|
||||
auto permute_params = std::make_shared<ngraph::opset1::Constant>(ngraph::element::i64,
|
||||
ngraph::Shape{inputs[1].size()},
|
||||
inputs[1]);
|
||||
auto permute = std::make_shared<ngraph::opset1::Transpose>(reshape1, permute_params);
|
||||
auto reshape2_pattern = std::make_shared<ngraph::op::Constant>(ngraph::element::i64,
|
||||
ngraph::Shape{2},
|
||||
std::vector<size_t>{1, input_dim});
|
||||
auto reshape2 = std::make_shared<ngraph::op::v1::Reshape>(permute, reshape2_pattern, false);
|
||||
function = std::make_shared<ngraph::Function>(reshape2, input, "reshape_permute_reshape");
|
||||
}
|
||||
|
||||
TEST_P(ReshapePermuteReshape, CompareWithRefs){
|
||||
Run();
|
||||
if (targetDevice == std::string{CommonTestUtils::DEVICE_GPU}) {
|
||||
PluginCache::get().reset();
|
||||
} };
|
||||
} // namespace LayerTestsDefinitions
|
@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
#include <layers/gna_permute.hpp>
|
||||
|
||||
using namespace GNAPluginNS;
|
||||
|
||||
class PermuteSequenceTest : public ::testing::Test {
|
||||
};
|
||||
|
||||
TEST_F(PermuteSequenceTest, testImpossiblePermute_neg_value) {
|
||||
ASSERT_ANY_THROW(genPermutations({-1}));
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, testImpossiblePermute_big_value) {
|
||||
ASSERT_ANY_THROW(genPermutations({1}));
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, testImpossiblePermute_big_value_2) {
|
||||
ASSERT_ANY_THROW(genPermutations({0, 2}));
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, testImpossiblePermute_same_value) {
|
||||
ASSERT_ANY_THROW(genPermutations({0, 1, 0}));
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, testIdentity1d) {
|
||||
ASSERT_EQ(0, genPermutations({0}).size());
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, testIdentity2d) {
|
||||
ASSERT_EQ(0, genPermutations({0, 1}).size());
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, testIdentity3d) {
|
||||
ASSERT_EQ(0, genPermutations({0, 1, 2}).size());
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, testIdentity4d) {
|
||||
ASSERT_EQ(0, genPermutations({0, 1, 2, 3}).size());
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, test2d) {
|
||||
ASSERT_EQ(1, genPermutations({1, 0}).size());
|
||||
ASSERT_EQ(std::make_pair(0, 1), genPermutations({1, 0}).front());
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, test3d_1_Permutation) {
|
||||
ASSERT_EQ(1, genPermutations({1, 0, 2}).size());
|
||||
ASSERT_EQ(std::make_pair(0, 1), genPermutations({1, 0, 2})[0]);
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, test3d_1_Permutation_2) {
|
||||
ASSERT_EQ(1, genPermutations({2, 1, 0}).size());
|
||||
ASSERT_EQ(std::make_pair(0, 2), genPermutations({2, 1, 0})[0]);
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, test3d_2_Permutations) {
|
||||
ASSERT_EQ(2, genPermutations({2, 0, 1}).size());
|
||||
ASSERT_EQ(std::make_pair(0, 2), genPermutations({2, 0, 1})[0]);
|
||||
ASSERT_EQ(std::make_pair(2, 1), genPermutations({2, 0, 1})[1]);
|
||||
}
|
||||
|
||||
TEST_F(PermuteSequenceTest, test3d_4_Permutation) {
|
||||
auto permutation = {2, 1, 4, 5, 6, 3, 0, 7};
|
||||
ASSERT_EQ(4, genPermutations(permutation).size());
|
||||
ASSERT_EQ(std::make_pair(0, 2), genPermutations(permutation)[0]);
|
||||
ASSERT_EQ(std::make_pair(2, 4), genPermutations(permutation)[1]);
|
||||
ASSERT_EQ(std::make_pair(4, 6), genPermutations(permutation)[2]);
|
||||
ASSERT_EQ(std::make_pair(3, 5), genPermutations(permutation)[3]);
|
||||
}
|
@ -64,9 +64,9 @@ const Permute3dimTestParam gna_permute3d_test_params[] = {
|
||||
{{{1, 0, 2}, {8, 1, 1}}, true},
|
||||
{{{1, 0, 2}, {4, 2, 1}}, false},
|
||||
{{{1, 0, 2}, {2, 4, 1}}, false},
|
||||
{{{1, 2, 0}, {1, 2, 4}}, false},
|
||||
{{{0, 1, 2}, {1, 2, 4}}, false},
|
||||
{{{0, 2, 1}, {2, 1, 4}}, false},
|
||||
{{{1, 2, 0}, {1, 2, 4}}, true},
|
||||
{{{0, 1, 2}, {1, 2, 4}}, true},
|
||||
{{{0, 2, 1}, {2, 1, 4}}, true},
|
||||
{{{2, 0, 1}, {1, 2, 4}}, false},
|
||||
{{{2, 1, 0}, {2, 1, 4}}, false}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user