Also use GpuOpsTestConfig for gpu_binary_ops_test.

We already use this for gpu_unary_ops_test. Also support adding Tout parameter
to the NodeDef.

PiperOrigin-RevId: 350113288
Change-Id: Id6821336be08f93cfa3c1ea6898f4d71136f6573
This commit is contained in:
Adrian Kuegel 2021-01-05 04:09:33 -08:00 committed by TensorFlower Gardener
parent 031c7398b1
commit 467e16b8a5
2 changed files with 42 additions and 35 deletions

View File

@ -48,14 +48,17 @@ class GpuBinaryOpTest : public OpsTestBase {
void SetOpKernel(const std::string& op_name, const TensorShape& lhs_shape, void SetOpKernel(const std::string& op_name, const TensorShape& lhs_shape,
const absl::InlinedVector<T, 10>& lhs_input, const absl::InlinedVector<T, 10>& lhs_input,
const TensorShape& rhs_shape, const TensorShape& rhs_shape,
const absl::InlinedVector<T, 10>& rhs_input, const absl::InlinedVector<T, 10>& rhs_input, bool add_t,
bool use_constraint) { bool add_tout) {
auto builder = NodeDefBuilder("some_name", op_name) auto builder = NodeDefBuilder("some_name", op_name)
.Input(FakeInput(DataTypeToEnum<T>::v())) .Input(FakeInput(DataTypeToEnum<T>::v()))
.Input(FakeInput(DataTypeToEnum<T>::v())); .Input(FakeInput(DataTypeToEnum<T>::v()));
if (use_constraint) { if (add_t) {
builder.Attr("T", DataTypeToEnum<T>::v()); builder.Attr("T", DataTypeToEnum<T>::v());
} }
if (add_tout) {
builder.Attr("Tout", DataTypeToEnum<OutT>::v());
}
TF_ASSERT_OK(builder.Finalize(node_def())); TF_ASSERT_OK(builder.Finalize(node_def()));
TF_ASSERT_OK(InitOp()); TF_ASSERT_OK(InitOp());
@ -73,16 +76,20 @@ class GpuBinaryOpTest : public OpsTestBase {
const absl::InlinedVector<T, 10>& rhs_input, const absl::InlinedVector<T, 10>& rhs_input,
const TensorShape& expected_shape, const TensorShape& expected_shape,
const absl::InlinedVector<OutT, 10>& expected_output, const absl::InlinedVector<OutT, 10>& expected_output,
bool use_constraint = true) { const test::GpuOpsTestConfig& config) {
SetOpKernel<T, OutT>(op_name, lhs_shape, lhs_input, rhs_shape, rhs_input, SetOpKernel<T, OutT>(op_name, lhs_shape, lhs_input, rhs_shape, rhs_input,
use_constraint); config.add_t, config.add_tout);
TF_ASSERT_OK(RunOpKernel()); TF_ASSERT_OK(RunOpKernel());
// Compare output to expectation. // Compare output to expectation.
Tensor expected_tensor(allocator(), DataTypeToEnum<OutT>::value, Tensor expected_tensor(allocator(), DataTypeToEnum<OutT>::value,
expected_shape); expected_shape);
test::FillValues<OutT>(&expected_tensor, expected_output); test::FillValues<OutT>(&expected_tensor, expected_output);
test::ExpectEqual(expected_tensor, *GetOutput(0)); if (config.expect_strictly_equal) {
test::ExpectEqual(expected_tensor, *GetOutput(0));
} else {
test::ExpectClose(expected_tensor, *GetOutput(0));
}
} }
template <typename T, typename OutT> template <typename T, typename OutT>
@ -91,9 +98,9 @@ class GpuBinaryOpTest : public OpsTestBase {
const absl::InlinedVector<T, 10>& lhs_input, const absl::InlinedVector<T, 10>& lhs_input,
const TensorShape& rhs_shape, const TensorShape& rhs_shape,
const absl::InlinedVector<T, 10>& rhs_input, const absl::InlinedVector<T, 10>& rhs_input,
bool use_constraint = true) { const test::GpuOpsTestConfig& config) {
SetOpKernel<T, OutT>(op_name, lhs_shape, lhs_input, rhs_shape, rhs_input, SetOpKernel<T, OutT>(op_name, lhs_shape, lhs_input, rhs_shape, rhs_input,
use_constraint); config.add_t, config.add_tout);
auto status = RunOpKernel(); auto status = RunOpKernel();
EXPECT_FALSE(status.ok()); EXPECT_FALSE(status.ok());
EXPECT_EQ(status.code(), error::INVALID_ARGUMENT); EXPECT_EQ(status.code(), error::INVALID_ARGUMENT);
@ -105,7 +112,7 @@ class GpuBinaryOpTest : public OpsTestBase {
void TestIncompatibleShapes(const std::string& op_name, void TestIncompatibleShapes(const std::string& op_name,
const absl::InlinedVector<T, 10>& lhs_input, const absl::InlinedVector<T, 10>& lhs_input,
const absl::InlinedVector<T, 10>& rhs_input, const absl::InlinedVector<T, 10>& rhs_input,
bool use_constraint = true) { const test::GpuOpsTestConfig& config) {
// Prepare incompatibly shaped inputs. // Prepare incompatibly shaped inputs.
TensorShape lhs_shape{3}; TensorShape lhs_shape{3};
TensorShape rhs_shape{2}; TensorShape rhs_shape{2};
@ -115,8 +122,7 @@ class GpuBinaryOpTest : public OpsTestBase {
test::RepeatInputToMatchShape(rhs_input, rhs_shape.num_elements()); test::RepeatInputToMatchShape(rhs_input, rhs_shape.num_elements());
RunAndExpectInvalidArgument<T, OutT>(op_name, lhs_shape, repeated_lhs_input, RunAndExpectInvalidArgument<T, OutT>(op_name, lhs_shape, repeated_lhs_input,
rhs_shape, repeated_rhs_input, rhs_shape, repeated_rhs_input, config);
use_constraint);
} }
template <typename T, typename BaselineT, typename OutT, template <typename T, typename BaselineT, typename OutT,
@ -125,7 +131,7 @@ class GpuBinaryOpTest : public OpsTestBase {
const absl::InlinedVector<T, 10>& lhs_input, const absl::InlinedVector<T, 10>& lhs_input,
const absl::InlinedVector<T, 10>& rhs_input, const absl::InlinedVector<T, 10>& rhs_input,
BaselineOutT (*baseline_callback)(BaselineT, BaselineT), BaselineOutT (*baseline_callback)(BaselineT, BaselineT),
bool use_constraint = true) { const test::GpuOpsTestConfig& config) {
// Prepare inputs. // Prepare inputs.
int input_size = shape.num_elements(); int input_size = shape.num_elements();
auto repeated_lhs_input = auto repeated_lhs_input =
@ -147,7 +153,7 @@ class GpuBinaryOpTest : public OpsTestBase {
RunAndExpectResult<T, OutT>(op_name, shape, repeated_lhs_input, shape, RunAndExpectResult<T, OutT>(op_name, shape, repeated_lhs_input, shape,
repeated_rhs_input, shape, expected_output, repeated_rhs_input, shape, expected_output,
use_constraint); config);
} }
template <typename T, typename BaselineT, typename OutT, template <typename T, typename BaselineT, typename OutT,
@ -156,7 +162,7 @@ class GpuBinaryOpTest : public OpsTestBase {
const TensorShape& other_shape, const TensorShape& other_shape,
const absl::InlinedVector<T, 10>& other_input, const absl::InlinedVector<T, 10>& other_input,
BaselineOutT (*baseline_callback)(BaselineT, BaselineT), BaselineOutT (*baseline_callback)(BaselineT, BaselineT),
bool use_constraint = true) { const test::GpuOpsTestConfig& config) {
// Prepare inputs. // Prepare inputs.
TensorShape scalar_shape{}; TensorShape scalar_shape{};
auto repeated_other_input = auto repeated_other_input =
@ -177,7 +183,7 @@ class GpuBinaryOpTest : public OpsTestBase {
RunAndExpectResult<T, OutT>(op_name, scalar_shape, scalar_input_vector, RunAndExpectResult<T, OutT>(op_name, scalar_shape, scalar_input_vector,
other_shape, repeated_other_input, other_shape, repeated_other_input,
/*expected_shape=*/other_shape, expected_output, /*expected_shape=*/other_shape, expected_output,
use_constraint); config);
} }
template <typename T, typename BaselineT, typename OutT, template <typename T, typename BaselineT, typename OutT,
@ -187,7 +193,7 @@ class GpuBinaryOpTest : public OpsTestBase {
const absl::InlinedVector<T, 10>& rhs_input, const absl::InlinedVector<T, 10>& rhs_input,
BaselineOutT (*baseline_callback)(BaselineT, BaselineOutT (*baseline_callback)(BaselineT,
BaselineT), BaselineT),
bool use_constraint = true) { const test::GpuOpsTestConfig& config) {
// Prepare inputs. // Prepare inputs.
TensorShape lhs_shape{1}; TensorShape lhs_shape{1};
TensorShape rhs_shape{6}; TensorShape rhs_shape{6};
@ -206,7 +212,7 @@ class GpuBinaryOpTest : public OpsTestBase {
RunAndExpectResult<T, OutT>( RunAndExpectResult<T, OutT>(
op_name, lhs_shape, repeated_lhs_input, rhs_shape, repeated_rhs_input, op_name, lhs_shape, repeated_lhs_input, rhs_shape, repeated_rhs_input,
/*expected_shape=*/rhs_shape, expected_output, use_constraint); /*expected_shape=*/rhs_shape, expected_output, config);
} }
template <typename T, typename BaselineT, typename OutT, template <typename T, typename BaselineT, typename OutT,
@ -216,7 +222,7 @@ class GpuBinaryOpTest : public OpsTestBase {
const absl::InlinedVector<T, 10>& rhs_input, const absl::InlinedVector<T, 10>& rhs_input,
BaselineOutT (*baseline_callback)(BaselineT, BaselineOutT (*baseline_callback)(BaselineT,
BaselineT), BaselineT),
bool use_constraint = true) { const test::GpuOpsTestConfig& config) {
// Prepare inputs. // Prepare inputs.
TensorShape lhs_shape{3}; TensorShape lhs_shape{3};
TensorShape rhs_shape{2, 3}; TensorShape rhs_shape{2, 3};
@ -235,7 +241,7 @@ class GpuBinaryOpTest : public OpsTestBase {
RunAndExpectResult<T, OutT>( RunAndExpectResult<T, OutT>(
op_name, lhs_shape, repeated_lhs_input, rhs_shape, repeated_rhs_input, op_name, lhs_shape, repeated_lhs_input, rhs_shape, repeated_rhs_input,
/*expected_shape=*/rhs_shape, expected_output, use_constraint); /*expected_shape=*/rhs_shape, expected_output, config);
} }
template <typename T, typename BaselineT, typename OutT, template <typename T, typename BaselineT, typename OutT,
@ -244,7 +250,7 @@ class GpuBinaryOpTest : public OpsTestBase {
const absl::InlinedVector<T, 10>& lhs_input, const absl::InlinedVector<T, 10>& lhs_input,
const absl::InlinedVector<T, 10>& rhs_input, const absl::InlinedVector<T, 10>& rhs_input,
BaselineOutT (*baseline_callback)(BaselineT, BaselineT), BaselineOutT (*baseline_callback)(BaselineT, BaselineT),
bool use_constraint = true) { const test::GpuOpsTestConfig& config) {
// Prepare inputs. // Prepare inputs.
TensorShape lhs_shape{2, 1}; TensorShape lhs_shape{2, 1};
TensorShape rhs_shape{3}; TensorShape rhs_shape{3};
@ -264,7 +270,7 @@ class GpuBinaryOpTest : public OpsTestBase {
RunAndExpectResult<T, OutT>(op_name, lhs_shape, repeated_lhs_input, RunAndExpectResult<T, OutT>(op_name, lhs_shape, repeated_lhs_input,
rhs_shape, repeated_rhs_input, expected_shape, rhs_shape, repeated_rhs_input, expected_shape,
expected_output, use_constraint); expected_output, config);
} }
template <typename T, typename BaselineT, typename OutT, template <typename T, typename BaselineT, typename OutT,
@ -272,7 +278,7 @@ class GpuBinaryOpTest : public OpsTestBase {
void TestEmptyShapeBroadcasting(const std::string& op_name, void TestEmptyShapeBroadcasting(const std::string& op_name,
const absl::InlinedVector<T, 10>& lhs_input, const absl::InlinedVector<T, 10>& lhs_input,
const absl::InlinedVector<T, 10>& rhs_input, const absl::InlinedVector<T, 10>& rhs_input,
bool use_constraint = true) { const test::GpuOpsTestConfig& config) {
// Prepare inputs. // Prepare inputs.
TensorShape lhs_shape{2, 0, 1}; TensorShape lhs_shape{2, 0, 1};
TensorShape rhs_shape{2, 0, 5}; TensorShape rhs_shape{2, 0, 5};
@ -284,7 +290,7 @@ class GpuBinaryOpTest : public OpsTestBase {
RunAndExpectResult<T, OutT>(op_name, lhs_shape, empty_input, rhs_shape, RunAndExpectResult<T, OutT>(op_name, lhs_shape, empty_input, rhs_shape,
empty_input, expected_shape, expected_output, empty_input, expected_shape, expected_output,
use_constraint); config);
} }
private: private:
@ -309,14 +315,13 @@ class GpuBinaryOpTest : public OpsTestBase {
// define your own test fixtures. // define your own test fixtures.
#define GENERATE_DEFAULT_TESTS_2(op_name, test_name, T, BaselineT, OutT, \ #define GENERATE_DEFAULT_TESTS_2(op_name, test_name, T, BaselineT, OutT, \
BaselineOutT, baseline_callback, \ BaselineOutT, baseline_callback, config) \
use_constraint) \
TEST_F(GpuBinaryOpTest, op_name##EqShapes##test_name) { \ TEST_F(GpuBinaryOpTest, op_name##EqShapes##test_name) { \
TestEqualShapes<T, BaselineT, OutT, BaselineOutT>( \ TestEqualShapes<T, BaselineT, OutT, BaselineOutT>( \
#op_name, /*shape=*/test::DefaultInputShape(), \ #op_name, /*shape=*/test::DefaultInputShape(), \
/*lhs_input=*/test::DefaultInput<T>(#op_name), \ /*lhs_input=*/test::DefaultInput<T>(#op_name), \
/*rhs_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \ /*rhs_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \
use_constraint); \ config); \
} \ } \
\ \
TEST_F(GpuBinaryOpTest, op_name##OneScalar##test_name) { \ TEST_F(GpuBinaryOpTest, op_name##OneScalar##test_name) { \
@ -324,45 +329,46 @@ class GpuBinaryOpTest : public OpsTestBase {
#op_name, /*scalar_input=*/test::DefaultScalarInput<T>(), \ #op_name, /*scalar_input=*/test::DefaultScalarInput<T>(), \
/*other_shape=*/test::DefaultInputShape(), \ /*other_shape=*/test::DefaultInputShape(), \
/*other_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \ /*other_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \
use_constraint); \ config); \
} \ } \
\ \
TEST_F(GpuBinaryOpTest, op_name##IncompatibleShapes##test_name) { \ TEST_F(GpuBinaryOpTest, op_name##IncompatibleShapes##test_name) { \
TestIncompatibleShapes<T, OutT>( \ TestIncompatibleShapes<T, OutT>( \
#op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \ #op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \
/*rhs_input=*/test::DefaultInput<T>(#op_name), use_constraint); \ /*rhs_input=*/test::DefaultInput<T>(#op_name), config); \
} \ } \
\ \
TEST_F(GpuBinaryOpTest, op_name##BroadcastingExpand##test_name) { \ TEST_F(GpuBinaryOpTest, op_name##BroadcastingExpand##test_name) { \
TestBroadcastingExpand<T, BaselineT, OutT, BaselineOutT>( \ TestBroadcastingExpand<T, BaselineT, OutT, BaselineOutT>( \
#op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \ #op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \
/*rhs_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \ /*rhs_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \
use_constraint); \ config); \
} \ } \
\ \
TEST_F(GpuBinaryOpTest, op_name##BroadcastingInDim##test_name) { \ TEST_F(GpuBinaryOpTest, op_name##BroadcastingInDim##test_name) { \
TestBroadcastingInDim<T, BaselineT, OutT, BaselineOutT>( \ TestBroadcastingInDim<T, BaselineT, OutT, BaselineOutT>( \
#op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \ #op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \
/*rhs_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \ /*rhs_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \
use_constraint); \ config); \
} \ } \
\ \
TEST_F(GpuBinaryOpTest, op_name##Broadcasting##test_name) { \ TEST_F(GpuBinaryOpTest, op_name##Broadcasting##test_name) { \
TestBroadcasting<T, BaselineT, OutT, BaselineOutT>( \ TestBroadcasting<T, BaselineT, OutT, BaselineOutT>( \
#op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \ #op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \
/*rhs_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \ /*rhs_input=*/test::DefaultInput<T>(#op_name), baseline_callback, \
use_constraint); \ config); \
} \ } \
\ \
TEST_F(GpuBinaryOpTest, op_name##EmptyShapeBroadcasting##test_name) { \ TEST_F(GpuBinaryOpTest, op_name##EmptyShapeBroadcasting##test_name) { \
TestEmptyShapeBroadcasting<T, BaselineT, OutT, BaselineOutT>( \ TestEmptyShapeBroadcasting<T, BaselineT, OutT, BaselineOutT>( \
#op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \ #op_name, /*lhs_input=*/test::DefaultInput<T>(#op_name), \
/*rhs_input=*/test::DefaultInput<T>(#op_name), use_constraint); \ /*rhs_input=*/test::DefaultInput<T>(#op_name), config); \
} }
#define GENERATE_DEFAULT_TESTS(op_name, test_name, T, OutT, baseline_callback) \ #define GENERATE_DEFAULT_TESTS(op_name, test_name, T, OutT, baseline_callback) \
GENERATE_DEFAULT_TESTS_2(op_name, test_name, T, T, OutT, OutT, \ GENERATE_DEFAULT_TESTS_2(op_name, test_name, T, T, OutT, OutT, \
baseline_callback, /*use_constraint=*/false) baseline_callback, \
test::GpuOpsTestConfig().ExpectStrictlyEqual())
#define GENERATE_DEFAULT_TESTS_SAME_INPUT_AND_OUTPUT_TYPE( \ #define GENERATE_DEFAULT_TESTS_SAME_INPUT_AND_OUTPUT_TYPE( \
op_name, test_name, T, baseline_callback) \ op_name, test_name, T, baseline_callback) \
@ -603,7 +609,7 @@ bool baseline_logical_and(bool lhs, bool rhs) { return lhs && rhs; }
GENERATE_DEFAULT_TESTS_2(LogicalAnd, /*test_name=*/Bool, /*T=*/bool, GENERATE_DEFAULT_TESTS_2(LogicalAnd, /*test_name=*/Bool, /*T=*/bool,
/*BaselineT=*/bool, /*OutT=*/bool, /*BaselineT=*/bool, /*OutT=*/bool,
/*BaselineOutT=*/bool, baseline_logical_and, /*BaselineOutT=*/bool, baseline_logical_and,
/*use_constraint=*/false) test::GpuOpsTestConfig().ExpectStrictlyEqual().NoT())
/// Test `tf.LogicalOr`. /// Test `tf.LogicalOr`.
@ -612,7 +618,7 @@ bool baseline_logical_or(bool lhs, bool rhs) { return lhs || rhs; }
GENERATE_DEFAULT_TESTS_2(LogicalOr, /*test_name=*/Bool, /*T=*/bool, GENERATE_DEFAULT_TESTS_2(LogicalOr, /*test_name=*/Bool, /*T=*/bool,
/*BaselineT=*/bool, /*OutT=*/bool, /*BaselineT=*/bool, /*OutT=*/bool,
/*BaselineOutT=*/bool, baseline_logical_or, /*BaselineOutT=*/bool, baseline_logical_or,
/*use_constraint=*/false) test::GpuOpsTestConfig().ExpectStrictlyEqual().NoT())
/// Test `tf.FloorDiv`. /// Test `tf.FloorDiv`.
template <typename T> template <typename T>

View File

@ -57,6 +57,7 @@ TensorShape DefaultInputShape();
struct GpuOpsTestConfig { struct GpuOpsTestConfig {
bool add_t = true; bool add_t = true;
bool add_tout = false; bool add_tout = false;
// Only used for gpu_unary_ops_test.
bool expect_buffer_reuse = true; bool expect_buffer_reuse = true;
bool expect_strictly_equal = false; bool expect_strictly_equal = false;
GpuOpsTestConfig ExpectStrictlyEqual() { GpuOpsTestConfig ExpectStrictlyEqual() {