@@ -17,37 +17,37 @@ namespace executorch {
1717namespace extension {
1818namespace {
1919#ifndef USE_ATEN_LIB
20- // No-op deleter that does nothing when called.
21- static void noop_deleter (void *) {}
22-
2320/* *
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.
3127 */
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;
4034
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+ }
5151 }
5252};
5353#endif // USE_ATEN_LIB
@@ -89,24 +89,23 @@ TensorImplPtr make_tensor_impl_ptr(
8989 strides = std::move (computed_strides);
9090 }
9191#ifndef USE_ATEN_LIB
92- auto tensor_impl = std::make_unique< exec_aten::TensorImpl> (
92+ exec_aten::TensorImpl tensor_impl (
9393 type,
9494 dim,
9595 sizes.data (),
9696 data,
9797 dim_order.data (),
9898 strides.data (),
9999 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);
110109#else
111110 auto options = c10::TensorOptions ()
112111 .dtype (c10::scalarTypeToTypeMeta (type))
@@ -139,16 +138,16 @@ TensorImplPtr make_tensor_impl_ptr(
139138 data.size () >= exec_aten::compute_numel (sizes.data (), sizes.size ()) *
140139 exec_aten::elementSize (type),
141140 " 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 ();
144142 return make_tensor_impl_ptr (
145143 std::move (sizes),
146- raw_data_ptr ,
144+ data_ptr ,
147145 std::move (dim_order),
148146 std::move (strides),
149147 type,
150148 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 *) {});
152151}
153152
154153} // namespace extension
0 commit comments