@@ -17,6 +17,9 @@ using namespace ::testing;
1717using executorch::runtime::HierarchicalAllocator;
1818using executorch::runtime::MemoryAllocator;
1919using executorch::runtime::MemoryManager;
20+ using executorch::runtime::Span;
21+ using executorch::runtime::etensor::Device;
22+ using executorch::runtime::etensor::DeviceType;
2023
2124TEST (MemoryManagerTest, MinimalCtor) {
2225 MemoryAllocator method_allocator (0 , nullptr );
@@ -93,3 +96,64 @@ TEST(MemoryManagerTest, CtorWithSameAllocator) {
9396 /* temp_allocator=*/ &method_allocator),
9497 " cannot be the same" );
9598}
99+
100+ TEST (MemoryManagerTest, ThreeArgCtorHasNoDeviceMemory) {
101+ MemoryAllocator method_allocator (0 , nullptr );
102+ HierarchicalAllocator planned_memory ({});
103+ MemoryAllocator temp_allocator (0 , nullptr );
104+
105+ MemoryManager mm (&method_allocator, &planned_memory, &temp_allocator);
106+
107+ EXPECT_FALSE (mm.has_device_memory ());
108+ EXPECT_EQ (mm.planned_buffer_devices ().size (), 0 );
109+ }
110+
111+ TEST (MemoryManagerTest, DelegatesDeviceMetadataToHierarchicalAllocator) {
112+ MemoryAllocator method_allocator (0 , nullptr );
113+ MemoryAllocator temp_allocator (0 , nullptr );
114+
115+ // 4 buffers: cpu:0, cpu:0, cuda:0, cuda:1. CPU buffers come first because
116+ // the runtime always sets up host-side planned memory before any device
117+ // buffers. The two CUDA entries use distinct indices to verify per-buffer
118+ // index tracking.
119+ constexpr size_t n_buffers = 4 ;
120+ uint8_t mem0[4 ];
121+ uint8_t mem1[4 ];
122+ uint8_t mem2[4 ];
123+ uint8_t mem3[4 ];
124+ Span<uint8_t > buffers[n_buffers]{
125+ {mem0, sizeof (mem0)},
126+ {mem1, sizeof (mem1)},
127+ {mem2, sizeof (mem2)},
128+ {mem3, sizeof (mem3)},
129+ };
130+ Device devices[] = {
131+ Device (DeviceType::CPU, 0 ),
132+ Device (DeviceType::CPU, 0 ),
133+ Device (DeviceType::CUDA, 0 ),
134+ Device (DeviceType::CUDA, 1 ),
135+ };
136+ Span<const Device> device_span (devices, n_buffers);
137+
138+ HierarchicalAllocator planned_memory ({buffers, n_buffers}, device_span);
139+ MemoryManager mm (&method_allocator, &planned_memory, &temp_allocator);
140+
141+ EXPECT_EQ (mm.method_allocator (), &method_allocator);
142+ EXPECT_EQ (mm.planned_memory (), &planned_memory);
143+ EXPECT_EQ (mm.temp_allocator (), &temp_allocator);
144+ EXPECT_TRUE (mm.has_device_memory ());
145+ EXPECT_EQ (mm.planned_buffer_devices ().size (), n_buffers);
146+ EXPECT_EQ (mm.planned_buffer_devices ()[0 ], Device (DeviceType::CPU, 0 ));
147+ EXPECT_EQ (mm.planned_buffer_devices ()[1 ], Device (DeviceType::CPU, 0 ));
148+ EXPECT_EQ (mm.planned_buffer_devices ()[2 ], Device (DeviceType::CUDA, 0 ));
149+ EXPECT_EQ (mm.planned_buffer_devices ()[3 ], Device (DeviceType::CUDA, 1 ));
150+ }
151+
152+ TEST (MemoryManagerTest, MinimalCtorHasNoDeviceMemory) {
153+ MemoryAllocator method_allocator (0 , nullptr );
154+
155+ MemoryManager mm (&method_allocator);
156+
157+ EXPECT_FALSE (mm.has_device_memory ());
158+ EXPECT_EQ (mm.planned_buffer_devices ().size (), 0 );
159+ }
0 commit comments