|
24 | 24 | #include "GPUParam.h" |
25 | 25 | #include "DataFormatsTPC/ClusterNative.h" |
26 | 26 | #include "TPCClusterDecompressor.inc" |
| 27 | +#include "GPUTPCCompressionKernels.inc" |
27 | 28 | #include "TPCCalibration/VDriftHelper.h" |
28 | 29 |
|
29 | 30 | using namespace o2::framework; |
@@ -103,6 +104,7 @@ void EntropyEncoderSpec::run(ProcessingContext& pc) |
103 | 104 | auto& buffer = pc.outputs().make<std::vector<o2::ctf::BufferType>>(Output{"TPC", "CTFDATA", 0, Lifetime::Timeframe}); |
104 | 105 | std::vector<bool> rejectHits, rejectTracks, rejectTrackHits, rejectTrackHitsReduced; |
105 | 106 | CompressedClusters clustersFiltered = clusters; |
| 107 | + std::vector<std::pair<std::vector<unsigned int>, std::vector<unsigned short>>> tmpBuffer(std::max<int>(mNThreads, 1)); |
106 | 108 | if (mSelIR) { |
107 | 109 | mCTFCoder.setSelectedIRFrames(pc.inputs().get<gsl::span<o2::dataformats::IRFrame>>("selIRFrames")); |
108 | 110 | rejectHits.resize(clusters.nUnattachedClusters); |
@@ -169,29 +171,52 @@ void EntropyEncoderSpec::run(ProcessingContext& pc) |
169 | 171 | offset += (i * GPUCA_ROW_COUNT + j >= clusters.nSliceRows) ? 0 : clusters.nSliceRowClusters[i * GPUCA_ROW_COUNT + j]; |
170 | 172 | } |
171 | 173 | } |
| 174 | + |
172 | 175 | #ifdef WITH_OPENMP |
173 | | -#pragma omp parallel for num_threads(mNThreads) |
| 176 | +#pragma omp parallel for num_threads(mNThreads) schedule(static, (GPUCA_NSLICES + mNThreads - 1) / mNThreads) // Static round-robin scheduling with one chunk per thread to ensure correct order of the final vector |
174 | 177 | #endif |
175 | | - for (unsigned int i = 0; i < GPUCA_NSLICES; i++) { |
176 | | - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { |
177 | | - if (i * GPUCA_ROW_COUNT + j >= clusters.nSliceRows) { |
178 | | - break; |
179 | | - } |
180 | | - auto checker = [i, j, &rejectHits, &clustersFiltered](const o2::tpc::ClusterNative& cl, unsigned int k) { |
181 | | - if (false) { |
182 | | - rejectHits[k] = true; |
183 | | - static std::atomic_flag lock = ATOMIC_FLAG_INIT; |
184 | | - while (lock.test_and_set(std::memory_order_acquire)) { |
185 | | - } |
186 | | - clustersFiltered.nSliceRowClusters[i * GPUCA_ROW_COUNT + j]--; |
187 | | - clustersFiltered.nUnattachedClusters--; |
188 | | - lock.clear(std::memory_order_release); |
| 178 | + for (unsigned int ii = 0; ii < clusters.nSliceRows; ii++) { |
| 179 | + unsigned int i = ii / GPUCA_ROW_COUNT; |
| 180 | + unsigned int j = ii % GPUCA_ROW_COUNT; |
| 181 | + o2::tpc::ClusterNative preCl; |
| 182 | +#ifdef WITH_OPENMP |
| 183 | + int myThread = omp_get_thread_num(); |
| 184 | +#else |
| 185 | + int myThread = 0; |
| 186 | +#endif |
| 187 | + unsigned int count = 0; |
| 188 | + auto checker = [i, j, firstIR, totalT, this, &preCl, &count, &outBuffer = tmpBuffer[myThread], &rejectHits, &clustersFiltered](const o2::tpc::ClusterNative& cl, unsigned int k) { |
| 189 | + const auto chkVal = firstIR + (cl.getTime() * constants::LHCBCPERTIMEBIN); |
| 190 | + const auto chkExt = totalT * constants::LHCBCPERTIMEBIN; |
| 191 | + const bool reject = mCTFCoder.getIRFramesSelector().check(o2::dataformats::IRFrame(chkVal, chkVal + 1), chkExt, 0) < 0; |
| 192 | + if (reject) { |
| 193 | + rejectHits[k] = true; |
| 194 | + clustersFiltered.nSliceRowClusters[i * GPUCA_ROW_COUNT + j]--; |
| 195 | + static std::atomic_flag lock = ATOMIC_FLAG_INIT; |
| 196 | + while (lock.test_and_set(std::memory_order_acquire)) { |
189 | 197 | } |
190 | | - }; |
191 | | - unsigned int end = offsets[i][j] + clusters.nSliceRowClusters[i * GPUCA_ROW_COUNT + j]; |
192 | | - o2::gpu::TPCClusterDecompressor::decompressHits(&clusters, offsets[i][j], end, checker); |
193 | | - } |
| 198 | + clustersFiltered.nUnattachedClusters--; |
| 199 | + lock.clear(std::memory_order_release); |
| 200 | + } else { |
| 201 | + outBuffer.first.emplace_back(0); |
| 202 | + outBuffer.second.emplace_back(0); |
| 203 | + GPUTPCCompression_EncodeUnattached(clustersFiltered.nComppressionModes, cl, outBuffer.first.back(), outBuffer.second.back(), count++ ? &preCl : nullptr); |
| 204 | + preCl = cl; |
| 205 | + } |
| 206 | + }; |
| 207 | + unsigned int end = offsets[i][j] + clusters.nSliceRowClusters[i * GPUCA_ROW_COUNT + j]; |
| 208 | + o2::gpu::TPCClusterDecompressor::decompressHits(&clusters, offsets[i][j], end, checker); |
| 209 | + } |
| 210 | + tmpBuffer[0].first.reserve(clustersFiltered.nUnattachedClusters); |
| 211 | + tmpBuffer[0].second.reserve(clustersFiltered.nUnattachedClusters); |
| 212 | + for (int i = 1; i < mNThreads; i++) { |
| 213 | + tmpBuffer[0].first.insert(tmpBuffer[0].first.end(), tmpBuffer[i].first.begin(), tmpBuffer[i].first.end()); |
| 214 | + tmpBuffer[i].first.clear(); |
| 215 | + tmpBuffer[0].second.insert(tmpBuffer[0].second.end(), tmpBuffer[i].second.begin(), tmpBuffer[i].second.end()); |
| 216 | + tmpBuffer[i].second.clear(); |
194 | 217 | } |
| 218 | + clustersFiltered.timeDiffU = tmpBuffer[0].first.data(); |
| 219 | + clustersFiltered.padDiffU = tmpBuffer[0].second.data(); |
195 | 220 | } |
196 | 221 | auto iosize = mCTFCoder.encode(buffer, clusters, clustersFiltered, mSelIR ? &rejectHits : nullptr, mSelIR ? &rejectTracks : nullptr, mSelIR ? &rejectTrackHits : nullptr, mSelIR ? &rejectTrackHitsReduced : nullptr); |
197 | 222 | pc.outputs().snapshot({"ctfrep", 0}, iosize); |
|
0 commit comments