Skip to content

Commit b63c68e

Browse files
swolchokfacebook-github-bot
authored andcommitted
migrate all unary_ufunc_realhb_to_floath op tests to general infra (2/2) (pytorch#5675)
Summary: Pull Request resolved: pytorch#5675 Follow up on previous diff by migrating all the tests. Most migrations were straightforward where ops just had the same test repeated; some of them had worse tests, some of them had different-but-equivalent tests that incorrectly skipped dynamic shape. No actual bugs found, which makes sense since the implementations are shared. ghstack-source-id: 245577588 Reviewed By: manuelcandales Differential Revision: D63431291 fbshipit-source-id: e95b56947c104ed839e936d0be08ad1c4b5df378
1 parent 829ba3e commit b63c68e

24 files changed

+280
-2317
lines changed

kernels/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ set(_optimized_kernels_test_sources
241241
"op_native_layer_norm_test.cpp"
242242
"op_neg_test.cpp"
243243
"op_sub_test.cpp"
244+
"UnaryUfuncRealHBToFloatHTest.cpp"
244245
${CMAKE_CURRENT_BINARY_DIR}/include/portable/executorch/kernels/test/supported_features.cpp
245246
)
246247

kernels/test/UnaryUfuncRealHBToFloatHTest.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,26 @@ class UnaryUfuncRealHBToFloatHTest : public OperatorTest {
5050

5151
exec_aten::Tensor out = tf_out.zeros(out_shape, dynamism);
5252

53-
std::vector<typename decltype(tf_in)::ctype> test_vector = {
54-
0, 1, 3, 5, 10, 100};
55-
std::vector<typename decltype(tf_out)::ctype> expected_vector;
56-
std::transform(
57-
test_vector.begin(),
58-
test_vector.end(),
59-
std::back_inserter(expected_vector),
60-
[this](auto x) { return this->op_reference(x); });
53+
using IN_CTYPE = typename decltype(tf_in)::ctype;
54+
using OUT_CTYPE = typename decltype(tf_out)::ctype;
55+
std::vector<IN_CTYPE> test_vector = {0, 1, 3, 5, 10, 100};
56+
std::vector<OUT_CTYPE> expected_vector;
57+
for (int ii = 0; ii < test_vector.size(); ++ii) {
58+
auto ref_result = this->op_reference(test_vector[ii]);
59+
// Drop test cases with high magnitude results due to precision
60+
// issues.
61+
if ((std::abs(ref_result) > 1e30 || std::abs(ref_result) < -1e30)) {
62+
test_vector[ii] = 2;
63+
ref_result = this->op_reference(2);
64+
}
65+
expected_vector.push_back(ref_result);
66+
}
6167

6268
// clang-format off
6369
op_out(tf_in.make({1, 6}, test_vector), out);
6470

65-
EXPECT_TENSOR_CLOSE(
66-
out,
67-
tf_out.make({1, 6}, expected_vector));
71+
auto expected = tf_out.make({1, 6}, expected_vector);
72+
EXPECT_TENSOR_CLOSE(out, expected);
6873
// clang-format on
6974
}
7075

kernels/test/op_acos_test.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@
1414
#include <cmath>
1515

1616
using exec_aten::Tensor;
17-
using torch::executor::testing::UnaryUfuncRealHBToFloatHTest;
18-
19-
class OpAcosOutTest : public UnaryUfuncRealHBToFloatHTest {
17+
class OpAcosOutTest
18+
: public torch::executor::testing::UnaryUfuncRealHBToFloatHTest {
2019
protected:
2120
Tensor& op_out(const Tensor& self, Tensor& out) override {
2221
return torch::executor::aten::acos_outf(context_, self, out);

kernels/test/op_acosh_test.cpp

Lines changed: 11 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -7,144 +7,27 @@
77
*/
88

99
#include <executorch/kernels/test/FunctionHeaderWrapper.h> // Declares the operator
10-
#include <executorch/kernels/test/TestUtil.h>
11-
#include <executorch/kernels/test/supported_features.h>
12-
#include <executorch/runtime/core/exec_aten/exec_aten.h>
13-
#include <executorch/runtime/core/exec_aten/testing_util/tensor_factory.h>
14-
#include <executorch/runtime/core/exec_aten/testing_util/tensor_util.h>
10+
#include <executorch/kernels/test/UnaryUfuncRealHBToFloatHTest.h>
1511

1612
#include <gtest/gtest.h>
1713

18-
using namespace ::testing;
19-
using exec_aten::ScalarType;
14+
#include <cmath>
15+
2016
using exec_aten::Tensor;
21-
using exec_aten::TensorShapeDynamism;
22-
using torch::executor::testing::TensorFactory;
2317

24-
class OpAcoshOutTest : public OperatorTest {
18+
class OpAcoshOutTest
19+
: public torch::executor::testing::UnaryUfuncRealHBToFloatHTest {
2520
protected:
26-
Tensor& op_acosh_out(const Tensor& self, Tensor& out) {
21+
Tensor& op_out(const Tensor& self, Tensor& out) override {
2722
return torch::executor::aten::acosh_outf(context_, self, out);
2823
}
2924

30-
// Common testing for acosh operator and all kinds of supported input types
31-
template <ScalarType IN_DTYPE, ScalarType OUT_DTYPE>
32-
void test_floating_point_acosh_out(
33-
const std::vector<int32_t>& out_shape = {1, 6},
34-
TensorShapeDynamism dynamism = TensorShapeDynamism::STATIC) {
35-
TensorFactory<IN_DTYPE> tf_in;
36-
TensorFactory<OUT_DTYPE> tf_out;
37-
38-
// Destination for the acosh operator.
39-
Tensor out = tf_out.zeros(out_shape, dynamism);
40-
41-
// clang-format off
42-
op_acosh_out(tf_in.make({1, 6}, { 0, 1, 3, 5, 10, 100 }), out);
43-
44-
// Check that it matches (or close to) the expected output.
45-
EXPECT_TENSOR_CLOSE(
46-
out,
47-
tf_out.make({1, 6}, { NAN, 0.000000, 1.762747, 2.292432, 2.993223, 5.298292 }));
48-
// clang-format on
25+
double op_reference(double x) const override {
26+
return std::acosh(x);
4927
}
5028

51-
// Unhandled output dtypes.
52-
template <ScalarType INPUT_DTYPE, ScalarType OUTPUT_DTYPE>
53-
void test_acosh_invalid_output_dtype_dies() {
54-
TensorFactory<INPUT_DTYPE> tf;
55-
TensorFactory<OUTPUT_DTYPE> tf_out;
56-
57-
const std::vector<int32_t> sizes = {2, 5};
58-
59-
Tensor in = tf.ones(sizes);
60-
Tensor out = tf_out.zeros(sizes);
61-
62-
ET_EXPECT_KERNEL_FAILURE(context_, op_acosh_out(in, out));
63-
}
29+
torch::executor::testing::SupportedFeatures* get_supported_features()
30+
const override;
6431
};
6532

66-
TEST_F(OpAcoshOutTest, HandleBoolInput) {
67-
TensorFactory<ScalarType::Bool> tf_bool;
68-
TensorFactory<ScalarType::Float> tf_float;
69-
70-
const std::vector<int32_t> sizes = {1, 2};
71-
72-
Tensor a = tf_bool.make(sizes, /*data=*/{false, true});
73-
Tensor out = tf_float.zeros(sizes);
74-
Tensor res = tf_float.make(sizes, /*data=*/{NAN, 0.000000});
75-
76-
EXPECT_TENSOR_CLOSE(op_acosh_out(a, out), res);
77-
}
78-
79-
TEST_F(OpAcoshOutTest, AllRealInputFloatOutputStaticDynamismSupport) {
80-
#define TEST_ENTRY(ctype, dtype) \
81-
test_floating_point_acosh_out<ScalarType::dtype, ScalarType::Float>();
82-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
83-
#undef TEST_ENTRY
84-
}
85-
86-
TEST_F(OpAcoshOutTest, AllRealInputDoubleOutputStaticDynamismSupport) {
87-
#define TEST_ENTRY(ctype, dtype) \
88-
test_floating_point_acosh_out<ScalarType::dtype, ScalarType::Double>();
89-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
90-
#undef TEST_ENTRY
91-
}
92-
93-
TEST_F(OpAcoshOutTest, AllRealInputFloatOutputBoundDynamismSupport) {
94-
#define TEST_ENTRY(ctype, dtype) \
95-
test_floating_point_acosh_out<ScalarType::dtype, ScalarType::Float>( \
96-
{10, 10}, TensorShapeDynamism::DYNAMIC_BOUND);
97-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
98-
#undef TEST_ENTRY
99-
}
100-
101-
TEST_F(OpAcoshOutTest, AllRealInputDoubleOutputBoundDynamismSupport) {
102-
#define TEST_ENTRY(ctype, dtype) \
103-
test_floating_point_acosh_out<ScalarType::dtype, ScalarType::Double>( \
104-
{10, 10}, TensorShapeDynamism::DYNAMIC_BOUND);
105-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
106-
#undef TEST_ENTRY
107-
}
108-
109-
TEST_F(OpAcoshOutTest, AllRealInputFloatOutputUnboundDynamismSupport) {
110-
if (!torch::executor::testing::SupportedFeatures::get()->is_aten) {
111-
GTEST_SKIP() << "Dynamic shape unbound not supported";
112-
}
113-
#define TEST_ENTRY(ctype, dtype) \
114-
test_floating_point_acosh_out<ScalarType::dtype, ScalarType::Float>( \
115-
{1, 1}, TensorShapeDynamism::DYNAMIC_UNBOUND);
116-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
117-
#undef TEST_ENTRY
118-
}
119-
120-
TEST_F(OpAcoshOutTest, AllRealInputDoubleOutputUnboundDynamismSupport) {
121-
if (!torch::executor::testing::SupportedFeatures::get()->is_aten) {
122-
GTEST_SKIP() << "Dynamic shape unbound not supported";
123-
}
124-
#define TEST_ENTRY(ctype, dtype) \
125-
test_floating_point_acosh_out<ScalarType::dtype, ScalarType::Double>( \
126-
{1, 1}, TensorShapeDynamism::DYNAMIC_UNBOUND);
127-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
128-
#undef TEST_ENTRY
129-
}
130-
131-
TEST_F(OpAcoshOutTest, AllNonFloatOutputDTypeDies) {
132-
#define TEST_ENTRY(ctype, dtype) \
133-
test_acosh_invalid_output_dtype_dies<ScalarType::Float, ScalarType::dtype>();
134-
ET_FORALL_INT_TYPES(TEST_ENTRY);
135-
#undef TEST_ENTRY
136-
}
137-
138-
// Mismatched shape tests.
139-
TEST_F(OpAcoshOutTest, MismatchedInputShapesDies) {
140-
if (torch::executor::testing::SupportedFeatures::get()->is_aten) {
141-
GTEST_SKIP() << "ATen kernel can handle mismatched input shapes";
142-
}
143-
144-
TensorFactory<ScalarType::Float> tf;
145-
146-
Tensor a = tf.ones(/*sizes=*/{4});
147-
Tensor out = tf.ones(/*sizes=*/{2, 2});
148-
149-
ET_EXPECT_KERNEL_FAILURE(context_, op_acosh_out(a, out));
150-
}
33+
IMPLEMENT_UNARY_UFUNC_REALHB_TO_FLOATH_TEST(OpAcoshOutTest)

kernels/test/op_asin_test.cpp

Lines changed: 11 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -7,164 +7,26 @@
77
*/
88

99
#include <executorch/kernels/test/FunctionHeaderWrapper.h> // Declares the operator
10-
#include <executorch/kernels/test/TestUtil.h>
11-
#include <executorch/kernels/test/supported_features.h>
12-
#include <executorch/runtime/core/exec_aten/exec_aten.h>
13-
#include <executorch/runtime/core/exec_aten/testing_util/tensor_factory.h>
14-
#include <executorch/runtime/core/exec_aten/testing_util/tensor_util.h>
10+
#include <executorch/kernels/test/UnaryUfuncRealHBToFloatHTest.h>
1511

1612
#include <gtest/gtest.h>
1713

18-
using namespace ::testing;
19-
using exec_aten::ScalarType;
20-
using exec_aten::Tensor;
21-
using exec_aten::TensorShapeDynamism;
22-
using torch::executor::testing::TensorFactory;
14+
#include <cmath>
2315

24-
class OpAsinOutTest : public OperatorTest {
16+
using exec_aten::Tensor;
17+
class OpAsinOutTest
18+
: public torch::executor::testing::UnaryUfuncRealHBToFloatHTest {
2519
protected:
26-
Tensor& op_asin_out(const Tensor& self, Tensor& out) {
20+
Tensor& op_out(const Tensor& self, Tensor& out) override {
2721
return torch::executor::aten::asin_outf(context_, self, out);
2822
}
2923

30-
// Common testing for asin operator and all kinds of supported input types
31-
template <ScalarType IN_DTYPE, ScalarType OUT_DTYPE>
32-
void test_floating_point_asin_out(
33-
const std::vector<int32_t>& out_shape = {1, 6},
34-
TensorShapeDynamism dynamism = TensorShapeDynamism::STATIC) {
35-
TensorFactory<IN_DTYPE> tf_in;
36-
TensorFactory<OUT_DTYPE> tf_out;
37-
38-
// Destination for the asin operator.
39-
Tensor out = tf_out.zeros(out_shape, dynamism);
40-
41-
// clang-format off
42-
op_asin_out(tf_in.make({1, 6}, { 0, 1, 3, 5, 10, 100 }), out);
43-
44-
// Check that it matches (or close to) the expected output.
45-
EXPECT_TENSOR_CLOSE(
46-
out,
47-
tf_out.make({1, 6}, { 0.000000, 1.570796, NAN, NAN, NAN, NAN }));
48-
// clang-format on
24+
double op_reference(double x) const override {
25+
return std::asin(x);
4926
}
5027

51-
// Unhandled output dtypes.
52-
template <ScalarType INPUT_DTYPE, ScalarType OUTPUT_DTYPE>
53-
void test_asin_invalid_output_dtype_dies() {
54-
TensorFactory<INPUT_DTYPE> tf;
55-
TensorFactory<OUTPUT_DTYPE> tf_out;
56-
57-
const std::vector<int32_t> sizes = {2, 5};
58-
59-
Tensor in = tf.ones(sizes);
60-
Tensor out = tf_out.zeros(sizes);
61-
62-
ET_EXPECT_KERNEL_FAILURE(context_, op_asin_out(in, out));
63-
}
28+
torch::executor::testing::SupportedFeatures* get_supported_features()
29+
const override;
6430
};
6531

66-
TEST_F(OpAsinOutTest, HandleBoolInput) {
67-
TensorFactory<ScalarType::Bool> tf_bool;
68-
TensorFactory<ScalarType::Float> tf_float;
69-
70-
const std::vector<int32_t> sizes = {1, 2};
71-
72-
Tensor a = tf_bool.make(sizes, /*data=*/{false, true});
73-
Tensor out = tf_float.zeros(sizes);
74-
Tensor res = tf_float.make(sizes, /*data=*/{0.000000, 1.5707960});
75-
76-
EXPECT_TENSOR_CLOSE(op_asin_out(a, out), res);
77-
}
78-
79-
TEST_F(OpAsinOutTest, AllRealInputHalfOutputStaticDynamismSupport) {
80-
if (torch::executor::testing::SupportedFeatures::get()->is_aten) {
81-
GTEST_SKIP() << "Test Half support only for ExecuTorch mode";
82-
}
83-
#define TEST_ENTRY(ctype, dtype) \
84-
test_floating_point_asin_out<ScalarType::dtype, ScalarType::Float>();
85-
ET_FORALL_REALH_TYPES(TEST_ENTRY);
86-
#undef TEST_ENTRY
87-
}
88-
89-
TEST_F(OpAsinOutTest, AllRealInputFloatOutputStaticDynamismSupport) {
90-
#define TEST_ENTRY(ctype, dtype) \
91-
test_floating_point_asin_out<ScalarType::dtype, ScalarType::Float>();
92-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
93-
#undef TEST_ENTRY
94-
}
95-
96-
TEST_F(OpAsinOutTest, AllRealInputDoubleOutputStaticDynamismSupport) {
97-
#define TEST_ENTRY(ctype, dtype) \
98-
test_floating_point_asin_out<ScalarType::dtype, ScalarType::Double>();
99-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
100-
#undef TEST_ENTRY
101-
}
102-
103-
TEST_F(OpAsinOutTest, AllRealInputHalfOutputBoundDynamismSupport) {
104-
if (torch::executor::testing::SupportedFeatures::get()->is_aten) {
105-
GTEST_SKIP() << "Test Half support only for ExecuTorch mode";
106-
}
107-
#define TEST_ENTRY(ctype, dtype) \
108-
test_floating_point_asin_out<ScalarType::dtype, ScalarType::Float>( \
109-
{10, 10}, TensorShapeDynamism::DYNAMIC_BOUND);
110-
ET_FORALL_REALH_TYPES(TEST_ENTRY);
111-
#undef TEST_ENTRY
112-
}
113-
114-
TEST_F(OpAsinOutTest, AllRealInputFloatOutputBoundDynamismSupport) {
115-
#define TEST_ENTRY(ctype, dtype) \
116-
test_floating_point_asin_out<ScalarType::dtype, ScalarType::Float>( \
117-
{10, 10}, TensorShapeDynamism::DYNAMIC_BOUND);
118-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
119-
#undef TEST_ENTRY
120-
}
121-
122-
TEST_F(OpAsinOutTest, AllRealInputDoubleOutputBoundDynamismSupport) {
123-
#define TEST_ENTRY(ctype, dtype) \
124-
test_floating_point_asin_out<ScalarType::dtype, ScalarType::Double>( \
125-
{10, 10}, TensorShapeDynamism::DYNAMIC_BOUND);
126-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
127-
#undef TEST_ENTRY
128-
}
129-
130-
TEST_F(OpAsinOutTest, AllRealInputFloatOutputUnboundDynamismSupport) {
131-
if (!torch::executor::testing::SupportedFeatures::get()->is_aten) {
132-
GTEST_SKIP() << "Dynamic shape unbound not supported";
133-
}
134-
#define TEST_ENTRY(ctype, dtype) \
135-
test_floating_point_asin_out<ScalarType::dtype, ScalarType::Float>( \
136-
{1, 1}, TensorShapeDynamism::DYNAMIC_UNBOUND);
137-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
138-
#undef TEST_ENTRY
139-
}
140-
141-
TEST_F(OpAsinOutTest, AllRealInputDoubleOutputUnboundDynamismSupport) {
142-
if (!torch::executor::testing::SupportedFeatures::get()->is_aten) {
143-
GTEST_SKIP() << "Dynamic shape unbound not supported";
144-
}
145-
#define TEST_ENTRY(ctype, dtype) \
146-
test_floating_point_asin_out<ScalarType::dtype, ScalarType::Double>( \
147-
{1, 1}, TensorShapeDynamism::DYNAMIC_UNBOUND);
148-
ET_FORALL_REAL_TYPES(TEST_ENTRY);
149-
#undef TEST_ENTRY
150-
}
151-
152-
TEST_F(OpAsinOutTest, AllNonFloatOutputDTypeDies) {
153-
#define TEST_ENTRY(ctype, dtype) \
154-
test_asin_invalid_output_dtype_dies<ScalarType::Float, ScalarType::dtype>();
155-
ET_FORALL_INT_TYPES(TEST_ENTRY);
156-
#undef TEST_ENTRY
157-
}
158-
159-
// Mismatched shape tests.
160-
TEST_F(OpAsinOutTest, MismatchedInputShapesDies) {
161-
if (torch::executor::testing::SupportedFeatures::get()->is_aten) {
162-
GTEST_SKIP() << "ATen kernel can handle mismatched input shapes";
163-
}
164-
TensorFactory<ScalarType::Float> tf;
165-
166-
Tensor a = tf.ones(/*sizes=*/{4});
167-
Tensor out = tf.ones(/*sizes=*/{2, 2});
168-
169-
ET_EXPECT_KERNEL_FAILURE(context_, op_asin_out(a, out));
170-
}
32+
IMPLEMENT_UNARY_UFUNC_REALHB_TO_FLOATH_TEST(OpAsinOutTest)

0 commit comments

Comments
 (0)