LCOV - code coverage report
Current view: top level - tpglibs/src - TPGenerator.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 47.7 % 65 31
Test Date: 2026-10-11 15:05:20 Functions: 50.0 % 6 3

            Line data    Source code
       1              : /**
       2              :  * @file TPGenerator.hpp
       3              :  *
       4              :  * @copyright This is part of the DUNE DAQ Software Suite, copyright 2020.
       5              :  * Licensing/copyright details are in the COPYING file that you should have
       6              :  * received with this code.
       7              :  */
       8              : 
       9              : #include "tpglibs/TPGenerator.hpp"
      10              : 
      11              : namespace tpglibs {
      12              : 
      13              : void
      14            3 : TPGenerator::configure(const std::vector<std::pair<std::string, nlohmann::json>>& configs,
      15              :                        const std::vector<std::pair<dunedaq::trgdataformats::channel_t, int16_t>> channel_plane_numbers,
      16              :                        const float sample_tick_difference)
      17              : {
      18            3 :   if (m_configured) {
      19            0 :     reset();
      20              :   }
      21              : 
      22            3 :   m_num_pipelines = channel_plane_numbers.size() / m_num_channels_per_pipeline;
      23            3 :   m_sample_tick_difference = sample_tick_difference;
      24              : 
      25           15 :   for (int p = 0; p < m_num_pipelines; p++) {
      26           12 :     AVXPipeline new_pipe = AVXPipeline();
      27           12 :     auto begin_channel_plane = channel_plane_numbers.begin() + p * m_num_channels_per_pipeline;
      28           12 :     auto end_channel_plane = begin_channel_plane + m_num_channels_per_pipeline;
      29           12 :     new_pipe.configure(
      30              :       configs,
      31           24 :       std::vector<std::pair<dunedaq::trgdataformats::channel_t, int16_t>>(begin_channel_plane, end_channel_plane));
      32           12 :     new_pipe.set_sot_minima(m_sot_minima);
      33           12 :     m_tpg_pipelines.push_back(new_pipe);
      34           12 :   }
      35              : 
      36            3 :   m_configured = true;
      37            3 : }
      38              : 
      39              : std::vector<std::pair<std::shared_ptr<AbstractProcessor<__m256i>>, int>>
      40            0 : TPGenerator::get_all_processor_references_with_pipeline_index()
      41              : {
      42            0 :   std::vector<std::pair<std::shared_ptr<AbstractProcessor<__m256i>>, int>> processor_references;
      43              : 
      44            0 :   for (int pipeline_id = 0; pipeline_id < m_num_pipelines; ++pipeline_id) {
      45            0 :     for (auto& processor : m_tpg_pipelines[pipeline_id].get_all_processor_references()) {
      46            0 :       processor_references.push_back(std::make_pair(processor, pipeline_id));
      47            0 :     }
      48              :   }
      49            0 :   return processor_references;
      50            0 : }
      51              : 
      52              : void
      53            2 : TPGenerator::reset()
      54              : {
      55            2 :   m_num_pipelines = 0;
      56            2 :   m_tpg_pipelines.clear();
      57            2 :   m_sample_tick_difference = 0;
      58            2 :   m_sot_minima = { 1, 1, 1 };
      59            2 :   m_configured = false;
      60            2 : }
      61              : 
      62              : void
      63            0 : TPGenerator::set_sot_minima(const std::vector<uint16_t>& sot_minima)
      64              : {
      65            0 :   m_sot_minima = sot_minima;
      66            0 : }
      67              : 
      68              : __m256i
      69          768 : TPGenerator::expand_frame(const __m256i& regi)
      70              : {
      71              :   // Refer to the diagram and documentation on frame expansion for details.
      72              : 
      73              :   // Prepare even (2,4,6,8), odd (1,3,5,7) rows in 64-bit sense.
      74          768 :   __m256i odd = _mm256_permutevar8x32_epi32(regi, _mm256_setr_epi32(1, 0, 1, 2, 3, 4, 5, 6));
      75              : 
      76              :   // Shift into place.
      77          768 :   __m256i even = _mm256_sllv_epi64(regi, _mm256_setr_epi64x(6, 14, 22, 30));
      78          768 :   odd = _mm256_srlv_epi64(odd, _mm256_setr_epi64x(30, 22, 14, 6));
      79              : 
      80              :   // Everything is center aligned in 32-bit. Mask and right-align the right side.
      81          768 :   __m256i both = _mm256_blend_epi32(even, odd, 0b01010101);
      82          768 :   __m256i right = _mm256_and_si256(_mm256_set1_epi32(0xFFFFu), both);
      83          768 :   __m256i left = _mm256_and_si256(_mm256_set1_epi32(0x3FFF0000u), both);
      84              : 
      85          768 :   right = _mm256_srli_epi32(right, 2);
      86          768 :   return _mm256_or_si256(left, right);
      87              : }
      88              : 
      89              : __m256i
      90            0 : TPGenerator::old_expand_frame(const __m256i& regi)
      91              : {
      92              :   // Refer to the diagram and documentation on frame expansion for details.
      93              : 
      94              :   // Rearrange original with row 3 doubled.
      95            0 :   __m256i idx = _mm256_set_epi32(6, 5, 4, 3, 3, 2, 1, 0);
      96            0 :   __m256i shuf1 = _mm256_permutevar8x32_epi32(regi, idx);
      97              : 
      98              :   // Left shift each row.
      99            0 :   __m256i count = _mm256_set_epi32(12, 8, 4, 0, 14, 10, 6, 2);
     100            0 :   __m256i high_half = _mm256_sllv_epi32(shuf1, count);
     101            0 :   high_half = _mm256_and_si256(high_half, _mm256_set1_epi32(0x3FFF0000u)); // Mask out the low half.
     102              : 
     103              :   // Left shift for low half later.
     104            0 :   count = _mm256_set_epi32(10, 6, 2, 0, 12, 8, 4, 0);
     105            0 :   __m256i shift2 = _mm256_sllv_epi32(shuf1, count);
     106              : 
     107              :   // Rearrange original and doubled rows 2 and 0.
     108            0 :   idx = _mm256_set_epi32(5, 4, 3, 2, 2, 1, 0, 0);
     109            0 :   __m256i shuf2 = _mm256_permutevar8x32_epi32(regi, idx);
     110              : 
     111              :   // Right shift each row.
     112            0 :   count = _mm256_set_epi32(22, 26, 30, 0, 20, 24, 28, 0);
     113            0 :   __m256i shift3 = _mm256_srlv_epi32(shuf2, count);
     114              : 
     115              :   // "Complete" the low half. Still more.
     116            0 :   __m256i low_half = _mm256_or_si256(shift2, shift3);
     117            0 :   low_half = _mm256_and_si256(low_half, _mm256_set1_epi32(0x3FFFu)); // Mask out the high half.
     118              : 
     119              :   // Combine halves and clear space for an odd entry.
     120            0 :   __m256i both = _mm256_or_si256(low_half, high_half);
     121            0 :   both = _mm256_andnot_si256(_mm256_set_epi32(0, 0, 0, 0xFFFFu, 0, 0, 0, 0), both);
     122              : 
     123              :   // There is a specific 16-bit entry that needs special handling.
     124              :   // Align it.
     125            0 :   __m256i shift4 = _mm256_srli_epi32(regi, 18);
     126              :   // Mask it.
     127            0 :   shift4 = _mm256_and_si256(_mm256_set_epi32(0, 0x3FFFu, 0, 0, 0, 0, 0, 0), shift4);
     128              : 
     129              :   // Permute into the right spot
     130            0 :   idx = _mm256_set_epi32(0, 0, 0, 6, 0, 0, 0, 0);
     131            0 :   __m256i shuf3 = _mm256_permutevar8x32_epi32(shift4, idx);
     132              : 
     133              :   // Add it in.
     134            0 :   both = _mm256_or_si256(both, shuf3);
     135            0 :   return both;
     136              : }
     137              : 
     138              : } // namespace tpglibs
        

Generated by: LCOV version 2.0-1