From 60ae24ee1a6c16114de456d77fcfba6f5a1160ca Mon Sep 17 00:00:00 2001 From: Eugene Zhulenev Date: Wed, 2 Oct 2019 12:44:06 -0700 Subject: Add block evaluation to TensorReshaping/TensorCasting/TensorPadding/TensorSelect --- unsupported/test/cxx11_tensor_block_eval.cpp | 180 ++++++++++++++++++++++++--- 1 file changed, 165 insertions(+), 15 deletions(-) (limited to 'unsupported/test/cxx11_tensor_block_eval.cpp') diff --git a/unsupported/test/cxx11_tensor_block_eval.cpp b/unsupported/test/cxx11_tensor_block_eval.cpp index e85b81141..ff98e170d 100644 --- a/unsupported/test/cxx11_tensor_block_eval.cpp +++ b/unsupported/test/cxx11_tensor_block_eval.cpp @@ -104,6 +104,17 @@ static TensorBlockParams FixedSizeBlock(DSizes dims) { return {offsets, dims, TensorBlockDescriptor(0, dims)}; } +inline Eigen::IndexList> NByOne(int n) { + Eigen::IndexList> ret; + ret.set(0, n); + return ret; +} +inline Eigen::IndexList, int> OneByM(int m) { + Eigen::IndexList, int> ret; + ret.set(1, m); + return ret; +} + // -------------------------------------------------------------------------- // // Verify that block expression evaluation produces the same result as a // TensorSliceOp (reading a tensor block is same to taking a tensor slice). @@ -174,7 +185,7 @@ static void test_eval_tensor_block() { // Identity tensor expression transformation. VerifyBlockEvaluator( - input, [&dims]() { return RandomBlock(dims, 10, 20); }); + input, [&dims]() { return RandomBlock(dims, 1, 10); }); } template @@ -184,7 +195,7 @@ static void test_eval_tensor_unary_expr_block() { input.setRandom(); VerifyBlockEvaluator( - input.square(), [&dims]() { return RandomBlock(dims, 10, 20); }); + input.square(), [&dims]() { return RandomBlock(dims, 1, 10); }); } template @@ -195,7 +206,7 @@ static void test_eval_tensor_binary_expr_block() { rhs.setRandom(); VerifyBlockEvaluator( - lhs + rhs, [&dims]() { return RandomBlock(dims, 10, 20); }); + lhs + rhs, [&dims]() { return RandomBlock(dims, 1, 10); }); } template @@ -207,7 +218,7 @@ static void test_eval_tensor_binary_with_unary_expr_block() { VerifyBlockEvaluator( (lhs.square() + rhs.square()).sqrt(), - [&dims]() { return RandomBlock(dims, 10, 20); }); + [&dims]() { return RandomBlock(dims, 1, 10); }); } template @@ -236,6 +247,114 @@ static void test_eval_tensor_broadcast() { [&bcasted_dims]() { return SkewedInnerBlock(bcasted_dims); }); } +template +static void test_eval_tensor_reshape() { + DSizes dims = RandomDims(1, 10); + + DSizes shuffled = dims; + std::shuffle(&shuffled[0], &shuffled[NumDims - 1], std::mt19937(g_seed)); + + Tensor input(dims); + input.setRandom(); + + VerifyBlockEvaluator( + input.reshape(shuffled), + [&shuffled]() { return RandomBlock(shuffled, 1, 10); }); + + VerifyBlockEvaluator( + input.reshape(shuffled), + [&shuffled]() { return SkewedInnerBlock(shuffled); }); +} + +template +static void test_eval_tensor_reshape_with_bcast() { + Index dim = internal::random(1, 100); + + Tensor lhs(1, dim); + Tensor rhs(dim, 1); + lhs.setRandom(); + rhs.setRandom(); + + auto reshapeLhs = NByOne(dim); + auto reshapeRhs = OneByM(dim); + + auto bcastLhs = OneByM(dim); + auto bcastRhs = NByOne(dim); + + DSizes dims(dim, dim); + + VerifyBlockEvaluator( + lhs.reshape(reshapeLhs).broadcast(bcastLhs) + + rhs.reshape(reshapeRhs).broadcast(bcastRhs), + [dims]() { return SkewedInnerBlock(dims); }); +} + +template +static void test_eval_tensor_cast() { + DSizes dims = RandomDims(10, 20); + Tensor input(dims); + input.setRandom(); + + VerifyBlockEvaluator( + input.template cast().template cast(), + [&dims]() { return RandomBlock(dims, 1, 10); }); +} + +template +static void test_eval_tensor_select() { + DSizes dims = RandomDims(10, 20); + Tensor lhs(dims); + Tensor rhs(dims); + Tensor cond(dims); + lhs.setRandom(); + rhs.setRandom(); + cond.setRandom(); + + VerifyBlockEvaluator(cond.select(lhs, rhs), [&dims]() { + return RandomBlock(dims, 1, 20); + }); +} + +template +static void test_eval_tensor_padding() { + const int inner_dim = Layout == static_cast(ColMajor) ? 0 : NumDims - 1; + + DSizes dims = RandomDims(10, 20); + Tensor input(dims); + input.setRandom(); + + DSizes pad_before = RandomDims(0, 4); + DSizes pad_after = RandomDims(0, 4); + array, NumDims> paddings; + for (int i = 0; i < NumDims; ++i) { + paddings[i] = std::make_pair(pad_before[i], pad_after[i]); + } + + // Test squeezing reads from inner dim. + if (internal::random()) { + pad_before[inner_dim] = 0; + pad_after[inner_dim] = 0; + paddings[inner_dim] = std::make_pair(0, 0); + } + + DSizes padded_dims; + for (int i = 0; i < NumDims; ++i) { + padded_dims[i] = dims[i] + pad_before[i] + pad_after[i]; + } + + VerifyBlockEvaluator( + input.pad(paddings), + [&padded_dims]() { return FixedSizeBlock(padded_dims); }); + + VerifyBlockEvaluator( + input.pad(paddings), + [&padded_dims]() { return RandomBlock(padded_dims, 1, 10); }); + + VerifyBlockEvaluator( + input.pad(paddings), + [&padded_dims]() { return SkewedInnerBlock(padded_dims); }); +} + // -------------------------------------------------------------------------- // // Verify that assigning block to a Tensor expression produces the same result // as an assignment to TensorSliceOp (writing a block is is identical to @@ -300,7 +419,7 @@ static void VerifyBlockAssignment(Tensor& tensor, // -------------------------------------------------------------------------- // template -static void test_assign_tensor_block() { +static void test_assign_to_tensor() { DSizes dims = RandomDims(10, 20); Tensor tensor(dims); @@ -312,11 +431,32 @@ static void test_assign_tensor_block() { tensor, map, [&dims]() { return FixedSizeBlock(dims); }); } -// -------------------------------------------------------------------------- // +template +static void test_assign_to_tensor_reshape() { + DSizes dims = RandomDims(10, 20); + Tensor tensor(dims); + + TensorMap> map(tensor.data(), dims); -//#define CALL_SUBTESTS(NAME) CALL_SUBTEST((NAME())) + DSizes shuffled = dims; + std::shuffle(&shuffled[0], &shuffled[NumDims - 1], std::mt19937(g_seed)); + + VerifyBlockAssignment( + tensor, map.reshape(shuffled), + [&shuffled]() { return RandomBlock(shuffled, 1, 10); }); -#define CALL_SUBTESTS(NAME) \ + VerifyBlockAssignment( + tensor, map.reshape(shuffled), + [&shuffled]() { return SkewedInnerBlock(shuffled); }); + + VerifyBlockAssignment( + tensor, map.reshape(shuffled), + [&shuffled]() { return FixedSizeBlock(shuffled); }); +} + +// -------------------------------------------------------------------------- // + +#define CALL_SUBTESTS_DIMS_LAYOUTS(NAME) \ CALL_SUBTEST((NAME())); \ CALL_SUBTEST((NAME())); \ CALL_SUBTEST((NAME())); \ @@ -326,14 +466,24 @@ static void test_assign_tensor_block() { CALL_SUBTEST((NAME())); \ CALL_SUBTEST((NAME())) +#define CALL_SUBTESTS_LAYOUTS(NAME) \ + CALL_SUBTEST((NAME())); \ + CALL_SUBTEST((NAME())) + EIGEN_DECLARE_TEST(cxx11_tensor_block_eval) { // clang-format off - CALL_SUBTESTS(test_eval_tensor_block); - CALL_SUBTESTS(test_eval_tensor_unary_expr_block); - CALL_SUBTESTS(test_eval_tensor_binary_expr_block); - CALL_SUBTESTS(test_eval_tensor_binary_with_unary_expr_block); - CALL_SUBTESTS(test_eval_tensor_broadcast); - - CALL_SUBTESTS(test_assign_tensor_block); + CALL_SUBTESTS_DIMS_LAYOUTS(test_eval_tensor_block); + CALL_SUBTESTS_DIMS_LAYOUTS(test_eval_tensor_unary_expr_block); + CALL_SUBTESTS_DIMS_LAYOUTS(test_eval_tensor_binary_expr_block); + CALL_SUBTESTS_DIMS_LAYOUTS(test_eval_tensor_binary_with_unary_expr_block); + CALL_SUBTESTS_DIMS_LAYOUTS(test_eval_tensor_broadcast); + CALL_SUBTESTS_DIMS_LAYOUTS(test_eval_tensor_reshape); + CALL_SUBTESTS_DIMS_LAYOUTS(test_eval_tensor_cast); + CALL_SUBTESTS_DIMS_LAYOUTS(test_eval_tensor_padding); + + CALL_SUBTESTS_LAYOUTS(test_eval_tensor_reshape_with_bcast); + + CALL_SUBTESTS_DIMS_LAYOUTS(test_assign_to_tensor); + CALL_SUBTESTS_DIMS_LAYOUTS(test_assign_to_tensor_reshape); // clang-format on } -- cgit v1.2.3