diff --git a/docs/ops/logical/LogicalNot_1.md b/docs/ops/logical/LogicalNot_1.md index 0552da02c7b..9c5f35081cc 100644 --- a/docs/ops/logical/LogicalNot_1.md +++ b/docs/ops/logical/LogicalNot_1.md @@ -6,31 +6,32 @@ **Short description**: *LogicalNot* performs element-wise logical negation operation with given tensor. -**Attributes**: - - No attributes available. - -**Inputs** - -* **1**: An tensor of type *T*. **Required.** - -**Outputs** - -* **1**: The result of element-wise logical negation operation. A tensor of type *T*. - -**Types** - -* *T*: boolean type. - -*LogicalNot* does the following with the input tensor *a*: +**Detailed description**: *LogicalNot* performs element-wise logical negation operation with given tensor, based on the following mathematical formula: \f[ a_{i} = \lnot a_{i} \f] -**Examples** +**Attributes**: *LogicalNot* operation has no attributes. -*Example 1* +**Inputs** + +* **1**: A tensor of type *T_BOOL* and arbitrary shape. **Required.** + +**Outputs** + +* **1**: The result of element-wise logical negation operation. A tensor of type *T_BOOL* and the same shape as input tensor. + +**Types** + +* *T_BOOL*: `boolean`. + +\f[ +a_{i} = \lnot a_{i} +\f] + + +**Example** ```xml diff --git a/docs/template_plugin/tests/functional/op_reference/logical.hpp b/docs/template_plugin/tests/functional/op_reference/logical.hpp index adf8e22f957..ee681f36141 100644 --- a/docs/template_plugin/tests/functional/op_reference/logical.hpp +++ b/docs/template_plugin/tests/functional/op_reference/logical.hpp @@ -18,15 +18,13 @@ namespace LogicalOpsRefTestDefinitions { struct RefLogicalParams { ngraph::helpers::LogicalTypes opType; - Tensor input1; - Tensor input2; + std::vector inputs; Tensor expected; }; struct Builder : ParamsBuilder { REFERENCE_TESTS_ADD_SET_PARAM(Builder, opType); - REFERENCE_TESTS_ADD_SET_PARAM(Builder, input1); - REFERENCE_TESTS_ADD_SET_PARAM(Builder, input2); + REFERENCE_TESTS_ADD_SET_PARAM(Builder, inputs); REFERENCE_TESTS_ADD_SET_PARAM(Builder, expected); }; @@ -34,28 +32,34 @@ class ReferenceLogicalLayerTest : public testing::TestWithParam& obj) { const auto& param = obj.param; std::ostringstream result; result << "LogicalType=" << param.opType << "_"; - result << "inpt_shape1=" << param.input1.shape << "_"; - result << "inpt_shape2=" << param.input2.shape << "_"; - result << "iType=" << param.input1.type << "_"; + for (size_t i =0; i< param.inputs.size(); i++) { + const auto input = param.inputs[i]; + result << "inpt_shape" << i << "=" << input.shape << "_"; + result << "inpt_type" << i << "=" << input.type << "_"; + } result << "oType=" << param.expected.type; return result.str(); } private: - static std::shared_ptr CreateFunction(ngraph::helpers::LogicalTypes op_type, const ngraph::PartialShape& input_shape1, - const ngraph::PartialShape& input_shape2, const ngraph::element::Type& elem_type) { - const auto in1 = std::make_shared(elem_type, input_shape1); - const auto in2 = std::make_shared(elem_type, input_shape2); - const auto logical_op = ngraph::builder::makeLogical(in1, in2, op_type); - return std::make_shared(ngraph::NodeVector {logical_op}, ngraph::ParameterVector {in1, in2}); + static std::shared_ptr CreateFunction(ngraph::helpers::LogicalTypes op_type, const std::vector& inputs) { + ngraph::ParameterVector params_vec; + for (auto& input : inputs) { + params_vec.push_back(std::make_shared(input.type, input.shape)); + } + + const auto logical_op = ngraph::builder::makeLogical(params_vec, op_type); + return std::make_shared(ngraph::NodeVector {logical_op}, ngraph::ParameterVector {params_vec}); } }; } // namespace LogicalOpsRefTestDefinitions diff --git a/docs/template_plugin/tests/functional/op_reference/logical_and.cpp b/docs/template_plugin/tests/functional/op_reference/logical_and.cpp index 0f19bbe50b4..0d1db90e21a 100644 --- a/docs/template_plugin/tests/functional/op_reference/logical_and.cpp +++ b/docs/template_plugin/tests/functional/op_reference/logical_and.cpp @@ -24,18 +24,18 @@ std::vector generateLogicalParams() { std::vector logicalParams { Builder {} .opType(LogicalTypes::LOGICAL_AND) - .input1({{2, 2}, element::boolean, std::vector {true, false, true, false}}) - .input2({{2, 2}, element::boolean, std::vector {false, true, true, false}}) + .inputs({{{2, 2}, element::boolean, std::vector {true, false, true, false}}, + {{2, 2}, element::boolean, std::vector {false, true, true, false}}}) .expected({{2, 2}, element::boolean, std::vector {false, false, true, false}}), Builder {} .opType(LogicalTypes::LOGICAL_AND) - .input1({{2, 1, 2, 1}, element::boolean, std::vector {true, false, true, false}}) - .input2({{1, 1, 2, 1}, element::boolean, std::vector {true, false}}) + .inputs({{{2, 1, 2, 1}, element::boolean, std::vector {true, false, true, false}}, + {{1, 1, 2, 1}, element::boolean, std::vector {true, false}}}) .expected({{2, 1, 2, 1}, element::boolean, std::vector {true, false, true, false}}), Builder {} .opType(LogicalTypes::LOGICAL_AND) - .input1({{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, true}}) - .input2({{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, false}}) + .inputs({{{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, true}}, + {{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, false}}}) .expected({{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, false}})}; return logicalParams; } diff --git a/docs/template_plugin/tests/functional/op_reference/logical_not.cpp b/docs/template_plugin/tests/functional/op_reference/logical_not.cpp new file mode 100644 index 00000000000..3bcfa3c6ba8 --- /dev/null +++ b/docs/template_plugin/tests/functional/op_reference/logical_not.cpp @@ -0,0 +1,37 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include +#include +#include +#include + +#include "logical.hpp" + +using namespace ngraph; +using namespace InferenceEngine; +using LogicalTypes = ngraph::helpers::LogicalTypes; + +namespace reference_tests { +namespace LogicalOpsRefTestDefinitions { +namespace { + +std::vector generateLogicalParams() { + std::vector logicalParams { + Builder {} + .opType(LogicalTypes::LOGICAL_NOT) + .inputs({{{2, 2}, element::boolean, std::vector {true, false, true, false}}}) + .expected({{2, 2}, element::boolean, std::vector {false, true, false, true}})}; + return logicalParams; +} + +INSTANTIATE_TEST_SUITE_P(smoke_LogicalNot_With_Hardcoded_Refs, ReferenceLogicalLayerTest, ::testing::ValuesIn(generateLogicalParams()), + ReferenceLogicalLayerTest::getTestCaseName); + +} // namespace +} // namespace LogicalOpsRefTestDefinitions +} // namespace reference_tests diff --git a/docs/template_plugin/tests/functional/op_reference/logical_or.cpp b/docs/template_plugin/tests/functional/op_reference/logical_or.cpp index 9bd4c61539f..e8c28f24468 100644 --- a/docs/template_plugin/tests/functional/op_reference/logical_or.cpp +++ b/docs/template_plugin/tests/functional/op_reference/logical_or.cpp @@ -24,18 +24,18 @@ std::vector generateLogicalParams() { std::vector logicalParams { Builder {} .opType(LogicalTypes::LOGICAL_OR) - .input1({{2, 2}, element::boolean, std::vector {true, false, true, false}}) - .input2({{2, 2}, element::boolean, std::vector {false, true, true, false}}) + .inputs({{{2, 2}, element::boolean, std::vector {true, false, true, false}}, + {{2, 2}, element::boolean, std::vector {false, true, true, false}}}) .expected({{2, 2}, element::boolean, std::vector {true, true, true, false}}), Builder {} .opType(LogicalTypes::LOGICAL_OR) - .input1({{2, 1, 2, 1}, element::boolean, std::vector {true, false, true, false}}) - .input2({{1, 1, 2, 1}, element::boolean, std::vector {true, false}}) + .inputs({{{2, 1, 2, 1}, element::boolean, std::vector {true, false, true, false}}, + {{1, 1, 2, 1}, element::boolean, std::vector {true, false}}}) .expected({{2, 1, 2, 1}, element::boolean, std::vector {true, false, true, false}}), Builder {} .opType(LogicalTypes::LOGICAL_OR) - .input1({{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, true}}) - .input2({{3, 4}, element::boolean, std::vector {true, true, true, true, true, true, true, false, false, true, true, false}}) + .inputs({{{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, true}}, + {{3, 4}, element::boolean, std::vector {true, true, true, true, true, true, true, false, false, true, true, false}}}) .expected({{3, 4}, element::boolean, std::vector {true, true, true, true, true, true, true, false, false, true, true, true}})}; return logicalParams; } diff --git a/docs/template_plugin/tests/functional/op_reference/logical_xor.cpp b/docs/template_plugin/tests/functional/op_reference/logical_xor.cpp index ac30a4c8352..52269ddb894 100644 --- a/docs/template_plugin/tests/functional/op_reference/logical_xor.cpp +++ b/docs/template_plugin/tests/functional/op_reference/logical_xor.cpp @@ -24,18 +24,18 @@ std::vector generateLogicalParams() { std::vector logicalParams { Builder {} .opType(LogicalTypes::LOGICAL_XOR) - .input1({{2, 2}, element::boolean, std::vector {true, false, true, false}}) - .input2({{2, 2}, element::boolean, std::vector {false, true, true, false}}) + .inputs({{{2, 2}, element::boolean, std::vector {true, false, true, false}}, + {{2, 2}, element::boolean, std::vector {false, true, true, false}}}) .expected({{2, 2}, element::boolean, std::vector {true, true, false, false}}), Builder {} .opType(LogicalTypes::LOGICAL_XOR) - .input1({{2, 1, 2, 1}, element::boolean, std::vector {true, false, true, false}}) - .input2({{1, 1, 2, 1}, element::boolean, std::vector {true, false}}) + .inputs({{{2, 1, 2, 1}, element::boolean, std::vector {true, false, true, false}}, + {{1, 1, 2, 1}, element::boolean, std::vector {true, false}}}) .expected({{2, 1, 2, 1}, element::boolean, std::vector {false, false, false, false}}), Builder {} .opType(LogicalTypes::LOGICAL_XOR) - .input1({{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, true}}) - .input2({{3, 4}, element::boolean, std::vector {true, true, true, true, true, true, true, false, false, true, true, false}}) + .inputs({{{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, true}}, + {{3, 4}, element::boolean, std::vector {true, true, true, true, true, true, true, false, false, true, true, false}}}) .expected({{3, 4}, element::boolean, std::vector {false, false, false, false, false, true, false, false, false, false, false, true}})}; return logicalParams; } diff --git a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py index 7a79d64fa9e..e35678eee29 100644 --- a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py +++ b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py @@ -61,7 +61,8 @@ VERIFIED_OP_REFERENCES = [ 'LRN-1', 'LSTMCell-4', 'LSTMSequence-5', - 'LogicalAnd-1' + 'LogicalAnd-1', + 'LogicalNot-1' 'LogicalOr-1' 'LogicalXor-1' 'LogSoftmax-5', diff --git a/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/builders.hpp b/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/builders.hpp index 8e70dfdc6d8..54db25a547f 100644 --- a/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/builders.hpp +++ b/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/builders.hpp @@ -451,6 +451,9 @@ std::shared_ptr makeLogical(const ngraph::Output &in0, const ngraph::Output &in1, ngraph::helpers::LogicalTypes logicalType); +std::shared_ptr makeLogical(const ngraph::ParameterVector& inputs, + ngraph::helpers::LogicalTypes logicalType); + std::shared_ptr makeDetectionOutput(const ngraph::OutputVector &inputs, const ngraph::op::DetectionOutputAttrs& attrs); diff --git a/inference-engine/tests/ngraph_helpers/ngraph_functions/src/logical.cpp b/inference-engine/tests/ngraph_helpers/ngraph_functions/src/logical.cpp index e21be58f158..784233a5c0a 100644 --- a/inference-engine/tests/ngraph_helpers/ngraph_functions/src/logical.cpp +++ b/inference-engine/tests/ngraph_helpers/ngraph_functions/src/logical.cpp @@ -27,5 +27,22 @@ std::shared_ptr makeLogical(const ngraph::Output &in0, } } +std::shared_ptr makeLogical(const ngraph::ParameterVector& inputs, + ngraph::helpers::LogicalTypes logicalType) { + switch (logicalType) { + case ngraph::helpers::LogicalTypes::LOGICAL_AND: + return std::make_shared(inputs[0], inputs[1]); + case ngraph::helpers::LogicalTypes::LOGICAL_OR: + return std::make_shared(inputs[0], inputs[1]); + case ngraph::helpers::LogicalTypes::LOGICAL_NOT: + return std::make_shared(inputs[0]); + case ngraph::helpers::LogicalTypes::LOGICAL_XOR: + return std::make_shared(inputs[0], inputs[1]); + default: { + throw std::runtime_error("Incorrect type of Logical operation"); + } + } +} + } // namespace builder -} // namespace ngraph \ No newline at end of file +} // namespace ngraph diff --git a/ngraph/core/src/op/not.cpp b/ngraph/core/src/op/not.cpp index a5e196a4f38..26dcc0d7345 100644 --- a/ngraph/core/src/op/not.cpp +++ b/ngraph/core/src/op/not.cpp @@ -9,6 +9,7 @@ #include "ngraph/op/util/elementwise_args.hpp" #include "ngraph/runtime/host_tensor.hpp" #include "ngraph/runtime/reference/not.hpp" +#include "ngraph/validation_util.hpp" using namespace ngraph; using namespace std; @@ -70,6 +71,7 @@ bool evaluate_not(const HostTensorPtr& arg0, const HostTensorPtr& out, const siz bool op::v1::LogicalNot::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const { NGRAPH_OP_SCOPE(v1_LogicalNot_evaluate); + NGRAPH_CHECK(validate_host_tensor_vector(outputs, 1) && validate_host_tensor_vector(inputs, 1)); return notop::evaluate_not(inputs[0], outputs[0], shape_size(get_output_shape(0))); } diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index a851e199d73..16ad46af9ed 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -156,6 +156,7 @@ set(SRC type_prop/idft.cpp type_prop/interpolate.cpp type_prop/logical_and.cpp + type_prop/logical_not.cpp type_prop/logical_or.cpp type_prop/logical_xor.cpp type_prop/lrn.cpp @@ -282,6 +283,7 @@ set(SRC visitors/op/log.cpp visitors/op/logical_and.cpp visitors/op/logical_or.cpp + visitors/op/logical_not.cpp visitors/op/logical_xor.cpp visitors/op/lrn.cpp visitors/op/lstm_cell.cpp @@ -459,7 +461,6 @@ set(MULTI_TEST_SRC backend/interpolate.in.cpp backend/log.in.cpp backend/log_softmax.in.cpp - backend/logical_not.in.cpp backend/lrn.in.cpp backend/matmul.in.cpp backend/matrix_nms.in.cpp diff --git a/ngraph/test/backend/logical_not.in.cpp b/ngraph/test/backend/logical_not.in.cpp deleted file mode 100644 index 4880b4b60d6..00000000000 --- a/ngraph/test/backend/logical_not.in.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include -#include -#include -#include -#include -#include - -// clang-format off -#ifdef ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS -#define DEFAULT_FLOAT_TOLERANCE_BITS ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS -#endif - -#ifdef ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS -#define DEFAULT_DOUBLE_TOLERANCE_BITS ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS -#endif -// clang-format on - -#include "gtest/gtest.h" -#include "ngraph/ngraph.hpp" -#include "util/engine/test_engines.hpp" -#include "util/test_case.hpp" -#include "util/test_control.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -using namespace std; -using namespace ngraph; - -static string s_manifest = "${MANIFEST}"; -using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME}); - -NGRAPH_TEST(${BACKEND_NAME}, not) { - Shape shape{2, 2}; - auto A = make_shared(element::boolean, shape); - auto f = make_shared(make_shared(A), ParameterVector{A}); - - std::vector a{1, 0, 1, 0}; - - auto test_case = test::TestCase(f); - test_case.add_input(shape, a); - test_case.add_expected_output(shape, {0, 1, 0, 1}); - test_case.run(); -} - -NGRAPH_TEST(${BACKEND_NAME}, not_i32) { - Shape shape{2, 2}; - auto A = make_shared(element::i32, shape); - auto f = make_shared(make_shared(A), ParameterVector{A}); - - std::vector a{1, 0, 2, 0}; - - auto test_case = test::TestCase(f); - test_case.add_input(shape, a); - test_case.add_expected_output(shape, {0, 1, 0, 1}); -} diff --git a/ngraph/test/type_prop/logical_not.cpp b/ngraph/test/type_prop/logical_not.cpp new file mode 100644 index 00000000000..0a0a8b6d9c4 --- /dev/null +++ b/ngraph/test/type_prop/logical_not.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "gtest/gtest.h" +#include "ngraph/ngraph.hpp" +#include "util/type_prop.hpp" + +using namespace std; +using namespace ngraph; + +namespace { +void type_check(const ngraph::element::Type& type) { + auto input = make_shared(type, Shape{1, 3, 6}); + auto logical_not = make_shared(input); + + ASSERT_EQ(logical_not->get_element_type(), type); +} +} // namespace + +TEST(type_prop, logical_not_i32) { + type_check(element::i32); +} + +TEST(type_prop, logical_not_i64) { + type_check(element::i64); +} + +TEST(type_prop, logical_not_u32) { + type_check(element::u32); +} + +TEST(type_prop, logical_not_u64) { + type_check(element::u64); +} + +TEST(type_prop, logical_not_f16) { + type_check(element::f16); +} + +TEST(type_prop, logical_not_f32) { + type_check(element::f32); +} + +TEST(type_prop, logical_not_shape_inference) { + auto input = make_shared(element::boolean, Shape{1, 3, 6}); + auto logical_not = make_shared(input); + ASSERT_EQ(logical_not->get_shape(), (Shape{1, 3, 6})); +} diff --git a/ngraph/test/visitors/op/logical_not.cpp b/ngraph/test/visitors/op/logical_not.cpp new file mode 100644 index 00000000000..5ff4dc80b2d --- /dev/null +++ b/ngraph/test/visitors/op/logical_not.cpp @@ -0,0 +1,9 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "unary_ops.hpp" + +using Type = ::testing::Types>; + +INSTANTIATE_TYPED_TEST_SUITE_P(visitor_without_attribute, UnaryOperatorVisitor, Type, UnaryOperatorTypeName);