LCOV - code coverage report
Current view: top level - tpglibs/unittest - avx_processors_internal_state_collect_test.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 98.0 % 537 526
Test Date: 2025-12-21 13:07:08 Functions: 98.5 % 68 67

            Line data    Source code
       1              : /**
       2              :  * @file avx_processors_internal_state_collect_test.cxx
       3              :  *
       4              :  * @brief Comprehensive unit tests for internal state collection in AVXFrugalPedestalSubtractProcessor
       5              :  *
       6              :  * @copyright This is part of the DUNE DAQ Software Suite, copyright 2020.
       7              :  * Licensing/copyright details are in the COPYING file that you should have
       8              :  * received with this code.
       9              :  */
      10              : 
      11              : #define BOOST_TEST_MODULE AVXProcessorInternalStateCollectionTest
      12              : #define FMT_HEADER_ONLY
      13              : 
      14              : #include "tpglibs/AVXFrugalPedestalSubtractProcessor.hpp"
      15              : 
      16              : #include <boost/test/unit_test.hpp>
      17              : #include <immintrin.h>
      18              : #include <atomic>
      19              : #include <thread>
      20              : #include <chrono>
      21              : #include <vector>
      22              : 
      23              : namespace tpglibs {
      24              : 
      25              : // Helper function to create test signal
      26           35 : __m256i create_test_signal(const int16_t values[16]) {
      27           35 :   return _mm256_set_epi16(
      28           35 :     values[15], values[14], values[13], values[12],
      29           35 :     values[11], values[10], values[9], values[8],
      30           35 :     values[7], values[6], values[5], values[4],
      31           35 :     values[3], values[2], values[1], values[0]
      32           35 :   );
      33              : }
      34              : 
      35              : // Helper function to extract values from __m256i
      36            0 : void extract_values(__m256i vec, int16_t output[16]) {
      37            0 :   _mm256_storeu_si256(reinterpret_cast<__m256i*>(output), vec);
      38            0 : }
      39              : 
      40              : // =============================================================================
      41              : // SECTION 1: Basic Configuration and Setup
      42              : // =============================================================================
      43              : 
      44              : BOOST_AUTO_TEST_SUITE(ConfigurationAndSetup)
      45              : 
      46            2 : BOOST_AUTO_TEST_CASE(test_basic_configuration) {
      47            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
      48            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
      49              : 
      50            1 :   nlohmann::json config = {
      51            2 :     {"accum_limit", 10},
      52              :     {"metric_collect_toggle_state", true},
      53              :     {"requested_internal_states", "pedestal,accum"}
      54           10 :   };
      55              : 
      56              :   // Should not crash
      57            1 :   pc->configure(config, plane_numbers);
      58              : 
      59            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
      60            1 :   BOOST_TEST(buffer_manager != nullptr);
      61            9 : }
      62              : 
      63            2 : BOOST_AUTO_TEST_CASE(test_configuration_without_internal_states) {
      64            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
      65            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
      66              : 
      67            1 :   nlohmann::json config = {
      68            2 :     {"accum_limit", 10},
      69              :     {"metric_collect_toggle_state", false}
      70            7 :   };
      71              : 
      72            1 :   pc->configure(config, plane_numbers);
      73              :   
      74            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
      75            1 :   BOOST_TEST(buffer_manager != nullptr);
      76            7 : }
      77              : 
      78            2 : BOOST_AUTO_TEST_CASE(test_configuration_different_accum_limits) {
      79            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
      80            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
      81              : 
      82            1 :   nlohmann::json config = {
      83            2 :     {"accum_limit", 42},
      84              :     {"metric_collect_toggle_state", true},
      85              :     {"requested_internal_states", "pedestal"}
      86           10 :   };
      87              : 
      88            1 :   pc->configure(config, plane_numbers);
      89              :   
      90            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
      91            1 :   BOOST_TEST(buffer_manager != nullptr);
      92            9 : }
      93              : 
      94            2 : BOOST_AUTO_TEST_CASE(test_configuration_with_sample_period) {
      95            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
      96            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
      97              : 
      98            1 :   nlohmann::json config = {
      99            2 :     {"accum_limit", 10},
     100              :     {"metric_collect_toggle_state", true},
     101            2 :     {"metric_collect_time_sample_period", 1024},
     102              :     {"requested_internal_states", "pedestal,accum"}
     103           13 :   };
     104              : 
     105            1 :   pc->configure(config, plane_numbers);
     106              :   
     107            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     108            1 :   BOOST_TEST(buffer_manager != nullptr);
     109           11 : }
     110              : 
     111            2 : BOOST_AUTO_TEST_CASE(test_processor_reports_requested_states) {
     112            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     113            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     114              : 
     115            1 :   nlohmann::json config = {
     116            2 :     {"accum_limit", 10},
     117              :     {"metric_collect_toggle_state", true},
     118              :     {"requested_internal_states", "pedestal,accum"}
     119           10 :   };
     120              : 
     121            1 :   pc->configure(config, plane_numbers);
     122              :   
     123              :   // Use the processor's clean interface method (delegates to registry)
     124            1 :   auto requested_states = pc->get_requested_internal_state_names();
     125              :   
     126            1 :   BOOST_TEST(requested_states.size() == 2);
     127            1 :   BOOST_TEST(requested_states[0] == "pedestal");
     128            1 :   BOOST_TEST(requested_states[1] == "accum");
     129            9 : }
     130              : 
     131            2 : BOOST_AUTO_TEST_CASE(test_processor_respects_config) {
     132            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     133            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     134              : 
     135            1 :   nlohmann::json config = {
     136            2 :     {"accum_limit", 10},
     137              :     {"metric_collect_toggle_state", true},
     138              :     {"requested_internal_states", "accum"}  // Only request accum
     139           10 :   };
     140              : 
     141            1 :   pc->configure(config, plane_numbers);
     142              :   
     143              :   // Clean interface - no need to access registry directly
     144            1 :   auto requested_states = pc->get_requested_internal_state_names();
     145              :   
     146              :   // Processor respects what was actually requested
     147            1 :   BOOST_TEST(requested_states.size() == 1);
     148            1 :   BOOST_TEST(requested_states[0] == "accum");
     149            9 : }
     150              : 
     151              : BOOST_AUTO_TEST_SUITE_END()
     152              : 
     153              : // =============================================================================
     154              : // SECTION 2: Single Internal State Collection
     155              : // =============================================================================
     156              : 
     157              : BOOST_AUTO_TEST_SUITE(SingleInternalStateCollection)
     158              : 
     159            2 : BOOST_AUTO_TEST_CASE(test_pedestal_only_collection) {
     160            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     161            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     162              : 
     163            1 :   nlohmann::json config = {
     164            2 :     {"accum_limit", 10},
     165              :     {"metric_collect_toggle_state", true},
     166              :     {"requested_internal_states", "pedestal"}
     167           10 :   };
     168              : 
     169            1 :   pc->configure(config, plane_numbers);
     170              : 
     171            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     172            1 :   buffer_manager->write_to_active_buffer();
     173              : 
     174            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     175              : 
     176            1 :   BOOST_TEST(state_value.m_size == 1);
     177            1 :   BOOST_TEST(state_value.m_data != nullptr);
     178              :   
     179              :   // Initial pedestal should be 0x4000 (16384) - 14-bit max
     180           17 :   for (int i = 0; i < 16; ++i) {
     181           16 :     BOOST_TEST(state_value.m_data[0][i] == 0x4000);
     182              :   }
     183            9 : }
     184              : 
     185            2 : BOOST_AUTO_TEST_CASE(test_accum_only_collection) {
     186            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     187            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     188              : 
     189            1 :   nlohmann::json config = {
     190            2 :     {"accum_limit", 10},
     191              :     {"metric_collect_toggle_state", true},
     192              :     {"requested_internal_states", "accum"}
     193           10 :   };
     194              : 
     195            1 :   pc->configure(config, plane_numbers);
     196              : 
     197            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     198            1 :   buffer_manager->write_to_active_buffer();
     199              : 
     200            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     201              : 
     202            1 :   BOOST_TEST(state_value.m_size == 1);
     203            1 :   BOOST_TEST(state_value.m_data != nullptr);
     204              :   
     205              :   // Initial accum should be 0
     206           17 :   for (int i = 0; i < 16; ++i) {
     207           16 :     BOOST_TEST(state_value.m_data[0][i] == 0);
     208              :   }
     209            9 : }
     210              : 
     211            2 : BOOST_AUTO_TEST_CASE(test_single_state_with_whitespace) {
     212            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     213            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     214              : 
     215            1 :   nlohmann::json config = {
     216            2 :     {"accum_limit", 10},
     217              :     {"metric_collect_toggle_state", true},
     218              :     {"requested_internal_states", "  pedestal  "}
     219           10 :   };
     220              : 
     221            1 :   pc->configure(config, plane_numbers);
     222              : 
     223            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     224            1 :   buffer_manager->write_to_active_buffer();
     225              : 
     226            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     227              : 
     228            1 :   BOOST_TEST(state_value.m_size == 1);
     229            1 :   BOOST_TEST(state_value.m_data != nullptr);
     230            9 : }
     231              : 
     232              : BOOST_AUTO_TEST_SUITE_END()
     233              : 
     234              : // =============================================================================
     235              : // SECTION 3: Multiple Internal State Collection
     236              : // =============================================================================
     237              : 
     238              : BOOST_AUTO_TEST_SUITE(MultipleInternalStateCollection)
     239              : 
     240            2 : BOOST_AUTO_TEST_CASE(test_pedestal_and_accum_collection) {
     241            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     242            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     243              : 
     244            1 :   nlohmann::json config = {
     245            2 :     {"accum_limit", 10},
     246              :     {"metric_collect_toggle_state", true},
     247              :     {"requested_internal_states", "pedestal,accum"}
     248           10 :   };
     249              : 
     250            1 :   pc->configure(config, plane_numbers);
     251              : 
     252            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     253            1 :   buffer_manager->write_to_active_buffer();
     254              : 
     255            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     256              : 
     257            1 :   BOOST_TEST(state_value.m_size == 2);
     258            1 :   BOOST_TEST(state_value.m_data != nullptr);
     259              :   
     260              :   // Check pedestal (first element)
     261           17 :   for (int i = 0; i < 16; ++i) {
     262           16 :     BOOST_TEST(state_value.m_data[0][i] == 0x4000);
     263              :   }
     264              :   
     265              :   // Check accum (second element)
     266           17 :   for (int i = 0; i < 16; ++i) {
     267           16 :     BOOST_TEST(state_value.m_data[1][i] == 0);
     268              :   }
     269            9 : }
     270              : 
     271            2 : BOOST_AUTO_TEST_CASE(test_reverse_order_collection) {
     272            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     273            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     274              : 
     275            1 :   nlohmann::json config = {
     276            2 :     {"accum_limit", 10},
     277              :     {"metric_collect_toggle_state", true},
     278              :     {"requested_internal_states", "accum,pedestal"}
     279           10 :   };
     280              : 
     281            1 :   pc->configure(config, plane_numbers);
     282              : 
     283            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     284            1 :   buffer_manager->write_to_active_buffer();
     285              : 
     286            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     287              : 
     288            1 :   BOOST_TEST(state_value.m_size == 2);
     289            1 :   BOOST_TEST(state_value.m_data != nullptr);
     290              :   
     291              :   // Order should follow requested order: accum first, pedestal second
     292              :   // Check accum (first element when requested in this order)
     293           17 :   for (int i = 0; i < 16; ++i) {
     294           16 :     BOOST_TEST(state_value.m_data[0][i] == 0);
     295              :   }
     296              :   
     297              :   // Check pedestal (second element)
     298           17 :   for (int i = 0; i < 16; ++i) {
     299           16 :     BOOST_TEST(state_value.m_data[1][i] == 0x4000);
     300              :   }
     301            9 : }
     302              : 
     303            2 : BOOST_AUTO_TEST_CASE(test_collection_with_extra_spaces) {
     304            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     305            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     306              : 
     307            1 :   nlohmann::json config = {
     308            2 :     {"accum_limit", 10},
     309              :     {"metric_collect_toggle_state", true},
     310              :     {"requested_internal_states", "  pedestal  ,  accum  "}
     311           10 :   };
     312              : 
     313            1 :   pc->configure(config, plane_numbers);
     314              : 
     315            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     316            1 :   buffer_manager->write_to_active_buffer();
     317              : 
     318            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     319              : 
     320            1 :   BOOST_TEST(state_value.m_size == 2);
     321            1 :   BOOST_TEST(state_value.m_data != nullptr);
     322            9 : }
     323              : 
     324              : BOOST_AUTO_TEST_SUITE_END()
     325              : 
     326              : // =============================================================================
     327              : // SECTION 4: Buffer Switching Correctness
     328              : // =============================================================================
     329              : 
     330              : BOOST_AUTO_TEST_SUITE(BufferSwitchingCorrectness)
     331              : 
     332            2 : BOOST_AUTO_TEST_CASE(test_multiple_writes_and_reads) {
     333            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     334            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     335              : 
     336            1 :   nlohmann::json config = {
     337            2 :     {"accum_limit", 10},
     338              :     {"metric_collect_toggle_state", true},
     339              :     {"requested_internal_states", "pedestal,accum"}
     340           10 :   };
     341              : 
     342            1 :   pc->configure(config, plane_numbers);
     343              : 
     344            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     345              : 
     346              :   // Write and read multiple times
     347            6 :   for (int iteration = 0; iteration < 5; ++iteration) {
     348            5 :     buffer_manager->write_to_active_buffer();
     349            5 :     auto state_value = buffer_manager->switch_buffer_and_read_casted();
     350              : 
     351            5 :     BOOST_TEST(state_value.m_size == 2);
     352            5 :     BOOST_TEST(state_value.m_data != nullptr);
     353              :   }
     354            9 : }
     355              : 
     356            2 : BOOST_AUTO_TEST_CASE(test_write_without_read) {
     357            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     358            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     359              : 
     360            1 :   nlohmann::json config = {
     361            2 :     {"accum_limit", 10},
     362              :     {"metric_collect_toggle_state", true},
     363              :     {"requested_internal_states", "pedestal,accum"}
     364           10 :   };
     365              : 
     366            1 :   pc->configure(config, plane_numbers);
     367              : 
     368            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     369              : 
     370              :   // Multiple writes without reads should not crash
     371            1 :   buffer_manager->write_to_active_buffer();
     372            1 :   buffer_manager->write_to_active_buffer();
     373            1 :   buffer_manager->write_to_active_buffer();
     374              : 
     375              :   // Final read should still work
     376            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     377            1 :   BOOST_TEST(state_value.m_size == 2);
     378            1 :   BOOST_TEST(state_value.m_data != nullptr);
     379            9 : }
     380              : 
     381            2 : BOOST_AUTO_TEST_CASE(test_read_without_write) {
     382            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     383            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     384              : 
     385            1 :   nlohmann::json config = {
     386            2 :     {"accum_limit", 10},
     387              :     {"metric_collect_toggle_state", true},
     388              :     {"requested_internal_states", "pedestal,accum"}
     389           10 :   };
     390              : 
     391            1 :   pc->configure(config, plane_numbers);
     392              : 
     393            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     394              : 
     395              :   // Read without explicit write should still work (buffer initialized)
     396            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     397              :   
     398              :   // May be empty or initialized, but should not crash
     399            1 :   BOOST_TEST(true);
     400            9 : }
     401              : 
     402            2 : BOOST_AUTO_TEST_CASE(test_alternating_write_read) {
     403            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     404            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     405              : 
     406            1 :   nlohmann::json config = {
     407            2 :     {"accum_limit", 10},
     408              :     {"metric_collect_toggle_state", true},
     409              :     {"requested_internal_states", "pedestal,accum"}
     410           10 :   };
     411              : 
     412            1 :   pc->configure(config, plane_numbers);
     413              : 
     414            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     415              : 
     416           11 :   for (int i = 0; i < 10; ++i) {
     417           10 :     buffer_manager->write_to_active_buffer();
     418           10 :     auto state_value = buffer_manager->switch_buffer_and_read_casted();
     419           10 :     BOOST_TEST(state_value.m_size == 2);
     420              :   }
     421            9 : }
     422              : 
     423              : BOOST_AUTO_TEST_SUITE_END()
     424              : 
     425              : // =============================================================================
     426              : // SECTION 5: Data Integrity with Processing
     427              : // =============================================================================
     428              : 
     429              : BOOST_AUTO_TEST_SUITE(DataIntegrityWithProcessing)
     430              : 
     431            2 : BOOST_AUTO_TEST_CASE(test_pedestal_adjustment_after_processing) {
     432            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     433            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     434              : 
     435            1 :   nlohmann::json config = {
     436            2 :     {"accum_limit", 3},  // Small limit for faster adjustment
     437              :     {"metric_collect_toggle_state", true},
     438            2 :     {"metric_collect_time_sample_period", 1},  // Collect every sample
     439              :     {"requested_internal_states", "pedestal,accum"}
     440           13 :   };
     441              : 
     442            1 :   pc->configure(config, plane_numbers);
     443              : 
     444              :   // Create signal consistently above initial pedestal
     445              :   int16_t signal_values[16];
     446           17 :   for (int i = 0; i < 16; ++i) {
     447           16 :     signal_values[i] = 0x5000;  // Above initial 0x4000
     448              :   }
     449            1 :   __m256i signal = create_test_signal(signal_values);
     450              : 
     451              :   // Process multiple times to trigger pedestal adjustment
     452              :   // Note: The buffer collection happens BEFORE processing in the current implementation,
     453              :   // so we need extra iterations to see the effect
     454           21 :   for (int i = 0; i < 20; ++i) {
     455           20 :     pc->process(signal);
     456              :   }
     457              : 
     458              :   // Capture final state after all processing
     459            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     460            1 :   buffer_manager->write_to_active_buffer();
     461            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     462              : 
     463            1 :   BOOST_TEST(state_value.m_size == 2);
     464              :   
     465              :   // With accum_limit=3 and signal consistently above pedestal,
     466              :   // after 20 iterations, pedestal should have increased
     467              :   // Check that at least some channels show pedestal increase
     468            1 :   bool pedestal_increased = false;
     469            1 :   for (int i = 0; i < 16; ++i) {
     470            1 :     if (state_value.m_data[0][i] > 0x4000) {
     471            1 :       pedestal_increased = true;
     472            1 :       break;
     473              :     }
     474              :   }
     475            1 :   BOOST_TEST(pedestal_increased);
     476           11 : }
     477              : 
     478            2 : BOOST_AUTO_TEST_CASE(test_accum_changes_with_processing) {
     479            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     480            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     481              : 
     482            1 :   nlohmann::json config = {
     483            2 :     {"accum_limit", 100},  // Large limit to prevent pedestal adjustment
     484              :     {"metric_collect_toggle_state", true},
     485            2 :     {"metric_collect_time_sample_period", 1},
     486              :     {"requested_internal_states", "accum"}
     487           13 :   };
     488              : 
     489            1 :   pc->configure(config, plane_numbers);
     490              : 
     491              :   // Signal above pedestal
     492              :   int16_t signal_values[16];
     493           17 :   for (int i = 0; i < 16; ++i) {
     494           16 :     signal_values[i] = 0x5000;
     495              :   }
     496            1 :   __m256i signal = create_test_signal(signal_values);
     497              : 
     498              :   // Process more times to ensure accumulation
     499           16 :   for (int i = 0; i < 15; ++i) {
     500           15 :     pc->process(signal);
     501              :   }
     502              : 
     503            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     504            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     505              : 
     506            1 :   BOOST_TEST(state_value.m_size == 1);
     507            1 :   BOOST_TEST(state_value.m_data != nullptr);
     508              :   
     509              :   // After many iterations with signal > pedestal, accum should accumulate
     510              :   // Note: Due to collection timing, just verify data is present and reasonable
     511           11 : }
     512              : 
     513            2 : BOOST_AUTO_TEST_CASE(test_negative_accum_with_low_signals) {
     514            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     515            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     516              : 
     517            1 :   nlohmann::json config = {
     518            2 :     {"accum_limit", 100},
     519              :     {"metric_collect_toggle_state", true},
     520            2 :     {"metric_collect_time_sample_period", 1},
     521              :     {"requested_internal_states", "accum"}
     522           13 :   };
     523              : 
     524            1 :   pc->configure(config, plane_numbers);
     525              : 
     526              :   // Signal below pedestal
     527              :   int16_t signal_values[16];
     528           17 :   for (int i = 0; i < 16; ++i) {
     529           16 :     signal_values[i] = 0x3000;  // Below initial 0x4000
     530              :   }
     531            1 :   __m256i signal = create_test_signal(signal_values);
     532              : 
     533              :   // Process more times
     534           16 :   for (int i = 0; i < 15; ++i) {
     535           15 :     pc->process(signal);
     536              :   }
     537              : 
     538            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     539            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     540              : 
     541            1 :   BOOST_TEST(state_value.m_size == 1);
     542            1 :   BOOST_TEST(state_value.m_data != nullptr);
     543              :   
     544              :   // After processing with low signals, accum tracking should work
     545              :   // Note: Due to collection timing, just verify mechanism works
     546           11 : }
     547              : 
     548            2 : BOOST_AUTO_TEST_CASE(test_accum_reset_after_limit) {
     549            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     550            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     551              : 
     552            1 :   nlohmann::json config = {
     553            2 :     {"accum_limit", 3},  // Small limit
     554              :     {"metric_collect_toggle_state", true},
     555            2 :     {"metric_collect_time_sample_period", 1},
     556              :     {"requested_internal_states", "accum"}
     557           13 :   };
     558              : 
     559            1 :   pc->configure(config, plane_numbers);
     560              : 
     561              :   // Signal above pedestal
     562              :   int16_t signal_values[16];
     563           17 :   for (int i = 0; i < 16; ++i) {
     564           16 :     signal_values[i] = 0x5000;
     565              :   }
     566            1 :   __m256i signal = create_test_signal(signal_values);
     567              : 
     568              :   // Process enough times to hit the limit and reset
     569           11 :   for (int i = 0; i < 10; ++i) {
     570           10 :     pc->process(signal);
     571              :   }
     572              : 
     573            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     574            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     575              : 
     576            1 :   BOOST_TEST(state_value.m_size == 1);
     577              :   
     578              :   // Accum should be small (reset after hitting limit multiple times)
     579            1 :   bool accum_reasonable = true;
     580           17 :   for (int i = 0; i < 16; ++i) {
     581           16 :     if (std::abs(state_value.m_data[0][i]) > 10) {
     582            0 :       accum_reasonable = false;
     583            0 :       break;
     584              :     }
     585              :   }
     586            1 :   BOOST_TEST(accum_reasonable);
     587           11 : }
     588              : 
     589            2 : BOOST_AUTO_TEST_CASE(test_processing_with_varying_signals) {
     590            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     591            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     592              : 
     593            1 :   nlohmann::json config = {
     594            2 :     {"accum_limit", 10},
     595              :     {"metric_collect_toggle_state", true},
     596            2 :     {"metric_collect_time_sample_period", 1},
     597              :     {"requested_internal_states", "pedestal,accum"}
     598           13 :   };
     599              : 
     600            1 :   pc->configure(config, plane_numbers);
     601              : 
     602              :   // Process with varying signals
     603           21 :   for (int iteration = 0; iteration < 20; ++iteration) {
     604              :     int16_t signal_values[16];
     605          340 :     for (int i = 0; i < 16; ++i) {
     606              :       // Alternating high and low signals
     607          480 :       signal_values[i] = (iteration % 2 == 0) ? 0x5000 : 0x3000;
     608              :     }
     609           20 :     __m256i signal = create_test_signal(signal_values);
     610           20 :     pc->process(signal);
     611              :   }
     612              : 
     613            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     614            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     615              : 
     616            1 :   BOOST_TEST(state_value.m_size == 2);
     617            1 :   BOOST_TEST(state_value.m_data != nullptr);
     618           11 : }
     619              : 
     620              : BOOST_AUTO_TEST_SUITE_END()
     621              : 
     622              : // =============================================================================
     623              : // SECTION 6: Edge Cases
     624              : // =============================================================================
     625              : 
     626              : BOOST_AUTO_TEST_SUITE(EdgeCases)
     627              : 
     628            2 : BOOST_AUTO_TEST_CASE(test_empty_requested_states) {
     629            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     630            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     631              : 
     632            1 :   nlohmann::json config = {
     633            2 :     {"accum_limit", 10},
     634              :     {"metric_collect_toggle_state", true},
     635              :     {"requested_internal_states", ""}
     636           10 :   };
     637              : 
     638            1 :   pc->configure(config, plane_numbers);
     639              : 
     640            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     641            1 :   buffer_manager->write_to_active_buffer();
     642              : 
     643            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     644              : 
     645              :   // Should return empty or size 0
     646            1 :   BOOST_TEST(state_value.m_size == 0);
     647            9 : }
     648              : 
     649            2 : BOOST_AUTO_TEST_CASE(test_invalid_state_name) {
     650            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     651            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     652              : 
     653            1 :   nlohmann::json config = {
     654            2 :     {"accum_limit", 10},
     655              :     {"metric_collect_toggle_state", true},
     656              :     {"requested_internal_states", "invalid_state_name"}
     657           10 :   };
     658              : 
     659            1 :   pc->configure(config, plane_numbers);
     660              : 
     661            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     662              :   
     663              :   // Should handle invalid state names gracefully without crashing
     664            1 :   buffer_manager->write_to_active_buffer();
     665            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     666              : 
     667              :   // Should return buffer with size matching requested items
     668            1 :   BOOST_TEST(state_value.m_size == 1);
     669            1 :   BOOST_TEST(state_value.m_data != nullptr);
     670              :   
     671              :   // Invalid state should have zeroed data
     672            1 :   bool all_zero = true;
     673           17 :   for (int i = 0; i < 16; ++i) {
     674           16 :     if (state_value.m_data[0][i] != 0) {
     675            0 :       all_zero = false;
     676            0 :       break;
     677              :     }
     678              :   }
     679            1 :   BOOST_TEST(all_zero);
     680            9 : }
     681              : 
     682            2 : BOOST_AUTO_TEST_CASE(test_partial_invalid_names) {
     683            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     684            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     685              : 
     686            1 :   nlohmann::json config = {
     687            2 :     {"accum_limit", 10},
     688              :     {"metric_collect_toggle_state", true},
     689              :     {"requested_internal_states", "pedestal,invalid,accum"}
     690           10 :   };
     691              : 
     692            1 :   pc->configure(config, plane_numbers);
     693              : 
     694            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     695              :   
     696              :   // Should handle mixture of valid and invalid names gracefully
     697            1 :   buffer_manager->write_to_active_buffer();
     698            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     699              : 
     700            1 :   BOOST_TEST(state_value.m_size == 3);
     701            1 :   BOOST_TEST(state_value.m_data != nullptr);
     702              :   
     703              :   // First element (pedestal) should have non-zero values (0x4000)
     704            1 :   bool pedestal_valid = false;
     705            1 :   for (int i = 0; i < 16; ++i) {
     706            1 :     if (state_value.m_data[0][i] == 0x4000) {
     707            1 :       pedestal_valid = true;
     708            1 :       break;
     709              :     }
     710              :   }
     711            1 :   BOOST_TEST(pedestal_valid);
     712              :   
     713              :   // Second element (invalid) should be all zeros
     714            1 :   bool invalid_zero = true;
     715           17 :   for (int i = 0; i < 16; ++i) {
     716           16 :     if (state_value.m_data[1][i] != 0) {
     717            0 :       invalid_zero = false;
     718            0 :       break;
     719              :     }
     720              :   }
     721            1 :   BOOST_TEST(invalid_zero);
     722              :   
     723              :   // Third element (accum) should be zero (initialized)
     724            1 :   bool accum_zero = true;
     725           17 :   for (int i = 0; i < 16; ++i) {
     726           16 :     if (state_value.m_data[2][i] != 0) {
     727            0 :       accum_zero = false;
     728            0 :       break;
     729              :     }
     730              :   }
     731            1 :   BOOST_TEST(accum_zero);
     732            9 : }
     733              : 
     734            2 : BOOST_AUTO_TEST_CASE(test_duplicate_state_names) {
     735            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     736            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     737              : 
     738            1 :   nlohmann::json config = {
     739            2 :     {"accum_limit", 10},
     740              :     {"metric_collect_toggle_state", true},
     741              :     {"requested_internal_states", "pedestal,pedestal,accum"}
     742           10 :   };
     743              : 
     744            1 :   pc->configure(config, plane_numbers);
     745              : 
     746            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     747            1 :   buffer_manager->write_to_active_buffer();
     748              : 
     749            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     750              : 
     751            1 :   BOOST_TEST(state_value.m_size == 3);
     752            9 : }
     753              : 
     754            2 : BOOST_AUTO_TEST_CASE(test_trailing_comma) {
     755            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     756            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     757              : 
     758            1 :   nlohmann::json config = {
     759            2 :     {"accum_limit", 10},
     760              :     {"metric_collect_toggle_state", true},
     761              :     {"requested_internal_states", "pedestal,accum,"}
     762           10 :   };
     763              : 
     764            1 :   pc->configure(config, plane_numbers);
     765              : 
     766            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     767            1 :   buffer_manager->write_to_active_buffer();
     768              : 
     769            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     770              : 
     771            1 :   BOOST_TEST(state_value.m_size == 2);
     772            9 : }
     773              : 
     774            2 : BOOST_AUTO_TEST_CASE(test_only_commas) {
     775            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     776            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     777              : 
     778            1 :   nlohmann::json config = {
     779            2 :     {"accum_limit", 10},
     780              :     {"metric_collect_toggle_state", true},
     781              :     {"requested_internal_states", ",,,"}
     782           10 :   };
     783              : 
     784            1 :   pc->configure(config, plane_numbers);
     785              : 
     786            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     787            1 :   buffer_manager->write_to_active_buffer();
     788              : 
     789            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     790              : 
     791            1 :   BOOST_TEST(state_value.m_size == 0);
     792            9 : }
     793              : 
     794              : BOOST_AUTO_TEST_SUITE_END()
     795              : 
     796              : // =============================================================================
     797              : // SECTION 7: Integration Tests
     798              : // =============================================================================
     799              : 
     800              : BOOST_AUTO_TEST_SUITE(IntegrationTests)
     801              : 
     802            2 : BOOST_AUTO_TEST_CASE(test_full_processing_cycle) {
     803            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     804            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     805              : 
     806            1 :   nlohmann::json config = {
     807            2 :     {"accum_limit", 5},
     808              :     {"metric_collect_toggle_state", true},
     809            2 :     {"metric_collect_time_sample_period", 1},
     810              :     {"requested_internal_states", "pedestal,accum"}
     811           13 :   };
     812              : 
     813            1 :   pc->configure(config, plane_numbers);
     814              :   
     815              :   // Check initial state
     816            1 :   auto buffer_manager = pc->_get_internal_state_buffer_manager();
     817            1 :   buffer_manager->write_to_active_buffer();
     818            1 :   auto initial_state = buffer_manager->switch_buffer_and_read_casted();
     819              :   
     820            1 :   int16_t initial_pedestal_value = initial_state.m_data[0][0];
     821              : 
     822              :   // Use a simpler test: constant high signal to force upward adaptation
     823            1 :   int16_t signal_values[16];
     824           17 :   for (int i = 0; i < 16; ++i) {
     825           16 :     signal_values[i] = 0x5000;  // Consistently above initial pedestal
     826              :   }
     827            1 :   __m256i signal = create_test_signal(signal_values);
     828              : 
     829              :   // Process enough times to see adaptation
     830           51 :   for (int iteration = 0; iteration < 50; ++iteration) {
     831           50 :     pc->process(signal);
     832              :   }
     833              : 
     834              :   // Capture final state after all processing
     835            1 :   buffer_manager->write_to_active_buffer();
     836            1 :   auto state_value = buffer_manager->switch_buffer_and_read_casted();
     837              : 
     838            1 :   BOOST_TEST(state_value.m_size == 2);
     839              :   
     840              :   // With constant high signal, pedestals should increase from initial
     841            1 :   bool pedestals_increased = false;
     842            1 :   for (int i = 0; i < 16; ++i) {
     843            1 :     int16_t final_pedestal = state_value.m_data[0][i];
     844              :     
     845              :     // Should have increased from initial value
     846            1 :     if (final_pedestal > initial_pedestal_value) {
     847            1 :       pedestals_increased = true;
     848            1 :       break;
     849              :     }
     850              :   }
     851            1 :   BOOST_TEST(pedestals_increased);
     852           11 : }
     853              : 
     854            2 : BOOST_AUTO_TEST_CASE(test_multiple_processors_independence) {
     855            1 :   auto pc1 = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     856            1 :   auto pc2 = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     857              :   
     858            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     859              : 
     860            1 :   nlohmann::json config1 = {
     861            2 :     {"accum_limit", 10},
     862              :     {"metric_collect_toggle_state", true},
     863              :     {"requested_internal_states", "pedestal"}
     864           10 :   };
     865              : 
     866            1 :   nlohmann::json config2 = {
     867            2 :     {"accum_limit", 20},
     868              :     {"metric_collect_toggle_state", true},
     869              :     {"requested_internal_states", "accum"}
     870           10 :   };
     871              : 
     872            1 :   pc1->configure(config1, plane_numbers);
     873            1 :   pc2->configure(config2, plane_numbers);
     874              : 
     875            1 :   auto bm1 = pc1->_get_internal_state_buffer_manager();
     876            1 :   auto bm2 = pc2->_get_internal_state_buffer_manager();
     877              : 
     878            1 :   bm1->write_to_active_buffer();
     879            1 :   bm2->write_to_active_buffer();
     880              : 
     881            1 :   auto state1 = bm1->switch_buffer_and_read_casted();
     882            1 :   auto state2 = bm2->switch_buffer_and_read_casted();
     883              : 
     884            1 :   BOOST_TEST(state1.m_size == 1);
     885            1 :   BOOST_TEST(state2.m_size == 1);
     886              :   
     887              :   // They should be independent
     888            1 :   BOOST_TEST(state1.m_data != state2.m_data);
     889           16 : }
     890              : 
     891            2 : BOOST_AUTO_TEST_CASE(test_reconfiguration) {
     892            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     893            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     894              : 
     895              :   // First configuration
     896            1 :   nlohmann::json config1 = {
     897            2 :     {"accum_limit", 10},
     898              :     {"metric_collect_toggle_state", true},
     899              :     {"requested_internal_states", "pedestal"}
     900           10 :   };
     901              : 
     902            1 :   pc->configure(config1, plane_numbers);
     903            1 :   auto bm = pc->_get_internal_state_buffer_manager();
     904            1 :   bm->write_to_active_buffer();
     905            1 :   auto state1 = bm->switch_buffer_and_read_casted();
     906            1 :   BOOST_TEST(state1.m_size == 1);
     907              : 
     908              :   // Reconfigure
     909            1 :   nlohmann::json config2 = {
     910            2 :     {"accum_limit", 20},
     911              :     {"metric_collect_toggle_state", true},
     912              :     {"requested_internal_states", "pedestal,accum"}
     913           10 :   };
     914              : 
     915            1 :   pc->configure(config2, plane_numbers);
     916            1 :   bm = pc->_get_internal_state_buffer_manager();
     917            1 :   bm->write_to_active_buffer();
     918            1 :   auto state2 = bm->switch_buffer_and_read_casted();
     919            1 :   BOOST_TEST(state2.m_size == 2);
     920           17 : }
     921              : 
     922            2 : BOOST_AUTO_TEST_CASE(test_long_running_collection) {
     923            1 :   auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     924            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     925              : 
     926            1 :   nlohmann::json config = {
     927            2 :     {"accum_limit", 10},
     928              :     {"metric_collect_toggle_state", true},
     929            2 :     {"metric_collect_time_sample_period", 1},
     930              :     {"requested_internal_states", "pedestal,accum"}
     931           13 :   };
     932              : 
     933            1 :   pc->configure(config, plane_numbers);
     934              : 
     935              :   // Simulate long running with periodic collections
     936           11 :   for (int cycle = 0; cycle < 10; ++cycle) {
     937              :     // Process some samples
     938              :     int16_t signal_values[16];
     939          170 :     for (int i = 0; i < 16; ++i) {
     940          160 :       signal_values[i] = 0x4000 + (cycle * 100);
     941              :     }
     942           10 :     __m256i signal = create_test_signal(signal_values);
     943              :     
     944          510 :     for (int i = 0; i < 50; ++i) {
     945          500 :       pc->process(signal);
     946              :     }
     947              : 
     948              :     // Collect state
     949           10 :     auto bm = pc->_get_internal_state_buffer_manager();
     950           10 :     auto state = bm->switch_buffer_and_read_casted();
     951           10 :     BOOST_TEST(state.m_size == 2);
     952              :   }
     953           11 : }
     954              : 
     955              : BOOST_AUTO_TEST_SUITE_END()
     956              : 
     957              : // =============================================================================
     958              : // SECTION 8: Memory and Cleanup
     959              : // =============================================================================
     960              : 
     961              : BOOST_AUTO_TEST_SUITE(MemoryAndCleanup)
     962              : 
     963            2 : BOOST_AUTO_TEST_CASE(test_processor_destruction) {
     964            1 :   {
     965            1 :     auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     966            1 :     int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     967              : 
     968            1 :     nlohmann::json config = {
     969            2 :       {"accum_limit", 10},
     970              :       {"metric_collect_toggle_state", true},
     971              :       {"requested_internal_states", "pedestal,accum"}
     972           10 :     };
     973              : 
     974            1 :     pc->configure(config, plane_numbers);
     975            1 :     auto bm = pc->_get_internal_state_buffer_manager();
     976            1 :     bm->write_to_active_buffer();
     977            1 :   }
     978              :   // Processor destroyed, should not leak
     979            1 :   BOOST_TEST(true);
     980            9 : }
     981              : 
     982            2 : BOOST_AUTO_TEST_CASE(test_multiple_allocations) {
     983            1 :   std::vector<std::shared_ptr<AVXFrugalPedestalSubtractProcessor>> processors;
     984            1 :   int16_t plane_numbers[16] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
     985              : 
     986            1 :   nlohmann::json config = {
     987            2 :     {"accum_limit", 10},
     988              :     {"metric_collect_toggle_state", true},
     989              :     {"requested_internal_states", "pedestal,accum"}
     990           10 :   };
     991              : 
     992              :   // Create multiple processors
     993           11 :   for (int i = 0; i < 10; ++i) {
     994           10 :     auto pc = std::make_shared<AVXFrugalPedestalSubtractProcessor>();
     995           10 :     pc->configure(config, plane_numbers);
     996           10 :     processors.push_back(pc);
     997           10 :   }
     998              : 
     999              :   // Use them all
    1000           11 :   for (auto& pc : processors) {
    1001           10 :     auto bm = pc->_get_internal_state_buffer_manager();
    1002           10 :     bm->write_to_active_buffer();
    1003           10 :     auto state = bm->switch_buffer_and_read_casted();
    1004           10 :     BOOST_TEST(state.m_size == 2);
    1005              :   }
    1006              : 
    1007              :   // Clean up
    1008            1 :   processors.clear();
    1009            1 :   BOOST_TEST(true);
    1010            9 : }
    1011              : 
    1012              : BOOST_AUTO_TEST_SUITE_END()
    1013              : 
    1014              : } // namespace tpglibs
        

Generated by: LCOV version 2.0-1