[ShapeInference] FFT based - revision and tests (part 1) (#19070)

* Reuse common shape validation for fft base

* Align helper names

* Common test class for fft ops

* Move all (I)DFT test cases to the common test class

* More test cases for param axes

* Init labels validation

* More label tests

* Labels validation for non const signal size

* Init label tests for IRDFT

* More label test for irdft

* Labels tests for RDFT

* Remove duplicated tests

* Rename common validation file

* Rename shape infer tests file

* Use node shape infer check

* Headers order alignment

* Add const to the test params vector

* Use this make_op

* Use OV_EXPECT_THROW in common fft tests

* Use OV_EXPECT_THROW iin rdft an irdft tests

* Pass input shapes and use SHAPE_INFER_CHECK

* Shorter error messages

* Update to use ov namespace in typeprop tests
This commit is contained in:
Katarzyna Mitrus 2023-08-25 12:27:18 +02:00 committed by GitHub
parent 06003f18d5
commit decc2e31f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 937 additions and 1288 deletions

View File

@ -4,6 +4,7 @@
#pragma once
#include <openvino/op/util/fft_base.hpp>
#include "fft_common_validation.hpp"
#include "openvino/core/axis_vector.hpp"
#include "utils.hpp"
@ -23,79 +24,14 @@ std::vector<TRShape> shape_infer(const util::FFTBase* op,
auto& output_shape = output_shapes[0];
auto axes = get_input_const_data_as<TRShape, int64_t>(op, 1, ta);
if (input_shape.rank().is_static()) {
const auto input_rank = input_shape.size();
NODE_VALIDATION_CHECK(op,
input_rank >= 2,
"The input rank must be greater or equal to 2. Got input rank: ",
input_rank);
NODE_VALIDATION_CHECK(op,
input_shape[input_rank - 1].compatible(2),
"The last dimension of input data must be 2. Got: ",
input_shape[input_rank - 1]);
if (axes_shape.is_static()) {
NODE_VALIDATION_CHECK(op,
input_rank >= static_cast<size_t>(axes_shape[0].get_length() + 1),
"The input rank must be greater than number of FFT op axes. Got "
"input rank: ",
input_rank,
", number of axes: ",
axes_shape[0].get_length());
}
// FFT operation supports for negative axes to transform. More precisely, according to
// the FFT operation specification, axes should be integers from -(r - 1) to (r - 2)
// inclusively, where r = rank(data). A negative axis 'a' is interpreted as an axis
// 'r - 1 + a'. The reason is the following: real input tensor of the shape
// [n_0, ..., n_{r - 1}, 2] is interpreted as a complex tensor with the shape
// [n_0, ..., n_{r - 1}].
if (axes_shape.rank().is_static() && axes) {
const auto axis_min_value = -static_cast<int64_t>(input_rank);
const auto axis_max_value = static_cast<int64_t>(input_rank) - 1;
ov::AxisSet axes_set;
for (int64_t& axis : *axes) {
NODE_VALIDATION_CHECK(op,
axis_min_value < axis && axis < axis_max_value,
"FFT op axis ",
axis,
" must be in the input rank range (",
axis_min_value,
", ",
axis_max_value,
").");
if (axis < 0) {
axis += input_rank - 1;
}
axes_set.insert(static_cast<size_t>(axis));
}
NODE_VALIDATION_CHECK(op, axes->size() == axes_set.size(), "FFT op axes must be unique.");
}
}
NODE_VALIDATION_CHECK(op, axes_shape.rank().compatible(1), "FFT op axes input must be 1D tensor.");
if (input_shapes.size() == 3) {
const auto& signal_size_shape = input_shapes[2];
NODE_VALIDATION_CHECK(op,
signal_size_shape.rank().compatible(1),
"FFT op signal size input must be 1D tensor. Got signal: ",
signal_size_shape);
if (axes_shape.is_static() && signal_size_shape.is_static()) {
NODE_VALIDATION_CHECK(op,
axes_shape[0].compatible(signal_size_shape[0]),
"Sizes of inputs 'axes' and 'signal_size' must be equal. Got "
"size of 'axes': ",
axes_shape[0],
"size of 'signal_size': ",
signal_size_shape[0]);
}
}
util::fft_common_validation::shape_validation(op,
input_shapes,
*axes,
static_cast<bool>(axes),
util::fft_common_validation::FFTKind::ComplexInput);
output_shape = input_shape;
if (input_shape.rank().is_static() && axes_shape.rank().is_static() && input_shapes.size() == 3 && axes) {
const auto& signal_size_shape = input_shapes[2];
auto signal_size = get_input_const_data_as<TRShape, int64_t>(op, 2, ta);

View File

@ -0,0 +1,149 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <openvino/op/util/fft_base.hpp>
#include "openvino/core/axis_vector.hpp"
#include "utils.hpp"
namespace ov {
namespace op {
namespace util {
namespace fft_common_validation {
enum class FFTKind { RealInput, ComplexInput };
template <class T>
void validate_input_rank(const ov::op::util::FFTBase* op,
const std::vector<T>& input_shapes,
const T& input_shape,
const T& axes_shape,
size_t input_rank,
FFTKind fft_kind) {
const size_t min_rank = (fft_kind == FFTKind::RealInput) ? 1 : 2;
NODE_SHAPE_INFER_CHECK(op,
input_shapes,
input_rank >= min_rank,
"The input rank must be greater or equal to ",
min_rank);
if (fft_kind == FFTKind::ComplexInput) {
NODE_SHAPE_INFER_CHECK(op,
input_shapes,
input_shape[input_rank - 1].compatible(2),
"The last dimension of input data must be 2.");
}
if (axes_shape.is_dynamic()) {
return;
}
if (fft_kind == FFTKind::RealInput) {
NODE_SHAPE_INFER_CHECK(op,
input_shapes,
input_rank >= static_cast<size_t>(axes_shape[0].get_length()),
"The input rank must be greater than or equal to the number of axes. ");
} else {
NODE_SHAPE_INFER_CHECK(op,
input_shapes,
input_rank >= static_cast<size_t>(axes_shape[0].get_length() + 1),
"The input rank must be greater than number of axes.");
}
}
template <class T>
void validate_axes(const ov::op::util::FFTBase* op,
const std::vector<T>& input_shapes,
const T& axes_shape,
std::vector<int64_t>& axes,
size_t input_rank,
bool axes_are_known,
FFTKind fft_kind) {
if (axes_shape.rank().is_dynamic() || !axes_are_known) {
return;
}
// IRDFT, DFT, IDFT, operations supports negative axes to transform. More precisely, according to
// the operation specification, axes should be integers from -(r - 1) to (r - 2)
// inclusively, where r = rank(data). A negative axis 'a' is interpreted as an axis
// 'r - 1 + a'. The reason is the following: real input tensor of the shape
// [n_0, ..., n_{r - 1}, 2] is interpreted as a complex tensor with the shape
// [n_0, ..., n_{r - 1}].
//
// But RDFT operation supports negative axes to transform in other sense. More precisely,
// according to the RDFT operation specification, axes should be integers from -r to (r - 1)
// inclusively, where r = rank(data). A negative axis 'a' is interpreted as an axis 'r + a'.
const int64_t axis_correction = (fft_kind == FFTKind::RealInput) ? input_rank : (input_rank - 1);
auto axis_min_value = -static_cast<int64_t>(input_rank);
auto axis_max_value = static_cast<int64_t>(input_rank) - 1;
// RDFT op axes can contain the last axis
if (fft_kind == FFTKind::RealInput) {
--axis_min_value;
++axis_max_value;
}
ov::AxisSet axes_set;
for (int64_t& axis : axes) {
NODE_SHAPE_INFER_CHECK(op,
input_shapes,
axis_min_value < axis && axis < axis_max_value,
"Axis value: ",
axis,
", must be in range (",
axis_min_value,
", ",
axis_max_value,
").");
if (axis < 0) {
axis += axis_correction;
}
axes_set.insert(static_cast<size_t>(axis));
}
NODE_VALIDATION_CHECK(op, axes.size() == axes_set.size(), "Each axis must be unique.");
}
template <class T>
void validate_signal_size(const ov::op::util::FFTBase* op,
const std::vector<T>& input_shapes,
const T& axes_shape,
const T& signal_size_shape) {
NODE_SHAPE_INFER_CHECK(op,
input_shapes,
signal_size_shape.rank().compatible(1),
"Signal size input must be 1D tensor.");
if (axes_shape.is_static() && signal_size_shape.is_static()) {
NODE_SHAPE_INFER_CHECK(op,
input_shapes,
axes_shape[0].compatible(signal_size_shape[0]),
"Sizes of inputs 'axes' and 'signal_size' must be equal.");
}
}
template <class T>
void shape_validation(const ov::op::util::FFTBase* op,
const std::vector<T>& input_shapes,
std::vector<int64_t>& axes,
bool axes_are_known,
FFTKind fft_kind) {
const auto& input_shape = input_shapes[0];
const auto& axes_shape = input_shapes[1];
if (input_shape.rank().is_static()) {
const auto input_rank = input_shape.size();
validate_input_rank(op, input_shapes, input_shape, axes_shape, input_rank, fft_kind);
validate_axes(op, input_shapes, axes_shape, axes, input_rank, axes_are_known, fft_kind);
}
NODE_SHAPE_INFER_CHECK(op, input_shapes, axes_shape.rank().compatible(1), "Axes input must be 1D tensor.");
if (input_shapes.size() == 3) {
const auto& signal_size_shape = input_shapes[2];
validate_signal_size(op, input_shapes, axes_shape, signal_size_shape);
}
}
} // namespace fft_common_validation
} // namespace util
} // namespace op
} // namespace ov

View File

@ -3,9 +3,9 @@
//
#pragma once
#include "fft_common_validation.hpp"
#include "openvino/core/axis_vector.hpp"
#include "openvino/op/irdft.hpp"
#include "rfft_common_validation.hpp"
#include "utils.hpp"
namespace ov {
@ -26,11 +26,11 @@ std::vector<TRShape> shape_infer(const IRDFT* op,
auto axes = get_input_const_data_as<TRShape, int64_t>(op, 1, ta);
auto axes_are_known = static_cast<bool>(axes);
util::rfft_common_validation::shape_validation(op,
util::fft_common_validation::shape_validation(op,
input_shapes,
*axes,
axes_are_known,
util::rfft_common_validation::RFFTKind::Inverse);
util::fft_common_validation::FFTKind::ComplexInput);
if (input_shape.rank().is_dynamic()) {
output_shape = ov::PartialShape::dynamic();

View File

@ -4,8 +4,8 @@
#pragma once
#include <openvino/op/rdft.hpp>
#include "fft_common_validation.hpp"
#include "openvino/core/axis_vector.hpp"
#include "rfft_common_validation.hpp"
#include "utils.hpp"
namespace ov {
@ -37,11 +37,11 @@ std::vector<TRShape> shape_infer(const RDFT* op,
auto& output_shape = output_shapes[0];
auto axes = get_input_const_data_as<TRShape, int64_t>(op, 1, ta);
util::rfft_common_validation::shape_validation(op,
util::fft_common_validation::shape_validation(op,
input_shapes,
*axes,
static_cast<bool>(axes),
util::rfft_common_validation::RFFTKind::Forward);
util::fft_common_validation::FFTKind::RealInput);
if (input_shape.rank().is_dynamic()) {
output_shape = ov::PartialShape::dynamic();

View File

@ -1,153 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <openvino/op/util/fft_base.hpp>
#include "openvino/core/axis_vector.hpp"
#include "utils.hpp"
namespace ov {
namespace op {
namespace util {
namespace rfft_common_validation {
enum class RFFTKind { Forward, Inverse };
template <class T>
void validate_input_rank(const ov::op::util::FFTBase* op,
const T& input_shape,
const T& axes_shape,
size_t input_rank,
RFFTKind rfft_kind) {
const size_t min_rank = (rfft_kind == RFFTKind::Forward) ? 1 : 2;
NODE_VALIDATION_CHECK(op,
input_rank >= min_rank,
"The input rank must be greater or equal to ",
min_rank,
". Got input rank: ",
input_rank);
if (rfft_kind == RFFTKind::Inverse) {
NODE_VALIDATION_CHECK(op,
input_shape[input_rank - 1].compatible(2),
"The last dimension of input data must be 2. Got: ",
input_shape[input_rank - 1]);
}
if (axes_shape.is_dynamic()) {
return;
}
if (rfft_kind == RFFTKind::Forward) {
NODE_VALIDATION_CHECK(op,
input_rank >= static_cast<size_t>(axes_shape[0].get_length()),
"The input rank must be greater than or equal to the number of RDFT op axes. "
"Got input rank: ",
input_rank,
", number of axes: ",
axes_shape[0].get_length());
} else {
NODE_VALIDATION_CHECK(op,
input_rank >= static_cast<size_t>(axes_shape[0].get_length() + 1),
"The input rank must be greater than number of IRDFT op axes. Got "
"input rank: ",
input_rank,
", number of axes: ",
axes_shape[0].get_length());
}
}
template <class T>
void validate_axes(const ov::op::util::FFTBase* op,
const T& axes_shape,
std::vector<int64_t>& axes,
size_t input_rank,
bool axes_are_known,
RFFTKind rfft_kind) {
if (axes_shape.rank().is_dynamic() || !axes_are_known) {
return;
}
// IRDFT operation supports negative axes to transform. More precisely, according to
// the IRDFT operation specification, axes should be integers from -(r - 1) to (r - 2)
// inclusively, where r = rank(data). A negative axis 'a' is interpreted as an axis
// 'r - 1 + a'. The reason is the following: real input tensor of the shape
// [n_0, ..., n_{r - 1}, 2] is interpreted as a complex tensor with the shape
// [n_0, ..., n_{r - 1}].
//
// But RDFT operation supports negative axes to transform in other sense. More precisely,
// according to the RDFT operation specification, axes should be integers from -r to (r - 1)
// inclusively, where r = rank(data). A negative axis 'a' is interpreted as an axis 'r + a'.
const int64_t axis_correction = (rfft_kind == RFFTKind::Forward) ? input_rank : (input_rank - 1);
auto axis_min_value = -static_cast<int64_t>(input_rank);
auto axis_max_value = static_cast<int64_t>(input_rank) - 1;
// RDFT op axes can contain the last axis
if (rfft_kind == RFFTKind::Forward) {
--axis_min_value;
++axis_max_value;
}
ov::AxisSet axes_set;
for (int64_t& axis : axes) {
NODE_VALIDATION_CHECK(op,
axis_min_value < axis && axis < axis_max_value,
"(I)RDFT op axis ",
axis,
" must be in the input rank range (",
axis_min_value,
", ",
axis_max_value,
").");
if (axis < 0) {
axis += axis_correction;
}
axes_set.insert(static_cast<size_t>(axis));
}
NODE_VALIDATION_CHECK(op, axes.size() == axes_set.size(), "(I)RDFT op axes must be unique.");
}
template <class T>
void validate_signal_size(const ov::op::util::FFTBase* op, const T& axes_shape, const T& signal_size_shape) {
NODE_VALIDATION_CHECK(op,
signal_size_shape.rank().compatible(1),
"(I)RDFT op signal size input must be 1D tensor. Got signal: ",
signal_size_shape);
if (axes_shape.is_static() && signal_size_shape.is_static()) {
NODE_VALIDATION_CHECK(op,
axes_shape[0].compatible(signal_size_shape[0]),
"Sizes of inputs 'axes' and 'signal_size' of (I)RDFT op must be equal. "
"Got size of 'axes': ",
axes_shape[0],
"size of 'signal_size': ",
signal_size_shape[0]);
}
}
template <class T>
void shape_validation(const ov::op::util::FFTBase* op,
const std::vector<T>& input_shapes,
std::vector<int64_t>& axes,
bool axes_are_known,
RFFTKind rfft_kind) {
const auto& input_shape = input_shapes[0];
const auto& axes_shape = input_shapes[1];
if (input_shape.rank().is_static()) {
const auto input_rank = input_shape.size();
validate_input_rank(op, input_shape, axes_shape, input_rank, rfft_kind);
validate_axes(op, axes_shape, axes, input_rank, axes_are_known, rfft_kind);
}
NODE_VALIDATION_CHECK(op, axes_shape.rank().compatible(1), "(I)RDFT op axes input must be 1D tensor.");
if (input_shapes.size() == 3) {
const auto& signal_size_shape = input_shapes[2];
validate_signal_size(op, axes_shape, signal_size_shape);
}
}
} // namespace rfft_common_validation
} // namespace util
} // namespace op
} // namespace ov

View File

@ -1,409 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "openvino/op/dft.hpp"
#include <gtest/gtest.h>
#include "common_test_utils/type_prop.hpp"
#include "openvino/op/constant.hpp"
using namespace ov;
struct ConstantAxesAndConstantSignalSizeTestParams {
PartialShape input_shape;
Shape axes_shape;
Shape signal_size_shape;
PartialShape ref_output_shape;
std::vector<int64_t> axes;
std::vector<int64_t> signal_size;
};
struct ConstantAxesAndConstantSignalSizeTest : ::testing::TestWithParam<ConstantAxesAndConstantSignalSizeTestParams> {};
TEST_P(ConstantAxesAndConstantSignalSizeTest, dft_constant_axes_and_signal_size) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = ov::op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
std::shared_ptr<op::v7::DFT> dft;
if (params.signal_size.empty()) {
dft = std::make_shared<op::v7::DFT>(data, axes_input);
} else {
auto signal_size_input =
ov::op::v0::Constant::create<int64_t>(element::i64, params.signal_size_shape, params.signal_size);
dft = std::make_shared<op::v7::DFT>(data, axes_input, signal_size_input);
}
EXPECT_EQ(dft->get_element_type(), element::f32);
ASSERT_TRUE(dft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
}
INSTANTIATE_TEST_SUITE_P(
type_prop,
ConstantAxesAndConstantSignalSizeTest,
::testing::Values(
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, Shape{}, {2, 180, 180, 2}, {1, 2}, {}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, Shape{}, {2, 180, 180, 2}, {2, 0}, {}},
ConstantAxesAndConstantSignalSizeTestParams{{16, 500, 180, 369, 2},
{3},
Shape{},
{16, 500, 180, 369, 2},
{0, 3, 1},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, Dimension(1, 18)},
{2},
Shape{},
{2, 180, 180, Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(7, 500), 2},
{2},
Shape{},
{2, 180, Dimension(7, 500), 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{2, 180, Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), 180, 2},
{2},
Shape{},
{2, Dimension(7, 500), 180, 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), 180, Dimension(1, 18)},
{2},
Shape{},
{2, Dimension(7, 500), 180, Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), Dimension(7, 500), 2},
{2},
Shape{},
{2, Dimension(7, 500), Dimension(7, 500), 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, 180, 2},
{2},
Shape{},
{Dimension(0, 2), 180, 180, 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, Dimension(7, 500), 2},
{2},
Shape{},
{Dimension(0, 2), 180, Dimension(7, 500), 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), 180, 2},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), 180, 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, {2}, {2, 180, 77, 2}, {1, 2}, {-1, 77}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, {2}, {87, 180, 390, 2}, {2, 0}, {390, 87}},
ConstantAxesAndConstantSignalSizeTestParams{{7, 50, 130, 400, 2},
{3},
{3},
{7, 40, 130, 600, 2},
{3, 0, 1},
{600, -1, 40}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(0, 200), 180, 2},
{2},
{2},
{2, Dimension(0, 200), 77, 2},
{1, 2},
{-1, 77}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400), 2},
{2},
{2},
{87, 180, 390, 2},
{2, 0},
{390, 87}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(8, 129), 50, 130, Dimension(0, 500), 2},
{3},
{3},
{Dimension(8, 129), 40, 130, 600, 2},
{3, 0, 1},
{600, -1, 40}}),
PrintToDummyParamName());
TEST(type_prop, dft_dynamic_axes) {
const auto input_shape = PartialShape{2, 180, 180, Dimension(1, 18)};
const auto axes_shape = PartialShape::dynamic();
const auto ref_output_shape =
PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)};
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::i64, axes_shape);
auto dft = std::make_shared<op::v7::DFT>(data, axes_input);
EXPECT_EQ(dft->get_element_type(), element::f32);
ASSERT_TRUE(dft->get_output_partial_shape(0).same_scheme(ref_output_shape));
}
struct NonConstantAxesTestParams {
PartialShape input_shape;
Shape axes_shape;
PartialShape ref_output_shape;
};
struct NonConstantAxesTest : ::testing::TestWithParam<NonConstantAxesTestParams> {};
TEST_P(NonConstantAxesTest, dft_non_constant_axes) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::i64, params.axes_shape);
auto dft = std::make_shared<op::v7::DFT>(data, axes_input);
EXPECT_EQ(dft->get_element_type(), element::f32);
ASSERT_TRUE(dft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
}
INSTANTIATE_TEST_SUITE_P(
type_prop,
NonConstantAxesTest,
::testing::Values(
NonConstantAxesTestParams{{2, 180, 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, 180, Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{2, 180, Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, Dimension(7, 500), 180, 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{2, Dimension(7, 500), 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, Dimension(7, 500), Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, 180, 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), Dimension(7, 500), 180, 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}}),
PrintToDummyParamName());
struct NonConstantSignalSizeTestParams {
PartialShape input_shape;
Shape axes_shape;
Shape signal_size_shape;
PartialShape ref_output_shape;
std::vector<int64_t> axes;
};
struct NonConstantSignalSizeTest : ::testing::TestWithParam<NonConstantSignalSizeTestParams> {};
TEST_P(NonConstantSignalSizeTest, dft_non_constant_signal_size) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = ov::op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
auto signal_size_input = std::make_shared<ov::op::v0::Parameter>(element::i64, params.signal_size_shape);
auto dft = std::make_shared<op::v7::DFT>(data, axes_input, signal_size_input);
EXPECT_EQ(dft->get_element_type(), element::f32);
ASSERT_TRUE(dft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
}
INSTANTIATE_TEST_SUITE_P(
type_prop,
NonConstantSignalSizeTest,
::testing::Values(NonConstantSignalSizeTestParams{{2, Dimension(0, 200), 180, 2},
{2},
{2},
{2, Dimension::dynamic(), Dimension::dynamic(), 2},
{1, 2}},
NonConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400), 2},
{2},
{2},
{Dimension::dynamic(), 180, Dimension::dynamic(), 2},
{2, 0}},
NonConstantSignalSizeTestParams{
{Dimension(8, 129), 50, 130, Dimension(0, 500), 2},
{3},
{3},
{Dimension::dynamic(), Dimension::dynamic(), 130, Dimension::dynamic(), 2},
{3, 0, 1}}),
PrintToDummyParamName());
TEST(type_prop, dft_invalid_input) {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{2});
auto dft = std::make_shared<op::v7::DFT>(data, axes);
FAIL() << "DFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The input rank must be greater or equal to 2.");
}
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3});
auto dft = std::make_shared<op::v7::DFT>(data, axes);
FAIL() << "DFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The last dimension of input data must be 2.");
}
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 2});
auto dft = std::make_shared<op::v7::DFT>(data, axes);
FAIL() << "DFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The input rank must be greater than number of FFT op axes.");
}
}
TEST(type_prop, dft_invalid_axes) {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3, 2});
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {3});
auto dft = std::make_shared<op::v7::DFT>(data, axes);
FAIL() << "DFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axis 3 must be in the input rank range");
}
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {-3});
auto dft = std::make_shared<op::v7::DFT>(data, axes);
FAIL() << "DFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axis -3 must be in the input rank range");
}
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, -2});
auto dft = std::make_shared<op::v7::DFT>(data, axes);
FAIL() << "DFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axes must be unique.");
}
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {2});
auto dft = std::make_shared<op::v7::DFT>(data, axes);
FAIL() << "DFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axis 2 must be in the input rank range");
}
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
auto dft = std::make_shared<op::v7::DFT>(data, axes);
FAIL() << "DFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axes input must be 1D tensor.");
}
}
TEST(type_prop, dft_invalid_signal_size) {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {0});
try {
auto signal_size = ov::op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
auto dft = std::make_shared<op::v7::DFT>(data, axes, signal_size);
FAIL() << "DFT node was created with invalid signal size.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op signal size input must be 1D tensor.");
}
try {
auto signal_size = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
auto dft = std::make_shared<op::v7::DFT>(data, axes, signal_size);
FAIL() << "DFT node was created with invalid signal size.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "Sizes of inputs 'axes' and 'signal_size' must be equal.");
}
}
TEST(type_prop, dft_dynamic_types) {
const auto input_shape = PartialShape{2, 180, 180, 2};
const auto axes_shape = PartialShape::dynamic();
const auto signal_size_shape = PartialShape::dynamic();
const auto ref_output_shape = PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2};
auto data = std::make_shared<ov::op::v0::Parameter>(element::dynamic, input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::dynamic, axes_shape);
auto signal_size_input = std::make_shared<ov::op::v0::Parameter>(element::dynamic, signal_size_shape);
auto dft = std::make_shared<op::v7::DFT>(data, axes_input, signal_size_input);
EXPECT_EQ(dft->get_element_type(), element::dynamic);
ASSERT_TRUE(dft->get_output_partial_shape(0).same_scheme(ref_output_shape));
}

View File

@ -0,0 +1,480 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <type_traits>
#include "common_test_utils/test_assertions.hpp"
#include "common_test_utils/type_prop.hpp"
#include "gmock/gmock.h"
#include "openvino/openvino.hpp"
#include "openvino/opsets/opset12.hpp"
namespace fft_base_test {
using namespace std;
using namespace ov;
using namespace op;
using namespace testing;
using FFTBaseTypes = Types<op::v7::DFT, op::v7::IDFT>;
struct FFTConstantAxesAndConstantSignalSizeTestParams {
PartialShape input_shape;
Shape axes_shape;
Shape signal_size_shape;
PartialShape ref_output_shape;
std::vector<int64_t> axes;
std::vector<int64_t> signal_size;
std::vector<ov::label_t> expected_labels;
};
template <class TOp>
class FFTConstantAxesAndConstantSignalSizeTest : public TypePropOpTest<TOp> {
public:
const std::vector<FFTConstantAxesAndConstantSignalSizeTestParams> test_params{
FFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, Shape{}, {2, 180, 180, 2}, {1, 2}, {}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, Shape{}, {2, 180, 180, 2}, {2, 0}, {}},
FFTConstantAxesAndConstantSignalSizeTestParams{{16, 500, 180, 369, 2},
{3},
Shape{},
{16, 500, 180, 369, 2},
{0, 3, 1},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, Dimension(1, 18)},
{2},
Shape{},
{2, 180, 180, Dimension(1, 18)},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(7, 500), 2},
{2},
Shape{},
{2, 180, Dimension(7, 500), 2},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{2, 180, Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), 180, 2},
{2},
Shape{},
{2, Dimension(7, 500), 180, 2},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), 180, Dimension(1, 18)},
{2},
Shape{},
{2, Dimension(7, 500), 180, Dimension(1, 18)},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), Dimension(7, 500), 2},
{2},
Shape{},
{2, Dimension(7, 500), Dimension(7, 500), 2},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, 180, 2},
{2},
Shape{},
{Dimension(0, 2), 180, 180, 2},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, Dimension(7, 500), 2},
{2},
Shape{},
{Dimension(0, 2), 180, Dimension(7, 500), 2},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), 180, 2},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), 180, 2},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2},
{2},
{2},
{2, 180, 77, 2},
{1, 2},
{-1, 77},
{10, 11, ov::no_label, 13}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2},
{2},
{2},
{87, 180, 390, 2},
{2, 0},
{390, 87},
{ov::no_label, 11, ov::no_label, 13}},
FFTConstantAxesAndConstantSignalSizeTestParams{{7, 50, 130, 400, 2},
{3},
{3},
{7, 40, 130, 600, 2},
{3, 0, 1},
{600, -1, 40},
{10, ov::no_label, 12, ov::no_label, 14}},
FFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(0, 200), 180, 2},
{2},
{2},
{2, Dimension(0, 200), 77, 2},
{1, 2},
{-1, 77},
{10, 11, ov::no_label, 13}},
FFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400), 2},
{2},
{2},
{87, 180, 390, 2},
{2, 0},
{390, 87},
{ov::no_label, 11, ov::no_label, 13}},
FFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(8, 129), 50, 130, Dimension(0, 500), 2},
{3},
{3},
{Dimension(8, 129), 40, 130, 600, 2},
{3, 0, 1},
{600, -1, 40},
{10, ov::no_label, 12, ov::no_label, 14}}};
};
TYPED_TEST_SUITE_P(FFTConstantAxesAndConstantSignalSizeTest);
TYPED_TEST_P(FFTConstantAxesAndConstantSignalSizeTest, constant_axes_and_signal_size) {
for (auto params : this->test_params) {
set_shape_labels(params.input_shape, 10);
auto data = std::make_shared<op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
std::shared_ptr<TypeParam> dft;
if (params.signal_size.empty()) {
dft = this->make_op(data, axes_input);
} else {
auto signal_size_input =
op::v0::Constant::create<int64_t>(element::i64, params.signal_size_shape, params.signal_size);
dft = this->make_op(data, axes_input, signal_size_input);
}
EXPECT_EQ(dft->get_element_type(), element::f32);
EXPECT_EQ(dft->get_output_partial_shape(0), params.ref_output_shape);
if (params.expected_labels.empty()) {
EXPECT_EQ(get_shape_labels(dft->get_output_partial_shape(0)), get_shape_labels(params.input_shape));
} else {
EXPECT_EQ(get_shape_labels(dft->get_output_partial_shape(0)), params.expected_labels);
}
}
}
REGISTER_TYPED_TEST_SUITE_P(FFTConstantAxesAndConstantSignalSizeTest, constant_axes_and_signal_size);
INSTANTIATE_TYPED_TEST_SUITE_P(type_prop, FFTConstantAxesAndConstantSignalSizeTest, FFTBaseTypes);
struct NonConstantAxesTestParams {
PartialShape input_shape;
PartialShape axes_shape;
PartialShape ref_output_shape;
};
template <class TOp>
class FFTNonConstantAxesTest : public TypePropOpTest<TOp> {
public:
const std::vector<NonConstantAxesTestParams> test_params{
NonConstantAxesTestParams{{2, 180, 180, Dimension(1, 18)},
PartialShape::dynamic(),
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{1, 180, Dimension(1, 18)},
PartialShape::dynamic(),
{Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, 180, 180, Dimension(1, 18)},
{-1},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, 180, 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, 180, Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{2, 180, Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, Dimension(7, 500), 180, 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{2, Dimension(7, 500), 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, Dimension(7, 500), Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, 180, 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), Dimension(7, 500), 180, 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}}};
};
TYPED_TEST_SUITE_P(FFTNonConstantAxesTest);
TYPED_TEST_P(FFTNonConstantAxesTest, non_constant_axes_no_signal_size) {
for (auto params : this->test_params) {
set_shape_labels(params.input_shape, 10);
auto data = std::make_shared<op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::i64, params.axes_shape);
auto dft = this->make_op(data, axes_input);
EXPECT_EQ(dft->get_element_type(), element::f32);
EXPECT_EQ(dft->get_output_partial_shape(0), params.ref_output_shape);
std::vector<label_t> expected_labels(params.input_shape.size() - 1, no_label);
expected_labels.push_back(get_shape_labels(params.input_shape).back());
EXPECT_EQ(get_shape_labels(dft->get_output_partial_shape(0)), expected_labels);
}
}
TYPED_TEST_P(FFTNonConstantAxesTest, non_constant_axes_param_signal_size) {
for (auto params : this->test_params) {
set_shape_labels(params.input_shape, 10);
auto data = std::make_shared<op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::i64, params.axes_shape);
auto signal_size_input = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{2});
auto dft = this->make_op(data, axes_input, signal_size_input);
EXPECT_EQ(dft->get_element_type(), element::f32);
EXPECT_EQ(dft->get_output_partial_shape(0), params.ref_output_shape);
std::vector<label_t> expected_labels(params.input_shape.size() - 1, no_label);
expected_labels.push_back(get_shape_labels(params.input_shape).back());
EXPECT_EQ(get_shape_labels(dft->get_output_partial_shape(0)), expected_labels);
}
}
TYPED_TEST_P(FFTNonConstantAxesTest, non_constant_axes_const_signal_size) {
for (auto params : this->test_params) {
set_shape_labels(params.input_shape, 10);
auto data = std::make_shared<op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::i64, params.axes_shape);
auto signal_size_input = op::v0::Constant::create<int64_t>(element::i64, Shape{2}, {100, 200});
auto dft = this->make_op(data, axes_input);
EXPECT_EQ(dft->get_element_type(), element::f32);
EXPECT_EQ(dft->get_output_partial_shape(0), params.ref_output_shape);
std::vector<label_t> expected_labels(params.input_shape.size() - 1, no_label);
expected_labels.push_back(get_shape_labels(params.input_shape).back());
EXPECT_EQ(get_shape_labels(dft->get_output_partial_shape(0)), expected_labels);
}
}
REGISTER_TYPED_TEST_SUITE_P(FFTNonConstantAxesTest,
non_constant_axes_no_signal_size,
non_constant_axes_param_signal_size,
non_constant_axes_const_signal_size);
INSTANTIATE_TYPED_TEST_SUITE_P(type_prop, FFTNonConstantAxesTest, FFTBaseTypes);
struct NonConstantSignalSizeTestParams {
PartialShape input_shape;
Shape axes_shape;
Shape signal_size_shape;
PartialShape ref_output_shape;
std::vector<int64_t> axes;
std::vector<ov::label_t> expected_labels;
};
template <class TOp>
class FFTNonConstantSignalSizeTest : public TypePropOpTest<TOp> {
public:
const std::vector<NonConstantSignalSizeTestParams> test_params{
NonConstantSignalSizeTestParams{{2, Dimension(0, 200), 180, 2},
{2},
{2},
{2, Dimension::dynamic(), Dimension::dynamic(), 2},
{1, 2},
{10, no_label, no_label, 13}},
NonConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400), 2},
{2},
{2},
{Dimension::dynamic(), 180, Dimension::dynamic(), 2},
{2, 0},
{no_label, 11, no_label, 13}},
NonConstantSignalSizeTestParams{{Dimension(8, 129), 50, 130, Dimension(0, 500), 2},
{3},
{3},
{Dimension::dynamic(), Dimension::dynamic(), 130, Dimension::dynamic(), 2},
{3, 0, 1},
{no_label, no_label, 12, no_label, 14}}};
};
TYPED_TEST_SUITE_P(FFTNonConstantSignalSizeTest);
TYPED_TEST_P(FFTNonConstantSignalSizeTest, non_constant_signal_size) {
for (auto params : this->test_params) {
set_shape_labels(params.input_shape, 10);
auto data = std::make_shared<op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
auto signal_size_input = std::make_shared<op::v0::Parameter>(element::i64, params.signal_size_shape);
auto dft = this->make_op(data, axes_input, signal_size_input);
EXPECT_EQ(dft->get_element_type(), element::f32);
EXPECT_EQ(dft->get_output_partial_shape(0), params.ref_output_shape);
EXPECT_EQ(get_shape_labels(dft->get_output_partial_shape(0)), params.expected_labels);
}
}
REGISTER_TYPED_TEST_SUITE_P(FFTNonConstantSignalSizeTest, non_constant_signal_size);
INSTANTIATE_TYPED_TEST_SUITE_P(type_prop, FFTNonConstantSignalSizeTest, FFTBaseTypes);
template <class TOp>
class FFTInvalidInput : public TypePropOpTest<TOp> {};
TYPED_TEST_SUITE_P(FFTInvalidInput);
TYPED_TEST_P(FFTInvalidInput, invalid_input_data) {
auto axes = op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
auto data = std::make_shared<op::v0::Parameter>(element::f32, Shape{2});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes),
ov::Exception,
HasSubstr("The input rank must be greater or equal to 2"));
data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 3});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes),
ov::Exception,
HasSubstr("The last dimension of input data must be 2"));
data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 2});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes),
ov::Exception,
HasSubstr("The input rank must be greater than number of axes."));
}
TYPED_TEST_P(FFTInvalidInput, invalid_axes) {
auto data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto axes = op::v0::Constant::create(element::i64, Shape{1}, {3});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes),
ov::Exception,
HasSubstr("Axis value: 3, must be in range (-3, 2)"));
axes = op::v0::Constant::create(element::i64, Shape{1}, {-3});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes),
ov::Exception,
HasSubstr("Axis value: -3, must be in range (-3, 2)"));
axes = op::v0::Constant::create(element::i64, Shape{2}, {0, -2});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes), ov::Exception, HasSubstr("Each axis must be unique"));
axes = op::v0::Constant::create(element::i64, Shape{1}, {2});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes),
ov::Exception,
HasSubstr("Axis value: 2, must be in range (-3, 2)"));
axes = op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes), ov::Exception, HasSubstr("Axes input must be 1D tensor."));
}
TYPED_TEST_P(FFTInvalidInput, invalid_signal_size) {
auto data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto axes = op::v0::Constant::create(element::i64, Shape{1}, {0});
auto signal_size = op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes, signal_size),
ov::Exception,
HasSubstr("Signal size input must be 1D tensor"));
signal_size = op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
OV_EXPECT_THROW(std::ignore = this->make_op(data, axes, signal_size),
ov::Exception,
HasSubstr("Sizes of inputs 'axes' and 'signal_size' must be equal."));
}
REGISTER_TYPED_TEST_SUITE_P(FFTInvalidInput, invalid_input_data, invalid_axes, invalid_signal_size);
INSTANTIATE_TYPED_TEST_SUITE_P(type_prop, FFTInvalidInput, FFTBaseTypes);
template <class TOp>
class FFTDynamicTypes : public TypePropOpTest<TOp> {};
TYPED_TEST_SUITE_P(FFTDynamicTypes);
TYPED_TEST_P(FFTDynamicTypes, dynamic_types) {
const auto input_shape = PartialShape{2, 180, 180, 2};
const auto axes_shape = PartialShape::dynamic();
const auto signal_size_shape = PartialShape::dynamic();
const auto ref_output_shape = PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2};
auto data = std::make_shared<op::v0::Parameter>(element::dynamic, input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::dynamic, axes_shape);
auto signal_size_input = std::make_shared<op::v0::Parameter>(element::dynamic, signal_size_shape);
auto dft = this->make_op(data, axes_input, signal_size_input);
EXPECT_EQ(dft->get_element_type(), element::dynamic);
EXPECT_EQ(dft->get_output_partial_shape(0), ref_output_shape);
}
REGISTER_TYPED_TEST_SUITE_P(FFTDynamicTypes, dynamic_types);
INSTANTIATE_TYPED_TEST_SUITE_P(type_prop, FFTDynamicTypes, FFTBaseTypes);
} // namespace fft_base_test

View File

@ -1,410 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "openvino/op/idft.hpp"
#include <gtest/gtest.h>
#include "common_test_utils/type_prop.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/parameter.hpp"
using namespace ov;
struct ConstantAxesAndConstantSignalSizeTestParams {
PartialShape input_shape;
Shape axes_shape;
Shape signal_size_shape;
PartialShape ref_output_shape;
std::vector<int64_t> axes;
std::vector<int64_t> signal_size;
};
struct ConstantAxesAndConstantSignalSizeTest : ::testing::TestWithParam<ConstantAxesAndConstantSignalSizeTestParams> {};
TEST_P(ConstantAxesAndConstantSignalSizeTest, idft_constant_axes_and_signal_size) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = ov::op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
std::shared_ptr<op::v7::IDFT> idft;
if (params.signal_size.empty()) {
idft = std::make_shared<op::v7::IDFT>(data, axes_input);
} else {
auto signal_size_input =
ov::op::v0::Constant::create<int64_t>(element::i64, params.signal_size_shape, params.signal_size);
idft = std::make_shared<op::v7::IDFT>(data, axes_input, signal_size_input);
}
EXPECT_EQ(idft->get_element_type(), element::f32);
ASSERT_TRUE(idft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
}
INSTANTIATE_TEST_SUITE_P(
type_prop,
ConstantAxesAndConstantSignalSizeTest,
::testing::Values(
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, Shape{}, {2, 180, 180, 2}, {1, 2}, {}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, Shape{}, {2, 180, 180, 2}, {2, 0}, {}},
ConstantAxesAndConstantSignalSizeTestParams{{16, 500, 180, 369, 2},
{3},
Shape{},
{16, 500, 180, 369, 2},
{0, 3, 1},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, Dimension(1, 18)},
{2},
Shape{},
{2, 180, 180, Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(7, 500), 2},
{2},
Shape{},
{2, 180, Dimension(7, 500), 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{2, 180, Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), 180, 2},
{2},
Shape{},
{2, Dimension(7, 500), 180, 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), 180, Dimension(1, 18)},
{2},
Shape{},
{2, Dimension(7, 500), 180, Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), Dimension(7, 500), 2},
{2},
Shape{},
{2, Dimension(7, 500), Dimension(7, 500), 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, 180, 2},
{2},
Shape{},
{Dimension(0, 2), 180, 180, 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, Dimension(7, 500), 2},
{2},
Shape{},
{Dimension(0, 2), 180, Dimension(7, 500), 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), 180, 2},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), 180, 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{1, 2},
{}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, {2}, {2, 180, 77, 2}, {1, 2}, {-1, 77}},
ConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, {2}, {87, 180, 390, 2}, {2, 0}, {390, 87}},
ConstantAxesAndConstantSignalSizeTestParams{{7, 50, 130, 400, 2},
{3},
{3},
{7, 40, 130, 600, 2},
{3, 0, 1},
{600, -1, 40}},
ConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(0, 200), 180, 2},
{2},
{2},
{2, Dimension(0, 200), 77, 2},
{1, 2},
{-1, 77}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400), 2},
{2},
{2},
{87, 180, 390, 2},
{2, 0},
{390, 87}},
ConstantAxesAndConstantSignalSizeTestParams{{Dimension(8, 129), 50, 130, Dimension(0, 500), 2},
{3},
{3},
{Dimension(8, 129), 40, 130, 600, 2},
{3, 0, 1},
{600, -1, 40}}),
PrintToDummyParamName());
TEST(type_prop, idft_dynamic_axes) {
const auto input_shape = PartialShape{2, 180, 180, Dimension(1, 18)};
const auto axes_shape = PartialShape::dynamic();
const auto ref_output_shape =
PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)};
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::i64, axes_shape);
auto idft = std::make_shared<op::v7::IDFT>(data, axes_input);
EXPECT_EQ(idft->get_element_type(), element::f32);
ASSERT_TRUE(idft->get_output_partial_shape(0).same_scheme(ref_output_shape));
}
struct NonConstantAxesTestParams {
PartialShape input_shape;
Shape axes_shape;
PartialShape ref_output_shape;
};
struct NonConstantAxesTest : ::testing::TestWithParam<NonConstantAxesTestParams> {};
TEST_P(NonConstantAxesTest, idft_non_constant_axes) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::i64, params.axes_shape);
auto idft = std::make_shared<op::v7::IDFT>(data, axes_input);
EXPECT_EQ(idft->get_element_type(), element::f32);
ASSERT_TRUE(idft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
}
INSTANTIATE_TEST_SUITE_P(
type_prop,
NonConstantAxesTest,
::testing::Values(
NonConstantAxesTestParams{{2, 180, 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, 180, Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{2, 180, Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, Dimension(7, 500), 180, 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{2, Dimension(7, 500), 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{2, Dimension(7, 500), Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, 180, 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), Dimension(7, 500), 180, 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}},
NonConstantAxesTestParams{{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2}},
NonConstantAxesTestParams{
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension(1, 18)}}),
PrintToDummyParamName());
struct NonConstantSignalSizeTestParams {
PartialShape input_shape;
Shape axes_shape;
Shape signal_size_shape;
PartialShape ref_output_shape;
std::vector<int64_t> axes;
};
struct NonConstantSignalSizeTest : ::testing::TestWithParam<NonConstantSignalSizeTestParams> {};
TEST_P(NonConstantSignalSizeTest, idft_non_constant_signal_size) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = ov::op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
auto signal_size_input = std::make_shared<ov::op::v0::Parameter>(element::i64, params.signal_size_shape);
auto idft = std::make_shared<op::v7::IDFT>(data, axes_input, signal_size_input);
EXPECT_EQ(idft->get_element_type(), element::f32);
ASSERT_TRUE(idft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
}
INSTANTIATE_TEST_SUITE_P(
type_prop,
NonConstantSignalSizeTest,
::testing::Values(NonConstantSignalSizeTestParams{{2, Dimension(0, 200), 180, 2},
{2},
{2},
{2, Dimension::dynamic(), Dimension::dynamic(), 2},
{1, 2}},
NonConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400), 2},
{2},
{2},
{Dimension::dynamic(), 180, Dimension::dynamic(), 2},
{2, 0}},
NonConstantSignalSizeTestParams{
{Dimension(8, 129), 50, 130, Dimension(0, 500), 2},
{3},
{3},
{Dimension::dynamic(), Dimension::dynamic(), 130, Dimension::dynamic(), 2},
{3, 0, 1}}),
PrintToDummyParamName());
TEST(type_prop, idft_invalid_input) {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{2});
auto idft = std::make_shared<op::v7::IDFT>(data, axes);
FAIL() << "IDFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The input rank must be greater or equal to 2.");
}
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3});
auto idft = std::make_shared<op::v7::IDFT>(data, axes);
FAIL() << "IDFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The last dimension of input data must be 2.");
}
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 2});
auto idft = std::make_shared<op::v7::IDFT>(data, axes);
FAIL() << "IDFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The input rank must be greater than number of FFT op axes.");
}
}
TEST(type_prop, idft_invalid_axes) {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3, 2});
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {3});
auto idft = std::make_shared<op::v7::IDFT>(data, axes);
FAIL() << "IDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axis 3 must be in the input rank range");
}
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {-3});
auto idft = std::make_shared<op::v7::IDFT>(data, axes);
FAIL() << "IDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axis -3 must be in the input rank range");
}
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, -2});
auto idft = std::make_shared<op::v7::IDFT>(data, axes);
FAIL() << "IDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axes must be unique.");
}
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {2});
auto idft = std::make_shared<op::v7::IDFT>(data, axes);
FAIL() << "IDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axis 2 must be in the input rank range");
}
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
auto idft = std::make_shared<op::v7::IDFT>(data, axes);
FAIL() << "IDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op axes input must be 1D tensor.");
}
}
TEST(type_prop, idft_invalid_signal_size) {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {0});
try {
auto signal_size = ov::op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
auto idft = std::make_shared<op::v7::IDFT>(data, axes, signal_size);
FAIL() << "IDFT node was created with invalid signal size.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "FFT op signal size input must be 1D tensor.");
}
try {
auto signal_size = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
auto idft = std::make_shared<op::v7::IDFT>(data, axes, signal_size);
FAIL() << "IDFT node was created with invalid signal size.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "Sizes of inputs 'axes' and 'signal_size' must be equal.");
}
}
TEST(type_prop, idft_dynamic_types) {
const auto input_shape = PartialShape{2, 180, 180, 2};
const auto axes_shape = PartialShape::dynamic();
const auto signal_size_shape = PartialShape::dynamic();
const auto ref_output_shape = PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2};
auto data = std::make_shared<ov::op::v0::Parameter>(element::dynamic, input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::dynamic, axes_shape);
auto signal_size_input = std::make_shared<ov::op::v0::Parameter>(element::dynamic, signal_size_shape);
auto idft = std::make_shared<op::v7::IDFT>(data, axes_input, signal_size_input);
EXPECT_EQ(idft->get_element_type(), element::dynamic);
ASSERT_TRUE(idft->get_output_partial_shape(0).same_scheme(ref_output_shape));
}

View File

@ -18,10 +18,13 @@
#include <gtest/gtest.h>
#include "common_test_utils/test_assertions.hpp"
#include "common_test_utils/type_prop.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/parameter.hpp"
using namespace ov;
using namespace testing;
struct IRDFTConstantAxesAndConstantSignalSizeTestParams {
PartialShape input_shape;
@ -30,6 +33,7 @@ struct IRDFTConstantAxesAndConstantSignalSizeTestParams {
PartialShape ref_output_shape;
std::vector<int64_t> axes;
std::vector<int64_t> signal_size;
std::vector<label_t> expected_labels;
};
struct IRDFTConstantAxesAndConstantSignalSizeTest
@ -38,164 +42,220 @@ struct IRDFTConstantAxesAndConstantSignalSizeTest
TEST_P(IRDFTConstantAxesAndConstantSignalSizeTest, irdft_constant_axes_and_signal_size) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = ov::op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
auto input_shape = params.input_shape;
set_shape_labels(input_shape, 10);
auto data = std::make_shared<op::v0::Parameter>(element::f32, input_shape);
auto axes_input = op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
std::shared_ptr<op::v9::IRDFT> irdft;
if (params.signal_size.empty()) {
irdft = std::make_shared<op::v9::IRDFT>(data, axes_input);
} else {
auto signal_size_input =
ov::op::v0::Constant::create<int64_t>(element::i64, params.signal_size_shape, params.signal_size);
op::v0::Constant::create<int64_t>(element::i64, params.signal_size_shape, params.signal_size);
irdft = std::make_shared<op::v9::IRDFT>(data, axes_input, signal_size_input);
}
EXPECT_EQ(irdft->get_element_type(), element::f32);
ASSERT_TRUE(irdft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
EXPECT_EQ(irdft->get_output_partial_shape(0), params.ref_output_shape);
EXPECT_EQ(get_shape_labels(irdft->get_output_partial_shape(0)), (params.expected_labels));
}
INSTANTIATE_TEST_SUITE_P(
type_prop,
IRDFTConstantAxesAndConstantSignalSizeTest,
::testing::Values(
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, Shape{}, {2, 180, 358}, {1, 2}, {}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, Shape{}, {2, 180, 180}, {2, 0}, {}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2},
{2},
Shape{},
{2, 180, 358},
{1, 2},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2},
{2},
Shape{},
{2, 180, 180},
{2, 0},
{},
{no_label, 11, 12}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{4, 180, 180, 2},
{2},
Shape{},
{6, 180, 180},
{2, 0},
{},
{no_label, 11, 12}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{16, 500, 180, 369, 2},
{3},
Shape{},
{16, 998, 180, 369},
{0, 3, 1},
{}},
{},
{10, no_label, 12, 13}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, Dimension(1, 18)},
{2},
Shape{},
{2, 180, 358},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(7, 500), 2},
{2},
Shape{},
{2, 180, Dimension(12, 998)},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{2, 180, Dimension(12, 998)},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), 180, 2},
{2},
Shape{},
{2, Dimension(7, 500), 358},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), 180, Dimension(1, 18)},
{2},
Shape{},
{2, Dimension(7, 500), 358},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), Dimension(7, 500), 2},
{2},
Shape{},
{2, Dimension(7, 500), Dimension(12, 998)},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{2, Dimension(7, 500), Dimension(12, 998)},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, 180, 2},
{2},
Shape{},
{Dimension(0, 2), 180, 358},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, 180, Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), 180, 358},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, Dimension(7, 500), 2},
{2},
Shape{},
{Dimension(0, 2), 180, Dimension(12, 998)},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), 180, Dimension(12, 998)},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), 180, 2},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), 358},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), 180, Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), 358},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), 2},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), Dimension(12, 998)},
{1, 2},
{}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{
{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500), Dimension(1, 18)},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), Dimension(12, 998)},
{1, 2},
{}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, {2}, {2, 180, 77}, {1, 2}, {-1, 77}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2}, {2}, {2}, {87, 180, 390}, {2, 0}, {390, 87}},
{},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2},
{2},
{2},
{2, 180, 77},
{1, 2},
{-1, 77},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180, 2},
{2},
{2},
{87, 180, 390},
{2, 0},
{390, 87},
{no_label, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{7, 50, 130, 400, 2},
{3},
{3},
{7, 40, 130, 600},
{3, 0, 1},
{600, -1, 40}},
{600, -1, 40},
{10, no_label, 12, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(0, 200), 180, 2},
{2},
{2},
{2, Dimension(0, 200), 77},
{1, 2},
{-1, 77}},
{-1, 77},
{10, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400), 2},
{2},
{2},
{87, 180, 390},
{2, 0},
{390, 87}},
{390, 87},
{no_label, 11, no_label}},
IRDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(8, 129), 50, 130, Dimension(0, 500), 2},
{3},
{3},
{Dimension(8, 129), 40, 130, 600},
{3, 0, 1},
{600, -1, 40}}),
{600, -1, 40},
{10, no_label, 12, no_label}}),
PrintToDummyParamName());
TEST(type_prop, irdft_dynamic_axes) {
const auto input_shape = PartialShape{2, 180, 180, Dimension(1, 18)};
auto input_shape = PartialShape{2, 180, 180, Dimension(1, 18)};
set_shape_labels(input_shape, 10);
const auto axes_shape = PartialShape::dynamic();
const auto ref_output_shape = PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()};
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::i64, axes_shape);
auto data = std::make_shared<op::v0::Parameter>(element::f32, input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::i64, axes_shape);
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes_input);
EXPECT_EQ(irdft->get_element_type(), element::f32);
ASSERT_TRUE(irdft->get_output_partial_shape(0).same_scheme(ref_output_shape));
EXPECT_EQ(irdft->get_output_partial_shape(0), ref_output_shape);
EXPECT_THAT(get_shape_labels(irdft->get_output_partial_shape(0)), Each(no_label));
}
struct IRDFTNonConstantAxesTestParams {
@ -208,13 +268,16 @@ struct IRDFTNonConstantAxesTest : ::testing::TestWithParam<IRDFTNonConstantAxesT
TEST_P(IRDFTNonConstantAxesTest, irdft_non_constant_axes) {
auto params = GetParam();
auto input_shape = params.input_shape;
set_shape_labels(input_shape, 10);
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::i64, params.axes_shape);
auto data = std::make_shared<op::v0::Parameter>(element::f32, input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::i64, params.axes_shape);
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes_input);
EXPECT_EQ(irdft->get_element_type(), element::f32);
ASSERT_TRUE(irdft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
EXPECT_EQ(irdft->get_output_partial_shape(0), params.ref_output_shape);
EXPECT_THAT(get_shape_labels(irdft->get_output_partial_shape(0)), Each(no_label));
}
INSTANTIATE_TEST_SUITE_P(
@ -274,6 +337,7 @@ struct IRDFTNonConstantSignalSizeTestParams {
Shape signal_size_shape;
PartialShape ref_output_shape;
std::vector<int64_t> axes;
std::vector<label_t> expected_labels;
};
struct IRDFTNonConstantSignalSizeTest : ::testing::TestWithParam<IRDFTNonConstantSignalSizeTestParams> {};
@ -281,13 +345,17 @@ struct IRDFTNonConstantSignalSizeTest : ::testing::TestWithParam<IRDFTNonConstan
TEST_P(IRDFTNonConstantSignalSizeTest, irdft_non_constant_signal_size) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = ov::op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
auto signal_size_input = std::make_shared<ov::op::v0::Parameter>(element::i64, params.signal_size_shape);
auto input_shape = params.input_shape;
set_shape_labels(input_shape, 10);
auto data = std::make_shared<op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
auto signal_size_input = std::make_shared<op::v0::Parameter>(element::i64, params.signal_size_shape);
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes_input, signal_size_input);
EXPECT_EQ(irdft->get_element_type(), element::f32);
ASSERT_TRUE(irdft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
EXPECT_EQ(irdft->get_output_partial_shape(0), params.ref_output_shape);
EXPECT_EQ(get_shape_labels(irdft->get_output_partial_shape(0)), params.expected_labels);
}
INSTANTIATE_TEST_SUITE_P(
@ -297,111 +365,84 @@ INSTANTIATE_TEST_SUITE_P(
{2},
{2},
{2, Dimension(0, 200), Dimension::dynamic()},
{1, 2}},
{1, 2},
{no_label, no_label, no_label}},
IRDFTNonConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400), 2},
{2},
{2},
{Dimension::dynamic(), 180, Dimension(0, 400)},
{2, 0}},
{2, 0},
{no_label, no_label, no_label}},
IRDFTNonConstantSignalSizeTestParams{
{Dimension(8, 129), 50, 130, Dimension(0, 500), 2},
{3},
{3},
{Dimension(8, 129), Dimension::dynamic(), 130, Dimension(0, 500)},
{3, 0, 1}}),
{3, 0, 1},
{no_label, no_label, no_label, no_label}}),
PrintToDummyParamName());
TEST(type_prop, irdft_invalid_input) {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
auto axes = op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{2});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes);
FAIL() << "IRDFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The input rank must be greater or equal to 2.");
}
auto data = std::make_shared<op::v0::Parameter>(element::f32, Shape{2});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes),
Exception,
HasSubstr("The input rank must be greater or equal to 2"));
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes);
FAIL() << "IRDFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The last dimension of input data must be 2.");
}
data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 3});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes),
Exception,
HasSubstr("The last dimension of input data must be 2"));
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 2});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes);
FAIL() << "IRDFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The input rank must be greater than number of IRDFT op axes.");
}
data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 2});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes),
Exception,
HasSubstr("The input rank must be greater than number of axes."));
}
TEST(type_prop, irdft_invalid_axes) {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 3, 2});
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {3});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes);
FAIL() << "IRDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op axis 3 must be in the input rank range");
}
auto axes = op::v0::Constant::create(element::i64, Shape{1}, {3});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes),
Exception,
HasSubstr("Axis value: 3, must be in range (-3, 2)"));
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {-3});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes);
FAIL() << "IRDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op axis -3 must be in the input rank range");
}
axes = op::v0::Constant::create(element::i64, Shape{1}, {-3});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes),
Exception,
HasSubstr("Axis value: -3, must be in range (-3, 2)"));
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, -2});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes);
FAIL() << "IRDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op axes must be unique.");
}
axes = op::v0::Constant::create(element::i64, Shape{2}, {0, -2});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes),
Exception,
HasSubstr("Each axis must be unique"));
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {2});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes);
FAIL() << "IRDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op axis 2 must be in the input rank range");
}
axes = op::v0::Constant::create(element::i64, Shape{1}, {2});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes),
Exception,
HasSubstr("Axis value: 2, must be in range (-3, 2)"));
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes);
FAIL() << "IRDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op axes input must be 1D tensor.");
}
axes = op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes),
Exception,
HasSubstr("Axes input must be 1D tensor."));
}
TEST(type_prop, irdft_invalid_signal_size) {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {0});
auto data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto axes = op::v0::Constant::create(element::i64, Shape{1}, {0});
try {
auto signal_size = ov::op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes, signal_size);
FAIL() << "IRDFT node was created with invalid signal size.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op signal size input must be 1D tensor.");
}
auto signal_size = op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes, signal_size),
Exception,
HasSubstr("Signal size input must be 1D tensor."));
try {
auto signal_size = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes, signal_size);
FAIL() << "IRDFT node was created with invalid signal size.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "Sizes of inputs 'axes' and 'signal_size' of (I)RDFT op must be equal.");
}
signal_size = op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::IRDFT>(data, axes, signal_size),
Exception,
HasSubstr("Sizes of inputs 'axes' and 'signal_size' must be equal."));
}
TEST(type_prop, irdft_dynamic_types) {
@ -410,11 +451,11 @@ TEST(type_prop, irdft_dynamic_types) {
const auto signal_size_shape = PartialShape::dynamic();
const auto ref_output_shape = PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()};
auto data = std::make_shared<ov::op::v0::Parameter>(element::dynamic, input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::dynamic, axes_shape);
auto signal_size_input = std::make_shared<ov::op::v0::Parameter>(element::dynamic, signal_size_shape);
auto data = std::make_shared<op::v0::Parameter>(element::dynamic, input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::dynamic, axes_shape);
auto signal_size_input = std::make_shared<op::v0::Parameter>(element::dynamic, signal_size_shape);
auto irdft = std::make_shared<op::v9::IRDFT>(data, axes_input, signal_size_input);
EXPECT_EQ(irdft->get_element_type(), element::dynamic);
ASSERT_TRUE(irdft->get_output_partial_shape(0).same_scheme(ref_output_shape));
EXPECT_EQ(irdft->get_output_partial_shape(0), ref_output_shape);
}

View File

@ -1,25 +1,18 @@
//*****************************************************************************
// Copyright 2017-2022 Intel Corporation
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************
#include "openvino/op/rdft.hpp"
#include <gtest/gtest.h>
#include "common_test_utils/test_assertions.hpp"
#include "common_test_utils/type_prop.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/parameter.hpp"
using namespace ov;
using namespace testing;
struct RDFTConstantAxesAndConstantSignalSizeTestParams {
PartialShape input_shape;
@ -28,6 +21,7 @@ struct RDFTConstantAxesAndConstantSignalSizeTestParams {
PartialShape ref_output_shape;
std::vector<int64_t> axes;
std::vector<int64_t> signal_size;
std::vector<ov::label_t> expected_labels;
};
struct RDFTConstantAxesAndConstantSignalSizeTest
@ -36,108 +30,148 @@ struct RDFTConstantAxesAndConstantSignalSizeTest
TEST_P(RDFTConstantAxesAndConstantSignalSizeTest, rdft_constant_axes_and_signal_size) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = ov::op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
auto input_shape = params.input_shape;
set_shape_labels(input_shape, 10);
auto data = std::make_shared<op::v0::Parameter>(element::f32, input_shape);
auto axes_input = op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
std::shared_ptr<op::v9::RDFT> rdft;
if (params.signal_size.empty()) {
rdft = std::make_shared<ov::op::v9::RDFT>(data, axes_input);
} else {
auto signal_size_input =
ov::op::v0::Constant::create<int64_t>(element::i64, params.signal_size_shape, params.signal_size);
op::v0::Constant::create<int64_t>(element::i64, params.signal_size_shape, params.signal_size);
rdft = std::make_shared<op::v9::RDFT>(data, axes_input, signal_size_input);
}
EXPECT_EQ(rdft->get_element_type(), element::f32);
ASSERT_TRUE(rdft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
EXPECT_EQ(rdft->get_output_partial_shape(0), params.ref_output_shape);
EXPECT_EQ(get_shape_labels(rdft->get_output_partial_shape(0)), params.expected_labels);
}
INSTANTIATE_TEST_SUITE_P(
type_prop,
RDFTConstantAxesAndConstantSignalSizeTest,
::testing::Values(
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180}, {2}, Shape{}, {2, 180, 91, 2}, {1, 2}, {}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{6, 180, 180}, {2}, Shape{}, {4, 180, 180, 2}, {2, 0}, {}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180},
{2},
Shape{},
{2, 180, 91, 2},
{1, 2},
{},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{6, 180, 180},
{2},
Shape{},
{4, 180, 180, 2},
{2, 0},
{},
{ov::no_label, 11, 12, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{16, 500, 180, 369},
{3},
Shape{},
{16, 251, 180, 369, 2},
{0, 3, 1},
{}},
{},
{10, ov::no_label, 12, 13, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(1, 18)},
{2},
Shape{},
{2, 180, Dimension(1, 10), 2},
{1, 2},
{}},
{},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, Dimension(7, 500)},
{2},
Shape{},
{2, 180, Dimension(4, 251), 2},
{1, 2},
{}},
{},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), 180},
{2},
Shape{},
{2, Dimension(7, 500), 91, 2},
{1, 2},
{}},
{},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(7, 500), Dimension(7, 500)},
{2},
Shape{},
{2, Dimension(7, 500), Dimension(4, 251), 2},
{1, 2},
{}},
{},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, 180},
{2},
Shape{},
{Dimension(0, 2), 180, 91, 2},
{1, 2},
{}},
{},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), 180, Dimension(7, 500)},
{2},
Shape{},
{Dimension(0, 2), 180, Dimension(4, 251), 2},
{1, 2},
{}},
{},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), 180},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), 91, 2},
{1, 2},
{}},
{},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 2), Dimension(7, 500), Dimension(7, 500)},
{2},
Shape{},
{Dimension(0, 2), Dimension(7, 500), Dimension(4, 251), 2},
{1, 2},
{}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180}, {2}, {2}, {2, 180, 39, 2}, {1, 2}, {-1, 77}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180}, {2}, {2}, {44, 180, 390, 2}, {2, 0}, {390, 87}},
{},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180},
{2},
{2},
{2, 180, 39, 2},
{1, 2},
{-1, 77},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, 180, 180},
{2},
{2},
{44, 180, 390, 2},
{2, 0},
{390, 87},
{0, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{7, 50, 130, 400},
{3},
{3},
{7, 21, 130, 600, 2},
{3, 0, 1},
{600, -1, 40}},
{600, -1, 40},
{10, ov::no_label, 12, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{2, Dimension(0, 200), 180},
{2},
{2},
{2, Dimension(0, 200), 39, 2},
{1, 2},
{-1, 77}},
{-1, 77},
{10, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400)},
{2},
{2},
{44, 180, 390, 2},
{2, 0},
{390, 87}},
{390, 87},
{ov::no_label, 11, ov::no_label, ov::no_label}},
RDFTConstantAxesAndConstantSignalSizeTestParams{{Dimension(8, 129), 50, 130, Dimension(0, 500)},
{3},
{3},
{Dimension(8, 129), 21, 130, 600, 2},
{3, 0, 1},
{600, -1, 40}}),
{600, -1, 40},
{10, ov::no_label, 12, ov::no_label, ov::no_label}}),
PrintToDummyParamName());
TEST(type_prop, rdft_dynamic_axes) {
@ -145,12 +179,12 @@ TEST(type_prop, rdft_dynamic_axes) {
const auto axes_shape = PartialShape::dynamic();
const auto ref_output_shape = PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2};
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::i64, axes_shape);
auto data = std::make_shared<op::v0::Parameter>(element::f32, input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::i64, axes_shape);
auto rdft = std::make_shared<op::v9::RDFT>(data, axes_input);
EXPECT_EQ(rdft->get_element_type(), element::f32);
ASSERT_TRUE(rdft->get_output_partial_shape(0).same_scheme(ref_output_shape));
EXPECT_EQ(rdft->get_output_partial_shape(0), ref_output_shape);
}
struct RDFTNonConstantAxesTestParams {
@ -164,12 +198,13 @@ struct RDFTNonConstantAxesTest : ::testing::TestWithParam<RDFTNonConstantAxesTes
TEST_P(RDFTNonConstantAxesTest, rdft_non_constant_axes) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::i64, params.axes_shape);
auto data = std::make_shared<op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::i64, params.axes_shape);
auto rdft = std::make_shared<op::v9::RDFT>(data, axes_input);
EXPECT_EQ(rdft->get_element_type(), element::f32);
ASSERT_TRUE(rdft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
EXPECT_EQ(rdft->get_output_partial_shape(0), params.ref_output_shape);
EXPECT_THAT(get_shape_labels(rdft->get_output_partial_shape(0)), Each(ov::no_label));
}
INSTANTIATE_TEST_SUITE_P(
@ -208,6 +243,7 @@ struct RDFTNonConstantSignalSizeTestParams {
Shape signal_size_shape;
PartialShape ref_output_shape;
std::vector<int64_t> axes;
std::vector<ov::label_t> expected_labels;
};
struct RDFTNonConstantSignalSizeTest : ::testing::TestWithParam<RDFTNonConstantSignalSizeTestParams> {};
@ -215,13 +251,14 @@ struct RDFTNonConstantSignalSizeTest : ::testing::TestWithParam<RDFTNonConstantS
TEST_P(RDFTNonConstantSignalSizeTest, rdft_non_constant_signal_size) {
auto params = GetParam();
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = ov::op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
auto signal_size_input = std::make_shared<ov::op::v0::Parameter>(element::i64, params.signal_size_shape);
auto data = std::make_shared<op::v0::Parameter>(element::f32, params.input_shape);
auto axes_input = op::v0::Constant::create<int64_t>(element::i64, params.axes_shape, params.axes);
auto signal_size_input = std::make_shared<op::v0::Parameter>(element::i64, params.signal_size_shape);
auto rdft = std::make_shared<op::v9::RDFT>(data, axes_input, signal_size_input);
EXPECT_EQ(rdft->get_element_type(), element::f32);
ASSERT_TRUE(rdft->get_output_partial_shape(0).same_scheme(params.ref_output_shape));
EXPECT_EQ(rdft->get_output_partial_shape(0), params.ref_output_shape);
EXPECT_EQ(get_shape_labels(rdft->get_output_partial_shape(0)), params.expected_labels);
}
INSTANTIATE_TEST_SUITE_P(
@ -231,96 +268,74 @@ INSTANTIATE_TEST_SUITE_P(
{2},
{2},
{2, Dimension(0, 200), Dimension::dynamic(), 2},
{1, 2}},
{1, 2},
{ov::no_label, ov::no_label, ov::no_label, ov::no_label}},
RDFTNonConstantSignalSizeTestParams{{Dimension(0, 18), 180, Dimension(0, 400)},
{2},
{2},
{Dimension::dynamic(), 180, Dimension(0, 400), 2},
{2, 0}},
{2, 0},
{ov::no_label, ov::no_label, ov::no_label, ov::no_label}},
RDFTNonConstantSignalSizeTestParams{
{Dimension(8, 129), 50, 130, Dimension(0, 500)},
{3},
{3},
{Dimension(8, 129), Dimension::dynamic(), 130, Dimension(0, 500), 2},
{3, 0, 1}}),
{3, 0, 1},
{ov::no_label, ov::no_label, ov::no_label, ov::no_label, ov::no_label}}),
PrintToDummyParamName());
TEST(type_prop, rdft_invalid_input) {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
auto axes = op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{});
auto rdft = std::make_shared<op::v9::RDFT>(data, axes);
FAIL() << "RDFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "The input rank must be greater or equal to 1.");
}
auto data = std::make_shared<op::v0::Parameter>(element::f32, Shape{});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::RDFT>(data, axes),
ov::Exception,
HasSubstr("The input rank must be greater or equal to 1"));
try {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
auto rdft = std::make_shared<op::v9::RDFT>(data, axes);
FAIL() << "RDFT node was created with invalid input.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(),
"The input rank must be greater than or equal to the number of RDFT op axes.");
}
data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::RDFT>(data, axes),
ov::Exception,
HasSubstr("The input rank must be greater than or equal to the number of axes."));
}
TEST(type_prop, rdft_invalid_axes) {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 3, 2});
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {3});
auto rdft = std::make_shared<op::v9::RDFT>(data, axes);
FAIL() << "RDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op axis 3 must be in the input rank range");
}
auto axes = op::v0::Constant::create(element::i64, Shape{1}, {3});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::RDFT>(data, axes),
ov::Exception,
HasSubstr("Axis value: 3, must be in range (-4, 3)"));
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {-4});
auto rdft = std::make_shared<op::v9::RDFT>(data, axes);
FAIL() << "RDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op axis -4 must be in the input rank range");
}
axes = op::v0::Constant::create(element::i64, Shape{1}, {-4});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::RDFT>(data, axes),
ov::Exception,
HasSubstr("Axis value: -4, must be in range (-4, 3)"));
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, -3});
auto rdft = std::make_shared<op::v9::RDFT>(data, axes);
FAIL() << "RDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op axes must be unique.");
}
axes = op::v0::Constant::create(element::i64, Shape{2}, {0, -3});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::RDFT>(data, axes),
ov::Exception,
HasSubstr("Each axis must be unique"));
try {
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
auto rdft = std::make_shared<op::v9::RDFT>(data, axes);
FAIL() << "RDFT node was created with invalid axes.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op axes input must be 1D tensor.");
}
axes = op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::RDFT>(data, axes),
ov::Exception,
HasSubstr("Axes input must be 1D tensor."));
}
TEST(type_prop, rdft_invalid_signal_size) {
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto axes = ov::op::v0::Constant::create(element::i64, Shape{1}, {0});
auto data = std::make_shared<op::v0::Parameter>(element::f32, Shape{4, 3, 2});
auto axes = op::v0::Constant::create(element::i64, Shape{1}, {0});
try {
auto signal_size = ov::op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
auto rdft = std::make_shared<op::v9::RDFT>(data, axes, signal_size);
FAIL() << "RDFT node was created with invalid signal size.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "(I)RDFT op signal size input must be 1D tensor.");
}
auto signal_size = op::v0::Constant::create(element::i64, Shape{1, 2}, {0, 1});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::RDFT>(data, axes, signal_size),
ov::Exception,
HasSubstr("Signal size input must be 1D tensor."));
try {
auto signal_size = ov::op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
auto rdft = std::make_shared<op::v9::RDFT>(data, axes, signal_size);
FAIL() << "RDFT node was created with invalid signal size.";
} catch (const NodeValidationFailure& error) {
EXPECT_HAS_SUBSTRING(error.what(), "Sizes of inputs 'axes' and 'signal_size' of (I)RDFT op must be equal.");
}
signal_size = op::v0::Constant::create(element::i64, Shape{2}, {0, 1});
OV_EXPECT_THROW(std::ignore = std::make_shared<op::v9::RDFT>(data, axes, signal_size),
ov::Exception,
HasSubstr("Sizes of inputs 'axes' and 'signal_size' must be equal."));
}
TEST(type_prop, rdft_dynamic_types) {
@ -329,11 +344,11 @@ TEST(type_prop, rdft_dynamic_types) {
const auto signal_size_shape = PartialShape::dynamic();
const auto ref_output_shape = PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), 2};
auto data = std::make_shared<ov::op::v0::Parameter>(element::dynamic, input_shape);
auto axes_input = std::make_shared<ov::op::v0::Parameter>(element::dynamic, axes_shape);
auto signal_size_input = std::make_shared<ov::op::v0::Parameter>(element::dynamic, signal_size_shape);
auto data = std::make_shared<op::v0::Parameter>(element::dynamic, input_shape);
auto axes_input = std::make_shared<op::v0::Parameter>(element::dynamic, axes_shape);
auto signal_size_input = std::make_shared<op::v0::Parameter>(element::dynamic, signal_size_shape);
auto rdft = std::make_shared<op::v9::RDFT>(data, axes_input, signal_size_input);
EXPECT_EQ(rdft->get_element_type(), element::dynamic);
ASSERT_TRUE(rdft->get_output_partial_shape(0).same_scheme(ref_output_shape));
EXPECT_EQ(rdft->get_output_partial_shape(0), ref_output_shape);
}