DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
TPGenerator.cpp
Go to the documentation of this file.
1
10
11namespace tpglibs {
12
13void
14TPGenerator::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 int sample_tick_difference) {
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));
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}
49
50std::shared_ptr<ProcessorMetricCollector<__m256i>> TPGenerator::get_processor_metric_collector_ptr() {
51 if (m_processor_metric_collector_ptr == nullptr) {
52 m_processor_metric_collector_ptr = std::make_shared<ProcessorMetricCollector<__m256i>>();
53 }
55}
56
60
61std::unordered_map<dunedaq::trgdataformats::channel_t, std::vector<std::pair<std::string, int16_t>>> TPGenerator::get_processor_metrics() {
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}
70
71
72void
73TPGenerator::set_sot_minima(const std::vector<uint16_t>& sot_minima) {
74 m_sot_minima = sot_minima;
75}
76
77
78__m256i
79TPGenerator::expand_frame(const __m256i& regi) {
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}
97
98__m256i
99TPGenerator::old_expand_frame(const __m256i& regi) {
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}
145
146
147} // namespace tpglibs
AVX typed TPG pipeline.
virtual void set_sot_minima(const std::vector< uint16_t > &sot_minima)
Set the samples over threshold minimum values.
virtual 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)
Configure the pieces to the pipeline.
std::shared_ptr< ProcessorMetricCollector< __m256i > > get_processor_metric_collector_ptr()
std::vector< uint16_t > m_sot_minima
void set_sot_minima(const std::vector< uint16_t > &sot_minima)
Set the minimum samples over threshold for a TP according to plane.
std::unordered_map< dunedaq::trgdataformats::channel_t, std::vector< std::pair< std::string, int16_t > > > get_processor_metrics()
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.
__m256i expand_frame(const __m256i &regi)
std::vector< AVXPipeline > m_tpg_pipelines
__m256i old_expand_frame(const __m256i &regi)
Expansion from 14-bit signals to 16-bit.
static const uint8_t m_num_channels_per_pipeline
std::shared_ptr< ProcessorMetricCollector< __m256i > > m_processor_metric_collector_ptr