Skip to content

Commit

Permalink
Revise less equal (#6720)
Browse files Browse the repository at this point in the history
* update spec, add visitors, backend test

* remove visitors test as it is implemented in another PR

* remove visitors test from CMakeLists

* remove old backend tests, refactor minor parts of the code

* add namespace

* refaactor template test for less_equal op
  • Loading branch information
bszmelcz authored Aug 4, 2021
1 parent e220b57 commit c963136
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 87 deletions.
37 changes: 20 additions & 17 deletions docs/ops/comparison/LessEqual_1.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,50 @@

**Category**: Comparison binary operation

**Short description**: *LessEqual* performs element-wise comparison operation with two given tensors applying multi-directional broadcast rules.
**Short description**: *LessEqual* performs element-wise comparison operation with two given tensors applying broadcast rules specified in the *auto_broadcast* attribute.

**Detailed description**
Before performing arithmetic operation, input tensors *a* and *b* are broadcasted if their shapes are different and `auto_broadcast` attributes is not `none`. Broadcasting is performed according to `auto_broadcast` value.

After broadcasting *LessEqual* does the following with the input tensors *a* and *b*:

\f[
o_{i} = a_{i} <= b_{i}
\f]

**Attributes**:

* *auto_broadcast*

* **Description**: specifies rules used for auto-broadcasting of input tensors.
* **Range of values**:
* *none* - no auto-broadcasting is allowed, all input shapes should match
* *numpy* - numpy broadcasting rules, aligned with ONNX Broadcasting. Description is available in <a href="https://github.com/onnx/onnx/blob/master/docs/Broadcasting.md">ONNX docs</a>.
* *none* - no auto-broadcasting is allowed, all input shapes should match,
* *numpy* - numpy broadcasting rules, description is available in [Broadcast Rules For Elementwise Operations](../broadcast_rules.md),
* *pdpd* - PaddlePaddle-style implicit broadcasting, description is available in [Broadcast Rules For Elementwise Operations](../broadcast_rules.md).
* **Type**: string
* **Default value**: "numpy"
* **Required**: *no*

**Inputs**

* **1**: A tensor of type *T*. **Required.**
* **2**: A tensor of type *T*. **Required.**
* **1**: A tensor of type *T* and arbitrary shape. **Required.**
* **2**: A tensor of type *T* and arbitrary shape. **Required.**

**Outputs**

* **1**: The result of element-wise comparison operation. A tensor of type boolean.
* **1**: The result of element-wise comparison operation applied to the input tensors. A tensor of type **boolean** and shape equal to broadcasted shape of two inputs.

**Types**

* *T*: arbitrary supported type.

**Detailed description**
Before performing arithmetic operation, input tensors *a* and *b* are broadcasted if their shapes are different and `auto_broadcast` attributes is not `none`. Broadcasting is performed according to `auto_broadcast` value.

After broadcasting *LessEqual* does the following with the input tensors *a* and *b*:

\f[
o_{i} = a_{i} <= b_{i}
\f]

**Examples**

*Example 1*
*Example 1: no broadcast*

```xml
<layer ... type="LessEqual">
<data auto_broadcast="none"/>
<input>
<port id="0">
<dim>256</dim>
Expand All @@ -65,9 +67,10 @@ o_{i} = a_{i} <= b_{i}
</layer>
```

*Example 2: broadcast*
*Example 2: numpy broadcast*
```xml
<layer ... type="LessEqual">
<data auto_broadcast="numpy"/>
<input>
<port id="0">
<dim>8</dim>
Expand Down
82 changes: 82 additions & 0 deletions docs/template_plugin/tests/functional/op_reference/less_eq.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include <gtest/gtest.h>

#include <ie_core.hpp>
#include <ie_ngraph_utils.hpp>
#include <ngraph/ngraph.hpp>
#include <shared_test_classes/base/layer_test_utils.hpp>

#include "comparison.hpp"

using namespace ngraph;
using namespace InferenceEngine;
using ComparisonTypes = ngraph::helpers::ComparisonTypes;

namespace reference_tests {
namespace ComparisonOpsRefTestDefinitions {
namespace {
TEST_P(ReferenceComparisonLayerTest, LessEqualCompareWithHardcodedRefs) {
Exec();
}

template <element::Type_t IN_ET>
std::vector<RefComparisonParams> generateComparisonParams(const element::Type& type) {
using T = typename element_type_traits<IN_ET>::value_type;
std::vector<RefComparisonParams> compParams {
// 1D // 2D // 3D // 4D
Builder {}
.compType(ComparisonTypes::LESS_EQUAL)
.input1({{2, 2}, type, std::vector<T> {0, 12, 23, 0}})
.input2({{2, 2}, type, std::vector<T> {0, 12, 23, 0}})
.expected({{2, 2}, element::boolean, std::vector<char> {1, 1, 1, 1}}),
Builder {}
.compType(ComparisonTypes::LESS_EQUAL)
.input1({{2, 3}, type, std::vector<T> {0, 6, 45, 1, 21, 21}})
.input2({{2, 3}, type, std::vector<T> {1, 18, 23, 1, 19, 21}})
.expected({{2, 3}, element::boolean, std::vector<char> {1, 1, 0, 1, 0, 1}}),
Builder {}
.compType(ComparisonTypes::LESS_EQUAL)
.input1({{1}, type, std::vector<T> {53}})
.input2({{1}, type, std::vector<T> {53}})
.expected({{1}, element::boolean, std::vector<char> {1}}),
Builder {}
.compType(ComparisonTypes::LESS_EQUAL)
.input1({{2, 4}, type, std::vector<T> {0, 12, 23, 0, 1, 5, 11, 8}})
.input2({{2, 4}, type, std::vector<T> {0, 12, 23, 0, 10, 5, 11, 8}})
.expected({{2, 4}, element::boolean, std::vector<char> {1, 1, 1, 1, 1, 1, 1, 1}}),
Builder {}
.compType(ComparisonTypes::LESS_EQUAL)
.input1({{3, 1, 2}, type, std::vector<T> {2, 1, 4, 1, 3, 1}})
.input2({{1, 2, 1}, type, std::vector<T> {1, 1}})
.expected({{3, 2, 2}, element::boolean, std::vector<char> {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}}),
Builder {}
.compType(ComparisonTypes::LESS_EQUAL)
.input1({{2, 1, 2, 1}, type, std::vector<T> {2, 1, 4, 1}})
.input2({{1, 2, 1}, type, std::vector<T> {1, 1}})
.expected({{2, 1, 2, 1}, element::boolean, std::vector<char> {0, 1, 0, 1}})};
return compParams;
}

std::vector<RefComparisonParams> generateComparisonCombinedParams() {
const std::vector<std::vector<RefComparisonParams>> compTypeParams {
generateComparisonParams<element::Type_t::f32>(element::f32),
generateComparisonParams<element::Type_t::f16>(element::f16),
generateComparisonParams<element::Type_t::i32>(element::i32),
generateComparisonParams<element::Type_t::u32>(element::u32),
generateComparisonParams<element::Type_t::u8>(element::boolean)};
std::vector<RefComparisonParams> combinedParams;

for (const auto& params : compTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}

} // namespace
INSTANTIATE_TEST_SUITE_P(smoke_Comparison_With_Hardcoded_Refs, ReferenceComparisonLayerTest, ::testing::ValuesIn(generateComparisonCombinedParams()),
ReferenceComparisonLayerTest::getTestCaseName);
} // namespace ComparisonOpsRefTestDefinitions
} // namespace reference_tests
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
'HardSigmoid-1',
'Interpolate-4',
'Less-1',
'LessEqual-1'
'LRN-1',
'LSTMCell-4',
'LSTMSequence-5',
Expand Down
67 changes: 0 additions & 67 deletions ngraph/test/backend/comparison.in.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,70 +109,3 @@ NGRAPH_TEST(${BACKEND_NAME}, greatereq)
handle->call_with_validate({result}, {a, b});
EXPECT_EQ((vector<char>{1, 1, 1, 1, 0, 1, 1, 0}), read_vector<char>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, lesseq)
{
Shape shape{2, 2, 2};
auto A = make_shared<op::Parameter>(element::f32, shape);
auto B = make_shared<op::Parameter>(element::f32, shape);
auto f = make_shared<Function>(make_shared<op::v1::LessEqual>(A, B), ParameterVector{A, B});

auto backend = runtime::Backend::create("${BACKEND_NAME}");

// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, shape);
copy_data(a, vector<float>{1, 8, -8, 17, -0.5, 0, 2, 1});
auto b = backend->create_tensor(element::f32, shape);
copy_data(b, vector<float>{1, 2, -8, 8, 0, 0, 0.5, 1.5});
auto result = backend->create_tensor(element::boolean, shape);

auto handle = backend->compile(f);
handle->call_with_validate({result}, {a, b});
EXPECT_EQ((vector<char>{1, 0, 1, 0, 1, 1, 0, 1}), read_vector<char>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, lesseq_int32)
{
Shape shape{2, 2};
auto A = make_shared<op::Parameter>(element::i32, shape);
auto B = make_shared<op::Parameter>(element::i32, shape);
auto f = make_shared<Function>(make_shared<op::v1::LessEqual>(A, B), ParameterVector{A, B});

auto backend = runtime::Backend::create("${BACKEND_NAME}");

// Create some tensors for input/output
auto a = backend->create_tensor(element::i32, shape);
copy_data(a, vector<int32_t>{0x40000170, 0x40000005, 0x40000005, -5});
auto b = backend->create_tensor(element::i32, shape);
copy_data(b, vector<int32_t>{0x40000140, 0x40000001, 0x40000005, 0});
auto result = backend->create_tensor(element::boolean, shape);

auto handle = backend->compile(f);
handle->call_with_validate({result}, {a, b});
EXPECT_EQ((vector<char>{0, 0, 1, 1}), read_vector<char>(result)); // NNP result {1, 1, 0, 1}
}

NGRAPH_TEST(${BACKEND_NAME}, lesseq_bool)
{
Shape shape{2, 2, 2};
auto A = make_shared<op::Parameter>(element::boolean, shape);
auto B = make_shared<op::Parameter>(element::boolean, shape);
auto f = make_shared<Function>(make_shared<op::v1::LessEqual>(A, B), ParameterVector{A, B});

auto backend = runtime::Backend::create("${BACKEND_NAME}");

// Create some tensors for input/output
auto a = backend->create_tensor(element::boolean, shape);
copy_data(a, vector<char>{1, 1, 1, 1, 1, 1, 1, 1});
auto b = backend->create_tensor(element::boolean, shape);
copy_data(b, vector<char>{0, 0, 0, 0, 0, 0, 0, 0});
auto result = backend->create_tensor(element::boolean, shape);

// Overwrite the initial result vector to make sure we're not just coincidentally getting the
// right value.
copy_data(result, vector<char>{1, 1, 1, 1, 1, 1, 1, 1});

auto handle = backend->compile(f);
handle->call_with_validate({result}, {a, b});
EXPECT_EQ((vector<char>{0, 0, 0, 0, 0, 0, 0, 0}), read_vector<char>(result));
}
3 changes: 0 additions & 3 deletions ngraph/test/runtime/ie/unit_test.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,6 @@ notequal
greater
greatereq
less
lesseq
sum_3d_to_scalar_int32
sum_2d_to_scalar_int8
max_pool_uint8
Expand Down Expand Up @@ -489,7 +488,6 @@ logical_xor
logical_or
logical_and
gather_axis_0_bool
lesseq_bool
auto_bcast_binary_elementwise
auto_bcast_binary_elementwise_pdpd
any_2x2_to_scalar_true
Expand Down Expand Up @@ -758,7 +756,6 @@ strided_slice_stride_optional
divide_int32
divide_cpp_rounding_int32
divide_python_rounding_int32
lesseq_int32

# Constant and Low Precision
constant_equality_u4_2x2x3
Expand Down

0 comments on commit c963136

Please sign in to comment.