diff --git a/tensorflow/lite/core/api/flatbuffer_conversions.h b/tensorflow/lite/core/api/flatbuffer_conversions.h index 070705fee13..d774afe8e85 100644 --- a/tensorflow/lite/core/api/flatbuffer_conversions.h +++ b/tensorflow/lite/core/api/flatbuffer_conversions.h @@ -29,7 +29,7 @@ namespace tflite { // Interface class for builtin data allocations. class BuiltinDataAllocator { public: - virtual void* Allocate(size_t size) = 0; + virtual void* Allocate(size_t size, size_t alignment_hint) = 0; virtual void Deallocate(void* data) = 0; // Allocate a structure, but make sure it is a POD structure that doesn't @@ -41,7 +41,7 @@ class BuiltinDataAllocator { // TODO(b/154346074): Change this to is_trivially_destructible when all // platform targets support that properly. static_assert(std::is_pod::value, "Builtin data structure must be POD."); - void* allocated_memory = this->Allocate(sizeof(T)); + void* allocated_memory = this->Allocate(sizeof(T), alignof(T)); return new (allocated_memory) T; } diff --git a/tensorflow/lite/core/api/flatbuffer_conversions_test.cc b/tensorflow/lite/core/api/flatbuffer_conversions_test.cc index 24d7ec97e42..89ca3f566ec 100644 --- a/tensorflow/lite/core/api/flatbuffer_conversions_test.cc +++ b/tensorflow/lite/core/api/flatbuffer_conversions_test.cc @@ -47,7 +47,7 @@ class MockErrorReporter : public ErrorReporter { class MockDataAllocator : public BuiltinDataAllocator { public: MockDataAllocator() : is_allocated_(false) {} - void* Allocate(size_t size) override { + void* Allocate(size_t size, size_t alignment_hint) override { EXPECT_FALSE(is_allocated_); const int max_size = kBufferSize; EXPECT_LE(size, max_size); diff --git a/tensorflow/lite/interpreter_builder.cc b/tensorflow/lite/interpreter_builder.cc index 65f4b8e547f..9426bdd94dc 100644 --- a/tensorflow/lite/interpreter_builder.cc +++ b/tensorflow/lite/interpreter_builder.cc @@ -34,6 +34,15 @@ limitations under the License. #include "tensorflow/lite/profiling/platform_profiler.h" #endif +// aligned_alloc is available (via cstdlib/stdlib.h) with C++17/C11. +#if __cplusplus >= 201703L || __STDC_VERSION__ >= 201112L +#if !defined(__ANDROID__) || __ANDROID_API__ >= 28 +#if !defined(__APPLE__) // Apple does not provide aligned_alloc. +#define TFLITE_USE_STD_ALIGNED_ALLOC +#endif +#endif +#endif + namespace tflite { namespace { @@ -197,7 +206,13 @@ std::vector FlatBufferIntArrayToVector(T* flat_array) { // Used to determine how the op data parsing function creates its working space. class MallocDataAllocator : public BuiltinDataAllocator { public: - void* Allocate(size_t size) override { return malloc(size); } + void* Allocate(size_t size, size_t alignment_hint) override { +#ifdef TFLITE_USE_STD_ALIGNED_ALLOC + return aligned_alloc(alignment_hint, size); +#else + return malloc(size); +#endif + } void Deallocate(void* data) override { free(data); } }; diff --git a/tensorflow/lite/micro/micro_allocator.cc b/tensorflow/lite/micro/micro_allocator.cc index 573ac2e0b11..28de77cdb6c 100644 --- a/tensorflow/lite/micro/micro_allocator.cc +++ b/tensorflow/lite/micro/micro_allocator.cc @@ -44,29 +44,13 @@ struct AllocationInfo { // requirement for SIMD extensions. constexpr int kBufferAlignment = 16; -// If building with GNU clib from GCC 4.8.x or lower, `max_align_t` is not a -// member of `std`. If using a newer version of clib, we import `max_align_t` -// into the local anonymous namespace to be able to use it like the global -// `max_align_t` from the older clib. -#if defined(__GNUC__) && defined(__GNUC_PREREQ) -#if __GNUC_PREREQ(4, 9) -using std::max_align_t; -#endif -#else -// We assume other compiler/clib configurations don't have this issue. -using std::max_align_t; -#endif - class MicroBuiltinDataAllocator : public BuiltinDataAllocator { public: explicit MicroBuiltinDataAllocator(SimpleMemoryAllocator* memory_allocator) : memory_allocator_(memory_allocator) {} - void* Allocate(size_t size) override { - // Align to an address that is proper for all primitive types, but no more - // than the size. - return memory_allocator_->AllocateFromTail( - size, std::min(size, alignof(max_align_t))); + void* Allocate(size_t size, size_t alignment_hint) override { + return memory_allocator_->AllocateFromTail(size, alignment_hint); } void Deallocate(void* data) override { // Do not deallocate, builtin data needs to be available for the life time