From cd2e8b6a3c27764369274c8fb50328a9caf90168 Mon Sep 17 00:00:00 2001 From: Shlomi Regev Date: Wed, 16 Apr 2025 11:07:12 +0000 Subject: [PATCH 1/5] Revert back from C/C++17 to C/C++11 There are older toolchains that don't support C++17 and are still used in shipping products. Rewrite hexdump.cc to not use C++17 features (std::byte and Class Template Argument Deduction). Also remove forcing of -std=libc for xtensa targets, which was added because stdlib isn't supported with -std=c++17. BUG=410831256 --- tensorflow/lite/micro/BUILD | 8 -- tensorflow/lite/micro/hexdump.cc | 14 ++-- tensorflow/lite/micro/hexdump.h | 4 +- tensorflow/lite/micro/static_vector.h | 83 ------------------- tensorflow/lite/micro/static_vector_test.cc | 82 ------------------ tensorflow/lite/micro/tools/make/Makefile | 5 +- .../tools/make/targets/xtensa_makefile.inc | 1 - 7 files changed, 11 insertions(+), 186 deletions(-) delete mode 100644 tensorflow/lite/micro/static_vector.h delete mode 100644 tensorflow/lite/micro/static_vector_test.cc diff --git a/tensorflow/lite/micro/BUILD b/tensorflow/lite/micro/BUILD index 9fcc83cc026..47d2f20031e 100644 --- a/tensorflow/lite/micro/BUILD +++ b/tensorflow/lite/micro/BUILD @@ -405,14 +405,6 @@ tflm_cc_library( hdrs = ["span.h"], ) -tflm_cc_library( - name = "static_vector", - hdrs = ["static_vector.h"], - deps = [ - "//tensorflow/lite/kernels:op_macros", - ], -) - tflm_cc_library( name = "system_setup", srcs = [ diff --git a/tensorflow/lite/micro/hexdump.cc b/tensorflow/lite/micro/hexdump.cc index fd0f6f7c84e..51339e55461 100644 --- a/tensorflow/lite/micro/hexdump.cc +++ b/tensorflow/lite/micro/hexdump.cc @@ -18,7 +18,6 @@ #include #include "tensorflow/lite/micro/debug_log.h" -#include "tensorflow/lite/micro/static_vector.h" namespace { @@ -52,7 +51,7 @@ tflite::Span output(const tflite::Span& buf, const char* format, } // end anonymous namespace -tflite::Span tflite::hexdump(const tflite::Span region, +tflite::Span tflite::hexdump(const tflite::Span region, const tflite::Span out) { tflite::Span buffer{out}; std::size_t byte_nr = 0; @@ -60,7 +59,8 @@ tflite::Span tflite::hexdump(const tflite::Span region, const int lines = (region.size() + per_line - 1) / per_line; // round up for (int line = 0; line < lines; ++line) { - tflite::StaticVector ascii; + char ascii[per_line]; + int ascii_nr = 0; // print address buffer = output(buffer, "%08X:", line); @@ -76,7 +76,7 @@ tflite::Span tflite::hexdump(const tflite::Span region, if (std::isprint(as_int)) { c = static_cast(as_int); } - ascii.push_back(c); + ascii[ascii_nr++] = c; } else { buffer = output(buffer, " "); } @@ -89,8 +89,8 @@ tflite::Span tflite::hexdump(const tflite::Span region, // print the ascii value buffer = output(buffer, " "); - for (const auto& c : ascii) { - buffer = output(buffer, "%c", c); + for (int ascii_index = 0; ascii_index < ascii_nr; ascii_index++) { + buffer = output(buffer, "%c", ascii[ascii_index]); } buffer = output(buffer, "%c", '\n'); } @@ -98,6 +98,6 @@ tflite::Span tflite::hexdump(const tflite::Span region, return {out.data(), out.size() - buffer.size()}; } -void tflite::hexdump(const tflite::Span region) { +void tflite::hexdump(const tflite::Span region) { hexdump(region, {nullptr, 0}); } diff --git a/tensorflow/lite/micro/hexdump.h b/tensorflow/lite/micro/hexdump.h index 0bdfcc47c05..0d651fafb1f 100644 --- a/tensorflow/lite/micro/hexdump.h +++ b/tensorflow/lite/micro/hexdump.h @@ -23,12 +23,12 @@ namespace tflite { // Displays the contents of a memory region, formatted in hexadecimal and ASCII // in a style matching Python's hexdump module, using DebugLog(). -void hexdump(Span region); +void hexdump(Span region); // Writes the contents of a memory region, formatted in hexadecimal and ASCII // in a style matching Python's hexdump module, to a buffer. Returns the portion // of the buffer written. -Span hexdump(Span region, Span buffer); +Span hexdump(Span region, Span buffer); } // end namespace tflite diff --git a/tensorflow/lite/micro/static_vector.h b/tensorflow/lite/micro/static_vector.h deleted file mode 100644 index 8b9e06392fb..00000000000 --- a/tensorflow/lite/micro/static_vector.h +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2024 The TensorFlow Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef TENSORFLOW_LITE_MICRO_STATIC_VECTOR_H_ -#define TENSORFLOW_LITE_MICRO_STATIC_VECTOR_H_ - -#include -#include -#include - -#include "tensorflow/lite/kernels/op_macros.h" // for TF_LITE_ASSERT - -namespace tflite { - -template -class StaticVector { - // A staticlly-allocated vector. Add to the interface as needed. - - private: - std::array array_; - std::size_t size_{0}; - - public: - using iterator = typename decltype(array_)::iterator; - using const_iterator = typename decltype(array_)::const_iterator; - using pointer = typename decltype(array_)::pointer; - using reference = typename decltype(array_)::reference; - using const_reference = typename decltype(array_)::const_reference; - - StaticVector() {} - - StaticVector(std::initializer_list values) { - for (const T& v : values) { - push_back(v); - } - } - - static constexpr std::size_t max_size() { return MaxSize; } - std::size_t size() const { return size_; } - bool full() const { return size() == max_size(); } - iterator begin() { return array_.begin(); } - const_iterator begin() const { return array_.begin(); } - iterator end() { return begin() + size(); } - const_iterator end() const { return begin() + size(); } - pointer data() { return array_.data(); } - reference operator[](int i) { return array_[i]; } - const_reference operator[](int i) const { return array_[i]; } - void clear() { size_ = 0; } - - template - bool operator==(const StaticVector& other) const { - return std::equal(begin(), end(), other.begin(), other.end()); - } - - template - bool operator!=(const StaticVector& other) const { - return !(*this == other); - } - - void push_back(const T& t) { - TF_LITE_ASSERT(!full()); - *end() = t; - ++size_; - } -}; - -template -StaticVector(T, U...) -> StaticVector; - -} // end namespace tflite - -#endif // TENSORFLOW_LITE_MICRO_STATIC_VECTOR_H_ diff --git a/tensorflow/lite/micro/static_vector_test.cc b/tensorflow/lite/micro/static_vector_test.cc deleted file mode 100644 index 6d601bcf89a..00000000000 --- a/tensorflow/lite/micro/static_vector_test.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2024 The TensorFlow Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "tensorflow/lite/micro/static_vector.h" - -#include "tensorflow/lite/micro/testing/micro_test.h" - -using tflite::StaticVector; - -TF_LITE_MICRO_TESTS_BEGIN - -TF_LITE_MICRO_TEST(StaticVectorPushBack) { - StaticVector a; - TF_LITE_MICRO_EXPECT(a.max_size() == 4); - TF_LITE_MICRO_EXPECT(a.size() == 0); - - a.push_back(1); - TF_LITE_MICRO_EXPECT(a.size() == 1); - TF_LITE_MICRO_EXPECT(a[0] == 1); - - a.push_back(2); - TF_LITE_MICRO_EXPECT(a.size() == 2); - TF_LITE_MICRO_EXPECT(a[1] == 2); - - a.push_back(3); - TF_LITE_MICRO_EXPECT(a.size() == 3); - TF_LITE_MICRO_EXPECT(a[2] == 3); -} - -TF_LITE_MICRO_TEST(StaticVectorInitializationPartial) { - const StaticVector a{1, 2, 3}; - TF_LITE_MICRO_EXPECT(a.max_size() == 4); - TF_LITE_MICRO_EXPECT(a.size() == 3); - TF_LITE_MICRO_EXPECT(a[0] == 1); - TF_LITE_MICRO_EXPECT(a[1] == 2); - TF_LITE_MICRO_EXPECT(a[2] == 3); -} - -TF_LITE_MICRO_TEST(StaticVectorInitializationFull) { - const StaticVector b{1, 2, 3}; - TF_LITE_MICRO_EXPECT(b.max_size() == 3); - TF_LITE_MICRO_EXPECT(b.size() == 3); -} - -TF_LITE_MICRO_TEST(StaticVectorEquality) { - const StaticVector a{1, 2, 3}; - const StaticVector b{1, 2, 3}; - TF_LITE_MICRO_EXPECT(a == b); - TF_LITE_MICRO_EXPECT(!(a != b)); -} - -TF_LITE_MICRO_TEST(StaticVectorInequality) { - const StaticVector a{1, 2, 3}; - const StaticVector b{3, 2, 1}; - TF_LITE_MICRO_EXPECT(a != b); - TF_LITE_MICRO_EXPECT(!(a == b)); -} - -TF_LITE_MICRO_TEST(StaticVectorSizeInequality) { - const StaticVector a{1, 2}; - const StaticVector b{1, 2, 3}; - TF_LITE_MICRO_EXPECT(a != b); -} - -TF_LITE_MICRO_TEST(StaticVectorPartialSizeInequality) { - const StaticVector a{1, 2}; - const StaticVector b{1, 2, 3}; - TF_LITE_MICRO_EXPECT(a != b); -} - -TF_LITE_MICRO_TESTS_END diff --git a/tensorflow/lite/micro/tools/make/Makefile b/tensorflow/lite/micro/tools/make/Makefile index 287661882f6..4814fa84386 100644 --- a/tensorflow/lite/micro/tools/make/Makefile +++ b/tensorflow/lite/micro/tools/make/Makefile @@ -183,7 +183,7 @@ ifeq ($(TARGET), $(HOST_OS)) endif CXXFLAGS := \ - -std=c++17 \ + -std=c++11 \ -fno-rtti \ -fno-exceptions \ -fno-threadsafe-statics \ @@ -192,7 +192,7 @@ CXXFLAGS := \ CCFLAGS := \ -Wimplicit-function-declaration \ - -std=c17 \ + -std=c11 \ $(COMMON_FLAGS) ARFLAGS := -r @@ -346,7 +346,6 @@ $(TENSORFLOW_ROOT)tensorflow/lite/micro/micro_time_test.cc \ $(TENSORFLOW_ROOT)tensorflow/lite/micro/micro_utils_test.cc \ $(TENSORFLOW_ROOT)tensorflow/lite/micro/recording_micro_allocator_test.cc \ $(TENSORFLOW_ROOT)tensorflow/lite/micro/span_test.cc \ -$(TENSORFLOW_ROOT)tensorflow/lite/micro/static_vector_test.cc \ $(TENSORFLOW_ROOT)tensorflow/lite/micro/arena_allocator/non_persistent_arena_buffer_allocator_test.cc \ $(TENSORFLOW_ROOT)tensorflow/lite/micro/arena_allocator/persistent_arena_buffer_allocator_test.cc \ $(TENSORFLOW_ROOT)tensorflow/lite/micro/arena_allocator/recording_single_arena_buffer_allocator_test.cc \ diff --git a/tensorflow/lite/micro/tools/make/targets/xtensa_makefile.inc b/tensorflow/lite/micro/tools/make/targets/xtensa_makefile.inc index 8a3ee7b6716..b8652664bc6 100644 --- a/tensorflow/lite/micro/tools/make/targets/xtensa_makefile.inc +++ b/tensorflow/lite/micro/tools/make/targets/xtensa_makefile.inc @@ -35,7 +35,6 @@ endif TARGET_ARCH_DEFINES := -D$(shell echo $(TARGET_ARCH) | tr [a-z] [A-Z]) PLATFORM_FLAGS = \ - -stdlib=libc++ \ -DTF_LITE_MCU_DEBUG_LOG \ -DTF_LITE_USE_CTIME \ --xtensa-core=$(XTENSA_CORE) \ From a81cc27fbddb42538667face141cb4dc5252c9ac Mon Sep 17 00:00:00 2001 From: Shlomi Regev Date: Wed, 16 Apr 2025 11:40:34 +0000 Subject: [PATCH 2/5] Remove Bazel rule for static_vector --- tensorflow/lite/micro/BUILD | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tensorflow/lite/micro/BUILD b/tensorflow/lite/micro/BUILD index 47d2f20031e..18bab796b1b 100644 --- a/tensorflow/lite/micro/BUILD +++ b/tensorflow/lite/micro/BUILD @@ -426,7 +426,6 @@ tflm_cc_library( deps = [ ":debug_log", ":span", - ":static_vector", ], ) @@ -640,18 +639,6 @@ tflm_cc_test( ], ) -tflm_cc_test( - name = "static_vector_test", - size = "small", - srcs = [ - "static_vector_test.cc", - ], - deps = [ - ":static_vector", - "//tensorflow/lite/micro/testing:micro_test", - ], -) - tflm_cc_test( name = "hexdump_test", size = "small", From 90067a30dd570262f7118c01ec6bc1842e436ba4 Mon Sep 17 00:00:00 2001 From: Shlomi Regev Date: Wed, 16 Apr 2025 11:54:36 +0000 Subject: [PATCH 3/5] Replace std::byte with unsigned char in hexdump_test.cc --- tensorflow/lite/micro/hexdump_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tensorflow/lite/micro/hexdump_test.cc b/tensorflow/lite/micro/hexdump_test.cc index 89d3a0404c5..840c0a2c2a3 100644 --- a/tensorflow/lite/micro/hexdump_test.cc +++ b/tensorflow/lite/micro/hexdump_test.cc @@ -22,8 +22,8 @@ constexpr tflite::Span input{ "This is an input string for testing."}; -const tflite::Span region{ - reinterpret_cast(input.data()), input.size()}; +const tflite::Span region{ + reinterpret_cast(input.data()), input.size()}; // clang-format off constexpr tflite::Span expected{ From 3c77b590def8742fbf61cdae3f674514dceb5948 Mon Sep 17 00:00:00 2001 From: Shlomi Regev Date: Wed, 16 Apr 2025 12:28:58 +0000 Subject: [PATCH 4/5] Replace unsigned char with uint8_t --- tensorflow/lite/micro/compression/metadata_test.cc | 4 ++-- tensorflow/lite/micro/hexdump.cc | 8 +++++--- tensorflow/lite/micro/hexdump.h | 5 +++-- tensorflow/lite/micro/hexdump_test.cc | 5 +++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/tensorflow/lite/micro/compression/metadata_test.cc b/tensorflow/lite/micro/compression/metadata_test.cc index a0d02165294..9a6abd963d9 100644 --- a/tensorflow/lite/micro/compression/metadata_test.cc +++ b/tensorflow/lite/micro/compression/metadata_test.cc @@ -81,8 +81,8 @@ metadata->subgraphs.push_back(std::move(subgraph0)); flatbuffers::FlatBufferBuilder builder; auto root = Metadata::Pack(builder, metadata.get()); builder.Finish(root); -auto flatbuffer = tflite::Span{ - reinterpret_cast(builder.GetBufferPointer()), +auto flatbuffer = tflite::Span{ + reinterpret_cast(builder.GetBufferPointer()), builder.GetSize()}; TF_LITE_MICRO_TEST(ReadbackEqualsWrite) { diff --git a/tensorflow/lite/micro/hexdump.cc b/tensorflow/lite/micro/hexdump.cc index 51339e55461..acd24825ab4 100644 --- a/tensorflow/lite/micro/hexdump.cc +++ b/tensorflow/lite/micro/hexdump.cc @@ -16,6 +16,7 @@ #include #include +#include #include "tensorflow/lite/micro/debug_log.h" @@ -51,8 +52,9 @@ tflite::Span output(const tflite::Span& buf, const char* format, } // end anonymous namespace -tflite::Span tflite::hexdump(const tflite::Span region, - const tflite::Span out) { +tflite::Span tflite::hexdump( + const tflite::Span region, + const tflite::Span out) { tflite::Span buffer{out}; std::size_t byte_nr = 0; constexpr int per_line = 16; @@ -98,6 +100,6 @@ tflite::Span tflite::hexdump(const tflite::Span regio return {out.data(), out.size() - buffer.size()}; } -void tflite::hexdump(const tflite::Span region) { +void tflite::hexdump(const tflite::Span region) { hexdump(region, {nullptr, 0}); } diff --git a/tensorflow/lite/micro/hexdump.h b/tensorflow/lite/micro/hexdump.h index 0d651fafb1f..07002e3b42f 100644 --- a/tensorflow/lite/micro/hexdump.h +++ b/tensorflow/lite/micro/hexdump.h @@ -16,6 +16,7 @@ #define TENSORFLOW_LITE_MICRO_HEXDUMP_H_ #include +#include #include "tensorflow/lite/micro/span.h" @@ -23,12 +24,12 @@ namespace tflite { // Displays the contents of a memory region, formatted in hexadecimal and ASCII // in a style matching Python's hexdump module, using DebugLog(). -void hexdump(Span region); +void hexdump(Span region); // Writes the contents of a memory region, formatted in hexadecimal and ASCII // in a style matching Python's hexdump module, to a buffer. Returns the portion // of the buffer written. -Span hexdump(Span region, Span buffer); +Span hexdump(Span region, Span buffer); } // end namespace tflite diff --git a/tensorflow/lite/micro/hexdump_test.cc b/tensorflow/lite/micro/hexdump_test.cc index 840c0a2c2a3..2e7e7f4c29a 100644 --- a/tensorflow/lite/micro/hexdump_test.cc +++ b/tensorflow/lite/micro/hexdump_test.cc @@ -15,6 +15,7 @@ #include "tensorflow/lite/micro/hexdump.h" #include +#include #include "tensorflow/lite/micro/span.h" #include "tensorflow/lite/micro/testing/micro_test.h" @@ -22,8 +23,8 @@ constexpr tflite::Span input{ "This is an input string for testing."}; -const tflite::Span region{ - reinterpret_cast(input.data()), input.size()}; +const tflite::Span region{ + reinterpret_cast(input.data()), input.size()}; // clang-format off constexpr tflite::Span expected{ From 2707c383cd2d2334fdb9f267ec3147c44f707962 Mon Sep 17 00:00:00 2001 From: Shlomi Regev Date: Wed, 16 Apr 2025 13:32:33 +0000 Subject: [PATCH 5/5] Fix coding style and no_tf_lite_static_memory build --- tensorflow/lite/micro/hexdump.cc | 5 ++--- tensorflow/lite/micro/tools/make/Makefile | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tensorflow/lite/micro/hexdump.cc b/tensorflow/lite/micro/hexdump.cc index acd24825ab4..e33394db9c0 100644 --- a/tensorflow/lite/micro/hexdump.cc +++ b/tensorflow/lite/micro/hexdump.cc @@ -52,9 +52,8 @@ tflite::Span output(const tflite::Span& buf, const char* format, } // end anonymous namespace -tflite::Span tflite::hexdump( - const tflite::Span region, - const tflite::Span out) { +tflite::Span tflite::hexdump(const tflite::Span region, + const tflite::Span out) { tflite::Span buffer{out}; std::size_t byte_nr = 0; constexpr int per_line = 16; diff --git a/tensorflow/lite/micro/tools/make/Makefile b/tensorflow/lite/micro/tools/make/Makefile index 4814fa84386..adb9291c12e 100644 --- a/tensorflow/lite/micro/tools/make/Makefile +++ b/tensorflow/lite/micro/tools/make/Makefile @@ -258,6 +258,10 @@ else ifeq ($(BUILD_TYPE), no_tf_lite_static_memory) # https://github.com/tensorflow/tensorflow/issues/43076 CXXFLAGS := $(filter-out -DTF_LITE_STATIC_MEMORY, $(CXXFLAGS)) CCFLAGS := $(filter-out -DTF_LITE_STATIC_MEMORY, $(CCFLAGS)) + + # array.h uses std::conditional_t, which is a C++14 feature + CXXFLAGS := $(filter-out -std=c++11, $(CXXFLAGS)) + CXXFLAGS += -std=c++14 endif # This library is the main target for this makefile. It will contain a minimal