6
6
* LICENSE file in the root directory of this source tree.
7
7
*/
8
8
9
+ #include < executorch/runtime/core/evalue.h>
10
+
9
11
#include < gtest/gtest.h>
10
12
11
- #include < executorch/runtime/core/evalue.h>
12
- #include < executorch/runtime/core/exec_aten/exec_aten.h>
13
13
#include < executorch/runtime/core/exec_aten/testing_util/tensor_factory.h>
14
+ #include < executorch/runtime/platform/runtime.h>
14
15
#include < executorch/test/utils/DeathTest.h>
15
16
16
17
using namespace ::testing;
18
+
19
+ namespace torch {
20
+ namespace executor {
21
+
17
22
using exec_aten::ScalarType;
18
23
using executorch::runtime::BoxedEvalueList;
19
24
using executorch::runtime::EValue;
20
25
using executorch::runtime::Tag;
21
26
using executorch::runtime::testing::TensorFactory;
22
27
23
- TEST (TestEValue, CopyTrivialType) {
28
+ class EValueTest : public ::testing::Test {
29
+ protected:
30
+ void SetUp () override {
31
+ // Since these tests cause ET_LOG to be called, the PAL must be initialized
32
+ // first.
33
+ runtime_init ();
34
+ }
35
+ };
36
+
37
+ // An utility class used in tests to simulate objects that manage Tensors.
38
+ // The overloaded operator*() is used to return the underlying Tensor, mimicking
39
+ // behavior of smart pointers.
40
+ class TensorWrapper {
41
+ public:
42
+ explicit TensorWrapper (exec_aten::Tensor tensor)
43
+ : tensor_(std::make_unique<exec_aten::Tensor>(std::move(tensor))) {}
44
+
45
+ exec_aten::Tensor& operator *() {
46
+ return *tensor_;
47
+ }
48
+
49
+ const exec_aten::Tensor& operator *() const {
50
+ return *tensor_;
51
+ }
52
+
53
+ operator bool () const {
54
+ return static_cast <bool >(tensor_);
55
+ }
56
+
57
+ bool operator ==(std::nullptr_t ) const {
58
+ return tensor_ == nullptr ;
59
+ }
60
+
61
+ bool operator !=(std::nullptr_t ) const {
62
+ return tensor_ != nullptr ;
63
+ }
64
+
65
+ private:
66
+ std::unique_ptr<exec_aten::Tensor> tensor_;
67
+ };
68
+
69
+ TEST_F (EValueTest, CopyTrivialType) {
24
70
EValue a;
25
71
EValue b (true );
26
72
EXPECT_TRUE (a.isNone ());
@@ -30,7 +76,7 @@ TEST(TestEValue, CopyTrivialType) {
30
76
EXPECT_EQ (b.to <bool >(), true );
31
77
}
32
78
33
- TEST (TestEValue , CopyTensor) {
79
+ TEST_F (EValueTest , CopyTensor) {
34
80
TensorFactory<ScalarType::Float> tf;
35
81
EValue a (tf.ones ({3 , 2 }));
36
82
EValue b (tf.ones ({1 }));
@@ -39,7 +85,7 @@ TEST(TestEValue, CopyTensor) {
39
85
EXPECT_EQ (a.toTensor ().dim (), 1 );
40
86
}
41
87
42
- TEST (TestEValue , TypeMismatchFatals) {
88
+ TEST_F (EValueTest , TypeMismatchFatals) {
43
89
ET_EXPECT_DEATH (
44
90
{
45
91
auto e = EValue (true );
@@ -48,12 +94,12 @@ TEST(TestEValue, TypeMismatchFatals) {
48
94
" " );
49
95
}
50
96
51
- TEST (TestEValue , NoneByDefault) {
97
+ TEST_F (EValueTest , NoneByDefault) {
52
98
EValue e;
53
99
EXPECT_TRUE (e.isNone ());
54
100
}
55
101
56
- TEST (TestEValue , ToOptionalInt) {
102
+ TEST_F (EValueTest , ToOptionalInt) {
57
103
EValue e ((int64_t )5 );
58
104
EXPECT_TRUE (e.isInt ());
59
105
EXPECT_FALSE (e.isNone ());
@@ -63,15 +109,15 @@ TEST(TestEValue, ToOptionalInt) {
63
109
EXPECT_EQ (o.value (), 5 );
64
110
}
65
111
66
- TEST (TestEValue , NoneToOptionalInt) {
112
+ TEST_F (EValueTest , NoneToOptionalInt) {
67
113
EValue e;
68
114
EXPECT_TRUE (e.isNone ());
69
115
70
116
exec_aten::optional<int64_t > o = e.toOptional <int64_t >();
71
117
EXPECT_FALSE (o.has_value ());
72
118
}
73
119
74
- TEST (TestEValue , ToOptionalScalar) {
120
+ TEST_F (EValueTest , ToOptionalScalar) {
75
121
exec_aten::Scalar s ((double )3.141 );
76
122
EValue e (s);
77
123
EXPECT_TRUE (e.isScalar ());
@@ -83,7 +129,7 @@ TEST(TestEValue, ToOptionalScalar) {
83
129
EXPECT_EQ (o.value ().to <double >(), 3.141 );
84
130
}
85
131
86
- TEST (TESTEValue , ScalarToType) {
132
+ TEST_F (EValueTest , ScalarToType) {
87
133
exec_aten::Scalar s_d ((double )3.141 );
88
134
EXPECT_EQ (s_d.to <double >(), 3.141 );
89
135
exec_aten::Scalar s_i ((int64_t )3 );
@@ -92,23 +138,23 @@ TEST(TESTEValue, ScalarToType) {
92
138
EXPECT_EQ (s_b.to <bool >(), true );
93
139
}
94
140
95
- TEST (TestEValue , NoneToOptionalScalar) {
141
+ TEST_F (EValueTest , NoneToOptionalScalar) {
96
142
EValue e;
97
143
EXPECT_TRUE (e.isNone ());
98
144
99
145
exec_aten::optional<exec_aten::Scalar> o = e.toOptional <exec_aten::Scalar>();
100
146
EXPECT_FALSE (o.has_value ());
101
147
}
102
148
103
- TEST (TestEValue , NoneToOptionalTensor) {
149
+ TEST_F (EValueTest , NoneToOptionalTensor) {
104
150
EValue e;
105
151
EXPECT_TRUE (e.isNone ());
106
152
107
153
exec_aten::optional<exec_aten::Tensor> o = e.toOptional <exec_aten::Tensor>();
108
154
EXPECT_FALSE (o.has_value ());
109
155
}
110
156
111
- TEST (TestEValue , ToScalarType) {
157
+ TEST_F (EValueTest , ToScalarType) {
112
158
EValue e ((int64_t )4 );
113
159
auto o = e.toScalarType ();
114
160
EXPECT_EQ (o, exec_aten::ScalarType::Long);
@@ -118,7 +164,7 @@ TEST(TestEValue, ToScalarType) {
118
164
EXPECT_EQ (o2.value (), exec_aten::ScalarType::Long);
119
165
}
120
166
121
- TEST (TestEValue , toString) {
167
+ TEST_F (EValueTest , toString) {
122
168
const EValue e (" foo" , 3 );
123
169
EXPECT_TRUE (e.isString ());
124
170
EXPECT_FALSE (e.isNone ());
@@ -127,28 +173,28 @@ TEST(TestEValue, toString) {
127
173
EXPECT_EQ (x, " foo" );
128
174
}
129
175
130
- TEST (TestEValue , MemoryFormat) {
176
+ TEST_F (EValueTest , MemoryFormat) {
131
177
const EValue e ((int64_t )0 );
132
178
EXPECT_TRUE (e.isInt ());
133
179
const exec_aten::MemoryFormat m = e.to <exec_aten::MemoryFormat>();
134
180
EXPECT_EQ (m, exec_aten::MemoryFormat::Contiguous);
135
181
}
136
182
137
- TEST (TestEValue , Layout) {
183
+ TEST_F (EValueTest , Layout) {
138
184
const EValue e ((int64_t )0 );
139
185
EXPECT_TRUE (e.isInt ());
140
186
const exec_aten::Layout l = e.to <exec_aten::Layout>();
141
187
EXPECT_EQ (l, exec_aten::Layout::Strided);
142
188
}
143
189
144
- TEST (TestEValue , Device) {
190
+ TEST_F (EValueTest , Device) {
145
191
const EValue e ((int64_t )0 );
146
192
EXPECT_TRUE (e.isInt ());
147
193
const exec_aten::Device d = e.to <exec_aten::Device>();
148
194
EXPECT_TRUE (d.is_cpu ());
149
195
}
150
196
151
- TEST (TestEValue , BoxedEvalueList) {
197
+ TEST_F (EValueTest , BoxedEvalueList) {
152
198
// create fake values table to point to
153
199
EValue values[3 ] = {
154
200
EValue ((int64_t )1 ), EValue ((int64_t )2 ), EValue ((int64_t )3 )};
@@ -164,7 +210,7 @@ TEST(TestEValue, BoxedEvalueList) {
164
210
EXPECT_EQ (unwrapped[2 ], 3 );
165
211
}
166
212
167
- TEST (TestEValue , toOptionalTensorList) {
213
+ TEST_F (EValueTest , toOptionalTensorList) {
168
214
// create list, empty evalue ctor gets tag::None
169
215
EValue values[2 ] = {EValue (), EValue ()};
170
216
EValue* values_p[2 ] = {&values[0 ], &values[1 ]};
@@ -185,3 +231,51 @@ TEST(TestEValue, toOptionalTensorList) {
185
231
EXPECT_FALSE (x[0 ].has_value ());
186
232
EXPECT_FALSE (x[1 ].has_value ());
187
233
}
234
+
235
+ TEST_F (EValueTest, ConstructFromUniquePtr) {
236
+ TensorFactory<ScalarType::Float> tf;
237
+ auto tensor_ptr = std::make_unique<exec_aten::Tensor>(tf.ones ({2 , 3 }));
238
+
239
+ EValue evalue (std::move (tensor_ptr));
240
+
241
+ EXPECT_TRUE (evalue.isTensor ());
242
+ EXPECT_EQ (evalue.toTensor ().dim (), 2 );
243
+ EXPECT_EQ (evalue.toTensor ().numel (), 6 );
244
+
245
+ EValue evalue2 (std::make_unique<exec_aten::Tensor>(tf.ones ({4 , 5 })));
246
+
247
+ EXPECT_TRUE (evalue2.isTensor ());
248
+ EXPECT_EQ (evalue2.toTensor ().dim (), 2 );
249
+ EXPECT_EQ (evalue2.toTensor ().numel (), 20 );
250
+ }
251
+
252
+ TEST_F (EValueTest, ConstructFromSharedPtr) {
253
+ TensorFactory<ScalarType::Float> tf;
254
+ auto tensor_ptr = std::make_shared<exec_aten::Tensor>(tf.ones ({4 , 5 }));
255
+
256
+ EValue evalue (tensor_ptr);
257
+
258
+ EXPECT_TRUE (evalue.isTensor ());
259
+ EXPECT_EQ (evalue.toTensor ().dim (), 2 );
260
+ EXPECT_EQ (evalue.toTensor ().numel (), 20 );
261
+ }
262
+
263
+ TEST_F (EValueTest, ConstructFromTensorWrapper) {
264
+ TensorFactory<ScalarType::Float> tf;
265
+ TensorWrapper tensor_wrapper (tf.ones ({4 , 5 }));
266
+
267
+ EValue evalue (tensor_wrapper);
268
+
269
+ EXPECT_TRUE (evalue.isTensor ());
270
+ EXPECT_EQ (evalue.toTensor ().dim (), 2 );
271
+ EXPECT_EQ (evalue.toTensor ().numel (), 20 );
272
+ }
273
+
274
+ TEST_F (EValueTest, ConstructFromNullPtrAborts) {
275
+ std::unique_ptr<exec_aten::Tensor> null_ptr;
276
+
277
+ ET_EXPECT_DEATH ({ EValue evalue (null_ptr); }, " " );
278
+ }
279
+
280
+ } // namespace executor
281
+ } // namespace torch
0 commit comments