diff --git a/packages/react-native-executorch/common/rnexecutorch/data_processing/FileUtils.h b/packages/react-native-executorch/common/rnexecutorch/data_processing/FileUtils.h index d97be6e69..3de942df0 100644 --- a/packages/react-native-executorch/common/rnexecutorch/data_processing/FileUtils.h +++ b/packages/react-native-executorch/common/rnexecutorch/data_processing/FileUtils.h @@ -20,11 +20,11 @@ inline std::string loadBytesFromFile(const std::string &path) { } std::string data; fs.seekg(0, std::ios::end); - size_t size = static_cast(fs.tellg()); + auto size = static_cast(fs.tellg()); fs.seekg(0, std::ios::beg); data.resize(size); fs.read(data.data(), size); return data; -}; +} } // namespace rnexecutorch::file_utils diff --git a/packages/react-native-executorch/common/rnexecutorch/data_processing/dsp.cpp b/packages/react-native-executorch/common/rnexecutorch/data_processing/dsp.cpp index d3761dced..e06b59e44 100644 --- a/packages/react-native-executorch/common/rnexecutorch/data_processing/dsp.cpp +++ b/packages/react-native-executorch/common/rnexecutorch/data_processing/dsp.cpp @@ -1,22 +1,25 @@ #include +#include +#include #include #include -#include +#include #include #include namespace rnexecutorch::dsp { -using namespace rnexecutorch::dsp; +using std::numbers::pi_v; -std::vector hannWindow(size_t size) { - // https://www.mathworks.com/help/signal/ref/hann.html - std::vector window(size); - for (size_t i = 0; i < size; i++) { - window[i] = 0.5f * (1 - std::cos(2 * M_PI * i / size)); - } - return window; -} +namespace { +std::vector hannWindow(size_t size) { + std::vector window(size); + for (size_t i = 0; i < size; i++) { + window[i] = 0.5f * (1.0f - std::cosf(2.0f * pi_v * static_cast(i) / static_cast(size))); + } + return window; +} +} // namespace std::vector stftFromWaveform(std::span waveform, size_t fftWindowSize, size_t hopSize) { @@ -26,8 +29,8 @@ std::vector stftFromWaveform(std::span waveform, const auto numFrames = 1 + (waveform.size() - fftWindowSize) / hopSize; const auto numBins = fftWindowSize / 2; const auto hann = hannWindow(fftWindowSize); - auto inBuffer = std::vector(fftWindowSize); - auto outBuffer = std::vector>(fftWindowSize); + std::vector inBuffer(fftWindowSize); + std::vector> outBuffer(fftWindowSize); // Output magnitudes in dB std::vector magnitudes; @@ -54,7 +57,7 @@ std::vector stftFromWaveform(std::span waveform, for (size_t i = 0; i < numBins; i++) { const auto magnitude = std::abs(outBuffer[i]) * magnitudeScale; const auto magnitude_db = - dbConversionFactor * log10f(magnitude + epsilon); + dbConversionFactor * std::log10f(magnitude + epsilon); magnitudes.push_back(magnitude_db); } } diff --git a/packages/react-native-executorch/common/rnexecutorch/data_processing/dsp.h b/packages/react-native-executorch/common/rnexecutorch/data_processing/dsp.h index 7eaa26d83..b1d4dd347 100644 --- a/packages/react-native-executorch/common/rnexecutorch/data_processing/dsp.h +++ b/packages/react-native-executorch/common/rnexecutorch/data_processing/dsp.h @@ -5,7 +5,6 @@ namespace rnexecutorch::dsp { -std::vector hannWindow(size_t size); std::vector stftFromWaveform(std::span waveform, size_t fftWindowSize, size_t hopSize); diff --git a/packages/react-native-executorch/common/rnexecutorch/tests/CMakeLists.txt b/packages/react-native-executorch/common/rnexecutorch/tests/CMakeLists.txt index 66758f6b2..82d41e3a8 100644 --- a/packages/react-native-executorch/common/rnexecutorch/tests/CMakeLists.txt +++ b/packages/react-native-executorch/common/rnexecutorch/tests/CMakeLists.txt @@ -14,17 +14,21 @@ include_directories(${CMAKE_SOURCE_DIR}/../data_processing) include_directories(${CMAKE_SOURCE_DIR}/..) # Source files -set(SOURCE_FILES ${CMAKE_SOURCE_DIR}/../data_processing/Numerical.cpp) +set(SOURCE_FILES ${CMAKE_SOURCE_DIR}/../data_processing/Numerical.cpp + ${CMAKE_SOURCE_DIR}/../data_processing/FileUtils.h) # Executables for the tests add_executable(NumericalTests NumericalTest.cpp ${SOURCE_FILES}) +add_executable(FileUtilsTests FileUtilsTest.cpp ${SOURCE_FILES}) add_executable(LogTests LogTest.cpp) # Libraries linking target_link_libraries(NumericalTests gtest gtest_main) +target_link_libraries(FileUtilsTests gtest gtest_main) target_link_libraries(LogTests gtest gtest_main) # Testing functionalities enable_testing() add_test(NAME NumericalTests COMMAND NumericalTests) +add_test(NAME FileUtilsTests COMMAND FileUtilsTests) add_test(NAME LogTests COMMAND LogTests) diff --git a/packages/react-native-executorch/common/rnexecutorch/tests/FileUtilsTest.cpp b/packages/react-native-executorch/common/rnexecutorch/tests/FileUtilsTest.cpp new file mode 100644 index 000000000..a40c99ebe --- /dev/null +++ b/packages/react-native-executorch/common/rnexecutorch/tests/FileUtilsTest.cpp @@ -0,0 +1,31 @@ +#include "../data_processing/FileUtils.h" +#include +#include +#include + +namespace rnexecutorch::file_utils { +class FileIOTest : public ::testing::Test { +protected: + std::string tempFileName = "temp_test_file.txt"; + + void SetUp() override { + std::ofstream out(tempFileName, std::ios::binary); + out << "Hello, world"; + out.close(); + } + + void TearDown() override { + std::remove(tempFileName.c_str()); + } +}; + +TEST_F(FileIOTest, LoadBytesFromFileSuccessfully) { + std::string data = loadBytesFromFile(tempFileName); + EXPECT_EQ(data, "Hello, world"); +} + +TEST_F(FileIOTest, LoadBytesFromFileFailOnNonExistentFile) { + EXPECT_THROW( + { loadBytesFromFile("non_existent_file.txt"); }, std::runtime_error); +} +} // namespace rnexecutorch::file_utils diff --git a/packages/react-native-executorch/common/runner/runner.cpp b/packages/react-native-executorch/common/runner/runner.cpp index 830d8509c..e21b60aea 100644 --- a/packages/react-native-executorch/common/runner/runner.cpp +++ b/packages/react-native-executorch/common/runner/runner.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace example { @@ -23,20 +24,6 @@ using ::executorch::runtime::Result; namespace llm = ::executorch::extension::llm; -std::string loadBytesFromFile(const std::string &path) { - std::ifstream fs(path, std::ios::in | std::ios::binary); - if (fs.fail()) { - throw std::runtime_error("Failed to open tokenizer file"); - } - std::string data; - fs.seekg(0, std::ios::end); - size_t size = static_cast(fs.tellg()); - fs.seekg(0, std::ios::beg); - data.resize(size); - fs.read(data.data(), size); - return data; -} - namespace { static constexpr auto kEnableDynamicShape = "enable_dynamic_shape"; static constexpr auto kEosIds = "get_eos_ids"; @@ -83,7 +70,7 @@ Error Runner::load() { ET_CHECK_OK_OR_RETURN_ERROR(module_->load_method("forward")); // load tokenizer. - auto blob = loadBytesFromFile(tokenizer_path_); + auto blob = rnexecutorch::file_utils::loadBytesFromFile(tokenizer_path_); tokenizer_ = tokenizers::Tokenizer::FromBlobJSON(blob); ET_LOG(Info, "Reading metadata from model");