Commit 364d1d2
authored
[BREAKING] Conv1D manages its own ring buffer (#181)
* Improve Conv1D class to manage its own ring buffer
- Add RingBuffer class to manage write/read pointers for Eigen::MatrixXf buffers
- Add Reset() method to Conv1D to initialize ring buffer and pre-allocate output
- Add get_output() method to Conv1D to access output buffer
- Rename process_() to Process() and update to use internal ring buffer
- Update ConvNet to use Conv1D internal buffers via Process() and get_output()
- Update WaveNet to use Conv1D internal buffers and propagate Reset()
- Add comprehensive tests for Conv1D in test_conv1d.cpp
Implements issue #145
* Fix RingBuffer to handle max lookback and add comprehensive tests
- Fix Reset() to zero buffer behind starting write position
- Fix Rewind() to copy receptive_field (max lookback) samples to start
- Set write position after receptive_field when rewinding
- Add comprehensive test suite for RingBuffer (12 tests)
- Tests cover: construction, reset, write/read, advance, rewind, lookback, etc.
Fixes issues with RingBuffer not properly handling max lookback when rewinding.
* Rename 'receptive field' to 'max lookback' in RingBuffer
- Rename _receptive_field member to _max_lookback
- Rename SetReceptiveField() to SetMaxLookback()
- Update all comments and documentation
- Update all test references from receptive_field to max_lookback
- More descriptive name for ring buffer context
* Remove trailing whitespace (formatting cleanup)
* Move RingBuffer and Conv1D to separate source and header files
- Create NAM/ring_buffer.h and NAM/ring_buffer.cpp for RingBuffer class
- Create NAM/conv1d.h and NAM/conv1d.cpp for Conv1D class
- Remove RingBuffer and Conv1D from NAM/dsp.h and NAM/dsp.cpp
- Update includes in convnet.h, wavenet.h, and test files
- All tests pass after refactoring
* Replace GetCapacity() with GetMaxBufferSize() in RingBuffer
- Remove GetCapacity() from public interface (storage size is internal detail)
- Add GetMaxBufferSize() to return the max_buffer_size passed to Reset()
- Store max_buffer_size as member variable
- Update tests to use GetMaxBufferSize() instead of GetCapacity()
- External code should trust that storage is sized correctly
* Add assertions in RingBuffer::Rewind() to prevent aliasing
- Assert that write pointer is at least 2 * max_lookback to avoid aliasing
- Assert that copy start position is within storage bounds
- Remove silent failure condition - now asserts instead of silently skipping
- Prevents data corruption from overlapping copy operations
* Rename Conv1D::get_output to GetOutput
- Renamed method in conv1d.h and conv1d.cpp
- Updated all usages in convnet.cpp and wavenet.cpp
- Updated all test cases in test_conv1d.cpp
- Matches naming convention with Conv1x1::GetOutput()
* Remove _total_written tracking and GetReadPos() from RingBuffer
- Remove _total_written member variable and all references
- Remove GetReadPos() method (read_pos calculation now inline in Read())
- Remove test_get_read_pos() test function
- Simplify RingBuffer for exclusive use by Conv1D layer
- Update tests to work without GetReadPos()
* Refactor LayerArray::Process() to remove head_outputs parameter and add GetHeadOutputs()
- Remove head_outputs parameter from both Process() overloads
- Add GetHeadOutputs() method to retrieve head outputs from _head_rechannel
- Update WaveNet::process() to use GetHeadOutputs() directly from layer arrays
- Remove deprecated set_num_frames_() methods from _Layer and _LayerArray
- Update _Layer::SetMaxBufferSize() to use Conv1D::SetMaxBufferSize() instead of Reset()
- Simplify head input zeroing in LayerArray::Process()
* Refactor WaveNet LayerArray and remove _DilatedConv wrapper
- Remove _DilatedConv wrapper class, use Conv1D directly in _Layer
- Refactor LayerArray::Process() to extract common logic into ProcessInner()
- Make _Layer::Process() RT-safe by removing resize in Process()
- Update _Layer::SetMaxBufferSize() to use Conv1D::SetMaxBufferSize()
- Update tests and ConvNet to use SetMaxBufferSize() instead of Reset()
- Simplify _Layer::Process() by combining conv and input_mixin processing
* Add comprehensive WaveNet tests organized by component
- Split WaveNet tests into three files by component:
- test_layer.cpp: Tests for individual WaveNet layers
- test_layer_array.cpp: Tests for layer arrays
- test_full.cpp: Tests for full WaveNet models
- Use nested namespaces: test_wavenet::test_layer, test_wavenet::test_layer_array, test_wavenet::test_full
- Remove old monolithic test_wavenet.cpp file
- Update test runner to include new test files directly
- Add 12 new comprehensive tests covering:
- Gated and non-gated layers
- Different activations
- Multi-channel layers
- Layer array processing
- Receptive field calculations
- Full model processing
- Edge cases (zero input, different buffer sizes)
- Prewarm functionality
* Refactor Conv1D and RingBuffer API, improve tests
- Add Conv1D constructor with shape parameters
- Rename Conv1D::Reset() to SetMaxBufferSize(), remove unused sampleRate param
- Add Conv1D::has_bias() method
- Reorganize RingBuffer public/private interface (move internal methods to private)
- Improve test assertions with numerical accuracy checks
- Clean up ring buffer tests, remove internal state checks
- Remove commented code from WaveNet
- Update NOTES with completed tasks
* Complete ConvNet refactoring to use Conv1D ring buffer API
- Refactor ConvNetBlock to add Process() and GetOutput() methods using new Conv1D API
- Simplify ConvNet::process() to eliminate _block_vals for Conv1D layers
- Simplify buffer management - Conv1D handles its own ring buffers
- Fix test expectations in test_conv1d.cpp (corrected weight ordering)
- Fix test bug in test_conv1d.cpp (output2 -> output)
- Fix ring buffer test assertion
- Add comprehensive ConvNet tests (test_convnet.cpp)
- Update test runner to include ConvNet tests
This completes the refactoring work for issue #145, making ConvNet use
Conv1D's new ring buffer API similar to how WaveNet was refactored.
* Fix Eigen Block resize error in wavenet Layer Process
Fixed assertion failure 'DenseBase::resize() does not actually allow to resize'
at wavenet.cpp:61. The issue occurred when assigning _z.leftCols() to
_output_head.leftCols() for gated layers, where _z has 2*channels rows but
_output_head has only channels rows.
Fix: Use _z.topRows(channels).leftCols(num_frames) for gated layers to
correctly select only the first channels rows that should be copied to
_output_head.
* Fix ConvNet test weight counts
Fixed incorrect weight counts in ConvNet tests. The tests were missing
bias weights when batchnorm=false (since !batchnorm=true means do_bias=true
in ConvNetBlock::set_weights_).
Changes:
- test_convnet_basic: Added 4 bias weights (2 per block) - 15 to 19 weights
- test_convnet_batchnorm: Removed 1 extra bias (batchnorm=true means no bias) - 10 to 9 weights
- test_convnet_multiple_blocks: Added 6 bias weights (2 per block) - 23 to 29 weights
- test_convnet_zero_input: Added 1 bias weight - 3 to 4 weights
- test_convnet_different_buffer_sizes: Added 1 bias weight - 3 to 4 weights
- test_convnet_prewarm: Added 6 bias weights (2 per block) - 23 to 29 weights
- test_convnet_multiple_calls: Added 1 bias weight - 3 to 4 weights
All tests now pass successfully.
* Add ConvNetBlock buffer management methods
Added SetMaxBufferSize and Process methods to ConvNetBlock to manage
output buffers independently from Conv1D, allowing proper batchnorm
and activation application on block-owned buffers.
* Remove unneeded includes
* Remove unused _head_arrays from WaveNet class
* Remove unused code from WaveNet class
- Remove WaveNet::_head_output member variable (never read)
- Remove WaveNet::_set_num_frames_ method declaration (never implemented)
- Remove _LayerArray::_get_receptive_field() private method (has TODO to remove)
- Remove _Head::_head member variable (never used)
- Remove entire _Head class (never instantiated in WaveNet)
* Optimize matrix operations and fix build warnings
- Add .noalias() to matrix assignments for better performance
- Remove unnecessary _z.setZero() call (matrix is initialized as needed)
- Remove redundant comment in SetMaxBufferSize
- Add build workaround for conv1d.cpp Eigen warnings
* Add real-time safety test for WaveNet process() method
- Add test_process_realtime_safe() to verify no allocations during process()
- Add allocation tracking using malloc/free hooks to catch Eigen allocations
- Add helper tests to verify allocation tracking works correctly
- Test processes buffers of multiple sizes with two layer arrays
- Ensures WaveNet::process() is real-time safe (no allocations/frees)
* Add real-time safety tests for Conv1D, Layer, and LayerArray
- Add test_conv1d_process_realtime_safe() to test Conv1D with full matrix input
- Add test_conv1d_process_block_realtime_safe() to test Conv1D with Block input
- Add test_layer_process_realtime_safe() to test Layer::Process()
- Add test_layer_array_process_realtime_safe() to test LayerArray::Process()
- Tests confirm Conv1D allocates when passed Block expressions
- Attempt to fix RingBuffer::Write() to avoid allocations (work in progress)
* Refine real-time tests to use full buffers and document RingBuffer usage
- Remove Conv1D Block-input real-time test and rely on full-matrix path
- Ensure tests and runtime code pass full buffers between layers, slicing only inside
- Simplify RingBuffer::Write to take MatrixXf and add note about full-buffer requirement
* Pass full buffers between WaveNet layers for real-time safety
- Add full-buffer getters for Conv1x1, _Layer, and _LayerArray
- Change LayerArray and WaveNet to pass full MatrixXf buffers and slice internally
- Simplify RingBuffer::Write API and document the full-buffer requirement
- Restore real-time safety test file and keep only full-matrix Conv1D test in runner
* Remove num_frames parameter from output getters, return full buffers
- Remove GetOutputHead(num_frames) and GetOutputNextLayer(num_frames) from _Layer
- Remove GetLayerOutputs(num_frames) and GetHeadOutputs(num_frames) from _LayerArray
- Rename *Full() methods to original names (GetOutputHead, GetOutputNextLayer, etc.)
- Update Conv1D and Conv1x1 GetOutput() to return full buffer (no num_frames param)
- Update all internal code and tests to use .leftCols(num_frames) on full buffers
- All methods now return pre-allocated full buffers; callers slice as needed
* Untrack some files that were accidentally added
* Remove accidentally-tracked files
* Add missing cassert include to activations.h
* Fix missing include
* Add --branch flag to benchmark_compare.sh to compare against different branches1 parent c6f0be3 commit 364d1d2
File tree
23 files changed
+2878
-547
lines changed- NAM
- tools
- test
- test_wavenet
23 files changed
+2878
-547
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
| 34 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
0 commit comments