diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 371f3002..3f4b04f7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -101,3 +101,31 @@ jobs: ./build_inline_libcxx/tools/benchmodel ./example_models/lstm.nam ./build_inline_libcxx/tools/render ./example_models/wavenet.nam ./example_audio/input.wav ./example_audio/output.wav + build-windows: + name: Build Windows + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Build Tools + working-directory: ${{github.workspace}}/build + run: | + cmake .. -DCMAKE_BUILD_TYPE=Debug + cmake --build . --config Debug + - name: Build Tools (Inline GEMM) + working-directory: ${{github.workspace}}/build_inline + run: | + cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-DNAM_USE_INLINE_GEMM" + cmake --build . --config Debug + - name: Run tests + working-directory: ${{github.workspace}} + run: | + ./build/tools/Debug/run_tests.exe + ./build/tools/Debug/benchmodel.exe ./example_models/wavenet.nam + ./build/tools/Debug/benchmodel.exe ./example_models/lstm.nam + ./build/tools/Debug/render.exe ./example_models/wavenet.nam ./example_audio/input.wav ./example_audio/output.wav + ./build_inline/tools/Debug/run_tests.exe + ./build_inline/tools/Debug/benchmodel.exe ./example_models/wavenet.nam + ./build_inline/tools/Debug/benchmodel.exe ./example_models/lstm.nam + ./build_inline/tools/Debug/render.exe ./example_models/wavenet.nam ./example_audio/input.wav ./example_audio/output.wav diff --git a/CMakeLists.txt b/CMakeLists.txt index d21f36a2..00f5b062 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,8 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") endif() elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows") add_compile_definitions(NOMINMAX WIN32_LEAN_AND_MEAN) + add_compile_definitions(_USE_MATH_DEFINES) + add_compile_options(/EHsc) else() message(FATAL_ERROR "Unrecognized Platform!") endif() @@ -62,9 +64,13 @@ endif() add_subdirectory(tools) -#file(MAKE_DIRECTORY build/tools) - -#add_custom_target(copy_tools ALL -# ${CMAKE_COMMAND} -E copy "$" tools/ -# DEPENDS tools -#) +# Copy example assets after build +add_custom_target(copy_tools ALL + COMMAND ${CMAKE_COMMAND} -E copy_directory + "${CMAKE_CURRENT_SOURCE_DIR}/example_models" + "${CMAKE_CURRENT_BINARY_DIR}/tools/example_models" + COMMAND ${CMAKE_COMMAND} -E copy_directory + "${CMAKE_CURRENT_SOURCE_DIR}/example_audio" + "${CMAKE_CURRENT_BINARY_DIR}/tools/example_audio" + DEPENDS tools +) diff --git a/build_inline/.gitignore b/build_inline/.gitignore index e69de29b..86d0cb27 100644 --- a/build_inline/.gitignore +++ b/build_inline/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 492fb676..4c139b02 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -20,8 +20,6 @@ add_executable(loadmodel loadmodel.cpp ${NAM_SOURCES}) add_executable(benchmodel benchmodel.cpp ${NAM_SOURCES}) add_executable(render render.cpp ${NAM_SOURCES} ${AUDIO_DSP_TOOLS_WAV_SOURCES}) target_compile_features(render PUBLIC cxx_std_20) -# AudioDSPTools wav.cpp has sign-compare issues; don't fail build -set_source_files_properties(${AUDIO_DSP_TOOLS_WAV_SOURCES} PROPERTIES COMPILE_FLAGS "-Wno-error") set_target_properties(render PROPERTIES CXX_VISIBILITY_PRESET hidden INTERPROCEDURAL_OPTIMIZATION TRUE @@ -36,6 +34,8 @@ if (MSVC) "$<$:/O2>" ) else() + # AudioDSPTools wav.cpp has sign-compare issues; don't fail build + set_source_files_properties(${AUDIO_DSP_TOOLS_WAV_SOURCES} PROPERTIES COMPILE_FLAGS "-Wno-error") target_compile_options(render PRIVATE -Wall -Wextra -Wpedantic -Wstrict-aliasing -Wunreachable-code -Weffc++ -Wno-unused-parameter "$<$:-Og;-ggdb;-Werror>" @@ -44,6 +44,7 @@ else() endif() add_executable(benchmodel_bufsize benchmodel_bufsize.cpp ${NAM_SOURCES}) add_executable(bench_a2_fast bench_a2_fast.cpp ${NAM_SOURCES}) +add_executable(run_tests run_tests.cpp test/allocation_tracking.cpp ${NAM_SOURCES}) target_compile_features(bench_a2_fast PUBLIC cxx_std_20) set_target_properties(bench_a2_fast PROPERTIES CXX_VISIBILITY_PRESET hidden @@ -61,11 +62,23 @@ else() "$<$:-Og;-ggdb;-Werror>" "$<$:-Ofast>" ) + # Compile run_tests without optimizations to ensure allocation tracking works correctly + # Also ensure assertions are enabled (NDEBUG is not defined) so tests actually run + set_target_properties(run_tests PROPERTIES COMPILE_OPTIONS "-O0") + # There's an error in eigen's + # /Users/steve/src/NeuralAmpModelerCore/Dependencies/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h + # Don't let this break my build on debug: + set_source_files_properties(../NAM/dsp.cpp PROPERTIES COMPILE_FLAGS "-Wno-error") + set_source_files_properties(../NAM/conv1d.cpp PROPERTIES COMPILE_FLAGS "-Wno-error") endif() -add_executable(run_tests run_tests.cpp test/allocation_tracking.cpp ${NAM_SOURCES}) -# Compile run_tests without optimizations to ensure allocation tracking works correctly -# Also ensure assertions are enabled (NDEBUG is not defined) so tests actually run -set_target_properties(run_tests PROPERTIES COMPILE_OPTIONS "-O0") + +# Only allow allocation tracking on Linux and macOS. Not on Windows and not on embedded. +if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") + target_compile_definitions(run_tests PRIVATE NAM_ALLOC_TRACKING_ENABLED=1) +else() + target_compile_definitions(run_tests PRIVATE NAM_ALLOC_TRACKING_ENABLED=0) +endif() + # Ensure assertions are enabled for run_tests by removing NDEBUG if it was set # Release/RelWithDebInfo/MinSizeRel build types automatically define NDEBUG # We use a compile option to undefine it, which works on GCC, Clang, and MSVC @@ -106,9 +119,3 @@ else() "$<$:-Ofast>" ) endif() - -# There's an error in eigen's -# /Users/steve/src/NeuralAmpModelerCore/Dependencies/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h -# Don't let this break my build on debug: -set_source_files_properties(../NAM/dsp.cpp PROPERTIES COMPILE_FLAGS "-Wno-error") -set_source_files_properties(../NAM/conv1d.cpp PROPERTIES COMPILE_FLAGS "-Wno-error") diff --git a/tools/bench_a2_fast.cpp b/tools/bench_a2_fast.cpp index 2dcaff1e..8b8dc075 100644 --- a/tools/bench_a2_fast.cpp +++ b/tools/bench_a2_fast.cpp @@ -12,9 +12,9 @@ #if defined(NAM_ENABLE_A2_FAST) + #include #include #include - #include #include #include #include diff --git a/tools/test/allocation_tracking.cpp b/tools/test/allocation_tracking.cpp index 983ed11d..ebc232a7 100644 --- a/tools/test/allocation_tracking.cpp +++ b/tools/test/allocation_tracking.cpp @@ -17,6 +17,7 @@ void (*original_free)(void*) = nullptr; void* (*original_realloc)(void*, size_t) = nullptr; } // namespace allocation_tracking +#if NAM_ALLOC_TRACKING_ENABLED // Override malloc/free to track Eigen allocations (Eigen uses malloc directly) extern "C" { void* malloc(size_t size) @@ -88,3 +89,4 @@ void operator delete[](void* ptr) noexcept ++allocation_tracking::g_deallocation_count; std::free(ptr); } +#endif diff --git a/tools/test/allocation_tracking.h b/tools/test/allocation_tracking.h index 00c110ab..cf67d4f7 100644 --- a/tools/test/allocation_tracking.h +++ b/tools/test/allocation_tracking.h @@ -6,11 +6,14 @@ #include #include -#include #include #include #include +#if NAM_ALLOC_TRACKING_ENABLED +#include +#endif + // Allocation tracking globals namespace allocation_tracking { @@ -53,6 +56,13 @@ void run_allocation_test(std::function setup, TestFunc test, std::functi if (teardown) teardown(); +#if !NAM_ALLOC_TRACKING_ENABLED + (void)expected_allocations; + (void)expected_deallocations; + (void)test_name; + return; +#endif + // Assert expected allocations/deallocations if (g_allocation_count != expected_allocations || g_deallocation_count != expected_deallocations) { @@ -95,6 +105,11 @@ void run_allocation_test_expect_allocations(std::function setup, TestFun if (teardown) teardown(); +#if !NAM_ALLOC_TRACKING_ENABLED + (void)test_name; + return; +#endif + // Assert that allocations occurred (this test verifies our tracking works) if (g_allocation_count == 0 && g_deallocation_count == 0) { diff --git a/tools/test/test_a2_fast.cpp b/tools/test/test_a2_fast.cpp index 60df7302..923c4308 100644 --- a/tools/test/test_a2_fast.cpp +++ b/tools/test/test_a2_fast.cpp @@ -6,9 +6,9 @@ #if defined(NAM_ENABLE_A2_FAST) + #include #include #include - #include #include #include #include diff --git a/tools/test/test_lstm.cpp b/tools/test/test_lstm.cpp index 8c655b98..3c19c869 100644 --- a/tools/test/test_lstm.cpp +++ b/tools/test/test_lstm.cpp @@ -1,8 +1,8 @@ // Tests for LSTM +#include #include #include -#include #include #include diff --git a/tools/test/test_wavenet_configurable_gating.cpp b/tools/test/test_wavenet_configurable_gating.cpp index dc3bbc48..81bdfd17 100644 --- a/tools/test/test_wavenet_configurable_gating.cpp +++ b/tools/test/test_wavenet_configurable_gating.cpp @@ -299,24 +299,35 @@ class TestConfigurableGating // Set some weights to make the layers produce different outputs std::vector weights; - // Add weights for conv layer (simplified - just enough to make it non-zero) - const int conv_weights = channels * 2 * bottleneck * kernelSize; // 2*bottleneck for gated + // Add weights for conv layer (2*bottleneck outputs for gated), including bias + const int conv_out_channels = 2 * bottleneck; + const int conv_weights = channels * conv_out_channels * kernelSize; + const int conv_bias = conv_out_channels; for (int i = 0; i < conv_weights; i++) { weights.push_back(0.1f * i); } + for (int i = 0; i < conv_bias; i++) + { + weights.push_back(0.01f * i); + } // Add weights for input mixin const int mixin_weights = conditionSize * 2 * bottleneck; for (int i = 0; i < mixin_weights; i++) { weights.push_back(0.05f * i); } - // Add weights for 1x1 conv + // Add weights for 1x1 conv, including bias const int conv1x1_weights = bottleneck * channels; + const int conv1x1_bias = channels; for (int i = 0; i < conv1x1_weights; i++) { weights.push_back(0.02f * i); } + for (int i = 0; i < conv1x1_bias; i++) + { + weights.push_back(0.03f * i); + } // Set weights for all layers auto weights_iter = weights.begin(); @@ -328,6 +339,8 @@ class TestConfigurableGating weights_iter = weights.begin(); layer_relu.set_weights_(weights_iter); + assert(weights_iter == weights.end()); + // Create some test input data Eigen::MatrixXf input(channels, num_frames); input.setRandom();