DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
tpglibs::TPGenerator Class Reference

TPG driving class. More...

#include <TPGenerator.hpp>

Public Member Functions

void configure (const std::vector< std::pair< std::string, nlohmann::json > > &configs, const std::vector< std::pair< dunedaq::trgdataformats::channel_t, int16_t > > channel_plane_numbers, const int sample_tick_difference)
 Setup and configure the AVX pipelines.
 
void set_sot_minima (const std::vector< uint16_t > &sot_minima)
 Set the minimum samples over threshold for a TP according to plane.
 
template<typename T >
std::vector< dunedaq::trgdataformats::TriggerPrimitiveoperator() (const T *frame)
 Driving function for the TPG.
 

Private Member Functions

__m256i expand_frame (const __m256i &regi)
 
__m256i old_expand_frame (const __m256i &regi)
 Expansion from 14-bit signals to 16-bit.
 

Private Attributes

uint8_t m_num_pipelines = 0
 
std::vector< AVXPipelinem_tpg_pipelines
 
int m_sample_tick_difference
 
std::vector< uint16_t > m_sot_minima {1,1,1}
 

Static Private Attributes

static const uint8_t m_num_channels_per_pipeline = 16
 

Detailed Description

TPG driving class.

This is the interface that receives raw data frames to process and outputs the TPs accordingly.

Definition at line 27 of file TPGenerator.hpp.

Member Function Documentation

◆ configure()

void tpglibs::TPGenerator::configure ( const std::vector< std::pair< std::string, nlohmann::json > > & configs,
const std::vector< std::pair< dunedaq::trgdataformats::channel_t, int16_t > > channel_plane_numbers,
const int sample_tick_difference )

Setup and configure the AVX pipelines.

Parameters
configsA vector of pairs: AVX pipeline to use and its configuration.
channel_plane_numbersA vector of channel numbers and their plane numbers.
sample_tick_differenceNumber of ticks between time samples in expected data frames.

Definition at line 14 of file TPGenerator.cpp.

16 {
17 m_num_pipelines = channel_plane_numbers.size() / m_num_channels_per_pipeline;
18 m_sample_tick_difference = sample_tick_difference;
19
20 for (int p = 0; p < m_num_pipelines; p++) {
21 AVXPipeline new_pipe = AVXPipeline();
22 auto begin_channel_plane = channel_plane_numbers.begin() + p*m_num_channels_per_pipeline;
23 auto end_channel_plane = begin_channel_plane + m_num_channels_per_pipeline;
24 new_pipe.configure(configs, std::vector<std::pair<dunedaq::trgdataformats::channel_t, int16_t>>(begin_channel_plane, end_channel_plane));
25 new_pipe.set_sot_minima(m_sot_minima);
26 m_tpg_pipelines.push_back(new_pipe);
27 }
28}
std::vector< uint16_t > m_sot_minima
std::vector< AVXPipeline > m_tpg_pipelines
static const uint8_t m_num_channels_per_pipeline

◆ expand_frame()

__m256i tpglibs::TPGenerator::expand_frame ( const __m256i & regi)
private

Definition at line 36 of file TPGenerator.cpp.

36 {
37 // Refer to the diagram and documentation on frame expansion for details.
38
39 // Prepare even (2,4,6,8), odd (1,3,5,7) rows in 64-bit sense.
40 __m256i odd = _mm256_permutevar8x32_epi32(regi, _mm256_setr_epi32(1, 0, 1, 2, 3, 4, 5, 6));
41
42 // Shift into place.
43 __m256i even = _mm256_sllv_epi64(regi, _mm256_setr_epi64x(6, 14, 22, 30));
44 odd = _mm256_srlv_epi64(odd, _mm256_setr_epi64x(30, 22, 14, 6));
45
46 // Everything is center aligned in 32-bit. Mask and right-align the right side.
47 __m256i both = _mm256_blend_epi32(even, odd, 0b01010101);
48 __m256i right = _mm256_and_si256(_mm256_set1_epi32(0xFFFFu), both);
49 __m256i left = _mm256_and_si256(_mm256_set1_epi32(0x3FFF0000u), both);
50
51 right = _mm256_srli_epi32(right, 2);
52 return _mm256_or_si256(left, right);
53}

◆ old_expand_frame()

__m256i tpglibs::TPGenerator::old_expand_frame ( const __m256i & regi)
private

Expansion from 14-bit signals to 16-bit.

Definition at line 56 of file TPGenerator.cpp.

56 {
57 // Refer to the diagram and documentation on frame expansion for details.
58
59 // Rearrange original with row 3 doubled.
60 __m256i idx = _mm256_set_epi32(6, 5, 4, 3, 3, 2, 1, 0);
61 __m256i shuf1 = _mm256_permutevar8x32_epi32(regi, idx);
62
63 // Left shift each row.
64 __m256i count = _mm256_set_epi32(12, 8, 4, 0, 14, 10, 6, 2);
65 __m256i high_half = _mm256_sllv_epi32(shuf1, count);
66 high_half = _mm256_and_si256(high_half, _mm256_set1_epi32(0x3FFF0000u)); // Mask out the low half.
67
68 // Left shift for low half later.
69 count = _mm256_set_epi32(10, 6, 2, 0, 12, 8, 4, 0);
70 __m256i shift2 = _mm256_sllv_epi32(shuf1, count);
71
72 // Rearrange original and doubled rows 2 and 0.
73 idx = _mm256_set_epi32(5, 4, 3, 2, 2, 1, 0, 0);
74 __m256i shuf2 = _mm256_permutevar8x32_epi32(regi, idx);
75
76 // Right shift each row.
77 count = _mm256_set_epi32(22, 26, 30, 0, 20, 24, 28, 0);
78 __m256i shift3 = _mm256_srlv_epi32(shuf2, count);
79
80 // "Complete" the low half. Still more.
81 __m256i low_half = _mm256_or_si256(shift2, shift3);
82 low_half = _mm256_and_si256(low_half, _mm256_set1_epi32(0x3FFFu)); // Mask out the high half.
83
84 // Combine halves and clear space for an odd entry.
85 __m256i both = _mm256_or_si256(low_half, high_half);
86 both = _mm256_andnot_si256(_mm256_set_epi32(0, 0, 0, 0xFFFFu, 0, 0, 0, 0), both);
87
88 // There is a specific 16-bit entry that needs special handling.
89 // Align it.
90 __m256i shift4 = _mm256_srli_epi32(regi, 18);
91 // Mask it.
92 shift4 = _mm256_and_si256(_mm256_set_epi32(0, 0x3FFFu, 0, 0, 0, 0, 0, 0), shift4);
93
94 // Permute into the right spot
95 idx = _mm256_set_epi32(0, 0, 0, 6, 0, 0, 0, 0);
96 __m256i shuf3 = _mm256_permutevar8x32_epi32(shift4, idx);
97
98 // Add it in.
99 both = _mm256_or_si256(both, shuf3);
100 return both;
101}

◆ operator()()

template<typename T >
std::vector< dunedaq::trgdataformats::TriggerPrimitive > tpglibs::TPGenerator::operator() ( const T * frame)
inline

Driving function for the TPG.

This function receives the frames, expands, sends down AVX pipelines, and returns TPs that were generated.

Parameters
frameA data frame to process and generate TPs from.
Returns
A vector of TPs.

Definition at line 62 of file TPGenerator.hpp.

62 {
63 // Max number of TPs for a channel: number of time samples / 2.
64 std::vector<dunedaq::trgdataformats::TriggerPrimitive> tp_aggr;
65 tp_aggr.reserve(T::s_num_channels * T::s_time_samples_per_frame / 2);
66
67 const typename T::word_t (*words_ptr)[T::s_bits_per_adc] = frame->adc_words;
68 const uint64_t timestamp = frame->get_timestamp();
69
70 const int register_alignment = T::s_bits_per_adc * m_num_channels_per_pipeline;
71 // Loop in time.
72 for (int t = 0; t < T::s_time_samples_per_frame; t++) {
73 const typename T::word_t *time_sample = *(words_ptr + t);
74 char* cursor = (char*) time_sample; // Need to walk in terms of bytes/bits.
75
76 // Loop in pipelines.
77 for (int p = 0; p < m_num_pipelines; p++) {
78 if (p == m_num_pipelines - 1)
79 cursor -= 4; // Take a step of 32 bit backwards for the last sub-frame.
80
81 __m256i regi = _mm256_lddqu_si256((__m256i*)cursor);
82
83 if (p == m_num_pipelines - 1) // Permute the row order to use the same operation.
84 regi = _mm256_permutevar8x32_epi32(regi, _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0));
85
86 __m256i expanded_subframe = expand_frame(regi);
87 std::vector<dunedaq::trgdataformats::TriggerPrimitive> tps = m_tpg_pipelines[p].process(expanded_subframe);
88
89 for (auto tp : tps) {
90 tp.time_start = (t - tp.samples_over_threshold) * m_sample_tick_difference + timestamp;
91 tp_aggr.push_back(tp);
92 }
93 cursor += register_alignment / 8; // Numerator is in bits. Need bytes.
94 }
95 }
96
97 return tp_aggr;
98 }
__m256i expand_frame(const __m256i &regi)

◆ set_sot_minima()

void tpglibs::TPGenerator::set_sot_minima ( const std::vector< uint16_t > & sot_minima)

Set the minimum samples over threshold for a TP according to plane.

Parameters
sot_minimaTPs from plane i will have at least sot_minima[i] value for its samples_over_threshold.

Definition at line 31 of file TPGenerator.cpp.

31 {
32 m_sot_minima = sot_minima;
33}

Member Data Documentation

◆ m_num_channels_per_pipeline

const uint8_t tpglibs::TPGenerator::m_num_channels_per_pipeline = 16
staticprivate

Definition at line 28 of file TPGenerator.hpp.

◆ m_num_pipelines

uint8_t tpglibs::TPGenerator::m_num_pipelines = 0
private

Definition at line 29 of file TPGenerator.hpp.

◆ m_sample_tick_difference

int tpglibs::TPGenerator::m_sample_tick_difference
private

Definition at line 31 of file TPGenerator.hpp.

◆ m_sot_minima

std::vector<uint16_t> tpglibs::TPGenerator::m_sot_minima {1,1,1}
private

Definition at line 32 of file TPGenerator.hpp.

32{1,1,1}; // Defaults to 1 for all planes.

◆ m_tpg_pipelines

std::vector<AVXPipeline> tpglibs::TPGenerator::m_tpg_pipelines
private

Definition at line 30 of file TPGenerator.hpp.


The documentation for this class was generated from the following files: