Skip to content

Commit b8d7fb0

Browse files
committed
Fix alignment calculation in XNNWeightsCache
1 parent 019c8da commit b8d7fb0

File tree

1 file changed

+35
-9
lines changed

1 file changed

+35
-9
lines changed

backends/xnnpack/runtime/XNNWeightsCache.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <executorch/runtime/core/memory_allocator.h>
1212
#include <sys/stat.h>
1313
#include <xnnpack.h>
14+
#include <exception>
15+
#include <memory>
1416
#include <string>
1517
#include <vector>
1618

@@ -155,21 +157,45 @@ size_t XNNWeightsCache::look_up(
155157
return packed_weight_entry->second.offset;
156158
}
157159

160+
/**
161+
* Reserve space in the weight cache for n bytes of weight data, aligned to
162+
* context->kPackedAllocationAlignment. This function will return nullptr if
163+
* the allocation fails.
164+
*/
158165
void* XNNWeightsCache::reserve_space(XNNWeightsCache* context, size_t n) {
159166
// MemoryAllocator* allocator = context->runtime_allocator_;
160167
// void* reserved_pointer = allocator->allocate(n,
161168
// context->kPackedAllocationAlignment);
162169

163170
// return reserved_pointer;
164-
std::string data_container;
165-
data_container.resize(n + context->kPackedAllocationAlignment);
166-
void* maybe_aligned_space = data_container.data();
167-
void* aligned_space = (void*)((intptr_t)maybe_aligned_space + 64 -
168-
(intptr_t)maybe_aligned_space % 64);
169-
170-
context->packed_pointer_to_container_[aligned_space] =
171-
std::move(data_container);
172-
return aligned_space;
171+
try {
172+
std::string data_container;
173+
auto raw_allocation_size = n + context->kPackedAllocationAlignment;
174+
data_container.resize(raw_allocation_size);
175+
176+
void* maybe_aligned_space = data_container.data();
177+
void* aligned_space = std::align(
178+
context->kPackedAllocationAlignment,
179+
n,
180+
maybe_aligned_space,
181+
raw_allocation_size // Note that std::align mutates this value.
182+
);
183+
ET_CHECK(aligned_space != nullptr, "Memory alignment failed.");
184+
185+
context->packed_pointer_to_container_[aligned_space] =
186+
std::move(data_container);
187+
return aligned_space;
188+
} catch (std::exception& e) {
189+
// XNNPACK can gracefully handle allocation failures, so return nullptr.
190+
// We want to be able to recover from a failed attempt to load a large
191+
// model without a crash.
192+
ET_LOG(
193+
Error,
194+
"XNN weight cache failed to allocate %zu bytes: %s.",
195+
n,
196+
e.what());
197+
return nullptr;
198+
}
173199
}
174200

175201
size_t XNNWeightsCache::look_up_or_insert(

0 commit comments

Comments
 (0)