xref: /aosp_15_r20/external/executorch/extension/tensor/test/tensor_ptr_test.cpp (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 #include <executorch/extension/tensor/tensor_ptr.h>
10 
11 #include <gtest/gtest.h>
12 
13 #include <executorch/runtime/platform/runtime.h>
14 #include <executorch/test/utils/DeathTest.h>
15 
16 using namespace ::executorch::extension;
17 using namespace ::executorch::runtime;
18 
19 class TensorPtrTest : public ::testing::Test {
20  protected:
SetUpTestSuite()21   static void SetUpTestSuite() {
22     runtime_init();
23   }
24 };
25 
TEST_F(TensorPtrTest,ScalarTensorCreation)26 TEST_F(TensorPtrTest, ScalarTensorCreation) {
27   float scalar_data = 3.14f;
28   auto tensor = make_tensor_ptr({}, &scalar_data);
29 
30   EXPECT_EQ(tensor->numel(), 1);
31   EXPECT_EQ(tensor->dim(), 0);
32   EXPECT_EQ(tensor->sizes().size(), 0);
33   EXPECT_EQ(tensor->strides().size(), 0);
34   EXPECT_EQ(tensor->const_data_ptr<float>(), &scalar_data);
35   EXPECT_EQ(tensor->const_data_ptr<float>()[0], 3.14f);
36 }
37 
TEST_F(TensorPtrTest,ScalarTensorOwningData)38 TEST_F(TensorPtrTest, ScalarTensorOwningData) {
39   auto tensor = make_tensor_ptr({}, {3.14f});
40 
41   EXPECT_EQ(tensor->numel(), 1);
42   EXPECT_EQ(tensor->dim(), 0);
43   EXPECT_EQ(tensor->sizes().size(), 0);
44   EXPECT_EQ(tensor->strides().size(), 0);
45   EXPECT_EQ(tensor->const_data_ptr<float>()[0], 3.14f);
46 }
47 
TEST_F(TensorPtrTest,ScalarTensorSingleValueCreation)48 TEST_F(TensorPtrTest, ScalarTensorSingleValueCreation) {
49   auto tensor_float = make_tensor_ptr(3.14f);
50   EXPECT_EQ(tensor_float->dim(), 0);
51   EXPECT_EQ(tensor_float->numel(), 1);
52   EXPECT_EQ(tensor_float->sizes().size(), 0);
53   EXPECT_EQ(tensor_float->strides().size(), 0);
54   EXPECT_EQ(tensor_float->const_data_ptr<float>()[0], 3.14f);
55   EXPECT_EQ(tensor_float->scalar_type(), exec_aten::ScalarType::Float);
56 
57   auto tensor_int32 = make_tensor_ptr(42);
58   EXPECT_EQ(tensor_int32->dim(), 0);
59   EXPECT_EQ(tensor_int32->numel(), 1);
60   EXPECT_EQ(tensor_int32->sizes().size(), 0);
61   EXPECT_EQ(tensor_int32->strides().size(), 0);
62   EXPECT_EQ(tensor_int32->const_data_ptr<int32_t>()[0], 42);
63   EXPECT_EQ(tensor_int32->scalar_type(), exec_aten::ScalarType::Int);
64 
65   auto tensor_double = make_tensor_ptr(2.718);
66   EXPECT_EQ(tensor_double->dim(), 0);
67   EXPECT_EQ(tensor_double->numel(), 1);
68   EXPECT_EQ(tensor_double->sizes().size(), 0);
69   EXPECT_EQ(tensor_double->strides().size(), 0);
70   EXPECT_EQ(tensor_double->const_data_ptr<double>()[0], 2.718);
71   EXPECT_EQ(tensor_double->scalar_type(), exec_aten::ScalarType::Double);
72 
73   auto tensor_int64 = make_tensor_ptr(static_cast<int64_t>(10000000000));
74   EXPECT_EQ(tensor_int64->dim(), 0);
75   EXPECT_EQ(tensor_int64->numel(), 1);
76   EXPECT_EQ(tensor_int64->sizes().size(), 0);
77   EXPECT_EQ(tensor_int64->strides().size(), 0);
78   EXPECT_EQ(tensor_int64->const_data_ptr<int64_t>()[0], 10000000000);
79   EXPECT_EQ(tensor_int64->scalar_type(), exec_aten::ScalarType::Long);
80 }
81 
TEST_F(TensorPtrTest,CreateTensorWithStridesAndDimOrder)82 TEST_F(TensorPtrTest, CreateTensorWithStridesAndDimOrder) {
83   float data[20] = {2};
84   auto tensor = make_tensor_ptr({4, 5}, data, {0, 1}, {5, 1});
85   EXPECT_EQ(tensor->dim(), 2);
86   EXPECT_EQ(tensor->size(0), 4);
87   EXPECT_EQ(tensor->size(1), 5);
88   EXPECT_EQ(tensor->strides()[0], 5);
89   EXPECT_EQ(tensor->strides()[1], 1);
90   EXPECT_EQ(tensor->const_data_ptr<float>(), data);
91   EXPECT_EQ(tensor->const_data_ptr<float>()[0], 2);
92 }
93 
TEST_F(TensorPtrTest,TensorSharingImpl)94 TEST_F(TensorPtrTest, TensorSharingImpl) {
95   float data[20] = {2};
96   auto tensor1 = make_tensor_ptr({4, 5}, data);
97   auto tensor2 = tensor1;
98   EXPECT_EQ(tensor1.get(), tensor2.get());
99   EXPECT_EQ(tensor1->unsafeGetTensorImpl(), tensor2->unsafeGetTensorImpl());
100 }
101 
TEST_F(TensorPtrTest,TensorLifetime)102 TEST_F(TensorPtrTest, TensorLifetime) {
103   TensorPtr tensor;
104   EXPECT_EQ(tensor, nullptr);
105   {
106     float data[20] = {2};
107     tensor = make_tensor_ptr({4, 5}, data);
108   }
109   EXPECT_EQ(tensor->dim(), 2);
110   EXPECT_EQ(tensor->size(0), 4);
111   EXPECT_EQ(tensor->size(1), 5);
112 }
113 
TEST_F(TensorPtrTest,TensorWithZeroDimensionAndElements)114 TEST_F(TensorPtrTest, TensorWithZeroDimensionAndElements) {
115   float data[20] = {2};
116   auto tensor = make_tensor_ptr({}, data);
117   EXPECT_EQ(tensor->dim(), 0);
118   EXPECT_EQ(tensor->numel(), 1);
119   tensor = make_tensor_ptr({0, 5}, data);
120   EXPECT_EQ(tensor->dim(), 2);
121   EXPECT_EQ(tensor->numel(), 0);
122 }
123 
TEST_F(TensorPtrTest,TensorResize)124 TEST_F(TensorPtrTest, TensorResize) {
125   float data[20] = {2};
126   auto tensor = make_tensor_ptr(
127       {4, 5},
128       data,
129       {},
130       {},
131       exec_aten::ScalarType::Float,
132       exec_aten::TensorShapeDynamism::DYNAMIC_UNBOUND);
133   EXPECT_EQ(resize_tensor_ptr(tensor, {5, 4}), Error::Ok);
134   EXPECT_EQ(tensor->size(0), 5);
135   EXPECT_EQ(tensor->size(1), 4);
136 }
137 
TEST_F(TensorPtrTest,TensorDataAccess)138 TEST_F(TensorPtrTest, TensorDataAccess) {
139   float data[6] = {1, 2, 3, 4, 5, 6};
140   auto tensor = make_tensor_ptr({2, 3}, data);
141   EXPECT_EQ(tensor->const_data_ptr<float>()[0], 1);
142   EXPECT_EQ(tensor->const_data_ptr<float>()[5], 6);
143   tensor->mutable_data_ptr<float>()[0] = 10;
144   EXPECT_EQ(tensor->const_data_ptr<float>()[0], 10);
145 }
146 
TEST_F(TensorPtrTest,TensorWithCustomDataDeleter)147 TEST_F(TensorPtrTest, TensorWithCustomDataDeleter) {
148   auto deleter_called = false;
149   float* data = new float[20]();
150   auto tensor = make_tensor_ptr(
151       {4, 5},
152       data,
153       {},
154       {},
155       exec_aten::ScalarType::Float,
156       exec_aten::TensorShapeDynamism::DYNAMIC_BOUND,
157       [&deleter_called](void* ptr) {
158         deleter_called = true;
159         delete[] static_cast<float*>(ptr);
160       });
161 
162   tensor.reset();
163   EXPECT_TRUE(deleter_called);
164 }
165 
TEST_F(TensorPtrTest,TensorManagesMovedVector)166 TEST_F(TensorPtrTest, TensorManagesMovedVector) {
167   auto deleter_called = false;
168   std::vector<float> data(20, 3.0f);
169   auto* data_ptr = data.data();
170   auto tensor = make_tensor_ptr(
171       {4, 5},
172       data_ptr,
173       {},
174       {},
175       exec_aten::ScalarType::Float,
176       exec_aten::TensorShapeDynamism::DYNAMIC_BOUND,
177       [moved_data = std::move(data), &deleter_called](void*) mutable {
178         deleter_called = true;
179       });
180 
181   EXPECT_TRUE(data.empty()); // NOLINT(bugprone-use-after-move)
182   EXPECT_EQ(tensor->data_ptr<float>(), data_ptr);
183 
184   tensor.reset();
185   EXPECT_TRUE(deleter_called);
186 }
187 
TEST_F(TensorPtrTest,TensorDeleterReleasesCapturedSharedPtr)188 TEST_F(TensorPtrTest, TensorDeleterReleasesCapturedSharedPtr) {
189   auto deleter_called = false;
190   std::shared_ptr<float[]> data_ptr(
191       new float[10], [](float* ptr) { delete[] ptr; });
192   auto tensor = make_tensor_ptr(
193       {4, 5},
194       data_ptr.get(),
195       {},
196       {},
197       exec_aten::ScalarType::Float,
198       exec_aten::TensorShapeDynamism::DYNAMIC_BOUND,
199       [data_ptr, &deleter_called](void*) mutable { deleter_called = true; });
200 
201   EXPECT_EQ(data_ptr.use_count(), 2);
202 
203   tensor.reset();
204   EXPECT_TRUE(deleter_called);
205   EXPECT_EQ(data_ptr.use_count(), 1);
206 }
207 
TEST_F(TensorPtrTest,TensorOwningData)208 TEST_F(TensorPtrTest, TensorOwningData) {
209   auto tensor = make_tensor_ptr(
210       {2, 5},
211       {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f},
212       {1, 0},
213       {1, 2});
214 
215   EXPECT_EQ(tensor->dim(), 2);
216   EXPECT_EQ(tensor->size(0), 2);
217   EXPECT_EQ(tensor->size(1), 5);
218   EXPECT_EQ(tensor->strides()[0], 1);
219   EXPECT_EQ(tensor->strides()[1], 2);
220   EXPECT_EQ(tensor->const_data_ptr<float>()[0], 1.0f);
221   EXPECT_EQ(tensor->const_data_ptr<float>()[9], 10.0f);
222 }
223 
TEST_F(TensorPtrTest,TensorOwningEmptyData)224 TEST_F(TensorPtrTest, TensorOwningEmptyData) {
225   auto tensor = make_tensor_ptr({0, 5}, std::vector<float>());
226 
227   EXPECT_EQ(tensor->dim(), 2);
228   EXPECT_EQ(tensor->size(0), 0);
229   EXPECT_EQ(tensor->size(1), 5);
230   EXPECT_EQ(tensor->strides()[0], 5);
231   EXPECT_EQ(tensor->strides()[1], 1);
232   EXPECT_EQ(tensor->data_ptr<float>(), nullptr);
233   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Float);
234 }
235 
TEST_F(TensorPtrTest,TensorDataOnly)236 TEST_F(TensorPtrTest, TensorDataOnly) {
237   auto tensor = make_tensor_ptr({1.0f, 2.0f, 3.0f, 4.0f});
238 
239   EXPECT_EQ(tensor->dim(), 1);
240   EXPECT_EQ(tensor->size(0), 4);
241   EXPECT_EQ(tensor->strides()[0], 1);
242   EXPECT_EQ(tensor->const_data_ptr<float>()[0], 1.0);
243   EXPECT_EQ(tensor->const_data_ptr<float>()[3], 4.0);
244   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Float);
245 }
246 
TEST_F(TensorPtrTest,TensorDataOnlyDoubleType)247 TEST_F(TensorPtrTest, TensorDataOnlyDoubleType) {
248   std::vector<double> data = {1.0, 2.0, 3.0, 4.0};
249   auto tensor = make_tensor_ptr(std::move(data));
250 
251   EXPECT_EQ(tensor->dim(), 1);
252   EXPECT_EQ(tensor->size(0), 4);
253   EXPECT_EQ(tensor->strides()[0], 1);
254   EXPECT_EQ(tensor->const_data_ptr<double>()[0], 1.0);
255   EXPECT_EQ(tensor->const_data_ptr<double>()[3], 4.0);
256   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Double);
257 }
258 
TEST_F(TensorPtrTest,TensorDataOnlyInt32Type)259 TEST_F(TensorPtrTest, TensorDataOnlyInt32Type) {
260   std::vector<int32_t> data = {10, 20, 30, 40};
261   auto tensor = make_tensor_ptr(std::move(data));
262 
263   EXPECT_EQ(tensor->dim(), 1);
264   EXPECT_EQ(tensor->size(0), 4);
265   EXPECT_EQ(tensor->strides()[0], 1);
266   EXPECT_EQ(tensor->const_data_ptr<int32_t>()[0], 10);
267   EXPECT_EQ(tensor->const_data_ptr<int32_t>()[3], 40);
268   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Int);
269 }
270 
TEST_F(TensorPtrTest,TensorDataOnlyInt64Type)271 TEST_F(TensorPtrTest, TensorDataOnlyInt64Type) {
272   std::vector<int64_t> data = {100, 200, 300, 400};
273   auto tensor = make_tensor_ptr(std::move(data));
274 
275   EXPECT_EQ(tensor->dim(), 1);
276   EXPECT_EQ(tensor->size(0), 4);
277   EXPECT_EQ(tensor->strides()[0], 1);
278   EXPECT_EQ(tensor->const_data_ptr<int64_t>()[0], 100);
279   EXPECT_EQ(tensor->const_data_ptr<int64_t>()[3], 400);
280   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Long);
281 }
282 
TEST_F(TensorPtrTest,TensorDataOnlyUint8Type)283 TEST_F(TensorPtrTest, TensorDataOnlyUint8Type) {
284   std::vector<uint8_t> data = {10, 20, 30, 40};
285   auto tensor = make_tensor_ptr(std::move(data));
286 
287   EXPECT_EQ(tensor->dim(), 1);
288   EXPECT_EQ(tensor->size(0), 4);
289   EXPECT_EQ(tensor->strides()[0], 1);
290   EXPECT_EQ(tensor->const_data_ptr<uint8_t>()[0], 10);
291   EXPECT_EQ(tensor->const_data_ptr<uint8_t>()[3], 40);
292   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Byte);
293 }
294 
TEST_F(TensorPtrTest,TensorAmbiguityWithMixedVectors)295 TEST_F(TensorPtrTest, TensorAmbiguityWithMixedVectors) {
296   std::vector<exec_aten::SizesType> sizes = {2, 2};
297   std::vector<float> data = {1.0f, 2.0f, 3.0f, 4.0f};
298   auto tensor = make_tensor_ptr(std::move(sizes), std::move(data));
299 
300   EXPECT_EQ(tensor->dim(), 2);
301   EXPECT_EQ(tensor->size(0), 2);
302   EXPECT_EQ(tensor->size(1), 2);
303   EXPECT_EQ(tensor->strides()[0], 2);
304   EXPECT_EQ(tensor->strides()[1], 1);
305   EXPECT_EQ(tensor->const_data_ptr<float>()[0], 1.0f);
306   EXPECT_EQ(tensor->const_data_ptr<float>()[3], 4.0f);
307 
308   auto tensor2 = make_tensor_ptr({2, 2}, {1.0f, 2.0f, 3.0f, 4.0f});
309 
310   EXPECT_EQ(tensor2->dim(), 2);
311   EXPECT_EQ(tensor2->size(0), 2);
312   EXPECT_EQ(tensor2->size(1), 2);
313   EXPECT_EQ(tensor2->strides()[0], 2);
314   EXPECT_EQ(tensor2->strides()[1], 1);
315   EXPECT_EQ(tensor2->const_data_ptr<float>()[0], 1.0f);
316   EXPECT_EQ(tensor2->const_data_ptr<float>()[3], 4.0f);
317 }
318 
TEST_F(TensorPtrTest,TensorSharingImplModifiesSharedDataVector)319 TEST_F(TensorPtrTest, TensorSharingImplModifiesSharedDataVector) {
320   std::vector<float> data = {1, 2, 3, 4, 5, 6};
321 
322   auto tensor1 = make_tensor_ptr({2, 3}, std::move(data));
323   auto tensor2 = tensor1;
324 
325   tensor1->mutable_data_ptr<float>()[0] = 10;
326   EXPECT_EQ(tensor2->const_data_ptr<float>()[0], 10);
327 
328   tensor2->mutable_data_ptr<float>()[5] = 20;
329   EXPECT_EQ(tensor1->const_data_ptr<float>()[5], 20);
330 }
331 
TEST_F(TensorPtrTest,TensorSharingImplResizingAffectsBothVector)332 TEST_F(TensorPtrTest, TensorSharingImplResizingAffectsBothVector) {
333   std::vector<float> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
334 
335   auto tensor1 = make_tensor_ptr({3, 4}, std::move(data));
336   auto tensor2 = tensor1;
337 
338   EXPECT_EQ(resize_tensor_ptr(tensor1, {2, 6}), Error::Ok);
339   EXPECT_EQ(tensor2->size(0), 2);
340   EXPECT_EQ(tensor2->size(1), 6);
341 
342   EXPECT_EQ(resize_tensor_ptr(tensor2, {4, 3}), Error::Ok);
343   EXPECT_EQ(tensor1->size(0), 4);
344   EXPECT_EQ(tensor1->size(1), 3);
345 }
346 
TEST_F(TensorPtrTest,MakeTensorPtrFromExistingTensorInt32)347 TEST_F(TensorPtrTest, MakeTensorPtrFromExistingTensorInt32) {
348   std::vector<int32_t> data = {1, 2, 3, 4};
349   auto tensor = make_tensor_ptr({2, 2}, data);
350   auto new_tensor = make_tensor_ptr(*tensor);
351 
352   EXPECT_EQ(new_tensor->dim(), tensor->dim());
353   EXPECT_EQ(new_tensor->size(0), tensor->size(0));
354   EXPECT_EQ(new_tensor->size(1), tensor->size(1));
355   EXPECT_EQ(
356       new_tensor->const_data_ptr<int32_t>(), tensor->const_data_ptr<int32_t>());
357   EXPECT_EQ(new_tensor->scalar_type(), exec_aten::ScalarType::Int);
358 }
359 
TEST_F(TensorPtrTest,CloneTensorPtrFromExistingTensorInt32)360 TEST_F(TensorPtrTest, CloneTensorPtrFromExistingTensorInt32) {
361   std::vector<int32_t> data = {1, 2, 3, 4};
362   auto tensor = make_tensor_ptr({2, 2}, std::move(data));
363   auto cloned_tensor = clone_tensor_ptr(*tensor);
364 
365   EXPECT_EQ(cloned_tensor->dim(), tensor->dim());
366   EXPECT_EQ(cloned_tensor->size(0), tensor->size(0));
367   EXPECT_EQ(cloned_tensor->size(1), tensor->size(1));
368   EXPECT_NE(
369       cloned_tensor->const_data_ptr<int32_t>(),
370       tensor->const_data_ptr<int32_t>());
371   EXPECT_EQ(cloned_tensor->const_data_ptr<int32_t>()[0], 1);
372   EXPECT_EQ(cloned_tensor->const_data_ptr<int32_t>()[3], 4);
373   EXPECT_EQ(cloned_tensor->scalar_type(), exec_aten::ScalarType::Int);
374 }
375 
TEST_F(TensorPtrTest,CloneTensorPtrFromTensorPtrInt32)376 TEST_F(TensorPtrTest, CloneTensorPtrFromTensorPtrInt32) {
377   std::vector<int32_t> data = {1, 2, 3, 4};
378   auto tensor = make_tensor_ptr({2, 2}, std::move(data));
379   auto cloned_tensor = clone_tensor_ptr(tensor);
380 
381   EXPECT_EQ(cloned_tensor->dim(), tensor->dim());
382   EXPECT_EQ(cloned_tensor->size(0), tensor->size(0));
383   EXPECT_EQ(cloned_tensor->size(1), tensor->size(1));
384   EXPECT_NE(
385       cloned_tensor->const_data_ptr<int32_t>(),
386       tensor->const_data_ptr<int32_t>());
387   EXPECT_EQ(cloned_tensor->const_data_ptr<int32_t>()[0], 1);
388   EXPECT_EQ(cloned_tensor->const_data_ptr<int32_t>()[3], 4);
389   EXPECT_EQ(cloned_tensor->scalar_type(), exec_aten::ScalarType::Int);
390 }
391 
TEST_F(TensorPtrTest,MakeTensorPtrFromExistingTensorDouble)392 TEST_F(TensorPtrTest, MakeTensorPtrFromExistingTensorDouble) {
393   std::vector<double> data = {1.0, 2.0, 3.0, 4.0};
394   auto tensor = make_tensor_ptr({2, 2}, data);
395   auto new_tensor = make_tensor_ptr(*tensor);
396 
397   EXPECT_EQ(new_tensor->dim(), tensor->dim());
398   EXPECT_EQ(new_tensor->size(0), tensor->size(0));
399   EXPECT_EQ(new_tensor->size(1), tensor->size(1));
400   EXPECT_EQ(
401       new_tensor->const_data_ptr<double>(), tensor->const_data_ptr<double>());
402   EXPECT_EQ(new_tensor->scalar_type(), exec_aten::ScalarType::Double);
403 }
404 
TEST_F(TensorPtrTest,CloneTensorPtrFromExistingTensorDouble)405 TEST_F(TensorPtrTest, CloneTensorPtrFromExistingTensorDouble) {
406   std::vector<double> data = {1.0, 2.0, 3.0, 4.0};
407   auto tensor = make_tensor_ptr({2, 2}, std::move(data));
408   auto cloned_tensor = clone_tensor_ptr(*tensor);
409 
410   EXPECT_EQ(cloned_tensor->dim(), tensor->dim());
411   EXPECT_EQ(cloned_tensor->size(0), tensor->size(0));
412   EXPECT_EQ(cloned_tensor->size(1), tensor->size(1));
413   EXPECT_NE(
414       cloned_tensor->const_data_ptr<double>(),
415       tensor->const_data_ptr<double>());
416   EXPECT_EQ(cloned_tensor->const_data_ptr<double>()[0], 1.0);
417   EXPECT_EQ(cloned_tensor->const_data_ptr<double>()[3], 4.0);
418   EXPECT_EQ(cloned_tensor->scalar_type(), exec_aten::ScalarType::Double);
419 }
420 
TEST_F(TensorPtrTest,CloneTensorPtrFromTensorPtrDouble)421 TEST_F(TensorPtrTest, CloneTensorPtrFromTensorPtrDouble) {
422   std::vector<double> data = {1.0, 2.0, 3.0, 4.0};
423   auto tensor = make_tensor_ptr({2, 2}, std::move(data));
424   auto cloned_tensor = clone_tensor_ptr(tensor);
425 
426   EXPECT_EQ(cloned_tensor->dim(), tensor->dim());
427   EXPECT_EQ(cloned_tensor->size(0), tensor->size(0));
428   EXPECT_EQ(cloned_tensor->size(1), tensor->size(1));
429   EXPECT_NE(
430       cloned_tensor->const_data_ptr<double>(),
431       tensor->const_data_ptr<double>());
432   EXPECT_EQ(cloned_tensor->const_data_ptr<double>()[0], 1.0);
433   EXPECT_EQ(cloned_tensor->const_data_ptr<double>()[3], 4.0);
434   EXPECT_EQ(cloned_tensor->scalar_type(), exec_aten::ScalarType::Double);
435 }
436 
TEST_F(TensorPtrTest,MakeTensorPtrFromExistingTensorInt64)437 TEST_F(TensorPtrTest, MakeTensorPtrFromExistingTensorInt64) {
438   std::vector<int64_t> data = {100, 200, 300, 400};
439   auto tensor = make_tensor_ptr({2, 2}, data);
440   auto new_tensor = make_tensor_ptr(*tensor);
441 
442   EXPECT_EQ(new_tensor->dim(), tensor->dim());
443   EXPECT_EQ(new_tensor->size(0), tensor->size(0));
444   EXPECT_EQ(new_tensor->size(1), tensor->size(1));
445   EXPECT_EQ(
446       new_tensor->const_data_ptr<int64_t>(), tensor->const_data_ptr<int64_t>());
447   EXPECT_EQ(new_tensor->scalar_type(), exec_aten::ScalarType::Long);
448 }
449 
TEST_F(TensorPtrTest,CloneTensorPtrFromExistingTensorInt64)450 TEST_F(TensorPtrTest, CloneTensorPtrFromExistingTensorInt64) {
451   std::vector<int64_t> data = {100, 200, 300, 400};
452   auto tensor = make_tensor_ptr({2, 2}, std::move(data));
453   auto cloned_tensor = clone_tensor_ptr(*tensor);
454 
455   EXPECT_EQ(cloned_tensor->dim(), tensor->dim());
456   EXPECT_EQ(cloned_tensor->size(0), tensor->size(0));
457   EXPECT_EQ(cloned_tensor->size(1), tensor->size(1));
458   EXPECT_NE(
459       cloned_tensor->const_data_ptr<int64_t>(),
460       tensor->const_data_ptr<int64_t>());
461   EXPECT_EQ(cloned_tensor->const_data_ptr<int64_t>()[0], 100);
462   EXPECT_EQ(cloned_tensor->const_data_ptr<int64_t>()[3], 400);
463   EXPECT_EQ(cloned_tensor->scalar_type(), exec_aten::ScalarType::Long);
464 }
465 
TEST_F(TensorPtrTest,CloneTensorPtrFromTensorPtrInt64)466 TEST_F(TensorPtrTest, CloneTensorPtrFromTensorPtrInt64) {
467   std::vector<int64_t> data = {100, 200, 300, 400};
468   auto tensor = make_tensor_ptr({2, 2}, std::move(data));
469   auto cloned_tensor = clone_tensor_ptr(tensor);
470 
471   EXPECT_EQ(cloned_tensor->dim(), tensor->dim());
472   EXPECT_EQ(cloned_tensor->size(0), tensor->size(0));
473   EXPECT_EQ(cloned_tensor->size(1), tensor->size(1));
474   EXPECT_NE(
475       cloned_tensor->const_data_ptr<int64_t>(),
476       tensor->const_data_ptr<int64_t>());
477   EXPECT_EQ(cloned_tensor->const_data_ptr<int64_t>()[0], 100);
478   EXPECT_EQ(cloned_tensor->const_data_ptr<int64_t>()[3], 400);
479   EXPECT_EQ(cloned_tensor->scalar_type(), exec_aten::ScalarType::Long);
480 }
481 
TEST_F(TensorPtrTest,CloneTensorPtrFromTensorPtrNull)482 TEST_F(TensorPtrTest, CloneTensorPtrFromTensorPtrNull) {
483   auto tensor = make_tensor_ptr({2, 2}, nullptr);
484   auto cloned_tensor = clone_tensor_ptr(tensor);
485 
486   EXPECT_EQ(cloned_tensor->dim(), tensor->dim());
487   EXPECT_EQ(cloned_tensor->size(0), tensor->size(0));
488   EXPECT_EQ(cloned_tensor->size(1), tensor->size(1));
489   EXPECT_EQ(cloned_tensor->const_data_ptr(), tensor->const_data_ptr());
490   EXPECT_EQ(cloned_tensor->const_data_ptr(), nullptr);
491 }
492 
TEST_F(TensorPtrTest,TensorDataCastingFromIntToFloat)493 TEST_F(TensorPtrTest, TensorDataCastingFromIntToFloat) {
494   std::vector<int32_t> int_data = {1, 2, 3, 4, 5, 6};
495   auto tensor = make_tensor_ptr(
496       {2, 3}, std::move(int_data), {}, {}, exec_aten::ScalarType::Float);
497 
498   EXPECT_EQ(tensor->dim(), 2);
499   EXPECT_EQ(tensor->size(0), 2);
500   EXPECT_EQ(tensor->size(1), 3);
501   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Float);
502 
503   auto data_ptr = tensor->const_data_ptr<float>();
504   EXPECT_FLOAT_EQ(data_ptr[0], 1.0f);
505   EXPECT_FLOAT_EQ(data_ptr[5], 6.0f);
506 }
507 
TEST_F(TensorPtrTest,TensorDataCastingFromIntToDouble)508 TEST_F(TensorPtrTest, TensorDataCastingFromIntToDouble) {
509   std::vector<int32_t> int_data = {1, 2, 3};
510   auto tensor =
511       make_tensor_ptr(std::move(int_data), exec_aten::ScalarType::Double);
512 
513   EXPECT_EQ(tensor->dim(), 1);
514   EXPECT_EQ(tensor->size(0), 3);
515   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Double);
516 
517   auto data_ptr = tensor->const_data_ptr<double>();
518   EXPECT_DOUBLE_EQ(data_ptr[0], 1.0);
519   EXPECT_DOUBLE_EQ(data_ptr[1], 2.0);
520   EXPECT_DOUBLE_EQ(data_ptr[2], 3.0);
521 }
522 
TEST_F(TensorPtrTest,TensorDataCastingFromFloatToHalf)523 TEST_F(TensorPtrTest, TensorDataCastingFromFloatToHalf) {
524   std::vector<float> float_data = {1.0f, 2.0f, 3.0f};
525   auto tensor =
526       make_tensor_ptr(std::move(float_data), exec_aten::ScalarType::Half);
527 
528   EXPECT_EQ(tensor->dim(), 1);
529   EXPECT_EQ(tensor->size(0), 3);
530   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Half);
531 
532   auto data_ptr = tensor->const_data_ptr<exec_aten::Half>();
533   EXPECT_EQ(static_cast<float>(data_ptr[0]), 1.0f);
534   EXPECT_EQ(static_cast<float>(data_ptr[1]), 2.0f);
535   EXPECT_EQ(static_cast<float>(data_ptr[2]), 3.0f);
536 }
537 
TEST_F(TensorPtrTest,TensorDataCastingFromDoubleToFloat)538 TEST_F(TensorPtrTest, TensorDataCastingFromDoubleToFloat) {
539   std::vector<double> double_data = {1.1, 2.2, 3.3};
540   auto tensor =
541       make_tensor_ptr(std::move(double_data), exec_aten::ScalarType::Float);
542 
543   EXPECT_EQ(tensor->dim(), 1);
544   EXPECT_EQ(tensor->size(0), 3);
545   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Float);
546 
547   auto data_ptr = tensor->const_data_ptr<float>();
548   EXPECT_FLOAT_EQ(data_ptr[0], 1.1f);
549   EXPECT_FLOAT_EQ(data_ptr[1], 2.2f);
550   EXPECT_FLOAT_EQ(data_ptr[2], 3.3f);
551 }
552 
TEST_F(TensorPtrTest,TensorDataCastingFromInt64ToInt32)553 TEST_F(TensorPtrTest, TensorDataCastingFromInt64ToInt32) {
554   std::vector<int64_t> int64_data = {10000000000, 20000000000, 30000000000};
555   auto tensor =
556       make_tensor_ptr(std::move(int64_data), exec_aten::ScalarType::Int);
557 
558   EXPECT_EQ(tensor->dim(), 1);
559   EXPECT_EQ(tensor->size(0), 3);
560   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Int);
561 
562   auto data_ptr = tensor->const_data_ptr<int32_t>();
563   EXPECT_NE(data_ptr[0], 10000000000); // Expected overflow
564 }
565 
TEST_F(TensorPtrTest,TensorDataCastingFromFloatToBFloat16)566 TEST_F(TensorPtrTest, TensorDataCastingFromFloatToBFloat16) {
567   std::vector<float> float_data = {1.0f, 2.0f, 3.0f};
568   auto tensor =
569       make_tensor_ptr(std::move(float_data), exec_aten::ScalarType::BFloat16);
570 
571   EXPECT_EQ(tensor->dim(), 1);
572   EXPECT_EQ(tensor->size(0), 3);
573   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::BFloat16);
574 
575   auto data_ptr = tensor->const_data_ptr<exec_aten::BFloat16>();
576   EXPECT_EQ(static_cast<float>(data_ptr[0]), 1.0f);
577   EXPECT_EQ(static_cast<float>(data_ptr[1]), 2.0f);
578   EXPECT_EQ(static_cast<float>(data_ptr[2]), 3.0f);
579 }
580 
TEST_F(TensorPtrTest,InitializerListDoubleToHalf)581 TEST_F(TensorPtrTest, InitializerListDoubleToHalf) {
582   auto tensor =
583       make_tensor_ptr<double>({1.5, 2.7, 3.14}, exec_aten::ScalarType::Half);
584   EXPECT_EQ(tensor->dim(), 1);
585   EXPECT_EQ(tensor->size(0), 3);
586   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Half);
587 
588   auto data_ptr = tensor->const_data_ptr<exec_aten::Half>();
589   EXPECT_NEAR(static_cast<float>(data_ptr[0]), 1.5f, 0.01);
590   EXPECT_NEAR(static_cast<float>(data_ptr[1]), 2.7f, 0.01);
591   EXPECT_NEAR(static_cast<float>(data_ptr[2]), 3.14f, 0.01);
592 }
593 
TEST_F(TensorPtrTest,InitializerListInt8ToInt64)594 TEST_F(TensorPtrTest, InitializerListInt8ToInt64) {
595   auto tensor =
596       make_tensor_ptr<int8_t>({1, -2, 3, -4}, exec_aten::ScalarType::Long);
597   EXPECT_EQ(tensor->dim(), 1);
598   EXPECT_EQ(tensor->size(0), 4);
599   EXPECT_EQ(tensor->scalar_type(), exec_aten::ScalarType::Long);
600 
601   auto data_ptr = tensor->const_data_ptr<int64_t>();
602   EXPECT_EQ(data_ptr[0], 1);
603   EXPECT_EQ(data_ptr[1], -2);
604   EXPECT_EQ(data_ptr[2], 3);
605   EXPECT_EQ(data_ptr[3], -4);
606 }
607 
TEST_F(TensorPtrTest,TensorInferredDimOrderAndStrides)608 TEST_F(TensorPtrTest, TensorInferredDimOrderAndStrides) {
609   float data[12] = {0};
610   auto tensor = make_tensor_ptr({3, 4}, data, {}, {4, 1});
611 
612   EXPECT_EQ(tensor->dim(), 2);
613   EXPECT_EQ(tensor->size(0), 3);
614   EXPECT_EQ(tensor->size(1), 4);
615   EXPECT_EQ(tensor->strides()[0], 4);
616   EXPECT_EQ(tensor->strides()[1], 1);
617   EXPECT_EQ(tensor->const_data_ptr(), data);
618 }
619 
TEST_F(TensorPtrTest,TensorInferredDimOrderCustomStrides)620 TEST_F(TensorPtrTest, TensorInferredDimOrderCustomStrides) {
621   float data[12] = {0};
622   auto tensor = make_tensor_ptr({3, 4}, data, {}, {1, 3});
623 
624   EXPECT_EQ(tensor->dim(), 2);
625   EXPECT_EQ(tensor->size(0), 3);
626   EXPECT_EQ(tensor->size(1), 4);
627   EXPECT_EQ(tensor->strides()[0], 1);
628   EXPECT_EQ(tensor->strides()[1], 3);
629 }
630 
TEST_F(TensorPtrTest,TensorDefaultDimOrderAndStrides)631 TEST_F(TensorPtrTest, TensorDefaultDimOrderAndStrides) {
632   float data[24] = {0};
633   auto tensor = make_tensor_ptr({2, 3, 4}, data);
634 
635   EXPECT_EQ(tensor->dim(), 3);
636   EXPECT_EQ(tensor->size(0), 2);
637   EXPECT_EQ(tensor->size(1), 3);
638   EXPECT_EQ(tensor->size(2), 4);
639   EXPECT_EQ(tensor->strides()[0], 12);
640   EXPECT_EQ(tensor->strides()[1], 4);
641   EXPECT_EQ(tensor->strides()[2], 1);
642 }
643 
TEST_F(TensorPtrTest,TensorMismatchStridesAndDimOrder)644 TEST_F(TensorPtrTest, TensorMismatchStridesAndDimOrder) {
645   float data[12] = {0};
646   ET_EXPECT_DEATH(
647       { auto _ = make_tensor_ptr({3, 4}, data, {1, 0}, {1, 4}); }, "");
648 }
649 
TEST_F(TensorPtrTest,TensorCustomDimOrderAndStrides)650 TEST_F(TensorPtrTest, TensorCustomDimOrderAndStrides) {
651   float data[12] = {0};
652   auto tensor = make_tensor_ptr({3, 4}, data, {1, 0}, {1, 3});
653 
654   EXPECT_EQ(tensor->dim(), 2);
655   EXPECT_EQ(tensor->size(0), 3);
656   EXPECT_EQ(tensor->size(1), 4);
657   EXPECT_EQ(tensor->strides()[0], 1);
658   EXPECT_EQ(tensor->strides()[1], 3);
659 }
660 
TEST_F(TensorPtrTest,TensorInvalidDimOrder)661 TEST_F(TensorPtrTest, TensorInvalidDimOrder) {
662   ET_EXPECT_DEATH(
663       {
664         float data[20] = {2};
665         auto _ = make_tensor_ptr({4, 5}, data, {2, 1}, {1, 4});
666       },
667       "");
668 }
669 
TEST_F(TensorPtrTest,TensorCustomDeleter)670 TEST_F(TensorPtrTest, TensorCustomDeleter) {
671   float data[20] = {4};
672   auto tensor = make_tensor_ptr({4, 5}, data);
673 
674   TensorPtr copied_tensor = tensor;
675   EXPECT_EQ(tensor.use_count(), copied_tensor.use_count());
676 
677   tensor.reset();
678   EXPECT_EQ(copied_tensor.use_count(), 1);
679 }
680 
TEST_F(TensorPtrTest,TensorDataDeleterReleasesCapturedSharedPtr)681 TEST_F(TensorPtrTest, TensorDataDeleterReleasesCapturedSharedPtr) {
682   auto deleter_called = false;
683   std::shared_ptr<float[]> data_ptr(
684       new float[10], [](float* ptr) { delete[] ptr; });
685   auto tensor = make_tensor_ptr(
686       {4, 5},
687       data_ptr.get(),
688       {},
689       {},
690       exec_aten::ScalarType::Float,
691       exec_aten::TensorShapeDynamism::DYNAMIC_BOUND,
692       [data_ptr, &deleter_called](void*) mutable { deleter_called = true; });
693 
694   EXPECT_EQ(data_ptr.use_count(), 2);
695 
696   tensor.reset();
697   EXPECT_TRUE(deleter_called);
698   EXPECT_EQ(data_ptr.use_count(), 1);
699 }
700 
TEST_F(TensorPtrTest,SharedDataManagement)701 TEST_F(TensorPtrTest, SharedDataManagement) {
702   auto data = std::make_shared<std::vector<float>>(100, 1.0f);
703   auto tensor1 = make_tensor_ptr({10, 10}, data->data());
704   auto tensor2 = tensor1;
705 
706   EXPECT_EQ(tensor1.get(), tensor2.get());
707   EXPECT_EQ(tensor1.use_count(), 2);
708   EXPECT_EQ(tensor1->const_data_ptr<float>()[0], 1.0f);
709 
710   tensor1->mutable_data_ptr<float>()[0] = 2.0f;
711   EXPECT_EQ(tensor1->const_data_ptr<float>()[0], 2.0f);
712 
713   tensor1.reset();
714   EXPECT_NE(tensor2.get(), nullptr);
715   EXPECT_EQ(tensor2.use_count(), 1);
716 
717   EXPECT_EQ(tensor2->const_data_ptr<float>()[0], 2.0f);
718 }
719 
TEST_F(TensorPtrTest,CustomDeleterWithSharedData)720 TEST_F(TensorPtrTest, CustomDeleterWithSharedData) {
721   auto data = std::make_shared<std::vector<float>>(100, 1.0f);
722   bool deleter_called = false;
723   {
724     auto tensor = make_tensor_ptr(
725         {10, 10},
726         data->data(),
727         {},
728         {},
729         exec_aten::ScalarType::Float,
730         exec_aten::TensorShapeDynamism::DYNAMIC_BOUND,
731         [data, &deleter_called](void*) mutable {
732           deleter_called = true;
733           data.reset();
734         });
735 
736     EXPECT_EQ(data.use_count(), 2);
737     EXPECT_FALSE(deleter_called);
738   }
739   EXPECT_TRUE(deleter_called);
740   EXPECT_EQ(data.use_count(), 1);
741 }
742 
TEST_F(TensorPtrTest,TensorDeducedScalarType)743 TEST_F(TensorPtrTest, TensorDeducedScalarType) {
744   std::vector<double> data = {1.0, 2.0, 3.0, 4.0};
745   auto tensor = make_tensor_ptr({2, 2}, std::move(data));
746 
747   EXPECT_EQ(tensor->dim(), 2);
748   EXPECT_EQ(tensor->size(0), 2);
749   EXPECT_EQ(tensor->size(1), 2);
750   EXPECT_EQ(tensor->strides()[0], 2);
751   EXPECT_EQ(tensor->strides()[1], 1);
752   EXPECT_EQ(tensor->const_data_ptr<double>()[0], 1.0);
753   EXPECT_EQ(tensor->const_data_ptr<double>()[3], 4.0);
754 }
755 
TEST_F(TensorPtrTest,TensorUint8BufferWithFloatScalarType)756 TEST_F(TensorPtrTest, TensorUint8BufferWithFloatScalarType) {
757   std::vector<uint8_t> data(
758       4 * exec_aten::elementSize(exec_aten::ScalarType::Float));
759 
760   float* float_data = reinterpret_cast<float*>(data.data());
761   float_data[0] = 1.0f;
762   float_data[1] = 2.0f;
763   float_data[2] = 3.0f;
764   float_data[3] = 4.0f;
765 
766   auto tensor = make_tensor_ptr({2, 2}, std::move(data));
767 
768   EXPECT_EQ(tensor->dim(), 2);
769   EXPECT_EQ(tensor->size(0), 2);
770   EXPECT_EQ(tensor->size(1), 2);
771   EXPECT_EQ(tensor->strides()[0], 2);
772   EXPECT_EQ(tensor->strides()[1], 1);
773 
774   EXPECT_EQ(tensor->const_data_ptr<float>()[0], 1.0f);
775   EXPECT_EQ(tensor->const_data_ptr<float>()[1], 2.0f);
776   EXPECT_EQ(tensor->const_data_ptr<float>()[2], 3.0f);
777   EXPECT_EQ(tensor->const_data_ptr<float>()[3], 4.0f);
778 }
779 
TEST_F(TensorPtrTest,TensorUint8BufferTooSmallExpectDeath)780 TEST_F(TensorPtrTest, TensorUint8BufferTooSmallExpectDeath) {
781   std::vector<uint8_t> data(
782       2 * exec_aten::elementSize(exec_aten::ScalarType::Float));
783   ET_EXPECT_DEATH(
784       { auto tensor = make_tensor_ptr({2, 2}, std::move(data)); }, "");
785 }
786 
TEST_F(TensorPtrTest,TensorUint8BufferTooLarge)787 TEST_F(TensorPtrTest, TensorUint8BufferTooLarge) {
788   std::vector<uint8_t> data(
789       4 * exec_aten::elementSize(exec_aten::ScalarType::Float));
790   auto tensor = make_tensor_ptr({2, 2}, std::move(data));
791 
792   EXPECT_EQ(tensor->dim(), 2);
793   EXPECT_EQ(tensor->size(0), 2);
794   EXPECT_EQ(tensor->size(1), 2);
795   EXPECT_EQ(tensor->strides()[0], 2);
796   EXPECT_EQ(tensor->strides()[1], 1);
797 }
798 
TEST_F(TensorPtrTest,StridesAndDimOrderMustMatchSizes)799 TEST_F(TensorPtrTest, StridesAndDimOrderMustMatchSizes) {
800   float data[12] = {0};
801   ET_EXPECT_DEATH({ auto _ = make_tensor_ptr({3, 4}, data, {}, {1}); }, "");
802   ET_EXPECT_DEATH({ auto _ = make_tensor_ptr({3, 4}, data, {0}, {4, 1}); }, "");
803 }
804 
TEST_F(TensorPtrTest,TensorDataCastingInvalidCast)805 TEST_F(TensorPtrTest, TensorDataCastingInvalidCast) {
806   std::vector<float> float_data = {1.0f, 2.0f, 3.0f};
807   ET_EXPECT_DEATH(
808       {
809         auto _ =
810             make_tensor_ptr(std::move(float_data), exec_aten::ScalarType::Int);
811       },
812       "");
813 }
814