1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #include <memory>
17 #include <string>
18 #include <vector>
19
20 #include "tensorflow/core/common_runtime/device.h"
21 #include "tensorflow/core/common_runtime/device_factory.h"
22 #include "tensorflow/core/framework/allocator.h"
23 #include "tensorflow/core/framework/fake_input.h"
24 #include "tensorflow/core/framework/node_def_builder.h"
25 #include "tensorflow/core/framework/op_kernel.h"
26 #include "tensorflow/core/framework/tensor.h"
27 #include "tensorflow/core/framework/types.h"
28 #include "tensorflow/core/kernels/ops_testutil.h"
29 #include "tensorflow/core/lib/core/status_test_util.h"
30 #include "tensorflow/core/public/session_options.h"
31 #include "tensorflow/core/public/version.h"
32
33 namespace tensorflow {
34 namespace {
35
36 class SerializeTensorOpTest : public OpsTestBase {
37 protected:
38 template <typename T>
MakeOp(const TensorShape & input_shape,std::function<T (int)> functor)39 void MakeOp(const TensorShape& input_shape, std::function<T(int)> functor) {
40 TF_ASSERT_OK(NodeDefBuilder("myop", "SerializeTensor")
41 .Input(FakeInput(DataTypeToEnum<T>::value))
42 .Finalize(node_def()));
43 TF_ASSERT_OK(InitOp());
44 AddInput<T>(input_shape, functor);
45 }
ParseSerializedWithNodeDef(const NodeDef & parse_node_def,Tensor * serialized,Tensor * parse_output)46 void ParseSerializedWithNodeDef(const NodeDef& parse_node_def,
47 Tensor* serialized, Tensor* parse_output) {
48 std::unique_ptr<Device> device(
49 DeviceFactory::NewDevice("CPU", {}, "/job:a/replica:0/task:0"));
50 gtl::InlinedVector<TensorValue, 4> inputs;
51 inputs.push_back({nullptr, serialized});
52 Status status;
53 std::unique_ptr<OpKernel> op(CreateOpKernel(DEVICE_CPU, device.get(),
54 cpu_allocator(), parse_node_def,
55 TF_GRAPH_DEF_VERSION, &status));
56 TF_EXPECT_OK(status);
57 OpKernelContext::Params params;
58 params.device = device.get();
59 params.inputs = &inputs;
60 params.frame_iter = FrameAndIter(0, 0);
61 params.op_kernel = op.get();
62 std::vector<AllocatorAttributes> attrs;
63 test::SetOutputAttrs(¶ms, &attrs);
64 OpKernelContext ctx(¶ms);
65 op->Compute(&ctx);
66 TF_EXPECT_OK(status);
67 *parse_output = *ctx.mutable_output(0);
68 }
69 template <typename T>
ParseSerializedOutput(Tensor * serialized,Tensor * parse_output)70 void ParseSerializedOutput(Tensor* serialized, Tensor* parse_output) {
71 NodeDef parse;
72 TF_ASSERT_OK(NodeDefBuilder("parse", "ParseTensor")
73 .Input(FakeInput(DT_STRING))
74 .Attr("out_type", DataTypeToEnum<T>::value)
75 .Finalize(&parse));
76 ParseSerializedWithNodeDef(parse, serialized, parse_output);
77 }
78 };
79
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_half)80 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_half) {
81 MakeOp<Eigen::half>(TensorShape({10}), [](int x) -> Eigen::half {
82 return static_cast<Eigen::half>(x / 10.);
83 });
84 TF_ASSERT_OK(RunOpKernel());
85 Tensor parse_output;
86 ParseSerializedOutput<Eigen::half>(GetOutput(0), &parse_output);
87 test::ExpectTensorEqual<Eigen::half>(parse_output, GetInput(0));
88 }
89
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_float)90 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_float) {
91 MakeOp<float>(TensorShape({1, 10}),
92 [](int x) -> float { return static_cast<float>(x / 10.); });
93 TF_ASSERT_OK(RunOpKernel());
94 Tensor parse_output;
95 ParseSerializedOutput<float>(GetOutput(0), &parse_output);
96 test::ExpectTensorEqual<float>(parse_output, GetInput(0));
97 }
98
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_double)99 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_double) {
100 MakeOp<double>(TensorShape({5, 5}),
101 [](int x) -> double { return static_cast<double>(x / 10.); });
102 TF_ASSERT_OK(RunOpKernel());
103 Tensor parse_output;
104 ParseSerializedOutput<double>(GetOutput(0), &parse_output);
105 test::ExpectTensorEqual<double>(parse_output, GetInput(0));
106 }
107
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_int64)108 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_int64) {
109 MakeOp<int64>(TensorShape({2, 3, 4}),
110 [](int x) -> int64 { return static_cast<int64>(x - 10); });
111 TF_ASSERT_OK(RunOpKernel());
112 Tensor parse_output;
113 ParseSerializedOutput<int64>(GetOutput(0), &parse_output);
114 test::ExpectTensorEqual<int64>(parse_output, GetInput(0));
115 }
116
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_int32)117 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_int32) {
118 MakeOp<int32>(TensorShape({4, 2}),
119 [](int x) -> int32 { return static_cast<int32>(x + 7); });
120 TF_ASSERT_OK(RunOpKernel());
121 Tensor parse_output;
122 ParseSerializedOutput<int32>(GetOutput(0), &parse_output);
123 test::ExpectTensorEqual<int32>(parse_output, GetInput(0));
124 }
125
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_int16)126 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_int16) {
127 MakeOp<int16>(TensorShape({8}),
128 [](int x) -> int16 { return static_cast<int16>(x + 18); });
129 TF_ASSERT_OK(RunOpKernel());
130 Tensor parse_output;
131 ParseSerializedOutput<int16>(GetOutput(0), &parse_output);
132 test::ExpectTensorEqual<int16>(parse_output, GetInput(0));
133 }
134
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_int8)135 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_int8) {
136 MakeOp<int8>(TensorShape({2}),
137 [](int x) -> int8 { return static_cast<int8>(x + 8); });
138 TF_ASSERT_OK(RunOpKernel());
139 Tensor parse_output;
140 ParseSerializedOutput<int8>(GetOutput(0), &parse_output);
141 test::ExpectTensorEqual<int8>(parse_output, GetInput(0));
142 }
143
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_uint16)144 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_uint16) {
145 MakeOp<uint16>(TensorShape({1, 3}),
146 [](int x) -> uint16 { return static_cast<uint16>(x + 2); });
147 TF_ASSERT_OK(RunOpKernel());
148 Tensor parse_output;
149 ParseSerializedOutput<uint16>(GetOutput(0), &parse_output);
150 test::ExpectTensorEqual<uint16>(parse_output, GetInput(0));
151 }
152
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_uint8)153 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_uint8) {
154 MakeOp<uint8>(TensorShape({2, 1, 1}),
155 [](int x) -> uint8 { return static_cast<uint8>(x + 1); });
156 TF_ASSERT_OK(RunOpKernel());
157 Tensor parse_output;
158 ParseSerializedOutput<uint8>(GetOutput(0), &parse_output);
159 test::ExpectTensorEqual<uint8>(parse_output, GetInput(0));
160 }
161
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_complex64)162 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_complex64) {
163 MakeOp<complex64>(TensorShape({}), [](int x) -> complex64 {
164 return complex64{static_cast<float>(x / 8.), static_cast<float>(x / 2.)};
165 });
166 TF_ASSERT_OK(RunOpKernel());
167 Tensor parse_output;
168 ParseSerializedOutput<complex64>(GetOutput(0), &parse_output);
169 test::ExpectTensorEqual<complex64>(parse_output, GetInput(0));
170 }
171
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_complex128)172 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_complex128) {
173 MakeOp<complex128>(TensorShape({3}), [](int x) -> complex128 {
174 return complex128{x / 3., x / 2.};
175 });
176 TF_ASSERT_OK(RunOpKernel());
177 Tensor parse_output;
178 ParseSerializedOutput<complex128>(GetOutput(0), &parse_output);
179 test::ExpectTensorEqual<complex128>(parse_output, GetInput(0));
180 }
181
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_bool)182 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_bool) {
183 MakeOp<bool>(TensorShape({1}),
184 [](int x) -> bool { return static_cast<bool>(x % 2); });
185 TF_ASSERT_OK(RunOpKernel());
186 Tensor parse_output;
187 ParseSerializedOutput<bool>(GetOutput(0), &parse_output);
188 test::ExpectTensorEqual<bool>(parse_output, GetInput(0));
189 }
190
TEST_F(SerializeTensorOpTest,SerializeTensorOpTest_string)191 TEST_F(SerializeTensorOpTest, SerializeTensorOpTest_string) {
192 MakeOp<tstring>(TensorShape({10}),
193 [](int x) -> tstring { return std::to_string(x / 10.); });
194 TF_ASSERT_OK(RunOpKernel());
195 Tensor parse_output;
196 ParseSerializedOutput<tstring>(GetOutput(0), &parse_output);
197 test::ExpectTensorEqual<tstring>(parse_output, GetInput(0));
198 }
199
200 } // namespace
201 } // namespace tensorflow
202