1 /* Copyright 2019 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 "tensorflow/lite/delegates/gpu/gl/kernels/mul.h"
17
18 #include <utility>
19 #include <vector>
20
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include "tensorflow/lite/delegates/gpu/common/operations.h"
24 #include "tensorflow/lite/delegates/gpu/gl/kernels/test_util.h"
25
26 using ::testing::FloatNear;
27 using ::testing::Pointwise;
28
29 namespace tflite {
30 namespace gpu {
31 namespace gl {
32 namespace {
33
TEST(MulTest,Scalar)34 TEST(MulTest, Scalar) {
35 TensorRef<BHWC> input;
36 input.type = DataType::FLOAT32;
37 input.ref = 0;
38 input.shape = BHWC(1, 2, 2, 1);
39
40 TensorRef<BHWC> output;
41 output.type = DataType::FLOAT32;
42 output.ref = 1;
43 output.shape = BHWC(1, 2, 2, 1);
44
45 ElementwiseAttributes attr;
46 attr.param = 2.f;
47
48 SingleOpModel model({ToString(OperationType::MUL), attr}, {input}, {output});
49 ASSERT_TRUE(model.PopulateTensor(0, {1, 2, 3, 4}));
50 ASSERT_OK(model.Invoke(*NewMultiplyNodeShader()));
51 EXPECT_THAT(model.GetOutput(0), Pointwise(FloatNear(1e-6), {2, 4, 6, 8}));
52 }
53
TEST(MulTest,Linear)54 TEST(MulTest, Linear) {
55 TensorRef<BHWC> input;
56 input.type = DataType::FLOAT32;
57 input.ref = 0;
58 input.shape = BHWC(1, 1, 2, 2);
59
60 TensorRef<BHWC> output;
61 output.type = DataType::FLOAT32;
62 output.ref = 1;
63 output.shape = BHWC(1, 1, 2, 2);
64
65 ElementwiseAttributes attr;
66 Tensor<Linear, DataType::FLOAT32> tensor;
67 tensor.shape.v = 2;
68 tensor.id = 1;
69 tensor.data = {2, 3};
70 attr.param = std::move(tensor);
71
72 SingleOpModel model({ToString(OperationType::MUL), attr}, {input}, {output});
73 ASSERT_TRUE(model.PopulateTensor(0, {1, 2, 3, 4}));
74 ASSERT_OK(model.Invoke(*NewMultiplyNodeShader()));
75 EXPECT_THAT(model.GetOutput(0), Pointwise(FloatNear(1e-6), {2, 6, 6, 12}));
76 }
77
TEST(MulTest,ConstTensor3D)78 TEST(MulTest, ConstTensor3D) {
79 TensorRef<BHWC> input;
80 input.type = DataType::FLOAT32;
81 input.ref = 0;
82 input.shape = BHWC(1, 1, 2, 2);
83
84 TensorRef<BHWC> output;
85 output.type = DataType::FLOAT32;
86 output.ref = 1;
87 output.shape = BHWC(1, 1, 2, 2);
88
89 ElementwiseAttributes attr;
90 Tensor<HWC, DataType::FLOAT32> tensor_3d;
91 tensor_3d.shape.h = 1;
92 tensor_3d.shape.w = 2;
93 tensor_3d.shape.c = 2;
94 tensor_3d.id = 2;
95 tensor_3d.data = {-2, 2, -3, 3};
96 attr.param = std::move(tensor_3d);
97
98 SingleOpModel model({ToString(OperationType::MUL), attr}, {input}, {output});
99 ASSERT_TRUE(model.PopulateTensor(0, {1, 2, 3, 4}));
100 ASSERT_OK(model.Invoke(*NewMultiplyNodeShader()));
101 EXPECT_THAT(model.GetOutput(0), Pointwise(FloatNear(1e-6), {-2, 4, -9, 12}));
102 }
103
TEST(MulTest,MaskChannel1)104 TEST(MulTest, MaskChannel1) {
105 TensorRef<BHWC> input;
106 input.type = DataType::FLOAT32;
107 input.ref = 0;
108 input.shape = BHWC(1, 1, 2, 2);
109
110 TensorRef<BHWC> mask;
111 mask.type = DataType::FLOAT32;
112 mask.ref = 1;
113 mask.shape = BHWC(1, 1, 2, 1);
114
115 TensorRef<BHWC> output;
116 output.type = DataType::FLOAT32;
117 output.ref = 2;
118 output.shape = BHWC(1, 1, 2, 2);
119
120 SingleOpModel model({ToString(OperationType::MUL), {}}, {input, mask},
121 {output});
122 ASSERT_TRUE(model.PopulateTensor(0, {1, 2, 3, 4}));
123 ASSERT_TRUE(model.PopulateTensor(1, {2, 3}));
124 ASSERT_OK(model.Invoke(*NewMultiplyNodeShader()));
125 EXPECT_THAT(model.GetOutput(0), Pointwise(FloatNear(1e-6), {2, 4, 9, 12}));
126 }
127
TEST(MulTest,MaskChannelEqualsToInputChannel)128 TEST(MulTest, MaskChannelEqualsToInputChannel) {
129 TensorRef<BHWC> input;
130 input.type = DataType::FLOAT32;
131 input.ref = 0;
132 input.shape = BHWC(1, 1, 2, 2);
133
134 TensorRef<BHWC> mask;
135 mask.type = DataType::FLOAT32;
136 mask.ref = 1;
137 mask.shape = BHWC(1, 1, 2, 2);
138
139 TensorRef<BHWC> output;
140 output.type = DataType::FLOAT32;
141 output.ref = 2;
142 output.shape = BHWC(1, 1, 2, 2);
143
144 SingleOpModel model({ToString(OperationType::MUL), {}}, {input, mask},
145 {output});
146 ASSERT_TRUE(model.PopulateTensor(0, {1, 2, 3, 4}));
147 ASSERT_TRUE(model.PopulateTensor(1, {1, 2, 3, 4}));
148 ASSERT_OK(model.Invoke(*NewMultiplyNodeShader()));
149 EXPECT_THAT(model.GetOutput(0), Pointwise(FloatNear(1e-6), {1, 4, 9, 16}));
150 }
151
152 } // namespace
153 } // namespace gl
154 } // namespace gpu
155 } // namespace tflite
156