Skip to content

Commit 7d55de1

Browse files
authored
FT0: new decoder, based on AVX512
1 parent 52175f2 commit 7d55de1

File tree

5 files changed

+726
-26
lines changed

5 files changed

+726
-26
lines changed

DataFormats/Detectors/FIT/common/include/DataFormatsFIT/Triggers.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ class Triggers
3030
{
3131
public:
3232
enum { bitA = 0,
33-
bitC = 1, // alias of bitAIn (FT0/FDD)
34-
bitAIn = 1, // alias of bitC (FV0)
35-
bitVertex = 2, // alias of bitAOut (FT0/FDD)
36-
bitAOut = 2, // alias of bitVertex (FV0)
33+
bitC = 1, // alias of bitAIn (FT0/FDD)
34+
bitAIn = 1, // alias of bitC (FV0)
35+
bitSCen = 2,
36+
bitAOut = 2, // alias of bitVertex (FV0)
3737
bitCen = 3,
38-
bitSCen = 4,
38+
bitVertex = 4, // alias of bitAOut (FT0/FDD)
3939
bitLaser = 5, // indicates the laser was triggered in this BC
4040
bitOutputsAreBlocked = 6, // indicates that laser-induced pulses should arrive from detector to FEE in this BC (and trigger outputs are blocked)
4141
bitDataIsValid = 7 };
@@ -44,7 +44,7 @@ class Triggers
4444
static const int16_t DEFAULT_ZERO = 0;
4545

4646
Triggers() = default;
47-
Triggers(uint8_t signals, int8_t chanA, int8_t chanC, int32_t aamplA, int32_t aamplC, int16_t atimeA, int16_t atimeC)
47+
Triggers(uint8_t signals, uint8_t chanA, uint8_t chanC, int32_t aamplA, int32_t aamplC, int16_t atimeA, int16_t atimeC)
4848
{
4949
triggersignals = signals;
5050
nChanA = chanA;
@@ -67,14 +67,14 @@ class Triggers
6767
bool getDataIsValid() const { return (triggersignals & (1 << bitDataIsValid)) != 0; }
6868

6969
int8_t getTriggersignals() const { return triggersignals; }
70-
int8_t getNChanA() const { return nChanA; }
71-
int8_t getNChanC() const { return nChanC; }
70+
uint8_t getNChanA() const { return nChanA; }
71+
uint8_t getNChanC() const { return nChanC; }
7272
int32_t getAmplA() const { return amplA; }
7373
int32_t getAmplC() const { return amplC; }
7474
int16_t getTimeA() const { return timeA; }
7575
int16_t getTimeC() const { return timeC; }
7676

77-
void setTriggers(uint8_t trgsig, int8_t chanA, int8_t chanC, int32_t aamplA, int32_t aamplC, int16_t atimeA, int16_t atimeC)
77+
void setTriggers(uint8_t trgsig, uint8_t chanA, uint8_t chanC, int32_t aamplA, int32_t aamplC, int16_t atimeA, int16_t atimeC)
7878
{
7979
triggersignals = trgsig;
8080
nChanA = chanA;
@@ -85,7 +85,7 @@ class Triggers
8585
timeC = atimeC;
8686
}
8787

88-
void setTriggers(Bool_t isA, Bool_t isC, Bool_t isVrtx, Bool_t isCnt, Bool_t isSCnt, int8_t chanA, int8_t chanC, int32_t aamplA,
88+
void setTriggers(Bool_t isA, Bool_t isC, Bool_t isVrtx, Bool_t isCnt, Bool_t isSCnt, uint8_t chanA, uint8_t chanC, int32_t aamplA,
8989
int32_t aamplC, int16_t atimeA, int16_t atimeC, Bool_t isLaser, Bool_t isOutputsAreBlocked, Bool_t isDataValid)
9090
{
9191
uint8_t trgsig = (isA << bitA) | (isC << bitC) | (isVrtx << bitVertex) | (isCnt << bitCen) | (isSCnt << bitSCen) | (isLaser << bitLaser) | (isOutputsAreBlocked << bitOutputsAreBlocked) | (isDataValid << bitDataIsValid);
@@ -112,14 +112,14 @@ class Triggers
112112

113113
public: // TODO: change to 'private' after modifying QC to use the setters/getters
114114
uint8_t triggersignals = DEFAULT_ZERO; // FIT trigger signals
115-
int8_t nChanA = DEFAULT_ZERO; // number of fired channels A side
116-
int8_t nChanC = DEFAULT_ZERO; // number of fired channels A side
115+
uint8_t nChanA = DEFAULT_ZERO; // number of fired channels A side
116+
uint8_t nChanC = DEFAULT_ZERO; // number of fired channels A side
117117
int32_t amplA = DEFAULT_AMP; // sum amplitude A side
118118
int32_t amplC = DEFAULT_AMP; // sum amplitude C side
119119
int16_t timeA = DEFAULT_TIME; // average time A side (shouldn't be used if nChanA == 0)
120120
int16_t timeC = DEFAULT_TIME; // average time C side (shouldn't be used if nChanC == 0)
121121

122-
ClassDefNV(Triggers, 4);
122+
ClassDefNV(Triggers, 5);
123123
};
124124

125125
} // namespace fit

Detectors/FIT/FT0/workflow/CMakeLists.txt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,36 @@
99
# granted to it by virtue of its status as an Intergovernmental Organization
1010
# or submit itself to any jurisdiction.
1111

12+
CHECK_CXX_COMPILER_FLAG("-mavx512f -mavx512vl -mavx512bw -mavx512dq" FT0_DECODER_AVX512_GOOD_FLAGS)
13+
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND FT0_DECODER_AVX512_GOOD_FLAGS)
14+
add_definitions(-DFT0_DECODER_AVX512)
15+
o2_add_library(FT0Workflow
16+
SOURCES src/RecoWorkflow.cxx
17+
src/ReconstructionSpec.cxx
18+
src/RecPointWriterSpec.cxx
19+
src/RecPointReaderSpec.cxx
20+
src/EntropyEncoderSpec.cxx
21+
src/EntropyDecoderSpec.cxx
22+
src/DigitReaderSpec.cxx
23+
src/FT0DigitWriterSpec.cxx
24+
src/RecoQCworkflow.cxx
25+
PUBLIC_LINK_LIBRARIES O2::DataFormatsFT0
26+
O2::FT0Reconstruction
27+
O2::FT0Raw
28+
O2::FT0Decoder
29+
O2::DetectorsCommonDataFormats
30+
O2::Framework
31+
O2::DPLUtils
32+
O2::DataFormatsGlobalTracking)
33+
o2_add_library(FT0Decoder
34+
SOURCES src/FT0DataDecoderDPLSpec.cxx
35+
PUBLIC_LINK_LIBRARIES O2::DataFormatsFT0
36+
O2::Framework
37+
O2::DetectorsCommonDataFormats
38+
O2::DPLUtils
39+
TARGETVARNAME targetDecoderAVX512)
40+
target_compile_options(${targetDecoderAVX512} PRIVATE -mavx512f -mavx512vl -mavx512bw -mavx512dq)
41+
else()
1242
o2_add_library(FT0Workflow
1343
SOURCES src/RecoWorkflow.cxx
1444
src/ReconstructionSpec.cxx
@@ -27,6 +57,8 @@ o2_add_library(FT0Workflow
2757
O2::DPLUtils
2858
O2::DataFormatsGlobalTracking)
2959

60+
endif()
61+
3062
o2_add_executable(reco-workflow
3163
SOURCES src/ft0-reco-workflow.cxx
3264
COMPONENT_NAME ft0
@@ -64,7 +96,6 @@ o2_add_executable(recpoints-reader-workflow
6496
SOURCES src/recpoints-reader-workflow.cxx
6597
COMPONENT_NAME ft0
6698
PUBLIC_LINK_LIBRARIES O2::FT0Workflow)
67-
6899
if(NOT APPLE)
69100

70101
set_property(TARGET ${fitrecoexe} PROPERTY LINK_WHAT_YOU_USE ON)
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// @file FT0DataDecoderDPLSpec.h
13+
14+
#if defined(__has_include)
15+
#if defined(__linux__) && (defined(__x86_64) || defined(__x86_64__)) && __has_include(<emmintrin.h>) && __has_include(<immintrin.h>) && defined(FT0_DECODER_AVX512)
16+
17+
#ifndef O2_FT0DATADECODERDPLSPEC_H
18+
#define O2_FT0DATADECODERPLSPEC_H
19+
#include "Framework/DataProcessorSpec.h"
20+
#include "Framework/Task.h"
21+
#include "Framework/CallbackService.h"
22+
#include "Framework/ConfigParamRegistry.h"
23+
#include "Framework/ControlService.h"
24+
#include "Framework/Lifetime.h"
25+
#include "Framework/Output.h"
26+
#include "Framework/WorkflowSpec.h"
27+
#include "Framework/SerializationMethods.h"
28+
#include "DPLUtils/DPLRawParser.h"
29+
#include "Framework/InputRecordWalker.h"
30+
#include <string>
31+
#include <iostream>
32+
#include <algorithm>
33+
#include <vector>
34+
#include <gsl/span>
35+
#include <chrono>
36+
#include "CommonUtils/VerbosityConfig.h"
37+
#include "DataFormatsFT0/Digit.h"
38+
#include "DataFormatsFT0/ChannelData.h"
39+
#include "DataFormatsFT0/LookUpTable.h"
40+
#include "DataFormatsFIT/Triggers.h"
41+
42+
using namespace o2::framework;
43+
44+
namespace o2
45+
{
46+
namespace ft0
47+
{
48+
class FT0DataDecoderDPLSpec : public Task
49+
{
50+
public:
51+
FT0DataDecoderDPLSpec() = default;
52+
~FT0DataDecoderDPLSpec() override = default;
53+
using Digit_t = o2::ft0::Digit;
54+
using ChannelData_t = o2::ft0::ChannelData;
55+
using LookupTable_t = o2::ft0::SingleLUT;
56+
static constexpr int sNorbits = 256;
57+
static constexpr int sNBC = 3564;
58+
static constexpr int sNlinksMax = 24;
59+
using NChDataBC_t = std::array<uint32_t, sNBC + 4>;
60+
using NChDataOrbitBC_t = std::array<NChDataBC_t, sNlinksMax>;
61+
std::array<std::array<uint32_t, 16>, sNlinksMax> mLUT;
62+
NChDataOrbitBC_t mPosChDataPerLinkOrbit[sNorbits];
63+
uint8_t mFEEID_TCM;
64+
void init(InitContext& ic) final
65+
{
66+
67+
auto ccdbUrl = ic.options().get<std::string>("ccdb-path");
68+
auto lutPath = ic.options().get<std::string>("lut-path");
69+
mVecDigits.resize(sNorbits * sNBC);
70+
mVecChannelData.resize(216 * sNorbits * sNBC);
71+
mVecTriggers.resize(sNBC);
72+
// mVecChannelDataBuf.resize(216*3564);
73+
mVecChannelDataBuf.resize(143);
74+
if (ccdbUrl != "") {
75+
LookupTable_t::setCCDBurl(ccdbUrl);
76+
}
77+
if (lutPath != "") {
78+
LookupTable_t::setLUTpath(lutPath);
79+
}
80+
LookupTable_t::Instance().printFullMap();
81+
82+
const auto& lut = LookupTable_t::Instance().getMapEntryPM2ChannelID();
83+
const auto& tcm = LookupTable_t::Instance().getEntryCRU_TCM();
84+
mFEEID_TCM = tcm.mLinkID + 12 * tcm.mEndPointID;
85+
std::array<uint32_t, 16> tmpChunk;
86+
std::fill_n(tmpChunk.begin(), 16, 0xff);
87+
std::fill_n(mLUT.begin(), 16, tmpChunk);
88+
for (const auto& entry : lut) {
89+
const auto& key = entry.first;
90+
const auto& value = entry.second;
91+
const auto feeID = key.mEntryCRU.mLinkID + 12 * key.mEntryCRU.mEndPointID;
92+
93+
if (feeID >= sNlinksMax || key.mLocalChannelID >= 16) {
94+
LOG(warning) << "Incorrect entry: " << key.mEntryCRU.mFEEID << " " << key.mLocalChannelID;
95+
} else {
96+
mLUT[feeID][key.mLocalChannelID] = value;
97+
}
98+
}
99+
}
100+
std::vector<o2::ft0::ChannelData> mVecChannelData;
101+
std::vector<std::array<o2::ft0::ChannelData, 25 * 216>> mVecChannelDataBuf; // buffer per orbit
102+
std::vector<o2::ft0::Digit> mVecDigits;
103+
std::vector<o2::fit::Triggers> mVecTriggers;
104+
void run(ProcessingContext& pc) final;
105+
};
106+
107+
framework::DataProcessorSpec getFT0DataDecoderDPLSpec(bool askSTFDist)
108+
{
109+
std::vector<OutputSpec> outputSpec;
110+
outputSpec.emplace_back(o2::header::gDataOriginFT0, "DIGITSBC", 0, Lifetime::Timeframe);
111+
outputSpec.emplace_back(o2::header::gDataOriginFT0, "DIGITSCH", 0, Lifetime::Timeframe);
112+
std::vector<InputSpec> inputSpec{{"STF", ConcreteDataTypeMatcher{"FT0", "RAWDATA"}, Lifetime::Optional}};
113+
if (askSTFDist) {
114+
inputSpec.emplace_back("STFDist", "FLP", "DISTSUBTIMEFRAME", 0, Lifetime::Timeframe);
115+
}
116+
std::string dataProcName = "ft0-datadecoder-dpl";
117+
LOG(info) << dataProcName;
118+
return DataProcessorSpec{
119+
dataProcName,
120+
inputSpec,
121+
outputSpec,
122+
adaptFromTask<FT0DataDecoderDPLSpec>(),
123+
{o2::framework::ConfigParamSpec{"ccdb-path", VariantType::String, "", {"CCDB url which contains LookupTable"}},
124+
o2::framework::ConfigParamSpec{"lut-path", VariantType::String, "", {"LookupTable path, e.g. FT0/LookupTable"}}}};
125+
}
126+
127+
} // namespace ft0
128+
} // namespace o2
129+
130+
#endif /* O2_FITDATAREADERDPL_H */
131+
#endif
132+
#endif

0 commit comments

Comments
 (0)