[CPU] add support for internal ops augrucell and augrusequence (#12647)
* [cpu] enable augru. * initiate opset_private_tbl.hpp for private ops. * fix ngraph_functions target_linker. * temporaliy disable a failure test.
This commit is contained in:
1 parent
4d1de75b24
commit
3bdb9cae54
16 files changed
+918
-13
No files matched your search
@@ -0,0 +1,11 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#ifndef _OPENVINO_OP_REG
|
||||
# warning "_OPENVINO_OP_REG not defined"
|
||||
# define _OPENVINO_OP_REG(x, y)
|
||||
#endif
|
||||
|
||||
_OPENVINO_OP_REG(AUGRUCell, ov::op::internal)
|
||||
_OPENVINO_OP_REG(AUGRUSequence, ov::op::internal)
|
||||
@@ -94,9 +94,11 @@ const InferenceEngine::details::caseless_unordered_map<std::string, Type> type_t
|
||||
{ "Transpose", Type::Transpose },
|
||||
{ "LSTMCell", Type::RNNCell },
|
||||
{ "GRUCell", Type::RNNCell },
|
||||
{ "AUGRUCell", Type::RNNCell },
|
||||
{ "RNNCell", Type::RNNCell },
|
||||
{ "LSTMSequence", Type::RNNSeq },
|
||||
{ "GRUSequence", Type::RNNSeq },
|
||||
{ "AUGRUSequence", Type::RNNSeq },
|
||||
{ "RNNSequence", Type::RNNSeq },
|
||||
{ "FakeQuantize", Type::FakeQuantize },
|
||||
{ "BinaryConvolution", Type::BinaryConvolution },
|
||||
|
||||
@@ -169,6 +169,30 @@ DnnlDesriptor::operator std::shared_ptr<dnnl::lbr_gru_forward::desc>() {
|
||||
return typeDesc->getPtr();
|
||||
}
|
||||
|
||||
DnnlDesriptor::DnnlDesriptor(std::shared_ptr<dnnl::augru_forward::desc> desc) {
|
||||
this->desc.reset(new DescFwdImpl<dnnl::augru_forward::desc>(desc));
|
||||
}
|
||||
|
||||
DnnlDesriptor::operator std::shared_ptr<dnnl::augru_forward::desc>() {
|
||||
auto typeDesc = std::dynamic_pointer_cast<DescFwdImpl<dnnl::augru_forward::desc>>(desc);
|
||||
if (typeDesc == nullptr) {
|
||||
IE_THROW() << "Cannot cast descriptor!";
|
||||
}
|
||||
return typeDesc->getPtr();
|
||||
}
|
||||
|
||||
DnnlDesriptor::DnnlDesriptor(std::shared_ptr<dnnl::lbr_augru_forward::desc> desc) {
|
||||
this->desc.reset(new DescFwdImpl<dnnl::lbr_augru_forward::desc>(desc));
|
||||
}
|
||||
|
||||
DnnlDesriptor::operator std::shared_ptr<dnnl::lbr_augru_forward::desc>() {
|
||||
auto typeDesc = std::dynamic_pointer_cast<DescFwdImpl<dnnl::lbr_augru_forward::desc>>(desc);
|
||||
if (typeDesc == nullptr) {
|
||||
IE_THROW() << "Cannot cast descriptor!";
|
||||
}
|
||||
return typeDesc->getPtr();
|
||||
}
|
||||
|
||||
DnnlDesriptor::DnnlDesriptor(std::shared_ptr<dnnl::eltwise_forward::desc> desc) {
|
||||
this->desc.reset(new DescFwdImpl<dnnl::eltwise_forward::desc>(desc));
|
||||
}
|
||||
|
||||
@@ -49,6 +49,12 @@ public:
|
||||
explicit DnnlDesriptor(std::shared_ptr<dnnl::lbr_gru_forward::desc> desc);
|
||||
operator std::shared_ptr<dnnl::lbr_gru_forward::desc>();
|
||||
|
||||
explicit DnnlDesriptor(std::shared_ptr<dnnl::augru_forward::desc> desc);
|
||||
operator std::shared_ptr<dnnl::augru_forward::desc>();
|
||||
|
||||
explicit DnnlDesriptor(std::shared_ptr<dnnl::lbr_augru_forward::desc> desc);
|
||||
operator std::shared_ptr<dnnl::lbr_augru_forward::desc>();
|
||||
|
||||
explicit DnnlDesriptor(std::shared_ptr<dnnl::eltwise_forward::desc> desc);
|
||||
operator std::shared_ptr<dnnl::eltwise_forward::desc>();
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
#include "memory_desc/dnnl_blocked_memory_desc.h"
|
||||
#include <common/primitive_hashing_utils.hpp>
|
||||
|
||||
#include "ngraph_ops/augru_cell.hpp"
|
||||
#include "ngraph_ops/augru_sequence.hpp"
|
||||
|
||||
#include <ngraph/node.hpp>
|
||||
|
||||
#include <string>
|
||||
@@ -61,6 +64,16 @@ static dnnl::algorithm ie2dnnl(const std::shared_ptr<const ov::Node>& op) {
|
||||
return dnnl::algorithm::lbr_gru;
|
||||
else
|
||||
return dnnl::algorithm::vanilla_gru;
|
||||
} else if (one_of(op->get_type_info(),
|
||||
ov::op::internal::AUGRUCell::get_type_info_static(),
|
||||
ov::op::internal::AUGRUSequence::get_type_info_static())) {
|
||||
auto gruCellOp = ov::as_type_ptr<const ov::op::internal::AUGRUCell>(op);
|
||||
auto gruSeqOp = ov::as_type_ptr<const ov::op::internal::AUGRUSequence>(op);
|
||||
if ((gruCellOp && gruCellOp->get_linear_before_reset()) ||
|
||||
(gruSeqOp && gruSeqOp->get_linear_before_reset()))
|
||||
return dnnl::algorithm::lbr_augru;
|
||||
else
|
||||
return dnnl::algorithm::vanilla_augru;
|
||||
} else if (one_of(op->get_type_info(),
|
||||
ov::op::v0::LSTMCell::get_type_info_static(),
|
||||
ov::op::v4::LSTMCell::get_type_info_static(),
|
||||
@@ -80,6 +93,8 @@ inline size_t gatesCount(const algorithm& alg) {
|
||||
switch (alg) {
|
||||
case algorithm::vanilla_rnn: return 1;
|
||||
case algorithm::vanilla_gru:
|
||||
case algorithm::vanilla_augru:
|
||||
case algorithm::lbr_augru:
|
||||
case algorithm::lbr_gru: return 3;
|
||||
case algorithm::vanilla_lstm: return 4;
|
||||
default:
|
||||
@@ -92,6 +107,8 @@ inline size_t statesCount(const dnnl::algorithm& alg) {
|
||||
switch (alg) {
|
||||
case dnnl::algorithm::vanilla_rnn:
|
||||
case dnnl::algorithm::vanilla_gru:
|
||||
case dnnl::algorithm::vanilla_augru:
|
||||
case dnnl::algorithm::lbr_augru:
|
||||
case dnnl::algorithm::lbr_gru: return 1;
|
||||
case dnnl::algorithm::vanilla_lstm: return 2;
|
||||
default:
|
||||
@@ -103,6 +120,9 @@ inline size_t statesCount(const dnnl::algorithm& alg) {
|
||||
inline bool haveCellState(const dnnl::algorithm& alg) {
|
||||
return alg == dnnl::algorithm::vanilla_lstm;
|
||||
}
|
||||
inline bool haveAttention(const dnnl::algorithm& alg) {
|
||||
return alg == dnnl::algorithm::vanilla_augru || alg == dnnl::algorithm::lbr_augru;
|
||||
}
|
||||
|
||||
const std::map<Precision, Precision> RNN::weightsByLayerPrec {
|
||||
// layer precision, weights precision
|
||||
@@ -177,6 +197,8 @@ bool RNN::isSupportedOperation(const std::shared_ptr<const ov::Node>& op, std::s
|
||||
try {
|
||||
if (!one_of(op->get_type_info(),
|
||||
ov::op::v3::GRUCell::get_type_info_static(),
|
||||
ov::op::internal::AUGRUCell::get_type_info_static(),
|
||||
ov::op::internal::AUGRUSequence::get_type_info_static(),
|
||||
ov::op::v0::LSTMCell::get_type_info_static(),
|
||||
ov::op::v4::LSTMCell::get_type_info_static(),
|
||||
ov::op::v0::RNNCell::get_type_info_static(),
|
||||
@@ -257,21 +279,28 @@ RNN::RNN(const std::shared_ptr<ov::Node>& op, const dnnl::engine& eng, WeightsSh
|
||||
IE_THROW(NotImplemented) << errorMessage;
|
||||
}
|
||||
|
||||
is_augru = one_of(op->get_type_info(),
|
||||
ov::op::internal::AUGRUCell::get_type_info_static(),
|
||||
ov::op::internal::AUGRUSequence::get_type_info_static());
|
||||
|
||||
is_cell = one_of(op->get_type_info(),
|
||||
ov::op::v0::RNNCell::get_type_info_static(),
|
||||
ov::op::v3::GRUCell::get_type_info_static(),
|
||||
ov::op::internal::AUGRUCell::get_type_info_static(),
|
||||
ov::op::v0::LSTMCell::get_type_info_static(),
|
||||
ov::op::v4::LSTMCell::get_type_info_static());
|
||||
|
||||
if (one_of(op->get_type_info(),
|
||||
ov::op::v0::RNNCell::get_type_info_static(),
|
||||
ov::op::v3::GRUCell::get_type_info_static())) {
|
||||
ov::op::v3::GRUCell::get_type_info_static(),
|
||||
ov::op::internal::AUGRUCell::get_type_info_static())) {
|
||||
wIdx = 2; rIdx = 3; bIdx = 4;
|
||||
} else if (one_of(op->get_type_info(),
|
||||
ov::op::v5::RNNSequence::get_type_info_static(),
|
||||
ov::op::v0::LSTMCell::get_type_info_static(),
|
||||
ov::op::v4::LSTMCell::get_type_info_static(),
|
||||
ov::op::v5::GRUSequence::get_type_info_static())) {
|
||||
ov::op::v5::GRUSequence::get_type_info_static(),
|
||||
ov::op::internal::AUGRUSequence::get_type_info_static())) {
|
||||
wIdx = 3; rIdx = 4; bIdx = 5;
|
||||
} else if (one_of(op->get_type_info(),
|
||||
ov::op::v0::LSTMSequence::get_type_info_static(),
|
||||
@@ -323,6 +352,8 @@ void RNN::initCell() {
|
||||
if (getInputShapeAtPort(0).getRank() != 2lu || getInputShapeAtPort(1).getRank() != 2lu)
|
||||
THROW_ERROR << "has incorrect input ranks. Data rank: " << getInputShapeAtPort(0).getRank() <<
|
||||
"; Hidden state rank: " << getInputShapeAtPort(1).getRank();
|
||||
if (is_augru && getInputShapeAtPort(5).getRank() != 2lu)
|
||||
THROW_ERROR << "has incorrect input ranks. Attention rank: " << getInputShapeAtPort(2).getRank();
|
||||
|
||||
T = {1, 1};
|
||||
if (cell_type == algorithm::vanilla_lstm)
|
||||
@@ -345,6 +376,13 @@ void RNN::initCell() {
|
||||
THROW_ERROR << "has incorrect input/output shapes. Cell state input: " << getInputShapeAtPort(2).toString() <<
|
||||
"; Cell state output: " << getOutputShapeAtPort(1).toString();
|
||||
}
|
||||
|
||||
if (is_augru) {
|
||||
const Shape shapeA{{N.minVal, 1}, {N.maxVal, 1}};
|
||||
if (getInputShapeAtPort(5).isStatic() && getInputShapeAtPort(5) != shapeA) {
|
||||
THROW_ERROR << "has incorrect input shapes. Attention shape: " << getInputShapeAtPort(5).toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RNN::fillCellDesc() {
|
||||
@@ -354,7 +392,11 @@ void RNN::fillCellDesc() {
|
||||
outShape = MemoryDescUtils::makeDummyShape({{T.minVal, N.minVal, SC}, {T.maxVal, N.maxVal, SC}});
|
||||
|
||||
// layer input plus states
|
||||
inDataDescs.reserve(S + 1);
|
||||
if (haveAttention(cell_type)) {
|
||||
inDataDescs.reserve(S + 2);
|
||||
} else {
|
||||
inDataDescs.reserve(S + 1);
|
||||
}
|
||||
outDataDescs.reserve(S + 1);
|
||||
|
||||
inDataDescs.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(inShape, dataType, memory::format_tag::tnc));
|
||||
@@ -368,6 +410,11 @@ void RNN::fillCellDesc() {
|
||||
outDataDescs.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(shapeS_4D, memory::data_type::f32, memory::format_tag::ldnc));
|
||||
}
|
||||
|
||||
if (haveAttention(cell_type)) {
|
||||
const Shape attnShape = MemoryDescUtils::makeDummyShape({{T.minVal, N.minVal, 1}, {T.maxVal, N.maxVal, 1}});
|
||||
inDataDescs.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(attnShape, dataType, memory::format_tag::tnc));
|
||||
}
|
||||
|
||||
copyWeightsData();
|
||||
|
||||
// Expected shapes.
|
||||
@@ -384,10 +431,15 @@ void RNN::fillCellDesc() {
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(shapeS, memory::data_type::f32, memory::format_tag::nc));
|
||||
outCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(shapeS, memory::data_type::f32, memory::format_tag::nc));
|
||||
}
|
||||
if (one_of(cell_type, dnnl::algorithm::vanilla_rnn, dnnl::algorithm::vanilla_gru, dnnl::algorithm::lbr_gru, dnnl::algorithm::vanilla_lstm)) {
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(WShape, memory::data_type::f32, memory::format_tag::nc));
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(RShape, memory::data_type::f32, memory::format_tag::nc));
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(BShape, memory::data_type::f32, memory::format_tag::x));
|
||||
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(WShape, memory::data_type::f32, memory::format_tag::nc));
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(RShape, memory::data_type::f32, memory::format_tag::nc));
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(BShape, memory::data_type::f32, memory::format_tag::x));
|
||||
|
||||
// note: the order matters. attention is the last input of augru.
|
||||
if (haveAttention(cell_type)) {
|
||||
Shape shapeAttn{{N.minVal, 1}, {N.maxVal, 1}};
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(shapeAttn, dataType, memory::format_tag::nc));
|
||||
}
|
||||
|
||||
createDescriptor(inCandidate, outCandidate);
|
||||
@@ -413,7 +465,11 @@ void RNN::initSequence() {
|
||||
DC = getInputShapeAtPort(3).getDims()[2];
|
||||
|
||||
// layer input plus states
|
||||
inDataDescs.reserve(S + 1);
|
||||
if (haveAttention(cell_type)) {
|
||||
inDataDescs.reserve(S + 2);
|
||||
} else {
|
||||
inDataDescs.reserve(S + 1);
|
||||
}
|
||||
outDataDescs.reserve(S + 1);
|
||||
}
|
||||
|
||||
@@ -437,6 +493,10 @@ void RNN::fillSequenceDesc() {
|
||||
inDataDescs.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(shapeS_4D, memory::data_type::f32, memory::format_tag::ldnc));
|
||||
outDataDescs.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(shapeS_4D, memory::data_type::f32, memory::format_tag::ldnc));
|
||||
}
|
||||
if (haveAttention(cell_type)) {
|
||||
const Shape attnShape = MemoryDescUtils::makeDummyShape({{T.minVal, N.minVal, 1}, {T.maxVal, N.maxVal, 1}});
|
||||
inDataDescs.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(attnShape, dataType, memory::format_tag::tnc));
|
||||
}
|
||||
|
||||
copyWeightsData();
|
||||
|
||||
@@ -472,6 +532,12 @@ void RNN::fillSequenceDesc() {
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(Shape{D, G * SC, SC}, memory::data_type::f32, memory::format_tag::ntc)); // R
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(Shape{D, Gb * SC}, memory::data_type::f32, memory::format_tag::nc)); // B
|
||||
|
||||
// note: the order matters. attention is the last input of augru.
|
||||
if (haveAttention(cell_type)) {
|
||||
Shape shapeAttn{{N.minVal, T.minVal, 1}, {N.maxVal, T.maxVal, 1}};
|
||||
inCandidate.emplace_back(std::make_shared<DnnlBlockedMemoryDesc>(shapeAttn, dataType, memory::format_tag::ntc));
|
||||
}
|
||||
|
||||
std::vector<MemoryDescPtr> outCandidate;
|
||||
outCandidate.reserve(3);
|
||||
|
||||
@@ -637,12 +703,12 @@ void RNN::copyWeightsData() {
|
||||
if (G > gate_map_lstm_size) {
|
||||
THROW_ERROR << ". G isn't equal to the size of gate_map.";
|
||||
}
|
||||
} else if (cell_type == dnnl::algorithm::vanilla_gru) {
|
||||
} else if (cell_type == dnnl::algorithm::vanilla_gru || cell_type == dnnl::algorithm::vanilla_augru) {
|
||||
gate_map = gate_map_gru;
|
||||
if (G > gate_map_gru_size) {
|
||||
THROW_ERROR << ". G isn't equal to the size of gate_map";
|
||||
}
|
||||
} else if (cell_type == dnnl::algorithm::lbr_gru) {
|
||||
} else if (cell_type == dnnl::algorithm::lbr_gru || cell_type == dnnl::algorithm::lbr_augru) {
|
||||
gate_map = gate_map_gru;
|
||||
if (G > gate_map_gru_size) {
|
||||
THROW_ERROR << ". G isn't equal to the size of gate_map.";
|
||||
@@ -734,6 +800,34 @@ void RNN::fillDescs() {
|
||||
/* Out State C */ outDataDescs[RNNInOutKind::CellState]->getDnnlDesc()));
|
||||
descs.push_back(desc);
|
||||
} break;
|
||||
case dnnl::algorithm::vanilla_augru: {
|
||||
DnnlDesriptor desc(std::make_shared<augru_forward::desc>(
|
||||
prop_kind::forward_scoring,
|
||||
direction,
|
||||
/* In Data */ inDataDescs[RNNInOutKind::Layer]->getDnnlDesc(),
|
||||
/* In State */ inDataDescs[RNNInOutKind::HiddenState]->getDnnlDesc(),
|
||||
/* In Attention */ inDataDescs[RNNInOutKind::Attention]->getDnnlDesc(),
|
||||
/* Weights data */ wDescs[0],
|
||||
/* Weights state */ wDescs[1],
|
||||
/* Bias */ wDescs[2],
|
||||
/* Out Data */ outDataDescs[RNNInOutKind::Layer]->getDnnlDesc(),
|
||||
/* Out State */ outDataDescs[RNNInOutKind::HiddenState]->getDnnlDesc()));
|
||||
descs.push_back(desc);
|
||||
} break;
|
||||
case dnnl::algorithm::lbr_augru: {
|
||||
DnnlDesriptor desc(std::make_shared<lbr_augru_forward::desc>(
|
||||
prop_kind::forward_scoring,
|
||||
direction,
|
||||
/* In Data */ inDataDescs[RNNInOutKind::Layer]->getDnnlDesc(),
|
||||
/* In State */ inDataDescs[RNNInOutKind::HiddenState]->getDnnlDesc(),
|
||||
/* In Attention */ inDataDescs[RNNInOutKind::Attention]->getDnnlDesc(),
|
||||
/* Weights data */ wDescs[0],
|
||||
/* Weights state */ wDescs[1],
|
||||
/* Bias */ wDescs[2],
|
||||
/* Out Data */ outDataDescs[RNNInOutKind::Layer]->getDnnlDesc(),
|
||||
/* Out State */ outDataDescs[RNNInOutKind::HiddenState]->getDnnlDesc()));
|
||||
descs.push_back(desc);
|
||||
} break;
|
||||
default:
|
||||
THROW_ERROR << "has unknown cell type.";
|
||||
}
|
||||
@@ -803,9 +897,12 @@ void RNN::prepareParams() {
|
||||
outDataDescs[2] = std::make_shared<DnnlBlockedMemoryDesc>(shapeS_4D, memory::data_type::f32, memory::format_tag::ldnc);
|
||||
}
|
||||
|
||||
if (haveAttention(cell_type)) {
|
||||
inDataDescs[2] = std::make_shared<DnnlBlockedMemoryDesc>(Shape{SL, B, 1}, dataType, memory::format_tag::tnc);
|
||||
}
|
||||
bool wFormatWasChanged = false;
|
||||
// WA To avoid different weights layer and iter formats in FP32 case.
|
||||
if (SL != 1 || B < optimalBatchSize) {
|
||||
if ((dataPrecision == Precision::FP32) && (SL != 1 || B < optimalBatchSize)) {
|
||||
if (wFormat != dnnl::memory::format_tag::ldigo) {
|
||||
wFormat = dnnl::memory::format_tag::ldigo;
|
||||
wFormatWasChanged = true;
|
||||
@@ -840,6 +937,12 @@ void RNN::prepareParams() {
|
||||
} else if (key.cellType == dnnl::algorithm::vanilla_lstm) {
|
||||
std::shared_ptr<lstm_forward::desc> desc = descs[0];
|
||||
return std::make_shared<lstm_forward>(lstm_forward::primitive_desc(*desc, attr, getEngine()));
|
||||
} else if (key.cellType == dnnl::algorithm::vanilla_augru) {
|
||||
std::shared_ptr<augru_forward::desc> desc = descs[0];
|
||||
return std::make_shared<augru_forward>(augru_forward::primitive_desc(*desc, attr, getEngine()));
|
||||
} else if (key.cellType == dnnl::algorithm::lbr_augru) {
|
||||
std::shared_ptr<lbr_augru_forward::desc> desc = descs[0];
|
||||
return std::make_shared<lbr_augru_forward>(lbr_augru_forward::primitive_desc(*desc, attr, getEngine()));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -909,6 +1012,10 @@ void RNN::execute(dnnl::stream strm) {
|
||||
for (size_t s = 0; s < S; s++) {
|
||||
args[state_i_tags[s]] = getParentEdgeAt(s+1)->getMemoryPtr()->GetPrimitive();
|
||||
}
|
||||
if (is_augru) {
|
||||
const auto atten_port = is_cell ? 5 : 6;
|
||||
args[DNNL_ARG_AUGRU_ATTENTION] = getParentEdgeAt(atten_port)->getMemoryPtr()->GetPrimitive();
|
||||
}
|
||||
|
||||
if (is_cell) {
|
||||
for (size_t s = 0; s < S; s++) {
|
||||
|
||||
@@ -59,6 +59,8 @@ private:
|
||||
/** Specify mode Cell or Seq. true - Cell, false - Seq */
|
||||
bool is_cell = false;
|
||||
|
||||
bool is_augru = false;
|
||||
|
||||
/** Native order if [batch, seq, data], other case is [seq, batch, data] */
|
||||
bool nativeOrder = true;
|
||||
|
||||
@@ -107,7 +109,8 @@ private:
|
||||
enum RNNInOutKind {
|
||||
Layer = 0,
|
||||
HiddenState = 1,
|
||||
CellState = 2
|
||||
CellState = 2,
|
||||
Attention = 2
|
||||
};
|
||||
|
||||
size_t wIdx = 0;
|
||||
|
||||
@@ -101,6 +101,9 @@
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <ngraph/graph_util.hpp>
|
||||
|
||||
#include "ngraph_ops/augru_cell.hpp"
|
||||
#include "ngraph_ops/augru_sequence.hpp"
|
||||
|
||||
#include <transformations/common_optimizations/lin_op_sequence_fusion.hpp>
|
||||
|
||||
#include <transformations/low_precision/disable_convert_constant_folding_on_const_path.hpp>
|
||||
@@ -355,6 +358,10 @@ static void TransformationUpToCPUSpecificOpSet(std::shared_ptr<ngraph::Function>
|
||||
node)) {
|
||||
return gru_cell->get_clip() == 0.0f
|
||||
&& gru_cell->get_activations() == std::vector<std::string>{"sigmoid", "tanh"};
|
||||
} else if (const auto &augru_cell = std::dynamic_pointer_cast<const ov::op::internal::AUGRUCell>(
|
||||
node)) {
|
||||
return augru_cell->get_clip() == 0.0f
|
||||
&& augru_cell->get_activations() == std::vector<std::string>{"sigmoid", "tanh"};
|
||||
} else if (const auto &lstm_cell = std::dynamic_pointer_cast<const ngraph::opset4::LSTMCell>(
|
||||
node)) {
|
||||
return lstm_cell->get_clip() == 0.0f &&
|
||||
@@ -391,6 +398,12 @@ static void TransformationUpToCPUSpecificOpSet(std::shared_ptr<ngraph::Function>
|
||||
gru_seq->get_activations() == std::vector<std::string>{"sigmoid", "tanh"} &&
|
||||
!ngraph::op::util::is_seq_len_provided(gru_seq->get_input_node_shared_ptr(2),
|
||||
max_seq_len);
|
||||
} else if (const auto &augru_seq = std::dynamic_pointer_cast<const ov::op::internal::AUGRUSequence>(
|
||||
node)) {
|
||||
return augru_seq->get_clip() == 0.0f &&
|
||||
augru_seq->get_activations() == std::vector<std::string>{"sigmoid", "tanh"} &&
|
||||
!ngraph::op::util::is_seq_len_provided(augru_seq->get_input_node_shared_ptr(2),
|
||||
max_seq_len);
|
||||
} else if (const auto &lstm_seq = std::dynamic_pointer_cast<const ngraph::opset6::LSTMSequence>(
|
||||
node)) {
|
||||
return lstm_seq->get_clip() == 0.0f &&
|
||||
|
||||
@@ -164,6 +164,9 @@ std::vector<std::string> disabledTestPatterns() {
|
||||
// is shared across plugins
|
||||
// passed local test and cpu has specific test cases with nms9 to cover
|
||||
R"(smoke_NmsLayerTest.*)",
|
||||
// Issue: 95915
|
||||
R"(smoke_dynamic/AUGRUCellCPUTest.CompareWithRefs/IS=\(\{\?\.1\}_\{\?\.1\}_\{\?\.1\}_\)_TS=\{\(1\.1\)_\(1\.1\)_\(1\.1\)\}_\{\(3\.1\)_\(3\.1\)_\(3\.1\)\}_\{\(5\.1\)_\(5\.1\)_\(5\.1\)\}_decompose=0_activations=\(sigmoid\.tanh\)_clip=0_linear=0_netPrec=f32__inFmts=nc\.nc_outFmts=nc_primitive=ref_any_PluginConf_ENFORCE_BF16=YES)", // NOLINT
|
||||
R"(smoke_dynamic/GRUCellCPUTest.CompareWithRefs/IS=\(\{\?\.1\}_\{\?\.1\}_\)_TS=\{\(1\.1\)_\(1\.1\)\}_\{\(3\.1\)_\(3\.1\)\}_\{\(5\.1\)_\(5\.1\)\}_decompose=0_activations=\(sigmoid\.tanh\)_clip=0_linear=0_netPrec=f32__inFmts=nc\.nc_outFmts=nc_primitive=ref_any_PluginConf_ENFORCE_BF16=YES)", // NOLINT
|
||||
// 94982. FP32->I32 conversion issue in the reference implementation. There can be some garbage in the rest of float values like 0.333333745.
|
||||
// The kernel does not have such garbage. The diff 0.000000745 is taken into account in calculations and affects further type conversion.
|
||||
// Reorder->GridSample->Reorder also does not work here. Potential fix is to use nearest conversion instead of truncation.
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "shared_test_classes/base/ov_subgraph.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "test_utils/cpu_test_utils.hpp"
|
||||
|
||||
using namespace CPUTestUtils;
|
||||
using namespace ov::test;
|
||||
|
||||
namespace CPULayerTestsDefinitions {
|
||||
|
||||
using AUGRUCellCpuSpecificParams = typename std::tuple<
|
||||
std::vector<InputShape>, // Shapes
|
||||
bool, // Using decompose to sub-ops transformation
|
||||
std::vector<std::string>, // Activations
|
||||
float, // Clip
|
||||
bool, // Linear before reset
|
||||
ElementType, // Network precision
|
||||
CPUSpecificParams, // CPU specific params
|
||||
std::map<std::string, std::string> // Additional config
|
||||
>;
|
||||
|
||||
class AUGRUCellCPUTest : public testing::WithParamInterface<AUGRUCellCpuSpecificParams>,
|
||||
virtual public ov::test::SubgraphBaseTest, public CPUTestsBase {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<AUGRUCellCpuSpecificParams> &obj) {
|
||||
std::vector<InputShape> inputShapes;
|
||||
bool decompose, linearBeforeReset;
|
||||
std::vector<std::string> activations;
|
||||
float clip = 0.f;
|
||||
ElementType netPrecision;
|
||||
CPUSpecificParams cpuParams;
|
||||
std::map<std::string, std::string> additionalConfig;
|
||||
|
||||
std::tie(inputShapes, decompose, activations, clip, linearBeforeReset, netPrecision, cpuParams, additionalConfig) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "IS=(";
|
||||
for (const auto& shape : inputShapes) {
|
||||
result << CommonTestUtils::partialShape2str({shape.first}) << "_";
|
||||
}
|
||||
result << ")_TS=";
|
||||
for (size_t i = 0lu; i < inputShapes.front().second.size(); i++) {
|
||||
result << "{";
|
||||
for (size_t j = 0lu; j < inputShapes.size(); j++) {
|
||||
result << CommonTestUtils::vec2str(inputShapes[j].second[i]) << (j < inputShapes.size() - 1 ? "_" : "");
|
||||
}
|
||||
result << "}_";
|
||||
}
|
||||
result << "decompose=" << decompose << "_";
|
||||
result << "activations=" << CommonTestUtils::vec2str(activations) << "_";
|
||||
result << "clip=" << clip << "_";
|
||||
result << "linear=" << linearBeforeReset << "_";
|
||||
result << "netPrec=" << netPrecision << "_";
|
||||
result << CPUTestsBase::getTestCaseName(cpuParams);
|
||||
|
||||
if (!additionalConfig.empty()) {
|
||||
result << "_PluginConf";
|
||||
for (auto &item : additionalConfig) {
|
||||
if (item.second == InferenceEngine::PluginConfigParams::YES)
|
||||
result << "_" << item.first << "=" << item.second;
|
||||
}
|
||||
}
|
||||
return result.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
std::vector<InputShape> inputShapes;
|
||||
bool decompose, linearBeforeReset;
|
||||
std::vector<std::string> activations;
|
||||
float clip = 0.f;
|
||||
ElementType netPrecision;
|
||||
CPUSpecificParams cpuParams;
|
||||
std::map<std::string, std::string> additionalConfig;
|
||||
|
||||
std::tie(inputShapes, decompose, activations, clip, linearBeforeReset, netPrecision, cpuParams, additionalConfig) = this->GetParam();
|
||||
std::tie(inFmts, outFmts, priority, selectedType) = cpuParams;
|
||||
targetDevice = CommonTestUtils::DEVICE_CPU;
|
||||
|
||||
init_input_shapes(inputShapes);
|
||||
|
||||
const size_t hiddenSize = targetStaticShapes.front()[1][1];
|
||||
const size_t inputSize = targetStaticShapes.front()[0][1];
|
||||
|
||||
configuration.insert(additionalConfig.begin(), additionalConfig.end());
|
||||
|
||||
if (additionalConfig[InferenceEngine::PluginConfigParams::KEY_ENFORCE_BF16] == InferenceEngine::PluginConfigParams::YES) {
|
||||
selectedType = makeSelectedTypeStr(selectedType, ElementType::bf16);
|
||||
} else {
|
||||
selectedType = makeSelectedTypeStr(selectedType, netPrecision);
|
||||
}
|
||||
|
||||
auto params = ngraph::builder::makeDynamicParams(netPrecision, inputDynamicShapes);
|
||||
std::vector<ngraph::Shape> WRB = {{3 * hiddenSize, inputSize}, {3 * hiddenSize, hiddenSize}, {(linearBeforeReset ? 4 : 3) * hiddenSize}};
|
||||
auto augruCellOp = ngraph::builder::makeAUGRU(
|
||||
ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)), WRB, hiddenSize/*, activations, {}, {}, clip, linearBeforeReset*/);
|
||||
|
||||
function = makeNgraphFunction(netPrecision, params, augruCellOp, "AUGRUCell");
|
||||
ov::pass::Serialize serializer("AUGRUCell.xml", "AUGRUCell.bin");
|
||||
serializer.run_on_model(function);
|
||||
std::cout << "Saved subgraph IR." << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(AUGRUCellCPUTest, CompareWithRefs) {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED()
|
||||
|
||||
run();
|
||||
CheckPluginRelatedResults(compiledModel, "RNNCell");
|
||||
}
|
||||
|
||||
namespace {
|
||||
/* CPU PARAMS */
|
||||
std::vector<std::map<std::string, std::string>> additionalConfig
|
||||
= {{{InferenceEngine::PluginConfigParams::KEY_ENFORCE_BF16, InferenceEngine::PluginConfigParams::NO}},
|
||||
{{InferenceEngine::PluginConfigParams::KEY_ENFORCE_BF16, InferenceEngine::PluginConfigParams::YES}}};
|
||||
|
||||
CPUSpecificParams cpuParams{{nc, nc}, {nc}, {"ref_any"}, "ref_any"};
|
||||
|
||||
std::vector<bool> shouldDecompose{false};
|
||||
// oneDNN supports only sigmoid-tanh
|
||||
std::vector<std::vector<std::string>> activations = {{"sigmoid", "tanh"}};
|
||||
// oneDNN supports only zero clip
|
||||
std::vector<float> clip = {0.f};
|
||||
// dev_api::augrucell does not support lbr so far.
|
||||
std::vector<bool> linearBeforeReset = {false};
|
||||
std::vector<ElementType> netPrecisions = { ElementType::f32 };
|
||||
|
||||
const std::vector<std::vector<ov::test::InputShape>> staticShapes = {
|
||||
{ { {}, { {1, 1} } }, // Static shapes
|
||||
{ {}, { {1, 1} } },
|
||||
{ {}, { {1, 1} } } },
|
||||
{ { {}, { {1, 1} } }, // Static shapes
|
||||
{ {}, { {1, 10} } },
|
||||
{ {}, { {1, 1} } } },
|
||||
{ { {}, { {1, 30} } }, // Static shapes
|
||||
{ {}, { {1, 10} } },
|
||||
{ {}, { {1, 1} } } },
|
||||
{ { {}, { {1, 30} } }, // Static shapes
|
||||
{ {}, { {1, 1} } },
|
||||
{ {}, { {1, 1} } } },
|
||||
{ { {}, { {3, 1} } }, // Static shapes
|
||||
{ {}, { {3, 1} } },
|
||||
{ {}, { {3, 1} } } },
|
||||
{ { {}, { {5, 1} } }, // Static shapes
|
||||
{ {}, { {5, 1} } },
|
||||
{ {}, { {5, 1} } } },
|
||||
{ { {}, { {5, 30} } }, // Static shapes
|
||||
{ {}, { {5, 10} } },
|
||||
{ {}, { {5, 1} } } }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_static, AUGRUCellCPUTest,
|
||||
::testing::Combine(::testing::ValuesIn(staticShapes),
|
||||
::testing::ValuesIn(shouldDecompose),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linearBeforeReset),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(cpuParams),
|
||||
::testing::ValuesIn(additionalConfig)),
|
||||
AUGRUCellCPUTest::getTestCaseName);
|
||||
|
||||
const std::vector<std::vector<ov::test::InputShape>> dynamicShapes = {
|
||||
{ { { {-1}, 1 }, // Dynamic shape 0
|
||||
{ {1, 1}, {3, 1}, {5, 1} } }, // Target shapes
|
||||
{ { {-1}, 1 }, // Dynamic shape 1
|
||||
{ {1, 1}, {3, 1}, {5, 1} } }, // Target shapes
|
||||
{ { {-1}, 1 }, // Dynamic shape 2
|
||||
{ {1, 1}, {3, 1}, {5, 1} } } }, // Target shapes
|
||||
{ { { {1, 10}, 30 }, // Dynamic shape 0
|
||||
{ {2, 30}, {5, 30}, {8, 30} } }, // Target shapes
|
||||
{ { {1, 10}, 10 }, // Dynamic shape 1
|
||||
{ {2, 10}, {5, 10}, {8, 10} } }, // Target shapes
|
||||
{ { {1, 10}, 1 }, // Dynamic shape 2
|
||||
{ {2, 1}, {5, 1}, {8, 1} } } }, // Target shapes
|
||||
{ { { {1, 10}, {25, 35} }, // Dynamic shape 0
|
||||
{ {2, 30}, {5, 30}, {8, 30} } }, // Target shapes
|
||||
{ { {1, 10}, -1 }, // Dynamic shape 1
|
||||
{ {2, 10}, {5, 10}, {8, 10} } }, // Target shapes
|
||||
{ { {1, 10}, 1 }, // Dynamic shape 2
|
||||
{ {2, 1}, {5, 1}, {8, 1} } } }, // Target shapes
|
||||
{ { { {1, 10}, {25, 35} }, // Dynamic shape 0
|
||||
{ {2, 30}, {5, 30}, {8, 30}, {2, 30}, {5, 30}, {8, 30} } }, // Target shapes
|
||||
{ { {1, 10}, -1 }, // Dynamic shape 1
|
||||
{ {2, 10}, {5, 10}, {8, 10}, {2, 10}, {5, 10}, {8, 10} } }, // Target shapes
|
||||
{ { {1, 10}, 1 }, // Dynamic shape 2
|
||||
{ {2, 1}, {5, 1}, {8, 1}, {2, 1}, {5, 1}, {8, 1} } } } // Target shapes
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_dynamic, AUGRUCellCPUTest,
|
||||
::testing::Combine(::testing::ValuesIn(dynamicShapes),
|
||||
::testing::ValuesIn(shouldDecompose),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linearBeforeReset),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(cpuParams),
|
||||
::testing::ValuesIn(additionalConfig)),
|
||||
AUGRUCellCPUTest::getTestCaseName);
|
||||
} // namespace
|
||||
} // namespace CPULayerTestsDefinitions
|
||||
@@ -0,0 +1,391 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "shared_test_classes/base/ov_subgraph.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "test_utils/cpu_test_utils.hpp"
|
||||
#include "transformations/op_conversions/bidirectional_sequences_decomposition.hpp"
|
||||
#include "transformations/op_conversions/convert_sequences_to_tensor_iterator.hpp"
|
||||
|
||||
using namespace CPUTestUtils;
|
||||
using namespace ov::test;
|
||||
|
||||
namespace CPULayerTestsDefinitions {
|
||||
|
||||
using AUGRUSequenceCpuSpecificParams = typename std::tuple<
|
||||
std::vector<InputShape>, // Shapes
|
||||
ngraph::helpers::SequenceTestsMode, // Pure Sequence or TensorIterator
|
||||
std::vector<std::string>, // Activations
|
||||
float, // Clip
|
||||
bool, // Linear_before_reset
|
||||
ov::op::RecurrentSequenceDirection, // Direction
|
||||
ElementType, // Network precision
|
||||
CPUSpecificParams, // CPU specific params
|
||||
std::map<std::string, std::string> // Additional config
|
||||
>;
|
||||
|
||||
class AUGRUSequenceCPUTest : public testing::WithParamInterface<AUGRUSequenceCpuSpecificParams>,
|
||||
virtual public ov::test::SubgraphBaseTest, public CPUTestsBase {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<AUGRUSequenceCpuSpecificParams> &obj) {
|
||||
std::vector<InputShape> inputShapes;
|
||||
ngraph::helpers::SequenceTestsMode seqMode;
|
||||
std::vector<std::string> activations;
|
||||
float clip;
|
||||
bool linearBeforeRest;
|
||||
ov::op::RecurrentSequenceDirection direction;
|
||||
ElementType netPrecision;
|
||||
CPUSpecificParams cpuParams;
|
||||
std::map<std::string, std::string> additionalConfig;
|
||||
|
||||
std::tie(inputShapes, seqMode, activations, clip, linearBeforeRest, direction, netPrecision, cpuParams, additionalConfig) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "IS=(";
|
||||
for (const auto& shape : inputShapes) {
|
||||
result << CommonTestUtils::partialShape2str({shape.first}) << "_";
|
||||
}
|
||||
result << ")_TS=";
|
||||
for (size_t i = 0lu; i < inputShapes.front().second.size(); i++) {
|
||||
result << "{";
|
||||
for (size_t j = 0lu; j < inputShapes.size(); j++) {
|
||||
result << CommonTestUtils::vec2str(inputShapes[j].second[i]) << (j < inputShapes.size() - 1 ? "_" : "");
|
||||
}
|
||||
result << "}_";
|
||||
}
|
||||
result << "seqMode=" << seqMode << "_";
|
||||
result << "activations=" << CommonTestUtils::vec2str(activations) << "_";
|
||||
result << "clip=" << clip << "_";
|
||||
result << "linear=" << linearBeforeRest << "_";
|
||||
result << "direction=" << direction << "_";
|
||||
result << "netPrec=" << netPrecision << "_";
|
||||
result << CPUTestsBase::getTestCaseName(cpuParams);
|
||||
|
||||
if (!additionalConfig.empty()) {
|
||||
result << "_PluginConf";
|
||||
for (auto &item : additionalConfig) {
|
||||
if (item.second == InferenceEngine::PluginConfigParams::YES)
|
||||
result << "_" << item.first << "=" << item.second;
|
||||
}
|
||||
}
|
||||
return result.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
std::vector<InputShape> inputShapes;
|
||||
ngraph::helpers::SequenceTestsMode seqMode;
|
||||
std::vector<std::string> activations;
|
||||
float clip;
|
||||
bool linearBeforeReset;
|
||||
ov::op::RecurrentSequenceDirection direction;
|
||||
ElementType netPrecision;
|
||||
CPUSpecificParams cpuParams;
|
||||
std::map<std::string, std::string> additionalConfig;
|
||||
|
||||
std::tie(inputShapes, seqMode, activations, clip, linearBeforeReset, direction, netPrecision, cpuParams, additionalConfig) = this->GetParam();
|
||||
std::tie(inFmts, outFmts, priority, selectedType) = cpuParams;
|
||||
targetDevice = CommonTestUtils::DEVICE_CPU;
|
||||
|
||||
init_input_shapes(inputShapes);
|
||||
if (inputDynamicShapes.size() == 2 && inputDynamicShapes[0][0].is_dynamic() && inputDynamicShapes[1][0].is_dynamic())
|
||||
throw std::runtime_error("Invalid test case. If 3rd input is constant, batch dimension must be static.");
|
||||
|
||||
// Method MemoryDesc::isSame can't correct compute layout for tensor with strides = 1
|
||||
// returned output format always tnc
|
||||
if (inFmts.size() == 2 && (inputDynamicShapes[0][0].is_static() && inputDynamicShapes[0][0].get_length() == 1 ||
|
||||
inputDynamicShapes[1].is_static() && ov::shape_size(inputDynamicShapes[1].to_shape()) == 1)) {
|
||||
inFmts[1] = tnc;
|
||||
}
|
||||
|
||||
configuration.insert(additionalConfig.begin(), additionalConfig.end());
|
||||
|
||||
const size_t hiddenSize = targetStaticShapes.front()[1][2];
|
||||
const size_t inputSize = targetStaticShapes.front()[0][2];
|
||||
const size_t numDirections = direction == ov::op::RecurrentSequenceDirection::BIDIRECTIONAL ? 2 : 1;
|
||||
|
||||
if (additionalConfig[InferenceEngine::PluginConfigParams::KEY_ENFORCE_BF16] == InferenceEngine::PluginConfigParams::YES) {
|
||||
selectedType = makeSelectedTypeStr(selectedType, ElementType::bf16);
|
||||
} else {
|
||||
selectedType = makeSelectedTypeStr(selectedType, netPrecision);
|
||||
}
|
||||
|
||||
auto params = ngraph::builder::makeDynamicParams(netPrecision, inputDynamicShapes);
|
||||
const size_t batchSize = inputDynamicShapes[0][0].is_static() ? inputDynamicShapes[0][0].get_length() :
|
||||
inputDynamicShapes[1][0].is_static() ? inputDynamicShapes[1][0].get_length() :
|
||||
inputDynamicShapes.size() > 2 && inputDynamicShapes[2][0].is_static() ? inputDynamicShapes[2][0].get_length() :
|
||||
1lu;
|
||||
/**
|
||||
* There are 2 options to paramter "in" when "make_sequence" is true.
|
||||
* 0 1 2 3
|
||||
* X init_hidden_state attention seq_length
|
||||
* or,
|
||||
* 0 1 2
|
||||
* X init_hidden_state attention
|
||||
*
|
||||
*/
|
||||
if (inputDynamicShapes.size() > 3) {
|
||||
if (!inputDynamicShapes[3].is_dynamic() &&
|
||||
seqMode != ngraph::helpers::SequenceTestsMode::CONVERT_TO_TI_MAX_SEQ_LEN_PARAM &&
|
||||
seqMode != ngraph::helpers::SequenceTestsMode::CONVERT_TO_TI_RAND_SEQ_LEN_PARAM) {
|
||||
params.pop_back();
|
||||
} else {
|
||||
params[3]->set_element_type(ElementType::i64);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ov::Shape> WRB = {{numDirections, 3 * hiddenSize, inputSize}, {numDirections, 3 * hiddenSize, hiddenSize},
|
||||
{numDirections, (linearBeforeReset ? 4 : 3) * hiddenSize}, {batchSize}};
|
||||
auto augruSequenceOp = ngraph::builder::makeAUGRU(ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
WRB,
|
||||
hiddenSize,
|
||||
true,
|
||||
direction,
|
||||
seqMode);
|
||||
|
||||
// method MemoryDesc::isSame can't correct compute layout for tensor with strides = 1
|
||||
// returned output format always tnc
|
||||
if (augruSequenceOp->get_output_partial_shape(0).is_static() && ov::shape_size(augruSequenceOp->get_output_shape(0)) == 1) {
|
||||
outFmts[0] = tnc;
|
||||
} else if (augruSequenceOp->get_output_partial_shape(1).is_static() && ov::shape_size(augruSequenceOp->get_output_shape(1)) == 1 ||
|
||||
augruSequenceOp->get_output_partial_shape(0)[0].is_static() && augruSequenceOp->get_output_partial_shape(0)[0].get_length() == 1) {
|
||||
outFmts[1] = tnc;
|
||||
}
|
||||
|
||||
function = makeNgraphFunction(netPrecision, params, augruSequenceOp, "augruSequenceOp");
|
||||
|
||||
if (seqMode != ngraph::helpers::SequenceTestsMode::PURE_SEQ) {
|
||||
// TODO: ConvertAUGRUSequenceToTensorIterator
|
||||
throw std::runtime_error("ConvertAUGRUSequenceToTensorIterator not implemented yet.");
|
||||
} else {
|
||||
bool ti_found = ngraph::helpers::is_tensor_iterator_exist(function);
|
||||
EXPECT_EQ(ti_found, false);
|
||||
}
|
||||
}
|
||||
|
||||
void generate_inputs(const std::vector<ov::Shape>& targetInputStaticShapes) override {
|
||||
SubgraphBaseTest::generate_inputs(targetInputStaticShapes);
|
||||
|
||||
const size_t batchSize = targetInputStaticShapes[0][0];
|
||||
const int64_t maxSeqLen = targetInputStaticShapes[0][1];
|
||||
const auto& funcInputs = function->inputs();
|
||||
if (funcInputs.size() > 3) {
|
||||
const auto& seqLenInput = inputs.find(funcInputs[3].get_node_shared_ptr());
|
||||
if (seqLenInput == inputs.end())
|
||||
throw std::runtime_error("Could not find Sequence length input.");
|
||||
|
||||
auto lenData = seqLenInput->second.data<ov::element_type_traits<ElementType::i64>::value_type>();
|
||||
std::fill(lenData, lenData + batchSize, maxSeqLen);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(AUGRUSequenceCPUTest, CompareWithRefs) {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED()
|
||||
|
||||
run();
|
||||
CheckPluginRelatedResults(compiledModel, "RNNSeq");
|
||||
}
|
||||
|
||||
namespace {
|
||||
/* CPU PARAMS */
|
||||
std::vector<std::map<std::string, std::string>> additionalConfig
|
||||
= {{{InferenceEngine::PluginConfigParams::KEY_ENFORCE_BF16, InferenceEngine::PluginConfigParams::NO}},
|
||||
{{InferenceEngine::PluginConfigParams::KEY_ENFORCE_BF16, InferenceEngine::PluginConfigParams::YES}}};
|
||||
|
||||
CPUSpecificParams cpuParams{{ntc, tnc}, {ntc, tnc}, {"ref_any"}, "ref_any"};
|
||||
CPUSpecificParams cpuParamsBatchSizeOne{{tnc, ntc}, {tnc, ntc}, {"ref_any"}, "ref_any"};;
|
||||
|
||||
std::vector<ngraph::helpers::SequenceTestsMode> mode{ngraph::helpers::SequenceTestsMode::PURE_SEQ};
|
||||
// output values increase rapidly without clip, so use only seq_lengths = 2
|
||||
std::vector<std::vector<std::string>> activations = {{"sigmoid", "tanh"}};
|
||||
// dev_api::augrucell does not support lbr so far.
|
||||
std::vector<bool> linearBeforeReset = {false};
|
||||
std::vector<float> clip{0.f};
|
||||
// dev_api::augrusequence only supports forward so far.
|
||||
std::vector<ov::op::RecurrentSequenceDirection> direction = {ov::op::RecurrentSequenceDirection::FORWARD};
|
||||
|
||||
std::vector<ElementType> netPrecisions = { ElementType::f32 };
|
||||
|
||||
const std::vector<std::vector<InputShape>> staticShapes = {
|
||||
{ { {}, { {10, 2, 10} } }, // #0. Static shapes
|
||||
{ {}, { {10, 1, 1} } },
|
||||
{ {}, { {10, 2, 1} } },
|
||||
{ {}, { {10} } } },
|
||||
{ { {}, { {10, 2, 10} } }, // #1. Static shapes
|
||||
{ {}, { {10, 1, 10} } },
|
||||
{ {}, { {10, 2, 1} } },
|
||||
{ {}, { {10} } } },
|
||||
{ { {}, { {1, 2, 10} } }, // #2. Static shapes
|
||||
{ {}, { {1, 1, 1} } },
|
||||
{ {}, { {1, 2, 1} } },
|
||||
{ {}, { {1} } } },
|
||||
{ { {}, { {1, 2, 10} } }, // #3. Static shapes
|
||||
{ {}, { {1, 1, 10} } },
|
||||
{ {}, { {1, 2, 1} } },
|
||||
{ {}, { {1} } } },
|
||||
{ { {}, { {10, 2, 10} } }, // #4. Static shapes
|
||||
{ {}, { {10, 1, 1} } },
|
||||
{ {}, { {10, 2, 1} } } },
|
||||
{ { {}, { {10, 2, 10} } }, // #5. Static shapes
|
||||
{ {}, { {10, 1, 10} } },
|
||||
{ {}, { {10, 2, 1} } } }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_static, AUGRUSequenceCPUTest,
|
||||
::testing::Combine(::testing::ValuesIn(std::vector<std::vector<InputShape>>{staticShapes[0], staticShapes[1]}),
|
||||
::testing::ValuesIn(mode),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linearBeforeReset),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(cpuParams),
|
||||
::testing::Values(std::map<std::string, std::string>{})),
|
||||
AUGRUSequenceCPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_static_BatchSizeOne, AUGRUSequenceCPUTest,
|
||||
::testing::Combine(::testing::ValuesIn(std::vector<std::vector<InputShape>>{staticShapes[3]}),
|
||||
::testing::ValuesIn(mode),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linearBeforeReset),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(cpuParamsBatchSizeOne),
|
||||
::testing::Values(std::map<std::string, std::string>{})),
|
||||
AUGRUSequenceCPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(nightly_static_bf16, AUGRUSequenceCPUTest,
|
||||
::testing::Combine(::testing::ValuesIn(std::vector<std::vector<InputShape>>{staticShapes[4], staticShapes[5]}),
|
||||
::testing::ValuesIn(mode),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linearBeforeReset),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(cpuParams),
|
||||
::testing::Values(additionalConfig[1])),
|
||||
AUGRUSequenceCPUTest::getTestCaseName);
|
||||
|
||||
const std::vector<std::vector<InputShape>> dynamicShapes = {
|
||||
{ { {-1, {1, 5}, 10}, // #0. Dynamic shape 0
|
||||
{ {10, 2, 10}, {8, 3, 10}, {5, 4, 10} } }, // Target shapes
|
||||
{ {{0, 15}, 1, 1}, // Dynamic shape 1
|
||||
{ {10, 1, 1}, {8, 1, 1}, {5, 1, 1} } }, // Target shapes
|
||||
{ {-1, {1, 5}, 1}, // Dynamic shape 2
|
||||
{ {10, 2, 1}, {8, 3, 1}, {5, 4, 1} } }, // Target shapes
|
||||
{ {{0, 12}}, // Dynamic shape 3
|
||||
{ {10}, {8}, {5} } } }, // Target shapes
|
||||
{ { {{0, 11}, -1, 10}, // #1. Dynamic shape 0
|
||||
{ {10, 2, 10}, {3, 4, 10}, {5, 5, 10} } }, // Target shapes
|
||||
{ {-1, 1, 10}, // Dynamic shape 1
|
||||
{ {10, 1, 10}, {3, 1, 10}, {5, 1, 10} } }, // Target shapes
|
||||
{ {{0, 11}, -1, 1}, // Dynamic shape 3
|
||||
{ {10, 2, 1}, {3, 4, 1}, {5, 5, 1} } }, // Target shapes
|
||||
{ {-1}, // Dynamic shape 2
|
||||
{ {10}, {3}, {5} } } }, // Target shapes
|
||||
{ { {{0, 11}, -1, {7, 11}}, // #2. Dynamic shape 0
|
||||
{ {10, 2, 10}, {3, 4, 10}, {5, 5, 10} } }, // Target shapes
|
||||
{ {-1, 1, {8, 12}}, // Dynamic shape 1
|
||||
{ {10, 1, 10}, {3, 1, 10}, {5, 1, 10} } }, // Target shapes
|
||||
{ {{0, 11}, -1, 1}, // Dynamic shape 3
|
||||
{ {10, 2, 1}, {3, 4, 1}, {5, 5, 1} } } , // Target shapes
|
||||
{ {-1}, // Dynamic shape 2
|
||||
{ {10}, {3}, {5} } } }, // Target shapes
|
||||
{ { {-1, {0, 7}, 10}, // #3. Dynamic shape 0
|
||||
{ {1, 2, 10}, {1, 3, 10}, {1, 6, 10} } }, // Target shapes
|
||||
{ {-1, 1, 1}, // Dynamic shape 1
|
||||
{ {1, 1, 1}, {1, 1, 1}, {1, 1, 1} } }, // Target shapes
|
||||
{ {-1, {0, 7}, 1}, // Dynamic shape 3
|
||||
{ {1, 2, 1}, {1, 3, 1}, {1, 6, 1} } }, // Target shapes
|
||||
{ {-1}, // Dynamic shape 2
|
||||
{ {1}, {1}, {1} } } }, // Target shapes
|
||||
{ { {1, -1, 10}, // #4. Dynamic shape 0
|
||||
{ {1, 2, 10}, {1, 4, 10}, {1, 8, 10} } }, // Target shapes
|
||||
{ {1, 1, 10}, // Dynamic shape 1
|
||||
{ {1, 1, 10}, {1, 1, 10}, {1, 1, 10} } }, // Target shapes
|
||||
{ {1, -1, 1}, // Dynamic shape 0
|
||||
{ {1, 2, 1}, {1, 4, 1}, {1, 8, 1} } }, // Target shapes
|
||||
{ {-1}, // Dynamic shape 2
|
||||
{ {1}, {1}, {1} } } }, // Target shapes
|
||||
{ { {-1, -1, -1}, // #5. Dynamic shape 0
|
||||
{ {1, 2, 10}, {1, 4, 10}, {1, 8, 10} } }, // Target shapes
|
||||
{ {-1, -1, -1}, // Dynamic shape 1
|
||||
{ {1, 1, 10}, {1, 1, 10}, {1, 1, 10} } }, // Target shapes
|
||||
{ {-1, -1, -1}, // Dynamic shape 0
|
||||
{ {1, 2, 1}, {1, 4, 1}, {1, 8, 1} } }, // Target shapes
|
||||
{ {-1}, // Dynamic shape 2
|
||||
{ {1}, {1}, {1} } } }, // Target shapes
|
||||
{ { {2, {1, 5}, 10}, // #6. Dynamic shape 0
|
||||
{ {2, 2, 10}, {2, 3, 10}, {2, 4, 10} } }, // Target shapes
|
||||
{ {2, 1, 1}, // Dynamic shape 1
|
||||
{ {2, 1, 1}, {2, 1, 1}, {2, 1, 1} } }, // Target shapes
|
||||
{ {2, {1, 5}, 1}, // Dynamic shape 2
|
||||
{ {2, 2, 1}, {2, 3, 1}, {2, 4, 1} } } }, // Target shapes
|
||||
{ { {5, -1, 10}, // #7. Dynamic shape 0
|
||||
{ {5, 2, 10}, {5, 4, 10}, {5, 5, 10} } }, // Target shapes
|
||||
{ {5, 1, 10}, // Dynamic shape 1
|
||||
{ {5, 1, 10}, {5, 1, 10}, {5, 1, 10} } }, // Target shapes
|
||||
{ {5, -1, 1}, // Dynamic shape 0
|
||||
{ {5, 2, 1}, {5, 4, 1}, {5, 5, 1} } } }, // Target shapes
|
||||
{ { {{0, 11}, -1, {7, 11}}, // #8. Dynamic shape 0
|
||||
{ {10, 2, 10}, {3, 4, 10}, {5, 5, 10}, {10, 2, 10}, {5, 5, 10} } }, // Target shapes
|
||||
{ {-1, 1, {8, 12}}, // Dynamic shape 1
|
||||
{ {10, 1, 10}, {3, 1, 10}, {5, 1, 10}, {10, 1, 10}, {5, 1, 10} } }, // Target shapes
|
||||
{ {{0, 11}, -1, 1}, // Dynamic shape 3
|
||||
{ {10, 2, 1}, {3, 4, 1}, {5, 5, 1}, {10, 2, 1}, {5, 5, 1} } }, // Target shapes
|
||||
{ {-1}, // Dynamic shape 2
|
||||
{ {10}, {3}, {5}, {10}, {5} } } } // Target shapes
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_dynamic, AUGRUSequenceCPUTest,
|
||||
::testing::Combine(::testing::ValuesIn({dynamicShapes[0], dynamicShapes[1], dynamicShapes[2]}),
|
||||
::testing::ValuesIn(mode),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linearBeforeReset),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(cpuParams),
|
||||
::testing::Values(std::map<std::string, std::string>{})),
|
||||
AUGRUSequenceCPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_dynamic_BatchSizeOne, AUGRUSequenceCPUTest,
|
||||
::testing::Combine(::testing::ValuesIn({dynamicShapes[4]}),
|
||||
::testing::ValuesIn(mode),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linearBeforeReset),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(cpuParamsBatchSizeOne),
|
||||
::testing::Values(std::map<std::string, std::string>{})),
|
||||
AUGRUSequenceCPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(nightly_dynamic, AUGRUSequenceCPUTest,
|
||||
::testing::Combine(::testing::ValuesIn({dynamicShapes[5], dynamicShapes[8]}),
|
||||
::testing::ValuesIn(mode),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linearBeforeReset),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(cpuParams),
|
||||
::testing::Values(std::map<std::string, std::string>{})),
|
||||
AUGRUSequenceCPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(nightly_dynamic_bf16, AUGRUSequenceCPUTest,
|
||||
::testing::Combine(::testing::ValuesIn({dynamicShapes[6], dynamicShapes[7]}),
|
||||
::testing::ValuesIn(mode),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linearBeforeReset),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(cpuParams),
|
||||
::testing::Values(additionalConfig[1])),
|
||||
AUGRUSequenceCPUTest::getTestCaseName);
|
||||
} // namespace
|
||||
} // namespace CPULayerTestsDefinitions
|
||||
@@ -166,6 +166,7 @@ void SubgraphBaseTest::compare(const std::vector<ov::Tensor>& expected,
|
||||
}
|
||||
}
|
||||
auto it = compareMap.find(inputNode->get_type_info());
|
||||
ASSERT_NE(it, compareMap.end());
|
||||
it->second(inputNode, i, expected[j], actual[j], abs_threshold, rel_threshold);
|
||||
}
|
||||
}
|
||||
@@ -232,6 +233,7 @@ void SubgraphBaseTest::generate_inputs(const std::vector<ov::Shape>& targetInput
|
||||
}
|
||||
}
|
||||
auto it = inputMap.find(nodePtr->get_type_info());
|
||||
ASSERT_NE(it, inputMap.end());
|
||||
for (size_t port = 0; port < nodePtr->get_input_size(); ++port) {
|
||||
if (nodePtr->get_input_node_ptr(port)->shared_from_this() == inputNode->shared_from_this()) {
|
||||
inputs.insert({param, it->second(nodePtr, port, param->get_element_type(), *itTargetShape++)});
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
//
|
||||
|
||||
#include "ngraph/ops.hpp"
|
||||
#include "ngraph_ops/augru_cell.hpp"
|
||||
#include "ngraph_ops/augru_sequence.hpp"
|
||||
|
||||
#include "shared_test_classes/base/layer_test_utils.hpp"
|
||||
#include "shared_test_classes/base/utils/compare_results.hpp"
|
||||
@@ -79,6 +81,7 @@ CompareMap getCompareMap() {
|
||||
#include "openvino/opsets/opset9_tbl.hpp"
|
||||
#include "openvino/opsets/opset10_tbl.hpp"
|
||||
|
||||
#include "ngraph_ops/opset_private_tbl.hpp"
|
||||
#undef _OPENVINO_OP_REG
|
||||
};
|
||||
return compareMap;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include <shared_test_classes/base/ov_subgraph.hpp>
|
||||
#include "ngraph/ops.hpp"
|
||||
#include "ngraph_ops/augru_cell.hpp"
|
||||
#include "ngraph_ops/augru_sequence.hpp"
|
||||
|
||||
#include <common_test_utils/ov_tensor_utils.hpp>
|
||||
|
||||
@@ -656,6 +658,54 @@ ov::runtime::Tensor generate(const std::shared_ptr<ngraph::op::v9::NonMaxSuppres
|
||||
}
|
||||
}
|
||||
|
||||
ov::runtime::Tensor generate(const std::shared_ptr<ov::op::internal::AUGRUSequence>& node,
|
||||
size_t port,
|
||||
const ov::element::Type& elemType,
|
||||
const ov::Shape& targetShape) {
|
||||
if (port == 6) {
|
||||
ov::runtime::Tensor tensor = ov::runtime::Tensor(elemType, targetShape);
|
||||
|
||||
const size_t range = 1;
|
||||
const size_t startFrom = 0;
|
||||
const size_t k = 1000;
|
||||
const int seed = 1;
|
||||
std::default_random_engine random(seed);
|
||||
std::uniform_int_distribution<int32_t> distribution(k * startFrom, k * (startFrom + range));
|
||||
|
||||
auto *dataPtr = tensor.data<float>();
|
||||
for (size_t i = 0; i < tensor.get_size(); i++) {
|
||||
auto value = static_cast<float>(distribution(random));
|
||||
dataPtr[i] = value / static_cast<float>(k);
|
||||
}
|
||||
return tensor;
|
||||
}
|
||||
return generate(std::dynamic_pointer_cast<ov::Node>(node), port, elemType, targetShape);
|
||||
}
|
||||
|
||||
ov::runtime::Tensor generate(const std::shared_ptr<ov::op::internal::AUGRUCell>& node,
|
||||
size_t port,
|
||||
const ov::element::Type& elemType,
|
||||
const ov::Shape& targetShape) {
|
||||
if (port == 5) {
|
||||
ov::runtime::Tensor tensor = ov::runtime::Tensor(elemType, targetShape);
|
||||
|
||||
const size_t range = 1;
|
||||
const size_t startFrom = 0;
|
||||
const size_t k = 1000;
|
||||
const int seed = 1;
|
||||
std::default_random_engine random(seed);
|
||||
std::uniform_int_distribution<int32_t> distribution(k * startFrom, k * (startFrom + range));
|
||||
|
||||
auto *dataPtr = tensor.data<float>();
|
||||
for (size_t i = 0; i < tensor.get_size(); i++) {
|
||||
auto value = static_cast<float>(distribution(random));
|
||||
dataPtr[i] = value / static_cast<float>(k);
|
||||
}
|
||||
return tensor;
|
||||
}
|
||||
return generate(std::dynamic_pointer_cast<ov::Node>(node), port, elemType, targetShape);
|
||||
}
|
||||
|
||||
template<ov::element::Type_t elemType>
|
||||
ov::runtime::Tensor generate_unique_possibilities(const ov::Shape &targetShape) {
|
||||
using value_type = typename element_type_traits<elemType>::value_type;
|
||||
@@ -691,7 +741,6 @@ ov::runtime::Tensor generate(const std::shared_ptr<ngraph::op::v6::ExperimentalD
|
||||
return generate(std::dynamic_pointer_cast<ov::Node>(node), port, elemType, targetShape);
|
||||
}
|
||||
|
||||
|
||||
ov::runtime::Tensor generate(const std::shared_ptr<ngraph::op::v5::RNNSequence>& node,
|
||||
size_t port,
|
||||
const ov::element::Type& elemType,
|
||||
@@ -733,6 +782,7 @@ InputsMap getInputMap() {
|
||||
#include "openvino/opsets/opset8_tbl.hpp"
|
||||
#include "openvino/opsets/opset9_tbl.hpp"
|
||||
|
||||
#include "ngraph_ops/opset_private_tbl.hpp"
|
||||
#undef _OPENVINO_OP_REG
|
||||
};
|
||||
return inputsMap;
|
||||
|
||||
@@ -20,6 +20,7 @@ addIeTarget(
|
||||
openvino::runtime
|
||||
ngraph_reference
|
||||
interpreter_backend
|
||||
openvino::runtime::dev
|
||||
ADD_CPPLINT
|
||||
DEVELOPER_PACKAGE
|
||||
tests
|
||||
|
||||
@@ -524,6 +524,13 @@ std::shared_ptr<ngraph::Node> makeGRU(const OutputVector& in,
|
||||
ngraph::op::RecurrentSequenceDirection direction = ngraph::op::RecurrentSequenceDirection::FORWARD,
|
||||
ngraph::helpers::SequenceTestsMode mode = ngraph::helpers::SequenceTestsMode::PURE_SEQ);
|
||||
|
||||
std::shared_ptr<ngraph::Node> makeAUGRU(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& constants,
|
||||
std::size_t hidden_size,
|
||||
bool make_sequence = false,
|
||||
ngraph::op::RecurrentSequenceDirection direction = ngraph::op::RecurrentSequenceDirection::FORWARD,
|
||||
ngraph::helpers::SequenceTestsMode mode = ngraph::helpers::SequenceTestsMode::PURE_SEQ);
|
||||
|
||||
std::shared_ptr<ngraph::Node> makeRNN(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& constants,
|
||||
std::size_t hidden_size,
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
|
||||
#include "ngraph_ops/augru_cell.hpp"
|
||||
#include "ngraph_ops/augru_sequence.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace builder {
|
||||
|
||||
/**
|
||||
* There are 2 options to paramter "in" when "make_sequence" is true.
|
||||
* 0 1 2 3
|
||||
* X init_hidden_state attention seq_length
|
||||
* or,
|
||||
* 0 1 2
|
||||
* X init_hidden_state attention
|
||||
*
|
||||
*/
|
||||
std::shared_ptr<ov::Node> makeAUGRU(const OutputVector& in,
|
||||
const std::vector<ov::Shape>& constants,
|
||||
std::size_t hidden_size,
|
||||
bool make_sequence,
|
||||
ov::op::RecurrentSequenceDirection direction,
|
||||
ngraph::helpers::SequenceTestsMode mode) {
|
||||
std::vector<float> empty;
|
||||
auto W = ngraph::builder::makeConstant(in[0].get_element_type(), constants[0], empty, true);
|
||||
W->set_friendly_name("augru_w");
|
||||
auto R = ngraph::builder::makeConstant(in[0].get_element_type(), constants[1], empty, true);
|
||||
R->set_friendly_name("augru_r");
|
||||
auto B = ngraph::builder::makeConstant(in[0].get_element_type(), constants[2], empty, true);
|
||||
B->set_friendly_name("augru_b");
|
||||
if (!make_sequence) {
|
||||
return std::make_shared<ov::op::internal::AUGRUCell>(in[0], in[1], W, R, B, in[2], hidden_size);
|
||||
} else {
|
||||
if (in.size() > 3 && in[3].get_partial_shape().is_dynamic()) {
|
||||
return std::make_shared<ov::op::internal::AUGRUSequence>(in[0], in[1], in[3], W, R, B, in[2], hidden_size);
|
||||
} else {
|
||||
std::shared_ptr<Node> seq_lengths;
|
||||
switch (mode) {
|
||||
case ngraph::helpers::SequenceTestsMode::PURE_SEQ:
|
||||
case ngraph::helpers::SequenceTestsMode::CONVERT_TO_TI_MAX_SEQ_LEN_CONST: {
|
||||
std::vector<float> lengths(in[0].get_partial_shape()[0].get_min_length(), in[0].get_partial_shape()[1].get_min_length());
|
||||
seq_lengths = ngraph::builder::makeConstant(element::i64, constants[3], lengths, false);
|
||||
break;
|
||||
}
|
||||
case ngraph::helpers::SequenceTestsMode::CONVERT_TO_TI_RAND_SEQ_LEN_CONST:
|
||||
case ngraph::helpers::SequenceTestsMode::PURE_SEQ_RAND_SEQ_LEN_CONST: {
|
||||
for (size_t i = 0; i <= in[0].get_shape().at(0); ++i) {
|
||||
std::vector<float> lengths;
|
||||
seq_lengths = ngraph::builder::makeConstant(element::i64, constants[3], lengths, true,
|
||||
static_cast<float>(in[0].get_shape()[1]), 0.f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ngraph::helpers::SequenceTestsMode::CONVERT_TO_TI_RAND_SEQ_LEN_PARAM:
|
||||
case ngraph::helpers::SequenceTestsMode::CONVERT_TO_TI_MAX_SEQ_LEN_PARAM:
|
||||
case ngraph::helpers::SequenceTestsMode::PURE_SEQ_RAND_SEQ_LEN_PARAM: {
|
||||
// Seq_lengths should be as a Parameter node for these two modes
|
||||
if (in.size() < 4) throw std::runtime_error("Incorrect number of inputs for creation of Sequence operation");
|
||||
seq_lengths = in.at(3).get_node_shared_ptr();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("Incorrect mode for creation of Sequence operation");
|
||||
}
|
||||
return std::make_shared<ov::op::internal::AUGRUSequence>(in[0], in[1], seq_lengths, W, R, B, in[2], hidden_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace builder
|
||||
} // namespace ngraph
|
||||
Reference in new issue
Block a user