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.
 
void * get_processor_metric_collector ()
 Lazily initialize and return the processor metric collector.
 
std::shared_ptr< ProcessorMetricCollector< __m256i > > get_processor_metric_collector_ptr ()
 
void set_metric_collector_enable_state (bool state)
 
bool get_metric_collector_enable_state ()
 
void signal_metric_collection ()
 
std::unordered_map< dunedaq::trgdataformats::channel_t, std::vector< std::pair< std::string, int16_t > > > get_processor_metrics ()
 
void free_metric_collector ()
 
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}
 
std::shared_ptr< ProcessorMetricCollector< __m256i > > m_processor_metric_collector_ptr {nullptr}
 
bool m_tpg_metric_collect_enabled {false}
 

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 31 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 (const auto& name_config : configs) {
21 if (name_config.second.contains("metric_collect_toggle_state") && name_config.second["metric_collect_toggle_state"] == true) {
23 }
24 }
25
26 if (m_tpg_metric_collect_enabled) get_processor_metric_collector_ptr()->configure(configs, channel_plane_numbers, m_num_pipelines);
27
28 for (int p = 0; p < m_num_pipelines; p++) {
29 AVXPipeline new_pipe = AVXPipeline();
30 auto begin_channel_plane = channel_plane_numbers.begin() + p*m_num_channels_per_pipeline;
31 auto end_channel_plane = begin_channel_plane + m_num_channels_per_pipeline;
32 new_pipe.configure(configs, std::vector<std::pair<dunedaq::trgdataformats::channel_t, int16_t>>(begin_channel_plane, end_channel_plane));
33 new_pipe.set_sot_minima(m_sot_minima);
34 m_tpg_pipelines.push_back(new_pipe);
35 }
36
37 int total_pipelines = m_tpg_pipelines.size();
38 int start_index = (total_pipelines >= m_num_pipelines) ? (total_pipelines - m_num_pipelines) : 0;
39 int pipeline_id = 0;
40 for (int i = start_index; i < total_pipelines && pipeline_id < m_num_pipelines; ++i, ++pipeline_id) {
41 auto& pipeline = m_tpg_pipelines[i];
42 if (m_tpg_metric_collect_enabled) pipeline.attach_to_metric_collector(*get_processor_metric_collector_ptr(), pipeline_id);
43 // I belive this is a current separate bug with repopulating the m_tpg_pipelines. Doing the safer treatment to take last pushed m_num_pipelines pipelines.
44 }
45
47
48}
std::shared_ptr< ProcessorMetricCollector< __m256i > > get_processor_metric_collector_ptr()
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 79 of file TPGenerator.cpp.

79 {
80 // Refer to the diagram and documentation on frame expansion for details.
81
82 // Prepare even (2,4,6,8), odd (1,3,5,7) rows in 64-bit sense.
83 __m256i odd = _mm256_permutevar8x32_epi32(regi, _mm256_setr_epi32(1, 0, 1, 2, 3, 4, 5, 6));
84
85 // Shift into place.
86 __m256i even = _mm256_sllv_epi64(regi, _mm256_setr_epi64x(6, 14, 22, 30));
87 odd = _mm256_srlv_epi64(odd, _mm256_setr_epi64x(30, 22, 14, 6));
88
89 // Everything is center aligned in 32-bit. Mask and right-align the right side.
90 __m256i both = _mm256_blend_epi32(even, odd, 0b01010101);
91 __m256i right = _mm256_and_si256(_mm256_set1_epi32(0xFFFFu), both);
92 __m256i left = _mm256_and_si256(_mm256_set1_epi32(0x3FFF0000u), both);
93
94 right = _mm256_srli_epi32(right, 2);
95 return _mm256_or_si256(left, right);
96}

◆ free_metric_collector()

void tpglibs::TPGenerator::free_metric_collector ( )
inline

Definition at line 84 of file TPGenerator.hpp.

84 {
85 if (m_processor_metric_collector_ptr != nullptr) {
87
89 }
90 }
std::shared_ptr< ProcessorMetricCollector< __m256i > > m_processor_metric_collector_ptr

◆ get_metric_collector_enable_state()

bool tpglibs::TPGenerator::get_metric_collector_enable_state ( )
inline

Definition at line 76 of file TPGenerator.hpp.

76 {
78 }

◆ get_processor_metric_collector()

void * tpglibs::TPGenerator::get_processor_metric_collector ( )

Lazily initialize and return the processor metric collector.

If the collector has not yet been created, allocate a new ProcessorMetricCollector<__m256i> instance and store it in m_processor_metric_collector.

Returns
void* Pointer to the processor metric collector instance.

◆ get_processor_metric_collector_ptr()

std::shared_ptr< ProcessorMetricCollector< __m256i > > tpglibs::TPGenerator::get_processor_metric_collector_ptr ( )

Definition at line 50 of file TPGenerator.cpp.

50 {
51 if (m_processor_metric_collector_ptr == nullptr) {
52 m_processor_metric_collector_ptr = std::make_shared<ProcessorMetricCollector<__m256i>>();
53 }
55}

◆ get_processor_metrics()

std::unordered_map< dunedaq::trgdataformats::channel_t, std::vector< std::pair< std::string, int16_t > > > tpglibs::TPGenerator::get_processor_metrics ( )

Definition at line 61 of file TPGenerator.cpp.

61 {
62 get_processor_metric_collector_ptr()->lock_metric_modify();
63
64 auto metrics = get_processor_metric_collector_ptr()->get_metrics();
65
66 get_processor_metric_collector_ptr()->unlock_metric_modify();
67
68 return metrics;
69}

◆ old_expand_frame()

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

Expansion from 14-bit signals to 16-bit.

Definition at line 99 of file TPGenerator.cpp.

99 {
100 // Refer to the diagram and documentation on frame expansion for details.
101
102 // Rearrange original with row 3 doubled.
103 __m256i idx = _mm256_set_epi32(6, 5, 4, 3, 3, 2, 1, 0);
104 __m256i shuf1 = _mm256_permutevar8x32_epi32(regi, idx);
105
106 // Left shift each row.
107 __m256i count = _mm256_set_epi32(12, 8, 4, 0, 14, 10, 6, 2);
108 __m256i high_half = _mm256_sllv_epi32(shuf1, count);
109 high_half = _mm256_and_si256(high_half, _mm256_set1_epi32(0x3FFF0000u)); // Mask out the low half.
110
111 // Left shift for low half later.
112 count = _mm256_set_epi32(10, 6, 2, 0, 12, 8, 4, 0);
113 __m256i shift2 = _mm256_sllv_epi32(shuf1, count);
114
115 // Rearrange original and doubled rows 2 and 0.
116 idx = _mm256_set_epi32(5, 4, 3, 2, 2, 1, 0, 0);
117 __m256i shuf2 = _mm256_permutevar8x32_epi32(regi, idx);
118
119 // Right shift each row.
120 count = _mm256_set_epi32(22, 26, 30, 0, 20, 24, 28, 0);
121 __m256i shift3 = _mm256_srlv_epi32(shuf2, count);
122
123 // "Complete" the low half. Still more.
124 __m256i low_half = _mm256_or_si256(shift2, shift3);
125 low_half = _mm256_and_si256(low_half, _mm256_set1_epi32(0x3FFFu)); // Mask out the high half.
126
127 // Combine halves and clear space for an odd entry.
128 __m256i both = _mm256_or_si256(low_half, high_half);
129 both = _mm256_andnot_si256(_mm256_set_epi32(0, 0, 0, 0xFFFFu, 0, 0, 0, 0), both);
130
131 // There is a specific 16-bit entry that needs special handling.
132 // Align it.
133 __m256i shift4 = _mm256_srli_epi32(regi, 18);
134 // Mask it.
135 shift4 = _mm256_and_si256(_mm256_set_epi32(0, 0x3FFFu, 0, 0, 0, 0, 0, 0), shift4);
136
137 // Permute into the right spot
138 idx = _mm256_set_epi32(0, 0, 0, 6, 0, 0, 0, 0);
139 __m256i shuf3 = _mm256_permutevar8x32_epi32(shift4, idx);
140
141 // Add it in.
142 both = _mm256_or_si256(both, shuf3);
143 return both;
144}

◆ 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 101 of file TPGenerator.hpp.

101 {
102 // Max number of TPs for a channel: number of time samples / 2.
103 std::vector<dunedaq::trgdataformats::TriggerPrimitive> tp_aggr;
104 tp_aggr.reserve(T::s_num_channels * T::s_time_samples_per_frame / 2);
105
106 const typename T::word_t (*words_ptr)[T::s_bits_per_adc] = frame->adc_words;
107 const uint64_t timestamp = frame->get_timestamp();
108
109 const int register_alignment = T::s_bits_per_adc * m_num_channels_per_pipeline;
110 // Loop in time.
111 for (int t = 0; t < T::s_time_samples_per_frame; t++) {
112 const typename T::word_t *time_sample = *(words_ptr + t);
113 char* cursor = (char*) time_sample; // Need to walk in terms of bytes/bits.
114
115 // Loop in pipelines.
116 for (int p = 0; p < m_num_pipelines; p++) {
117 if (p == m_num_pipelines - 1)
118 cursor -= 4; // Take a step of 32 bit backwards for the last sub-frame.
119
120 __m256i regi = _mm256_lddqu_si256((__m256i*)cursor);
121
122 if (p == m_num_pipelines - 1) // Permute the row order to use the same operation.
123 regi = _mm256_permutevar8x32_epi32(regi, _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0));
124
125 __m256i expanded_subframe = expand_frame(regi);
126 std::vector<dunedaq::trgdataformats::TriggerPrimitive> tps = m_tpg_pipelines[p].process(expanded_subframe);
127
128 for (auto tp : tps) {
129 tp.time_start = (t - tp.samples_over_threshold) * m_sample_tick_difference + timestamp;
130 tp_aggr.push_back(tp);
131 }
132 cursor += register_alignment / 8; // Numerator is in bits. Need bytes.
133 }
134 }
135
136 return tp_aggr;
137 }
__m256i expand_frame(const __m256i &regi)

◆ set_metric_collector_enable_state()

void tpglibs::TPGenerator::set_metric_collector_enable_state ( bool state)
inline

Definition at line 72 of file TPGenerator.hpp.

72 {
74 }

◆ 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 73 of file TPGenerator.cpp.

73 {
74 m_sot_minima = sot_minima;
75}

◆ signal_metric_collection()

void tpglibs::TPGenerator::signal_metric_collection ( )

Definition at line 57 of file TPGenerator.cpp.

57 {
58 get_processor_metric_collector_ptr()->signal_collect();
59}

Member Data Documentation

◆ m_num_channels_per_pipeline

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

Definition at line 32 of file TPGenerator.hpp.

◆ m_num_pipelines

uint8_t tpglibs::TPGenerator::m_num_pipelines = 0
private

Definition at line 33 of file TPGenerator.hpp.

◆ m_processor_metric_collector_ptr

std::shared_ptr<ProcessorMetricCollector<__m256i> > tpglibs::TPGenerator::m_processor_metric_collector_ptr {nullptr}
private

Definition at line 37 of file TPGenerator.hpp.

37{nullptr};

◆ m_sample_tick_difference

int tpglibs::TPGenerator::m_sample_tick_difference
private

Definition at line 35 of file TPGenerator.hpp.

◆ m_sot_minima

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

Definition at line 36 of file TPGenerator.hpp.

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

◆ m_tpg_metric_collect_enabled

bool tpglibs::TPGenerator::m_tpg_metric_collect_enabled {false}
private

Definition at line 38 of file TPGenerator.hpp.

38{false};

◆ m_tpg_pipelines

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

Definition at line 34 of file TPGenerator.hpp.


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