@@ -17,37 +17,37 @@ namespace executorch {
17
17
namespace extension {
18
18
namespace {
19
19
#ifndef USE_ATEN_LIB
20
- // No-op deleter that does nothing when called.
21
- static void noop_deleter (void *) {}
22
-
23
20
/* *
24
- * Custom deleter for TensorImplPtr that ensures the memory associated with
25
- * dynamic metadata (sizes, dim_order, and strides) is properly managed when the
26
- * TensorImpl is destroyed.
27
- *
28
- * Since TensorImpl does not own the metadata arrays (sizes, dim_order,
29
- * strides), this deleter is responsible for releasing that memory when the
30
- * TensorImpl is destroyed.
21
+ * A structure that consolidates the metadata (sizes, dim_order, strides) and
22
+ * the data buffer associated with a TensorImpl. Since TensorImpl does not own
23
+ * the memory for these metadata arrays or the data itself, this structure
24
+ * ensures that they are managed together and have the same lifetime as the
25
+ * TensorImpl. When the TensorImpl is destroyed, the Storage structure ensures
26
+ * proper cleanup of the associated metadata and data if needed.
31
27
*/
32
- struct TensorImplPtrDeleter final {
33
- // A custom deleter of the std::shared_ptr is required to be copyable until
34
- // C++20, so any data it holds must be copyable too. Hence, we use shared_ptr
35
- // to hold the data and metadata to avoid unnecessary copies.
36
- std::shared_ptr<void > data;
37
- std::shared_ptr<std::vector<exec_aten::SizesType>> sizes;
38
- std::shared_ptr<std::vector<exec_aten::DimOrderType>> dim_order;
39
- std::shared_ptr<std::vector<exec_aten::StridesType>> strides;
28
+ struct Storage final {
29
+ exec_aten::TensorImpl tensor_impl;
30
+ std::vector<exec_aten::SizesType> sizes;
31
+ std::vector<exec_aten::DimOrderType> dim_order;
32
+ std::vector<exec_aten::StridesType> strides;
33
+ std::function<void (void *)> deleter;
40
34
41
- void operator ()(exec_aten::TensorImpl* pointer) {
42
- // Release all resources immediately since the data held by the
43
- // TensorImplPtrDeleter is tied to the managed object, not the smart pointer
44
- // itself. We need to free this memory when the object is destroyed, not
45
- // when the smart pointer (and deleter) are eventually destroyed or reset.
46
- data.reset ();
47
- sizes.reset ();
48
- dim_order.reset ();
49
- strides.reset ();
50
- delete pointer;
35
+ Storage (
36
+ exec_aten::TensorImpl&& tensor_impl,
37
+ std::vector<exec_aten::SizesType>&& sizes,
38
+ std::vector<exec_aten::DimOrderType>&& dim_order,
39
+ std::vector<exec_aten::StridesType>&& strides,
40
+ std::function<void (void *)>&& deleter)
41
+ : tensor_impl(std::move(tensor_impl)),
42
+ sizes (std::move(sizes)),
43
+ dim_order(std::move(dim_order)),
44
+ strides(std::move(strides)),
45
+ deleter(std::move(deleter)) {}
46
+
47
+ ~Storage () {
48
+ if (deleter) {
49
+ deleter (tensor_impl.mutable_data ());
50
+ }
51
51
}
52
52
};
53
53
#endif // USE_ATEN_LIB
@@ -89,24 +89,23 @@ TensorImplPtr make_tensor_impl_ptr(
89
89
strides = std::move (computed_strides);
90
90
}
91
91
#ifndef USE_ATEN_LIB
92
- auto tensor_impl = std::make_unique< exec_aten::TensorImpl> (
92
+ exec_aten::TensorImpl tensor_impl (
93
93
type,
94
94
dim,
95
95
sizes.data (),
96
96
data,
97
97
dim_order.data (),
98
98
strides.data (),
99
99
dim > 0 ? dynamism : exec_aten::TensorShapeDynamism::STATIC);
100
- return TensorImplPtr (
101
- tensor_impl.release (),
102
- TensorImplPtrDeleter{
103
- std::shared_ptr<void >(
104
- data, deleter ? std::move (deleter) : noop_deleter),
105
- std::make_shared<std::vector<exec_aten::SizesType>>(std::move (sizes)),
106
- std::make_shared<std::vector<exec_aten::DimOrderType>>(
107
- std::move (dim_order)),
108
- std::make_shared<std::vector<exec_aten::StridesType>>(
109
- std::move (strides))});
100
+ auto storage = std::make_shared<Storage>(
101
+ std::move (tensor_impl),
102
+ std::move (sizes),
103
+ std::move (dim_order),
104
+ std::move (strides),
105
+ std::move (deleter));
106
+ const auto tensor_impl_ptr = &storage->tensor_impl ;
107
+ return std::shared_ptr<exec_aten::TensorImpl>(
108
+ std::move (storage), tensor_impl_ptr);
110
109
#else
111
110
auto options = c10::TensorOptions ()
112
111
.dtype (c10::scalarTypeToTypeMeta (type))
@@ -139,16 +138,16 @@ TensorImplPtr make_tensor_impl_ptr(
139
138
data.size () >= exec_aten::compute_numel (sizes.data (), sizes.size ()) *
140
139
exec_aten::elementSize (type),
141
140
" Data size is smaller than required by sizes and scalar type." );
142
- auto raw_data_ptr = data.data ();
143
- auto data_ptr = std::make_shared<std::vector<uint8_t >>(std::move (data));
141
+ auto data_ptr = data.data ();
144
142
return make_tensor_impl_ptr (
145
143
std::move (sizes),
146
- raw_data_ptr ,
144
+ data_ptr ,
147
145
std::move (dim_order),
148
146
std::move (strides),
149
147
type,
150
148
dynamism,
151
- [data_ptr = std::move (data_ptr)](void *) {});
149
+ // Data is moved into the deleter and is destroyed together with Storage.
150
+ [data = std::move (data)](void *) {});
152
151
}
153
152
154
153
} // namespace extension
0 commit comments