/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ #include // Declares the operator #include #include #include #include #include #include #include using namespace ::testing; using exec_aten::ScalarType; using exec_aten::Tensor; using torch::executor::native::allclose_out; using torch::executor::testing::IsCloseTo; using torch::executor::testing::TensorFactory; const double default_atol{1e-08}; const double default_rtol{1e-05}; TEST(OpAllCloseTest, IdenticalFloatTensors) { TensorFactory tf_float; Tensor a = tf_float.ones(/*sizes=*/{2, 2}); Tensor b = tf_float.ones(/*sizes=*/{2, 2}); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], true); } TEST(OpAllCloseTest, IdenticalDoubleTensors) { TensorFactory tf_double; Tensor a = tf_double.ones(/*sizes=*/{2, 2}); Tensor b = tf_double.ones(/*sizes=*/{2, 2}); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], true); } TEST(OpAllCloseTest, NonEqualFloatTensors) { TensorFactory tf_float; Tensor a = tf_float.make(/*sizes=*/{2, 2}, /*data=*/{1., 2., 3., 4.}); Tensor b = tf_float.make(/*sizes=*/{2, 2}, /*data=*/{5., 6., 7., 8.}); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); } TEST(OpAllCloseTest, NonEqualDoubleTensors) { TensorFactory tf_double; Tensor a = tf_double.make(/*sizes=*/{2, 2}, /*data=*/{1., 2., 3., 4.}); Tensor b = tf_double.make(/*sizes=*/{2, 2}, /*data=*/{5., 6., 7., 8.}); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); } TEST(OpAllCloseTest, IdenticalIntTensors) { TensorFactory tf_int; Tensor a = tf_int.ones(/*sizes=*/{2, 2}); Tensor b = tf_int.ones(/*sizes=*/{2, 2}); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], true); } TEST(OpAllCloseTest, NonEqualIntTensors) { TensorFactory tf_int; Tensor a = tf_int.make(/*sizes=*/{2, 2}, /*data=*/{1, 2, 3, 4}); Tensor b = tf_int.make(/*sizes=*/{2, 2}, /*data=*/{5, 6, 7, 8}); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); } TEST(OpAllCloseTest, IdenticalBoolTensors) { TensorFactory tf_bool; Tensor a = tf_bool.ones(/*sizes=*/{2, 2}); Tensor b = tf_bool.ones(/*sizes=*/{2, 2}); Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], true); } TEST(OpAllCloseTest, NonEqualBoolTensors) { TensorFactory tf_bool; Tensor a = tf_bool.ones(/*sizes=*/{2, 2}); Tensor b = tf_bool.ones(/*sizes=*/{2, 2}); auto b_data = b.data_ptr(); b_data[0] = false; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); } TEST(OpAllCloseTest, MismatchedInputShapesDeath) { TensorFactory tf_int; Tensor a = tf_int.ones(/*sizes=*/{2, 1}); Tensor b = tf_int.ones(/*sizes=*/{2, 2}); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); ET_EXPECT_DEATH( allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out), ""); } TEST(OpAllCloseTest, MismatchedInputDtypesDeath) { TensorFactory tf_float; Tensor a = tf_float.ones(/*sizes=*/{2, 2}); TensorFactory tf_int; Tensor b = tf_int.ones(/*sizes=*/{2, 2}); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); ET_EXPECT_DEATH( allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out), ""); } TEST(OpAllCloseTest, IncorrectOutputDtypeDeath) { TensorFactory tf_float; Tensor a = tf_float.ones(/*sizes=*/{2, 2}); Tensor b = tf_float.ones(/*sizes=*/{2, 2}); Tensor out = tf_float.zeros(/*sizes=*/{1}); ET_EXPECT_DEATH( allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out), ""); } TEST(OpAllCloseTest, IncorrectOutputShapeDeath) { TensorFactory tf_float; Tensor a = tf_float.ones(/*sizes=*/{2, 2}); Tensor b = tf_float.ones(/*sizes=*/{2, 2}); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{2, 2}); ET_EXPECT_DEATH( allclose_out( a, b, default_rtol, default_atol, /*equal_nan=*/false, /*dummy_param=*/false, out), ""); } TEST(OpAllCloseTest, FloatTensorsVaryWithinRelativeTolerance) { const double rtol = 1e-05; const double rdiff = 1e-06; TensorFactory tf_float; Tensor a = tf_float.ones(/*sizes=*/{2, 2}); Tensor b = tf_float.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] * (1. + rdiff); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, rtol, /*atol=*/0., /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], true); } TEST(OpAllCloseTest, DoubleTensorsVaryWithinRelativeTolerance) { const double rtol = 1e-05; const double rdiff = 1e-06; TensorFactory tf_double; Tensor a = tf_double.ones(/*sizes=*/{2, 2}); Tensor b = tf_double.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] * (1. + rdiff); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, rtol, /*atol=*/0., /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], true); } TEST(OpAllCloseTest, FloatTensorsVaryOutsideRelativeTolerance) { const double rtol = 1e-05; const double rdiff = 1e-04; TensorFactory tf_float; Tensor a = tf_float.ones(/*sizes=*/{2, 2}); Tensor b = tf_float.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] * (1. + rdiff); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, rtol, /*atol=*/0., /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); } TEST(OpAllCloseTest, DoubleTensorsVaryOutsideRelativeTolerance) { const double rtol = 1e-05; const double rdiff = 1e-04; TensorFactory tf_double; Tensor a = tf_double.ones(/*sizes=*/{2, 2}); Tensor b = tf_double.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] * (1. + rdiff); TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, rtol, /*atol=*/0., /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); } TEST(OpAllCloseTest, FloatTensorsVaryWithinAbsoluteTolerance) { const double atol = 1e-08; const double adiff = 1e-09; TensorFactory tf_float; Tensor a = tf_float.ones(/*sizes=*/{2, 2}); Tensor b = tf_float.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] + adiff; TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, /*rtol=*/0., atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], true); } TEST(OpAllCloseTest, DoubleTensorsVaryWithinAbsoluteTolerance) { const double atol = 1e-08; const double adiff = 1e-09; TensorFactory tf_double; Tensor a = tf_double.ones(/*sizes=*/{2, 2}); Tensor b = tf_double.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] + adiff; TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, /*rtol=*/0., atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], true); } TEST(OpAllCloseTest, FloatTensorsVaryOutsideAbsoluteTolerance) { const double atol = 1e-08; const double adiff = 1e-07; TensorFactory tf_float; Tensor a = tf_float.ones(/*sizes=*/{2, 2}); Tensor b = tf_float.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] + adiff; TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, /*rtol=*/0., atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); } TEST(OpAllCloseTest, DoubleTensorsVaryOutsideAbsoluteTolerance) { const double atol = 1e-08; const double adiff = 1e-07; TensorFactory tf_double; Tensor a = tf_double.ones(/*sizes=*/{2, 2}); Tensor b = tf_double.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] + adiff; TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, /*rtol=*/0., atol, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); } TEST(OpAllCloseTest, FloatTensorsVaryWithZeroTolerance) { TensorFactory tf_float; Tensor a = tf_float.ones(/*sizes=*/{2, 2}); Tensor b = tf_float.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] + 1e-07; TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, /*rtol=*/0., /*atol=*/0, /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); } TEST(OpAllCloseTest, DoubleTensorsVaryWithZeroTolerance) { TensorFactory tf_double; Tensor a = tf_double.ones(/*sizes=*/{2, 2}); Tensor b = tf_double.ones(/*sizes=*/{2, 2}); auto a_data = a.data_ptr(); auto b_data = b.data_ptr(); b_data[0] = a_data[0] + 1e-09; TensorFactory tf_bool; Tensor out = tf_bool.zeros(/*sizes=*/{1}); allclose_out( a, b, /*rtol=*/0., /*atol=*/0., /*equal_nan=*/false, /*dummy_param=*/false, out); auto out_data = out.data_ptr(); EXPECT_EQ(out_data[0], false); }